10c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* 20c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Copyright (C) 2012 The Android Open Source Project 30c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 40c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Licensed under the Apache License, Version 2.0 (the "License"); 50c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * you may not use this file except in compliance with the License. 60c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * You may obtain a copy of the License at 70c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 80c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * http://www.apache.org/licenses/LICENSE-2.0 90c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Unless required by applicable law or agreed to in writing, software 110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * distributed under the License is distributed on an "AS IS" BASIS, 120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * See the License for the specific language governing permissions and 140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * limitations under the License. 150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/*! \file LowerConst.cpp 190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen \brief This file lowers the following bytecodes: CONST_XXX 200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Functions are called from the lowered native sequence: 220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1> const_string_resolve 230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen INPUT: const pool index in %eax 240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OUTPUT: resolved string in %eax 250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen The only register that is still live after this function is ebx 260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2> class_resolve 270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen INPUT: const pool index in %eax 280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OUTPUT: resolved class in %eax 290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen The only register that is still live after this function is ebx 300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "libdex/DexOpcodes.h" 320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "libdex/DexFile.h" 330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "Lower.h" 340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "NcgAot.h" 350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "enc_wrapper.h" 360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#define P_GPR_1 PhysicalReg_EBX 380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#define P_GPR_2 PhysicalReg_ECX 390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! LOWER bytecode CONST_STRING without usage of helper function 410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! It calls const_string_resolve (%ebx is live across the call) 430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! Since the register allocator does not handle control flow within the lowered native sequence, 440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! we define an interface between the lowering module and register allocator: 450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! rememberState, gotoState, transferToState 460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! to make sure at the control flow merge point the state of registers is the same 470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint const_string_common_nohelper(u4 tmp, u2 vA) { 480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* for trace-based JIT, the string is already resolved since this code has been executed */ 490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen void *strPtr = (void*) 500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (currentMethod->clazz->pDvmDex->pResStrings[tmp]); 510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(strPtr != NULL); 520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA, OpndSize_32, (int) strPtr ); 530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! dispatcher to select either const_string_common_helper or const_string_common_nohelper 560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint const_string_common(u4 tmp, u2 vA) { 590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return const_string_common_nohelper(tmp, vA); 600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#undef P_GPR_1 620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#undef P_GPR_2 630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! lower bytecode CONST_4 650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint op_const_4() { 680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 vA = INST_A(inst); 690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen s4 tmp = (s4) (INST_B(inst) << 28) >> 28; 700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA, OpndSize_32, tmp); 710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC += 1; 720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 1; 730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! lower bytecode CONST_16 750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint op_const_16() { 780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 BBBB = FETCH(1); 790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 vA = INST_AA(inst); 800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA, OpndSize_32, (s2)BBBB); 810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC += 2; 820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 1; 830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! lower bytecode CONST 850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint op_const() { 880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 vA = INST_AA(inst); 890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u4 tmp = FETCH(1); 900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmp |= (u4)FETCH(2) << 16; 910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA, OpndSize_32, (s4)tmp); 920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC += 3; 930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 1; 940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! lower bytecode CONST_HIGH16 960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint op_const_high16() { 990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 vA = INST_AA(inst); 1000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 tmp = FETCH(1); 1010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA, OpndSize_32, (s4)tmp<<16); //?? 1020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC += 2; 1030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 1; 1040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! lower bytecode CONST_WIDE_16 1060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 1080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint op_const_wide_16() { 1090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 vA = INST_AA(inst); 1100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 tmp = FETCH(1); 1110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA, OpndSize_32, (s2)tmp); 1120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA+1, OpndSize_32, (s2)tmp>>31); 1130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC += 2; 1140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 2; 1150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! lower bytecode CONST_WIDE_32 1170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 1190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint op_const_wide_32() { 1200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 vA = INST_AA(inst); 1210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u4 tmp = FETCH(1); 1220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmp |= (u4)FETCH(2) << 16; 1230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA, OpndSize_32, (s4)tmp); 1240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA+1, OpndSize_32, (s4)tmp>>31); 1250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC += 3; 1260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 2; 1270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! lower bytecode CONST_WIDE 1290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 1310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint op_const_wide() { 1320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 vA = INST_AA(inst); 1330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u4 tmp = FETCH(1); 1340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmp |= (u8)FETCH(2) << 16; 1350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA, OpndSize_32, (s4)tmp); 1360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmp = (u8)FETCH(3); 1370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmp |= (u8)FETCH(4) << 16; 1380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA+1, OpndSize_32, (s4)tmp); 1390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC += 5; 1400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 2; 1410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! lower bytecode CONST_WIDE_HIGH16 1430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 1450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint op_const_wide_high16() { 1460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 vA = INST_AA(inst); 1470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 tmp = FETCH(1); 1480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA, OpndSize_32, 0); 1490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA+1, OpndSize_32, (s4)tmp<<16); 1500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC += 2; 1510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 2; 1520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! lower bytecode CONST_STRING 1540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 1560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint op_const_string() { 1570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 vB = FETCH(1); 1580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 vA = INST_AA(inst); 1590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u4 tmp = vB; 1600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int retval = const_string_common(tmp, vA); 1610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC += 2; 1620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return retval; 1630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! lower bytecode CONST_STRING_JUMBO 1650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 1670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint op_const_string_jumbo() { 1680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 vA = INST_AA(inst); 1690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u4 tmp = FETCH(1); 1700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmp |= (u4)FETCH(2) << 16; 1710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int retval = const_string_common(tmp, vA); 1720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC += 3; 1730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return retval; 1740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#define P_GPR_1 PhysicalReg_EBX 1770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! LOWER bytecode CONST_CLASS 1780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! It calls class_resolve (%ebx is live across the call) 1800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! Since the register allocator does not handle control flow within the lowered native sequence, 1810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! we define an interface between the lowering module and register allocator: 1820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! rememberState, gotoState, transferToState 1830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! to make sure at the control flow merge point the state of registers is the same 1840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint op_const_class() { 1850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 vA = INST_AA(inst); 1860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u4 tmp = (u4)FETCH(1); 1870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* for trace-based JIT, the class is already resolved since this code has been executed */ 1880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen void *classPtr = (void*) 1890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (currentMethod->clazz->pDvmDex->pResClasses[tmp]); 1900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(classPtr != NULL); 1910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm(vA, OpndSize_32, (int) classPtr ); 1920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC += 2; 1930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 1940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#undef P_GPR_1 1970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 198