Factory.cpp revision c6f1066fd2dd761349128a9f422bc1ce3c3de595
19bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee/* 29bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * Copyright (C) 2009 The Android Open Source Project 39bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * 49bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * Licensed under the Apache License, Version 2.0 (the "License"); 59bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * you may not use this file except in compliance with the License. 69bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * You may obtain a copy of the License at 79bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * 89bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * http://www.apache.org/licenses/LICENSE-2.0 99bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * 109bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * Unless required by applicable law or agreed to in writing, software 119bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * distributed under the License is distributed on an "AS IS" BASIS, 129bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * See the License for the specific language governing permissions and 149bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * limitations under the License. 159bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee */ 169bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 179bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee/* 189bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * This file contains codegen for the Thumb ISA and is intended to be 19270c1d64a192341be842f46734054c692bac061eBill Buzbee * includes by: 209bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * 219bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * Codegen-$(TARGET_ARCH_VARIANT).c 229bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * 239bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee */ 249bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int coreTemps[] = {r0, r1, r2, r3, r4PC, r7, r8, r9, r10, r11, r12}; 265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int corePreserved[] = {}; 275d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int fpTemps[] = {fr16, fr17, fr18, fr19, fr20, fr21, fr22, fr23, 28c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee fr24, fr25, fr26, fr27, fr28, fr29, fr30, fr31}; 295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int fpPreserved[] = {}; 305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeImmSingle(int value) 325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int res; 345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bitA = (value & 0x80000000) >> 31; 355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int notBitB = (value & 0x40000000) >> 30; 365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bitB = (value & 0x20000000) >> 29; 375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bSmear = (value & 0x3e000000) >> 25; 385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int slice = (value & 0x01f80000) >> 19; 395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int zeroes = (value & 0x0007ffff); 405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (zeroes != 0) 415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (bitB) { 435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if ((notBitB != 0) || (bSmear != 0x1f)) 445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if ((notBitB != 1) || (bSmear != 0x0)) 475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = (bitA << 7) | (bitB << 6) | slice; 505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadFPConstantValue(CompilationUnit *cUnit, int rDest, 545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int value) 555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int encodedImm = encodeImmSingle(value); 575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(SINGLEREG(rDest)); 585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (encodedImm >= 0) { 595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return newLIR2(cUnit, kThumb2Vmovs_IMM8, rDest, encodedImm); 605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *dataTarget = scanLiteralPool(cUnit, value, 0); 625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (dataTarget == NULL) { 635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dataTarget = addWordData(cUnit, value, false); 645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *loadPcRel = dvmCompilerNew(sizeof(ArmLIR), true); 665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->opCode = kThumb2Vldrs; 675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->generic.target = (LIR *) dataTarget; 685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->operands[0] = rDest; 695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->operands[1] = rpc; 705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(loadPcRel); 715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel); 725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return loadPcRel; 735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic int leadingZeros(u4 val) 761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee u4 alt; 781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int n; 791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int count; 801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee count = 16; 821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee n = 32; 831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee do { 841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee alt = val >> count; 851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (alt != 0) { 861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee n = n - count; 871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee val = alt; 881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee count >>= 1; 901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } while (count); 911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return n - val; 921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 939bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 949bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee/* 951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * Determine whether value can be encoded as a Thumb2 modified 961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * immediate. If not, return -1. If so, return i:imm3:a:bcdefgh form. 979bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee */ 981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic int modifiedImmediate(u4 value) 991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 1001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int zLeading; 1011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int zTrailing; 1021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee u4 b0 = value & 0xff; 1031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 1041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* Note: case of value==0 must use 0:000:0:0000000 encoding */ 1051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (value <= 0xFF) 1061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return b0; // 0:000:a:bcdefgh 1071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (value == ((b0 << 16) | b0)) 1081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return (0x1 << 8) | b0; /* 0:001:a:bcdefgh */ 1091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (value == ((b0 << 24) | (b0 << 16) | (b0 << 8) | b0)) 1101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return (0x3 << 8) | b0; /* 0:011:a:bcdefgh */ 1111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee b0 = (value >> 8) & 0xff; 1121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (value == ((b0 << 24) | (b0 << 8))) 1131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return (0x2 << 8) | b0; /* 0:010:a:bcdefgh */ 1141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* Can we do it with rotation? */ 1151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee zLeading = leadingZeros(value); 1161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee zTrailing = 32 - leadingZeros(~value & (value - 1)); 1171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* A run of eight or fewer active bits? */ 1181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if ((zLeading + zTrailing) < 24) 1191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return -1; /* No - bail */ 1201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* left-justify the constant, discarding msb (known to be 1) */ 1211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee value <<= zLeading + 1; 1221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* Create bcdefgh */ 1231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee value >>= 25; 1241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* Put it all together */ 1251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return value | ((0x8 + zLeading) << 7); /* [01000..11111]:bcdefgh */ 1261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 1279bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 1289bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee/* 1295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Load a immediate using a shortcut if possible; otherwise 1305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * grab from the per-translation literal pool. 1319bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee */ 1325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadConstantValue(CompilationUnit *cUnit, int rDest, int value) 1339bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{ 1345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *res; 1355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int modImm; 1369bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 1375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (FPREG(rDest)) { 1385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return loadFPConstantValue(cUnit, rDest, value); 1391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1409bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 1415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* See if the value can be constructed cheaply */ 1425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (LOWREG(rDest) && (value >= 0) && (value <= 255)) { 1435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return newLIR2(cUnit, kThumbMovImm, rDest, value); 1441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* Check Modified immediate special cases */ 1465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng modImm = modifiedImmediate(value); 1475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (modImm >= 0) { 1485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = newLIR2(cUnit, kThumb2MovImmShift, rDest, modImm); 1495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1509bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee } 1515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng modImm = modifiedImmediate(~value); 1525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (modImm >= 0) { 1535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = newLIR2(cUnit, kThumb2MvnImmShift, rDest, modImm); 1545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 155a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee } 1565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* 16-bit immediate? */ 1575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if ((value & 0xffff) == value) { 1585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = newLIR2(cUnit, kThumb2MovImm16, rDest, value); 1595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 160270c1d64a192341be842f46734054c692bac061eBill Buzbee } 1615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* No shortcut - go ahead and use literal pool */ 1625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *dataTarget = scanLiteralPool(cUnit, value, 255); 1635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (dataTarget == NULL) { 1645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dataTarget = addWordData(cUnit, value, false); 1655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *loadPcRel = dvmCompilerNew(sizeof(ArmLIR), true); 1675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->opCode = LOWREG(rDest) ? kThumbLdrPcRel : kThumb2LdrPcRel12; 1685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->generic.target = (LIR *) dataTarget; 1695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->operands[0] = rDest; 1705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(loadPcRel); 1715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = loadPcRel; 1725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel); 173270c1d64a192341be842f46734054c692bac061eBill Buzbee 1745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* 1755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * To save space in the constant pool, we use the ADD_RRI8 instruction to 1765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * add up to 255 to an existing constant value. 1775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 1785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (dataTarget->operands[0] != value) { 1795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opRegImm(cUnit, kOpAdd, rDest, value - dataTarget->operands[0]); 1807ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee } 1817ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return res; 1827ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee} 1837ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee 1845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* 1855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Load an immediate value into a fixed or temp register. Target 1865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * register is clobbered, and marked inUse. 1875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 1885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value) 1899bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{ 190c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee if (dvmCompilerIsTemp(cUnit, rDest)) { 191c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rDest); 192c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmcompilerMarkInUse(cUnit, rDest); 1935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return loadConstantValue(cUnit, rDest, value); 1959bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee} 1969bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 1971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opNone(CompilationUnit *cUnit, OpKind op) 1989bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{ 1991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmOpCode opCode = kThumbBkpt; 2001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (op) { 2011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpUncondBr: 2021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbBUncond; 203270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 204270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 205270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 206270c1d64a192341be842f46734054c692bac061eBill Buzbee } 2071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR0(cUnit, opCode); 2089bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee} 2099bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 2101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opCondBranch(CompilationUnit *cUnit, ArmConditionCode cc) 2119bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{ 2121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR2(cUnit, kThumbBCond, 0 /* offset to be patched */, cc); 2131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 2141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 2151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opImm(CompilationUnit *cUnit, OpKind op, int value) 2161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 2171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmOpCode opCode = kThumbBkpt; 2181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (op) { 2191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpPush: 2201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = ((value & 0xff00) != 0) ? kThumb2Push : kThumbPush; 221270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpPop: 2231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = ((value & 0xff00) != 0) ? kThumb2Pop : kThumbPop; 224270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 225270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 226270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 2279bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee } 2281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR1(cUnit, opCode, value); 229d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng} 230d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 2311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc) 232d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng{ 2331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmOpCode opCode = kThumbBkpt; 2341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (op) { 2351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpBlx: 2361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbBlxR; 2371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 2381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 2391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 240d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 2411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR1(cUnit, opCode, rDestSrc); 242d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng} 243d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 2441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegShift(CompilationUnit *cUnit, OpKind op, int rDestSrc1, 2451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rSrc2, int shift) 246270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 247270c1d64a192341be842f46734054c692bac061eBill Buzbee bool thumbForm = ((shift == 0) && LOWREG(rDestSrc1) && LOWREG(rSrc2)); 2481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmOpCode opCode = kThumbBkpt; 249270c1d64a192341be842f46734054c692bac061eBill Buzbee switch (op) { 2501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdc: 2511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbAdcRR : kThumb2AdcRRR; 252270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAnd: 2541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbAndRR : kThumb2AndRRR; 255270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpBic: 2571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbBicRR : kThumb2BicRRR; 258270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpCmn: 260270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 2611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbCmnRR : kThumb2CmnRR; 262270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpCmp: 264270c1d64a192341be842f46734054c692bac061eBill Buzbee if (thumbForm) 2651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbCmpRR; 266270c1d64a192341be842f46734054c692bac061eBill Buzbee else if ((shift == 0) && !LOWREG(rDestSrc1) && !LOWREG(rSrc2)) 2671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbCmpHH; 268270c1d64a192341be842f46734054c692bac061eBill Buzbee else if ((shift == 0) && LOWREG(rDestSrc1)) 2691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbCmpLH; 270270c1d64a192341be842f46734054c692bac061eBill Buzbee else if (shift == 0) 2711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbCmpHL; 272dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng else 2731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2CmpRR; 274270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpXor: 2761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbEorRR : kThumb2EorRRR; 277270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMov: 279270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 280270c1d64a192341be842f46734054c692bac061eBill Buzbee if (LOWREG(rDestSrc1) && LOWREG(rSrc2)) 2811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbMovRR; 282270c1d64a192341be842f46734054c692bac061eBill Buzbee else if (!LOWREG(rDestSrc1) && !LOWREG(rSrc2)) 2831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbMovRR_H2H; 284270c1d64a192341be842f46734054c692bac061eBill Buzbee else if (LOWREG(rDestSrc1)) 2851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbMovRR_H2L; 286270c1d64a192341be842f46734054c692bac061eBill Buzbee else 2871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbMovRR_L2H; 288270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMul: 290270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 2911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbMul : kThumb2MulRRR; 292270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMvn: 2941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbMvn : kThumb2MnvRR; 295270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpNeg: 297270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 2981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbNeg : kThumb2NegRR; 299270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpOr: 3011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbOrr : kThumb2OrrRRR; 302270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSbc: 3041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbSbc : kThumb2SbcRRR; 305270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpTst: 3071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbTst : kThumb2TstRR; 308270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsl: 310270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbLslRR : kThumb2LslRRR; 312270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsr: 314270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbLsrRR : kThumb2LsrRRR; 316270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAsr: 318270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbAsrRR : kThumb2AsrRRR; 320270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpRor: 322270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbRorRR : kThumb2RorRRR; 324270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdd: 3261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR; 327270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSub: 3291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR; 330270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOp2Byte: 332270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 8); 3341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOp2Short: 335270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 16); 3371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOp2Char: 338270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR4(cUnit, kThumb2Ubfx, rDestSrc1, rSrc2, 0, 16); 340270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 341270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 342270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 343270c1d64a192341be842f46734054c692bac061eBill Buzbee } 344270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(opCode >= 0); 345270c1d64a192341be842f46734054c692bac061eBill Buzbee if (EncodingMap[opCode].flags & IS_BINARY_OP) 346270c1d64a192341be842f46734054c692bac061eBill Buzbee return newLIR2(cUnit, opCode, rDestSrc1, rSrc2); 347270c1d64a192341be842f46734054c692bac061eBill Buzbee else if (EncodingMap[opCode].flags & IS_TERTIARY_OP) { 3481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (EncodingMap[opCode].fieldLoc[2].kind == kFmtShift) 349270c1d64a192341be842f46734054c692bac061eBill Buzbee return newLIR3(cUnit, opCode, rDestSrc1, rSrc2, shift); 350270c1d64a192341be842f46734054c692bac061eBill Buzbee else 351270c1d64a192341be842f46734054c692bac061eBill Buzbee return newLIR3(cUnit, opCode, rDestSrc1, rDestSrc1, rSrc2); 352270c1d64a192341be842f46734054c692bac061eBill Buzbee } else if (EncodingMap[opCode].flags & IS_QUAD_OP) 353270c1d64a192341be842f46734054c692bac061eBill Buzbee return newLIR4(cUnit, opCode, rDestSrc1, rDestSrc1, rSrc2, shift); 354270c1d64a192341be842f46734054c692bac061eBill Buzbee else { 355270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 356270c1d64a192341be842f46734054c692bac061eBill Buzbee return NULL; 357270c1d64a192341be842f46734054c692bac061eBill Buzbee } 358270c1d64a192341be842f46734054c692bac061eBill Buzbee} 359270c1d64a192341be842f46734054c692bac061eBill Buzbee 360270c1d64a192341be842f46734054c692bac061eBill Buzbeestatic ArmLIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1, 361270c1d64a192341be842f46734054c692bac061eBill Buzbee int rSrc2) 362270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 363270c1d64a192341be842f46734054c692bac061eBill Buzbee return opRegRegShift(cUnit, op, rDestSrc1, rSrc2, 0); 364270c1d64a192341be842f46734054c692bac061eBill Buzbee} 365270c1d64a192341be842f46734054c692bac061eBill Buzbee 3661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegRegShift(CompilationUnit *cUnit, OpKind op, 3671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rDest, int rSrc1, int rSrc2, int shift) 3681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 3691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmOpCode opCode = kThumbBkpt; 3701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumbForm = (shift == 0) && LOWREG(rDest) && LOWREG(rSrc1) && 3711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee LOWREG(rSrc2); 3721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (op) { 3731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdd: 3741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR; 3751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 3761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSub: 3771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR; 3781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 3791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdc: 3801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2AdcRRR; 3811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 3821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAnd: 3831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2AndRRR; 3841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 3851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpBic: 3861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2BicRRR; 3871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 3881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpXor: 3891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2EorRRR; 3901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 3911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMul: 3921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 3931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2MulRRR; 3941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 3951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpOr: 3961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2OrrRRR; 3971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 3981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSbc: 3991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2SbcRRR; 4001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsl: 4021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2LslRRR; 4041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsr: 4061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2LsrRRR; 4081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAsr: 4101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2AsrRRR; 4121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpRor: 4141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2RorRRR; 4161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 4181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 4191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 4211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(opCode >= 0); 4221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (EncodingMap[opCode].flags & IS_QUAD_OP) 4231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR4(cUnit, opCode, rDest, rSrc1, rSrc2, shift); 4241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else { 4251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(EncodingMap[opCode].flags & IS_TERTIARY_OP); 4261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, opCode, rDest, rSrc1, rSrc2); 4271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 4281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 4291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 4301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegReg(CompilationUnit *cUnit, OpKind op, int rDest, 4311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rSrc1, int rSrc2) 4321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 4331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return opRegRegRegShift(cUnit, op, rDest, rSrc1, rSrc2, 0); 4341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 4351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 4361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest, 4371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rSrc1, int value) 4381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 4391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 4401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool neg = (value < 0); 4411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int absValue = (neg) ? -value : value; 4421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmOpCode opCode = kThumbBkpt; 4431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmOpCode altOpCode = kThumbBkpt; 4441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = (LOWREG(rDest) && LOWREG(rSrc1)); 4451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int modImm = modifiedImmediate(value); 4461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int modImmNeg = modifiedImmediate(-value); 4471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 4481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch(op) { 4491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsl: 4501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs) 4511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbLslRRI5, rDest, rSrc1, value); 4521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 4531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumb2LslRRI5, rDest, rSrc1, value); 4541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsr: 4551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs) 4561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbLsrRRI5, rDest, rSrc1, value); 4571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 4581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumb2LsrRRI5, rDest, rSrc1, value); 4591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAsr: 4601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs) 4611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbAsrRRI5, rDest, rSrc1, value); 4621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 4631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumb2AsrRRI5, rDest, rSrc1, value); 4641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpRor: 4651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumb2RorRRI5, rDest, rSrc1, value); 4661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdd: 4671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(rDest) && (rSrc1 == 13) && 4681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (value <= 1020) && ((value & 0x3)==0)) { 4691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbAddSpRel, rDest, rSrc1, 4701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee value >> 2); 4711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (LOWREG(rDest) && (rSrc1 == rpc) && 4721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (value <= 1020) && ((value & 0x3)==0)) { 4731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbAddPcRel, rDest, rSrc1, 4741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee value >> 2); 4751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 4761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2AddRRI8; 4771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee altOpCode = kThumb2AddRRR; 4781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee // Note: intentional fallthrough 4791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSub: 4801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && ((absValue & 0x7) == absValue)) { 4811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (op == kOpAdd) 4821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (neg) ? kThumbSubRRI3 : kThumbAddRRI3; 4831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 4841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (neg) ? kThumbAddRRI3 : kThumbSubRRI3; 4851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, opCode, rDest, rSrc1, absValue); 4861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if ((absValue & 0xff) == absValue) { 4871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (op == kOpAdd) 4881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (neg) ? kThumb2SubRRI12 : kThumb2AddRRI12; 4891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 4901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (neg) ? kThumb2AddRRI12 : kThumb2SubRRI12; 4911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, opCode, rDest, rSrc1, absValue); 4921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 4931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (modImmNeg >= 0) { 4941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee op = (op == kOpAdd) ? kOpSub : kOpAdd; 4951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee modImm = modImmNeg; 4961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 4971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (op == kOpSub) { 4981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2SubRRI8; 4991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee altOpCode = kThumb2SubRRR; 5001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdc: 5031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2AdcRRI8; 5041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee altOpCode = kThumb2AdcRRR; 5051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSbc: 5071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2SbcRRI8; 5081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee altOpCode = kThumb2SbcRRR; 5091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpOr: 5111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2OrrRRI8; 5121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee altOpCode = kThumb2OrrRRR; 5131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAnd: 5151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2AndRRI8; 5161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee altOpCode = kThumb2AndRRR; 5171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpXor: 5191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2EorRRI8; 5201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee altOpCode = kThumb2EorRRR; 5211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMul: 5231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee //TUNING: power of 2, shift & add 5241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee modImm = -1; 5251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee altOpCode = kThumb2MulRRR; 5261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpCmp: { 5281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int modImm = modifiedImmediate(value); 5291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 5301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (modImm >= 0) { 5311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumb2CmpRI8, rSrc1, modImm); 5321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 533c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int rTmp = dvmCompilerAllocTemp(cUnit); 5341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadConstant(cUnit, rTmp, value); 5351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegReg(cUnit, kOpCmp, rSrc1, rTmp); 536c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, rTmp); 5371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 5391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 5411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 5421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 5441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (modImm >= 0) { 5451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, opCode, rDest, rSrc1, modImm); 5461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 547c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int rScratch = dvmCompilerAllocTemp(cUnit); 5481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee loadConstant(cUnit, rScratch, value); 5491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (EncodingMap[altOpCode].flags & IS_QUAD_OP) 5501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR4(cUnit, altOpCode, rDest, rSrc1, rScratch, 0); 5511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 5521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR3(cUnit, altOpCode, rDest, rSrc1, rScratch); 553c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, rScratch); 5541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 5551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 5571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 558270c1d64a192341be842f46734054c692bac061eBill Buzbee/* Handle Thumb-only variants here - otherwise punt to opRegRegImm */ 559270c1d64a192341be842f46734054c692bac061eBill Buzbeestatic ArmLIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1, 5601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int value) 561270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 562270c1d64a192341be842f46734054c692bac061eBill Buzbee ArmLIR *res; 563270c1d64a192341be842f46734054c692bac061eBill Buzbee bool neg = (value < 0); 564270c1d64a192341be842f46734054c692bac061eBill Buzbee int absValue = (neg) ? -value : value; 565270c1d64a192341be842f46734054c692bac061eBill Buzbee bool shortForm = (((absValue & 0xff) == absValue) && LOWREG(rDestSrc1)); 5661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmOpCode opCode = kThumbBkpt; 567270c1d64a192341be842f46734054c692bac061eBill Buzbee switch (op) { 5681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdd: 569270c1d64a192341be842f46734054c692bac061eBill Buzbee if ( !neg && (rDestSrc1 == 13) && (value <= 508)) { /* sp */ 570270c1d64a192341be842f46734054c692bac061eBill Buzbee assert((value & 0x3) == 0); 5711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR1(cUnit, kThumbAddSpI7, value >> 2); 572270c1d64a192341be842f46734054c692bac061eBill Buzbee } else if (shortForm) { 5731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (neg) ? kThumbSubRI8 : kThumbAddRI8; 574270c1d64a192341be842f46734054c692bac061eBill Buzbee } 575270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 5761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSub: 577270c1d64a192341be842f46734054c692bac061eBill Buzbee if (!neg && (rDestSrc1 == 13) && (value <= 508)) { /* sp */ 578270c1d64a192341be842f46734054c692bac061eBill Buzbee assert((value & 0x3) == 0); 5791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR1(cUnit, kThumbSubSpI7, value >> 2); 580270c1d64a192341be842f46734054c692bac061eBill Buzbee } else if (shortForm) { 5811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (neg) ? kThumbAddRI8 : kThumbSubRI8; 582270c1d64a192341be842f46734054c692bac061eBill Buzbee } 583270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 5841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpCmp: 585270c1d64a192341be842f46734054c692bac061eBill Buzbee if (LOWREG(rDestSrc1) && shortForm) 5861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (shortForm) ? kThumbCmpRI8 : kThumbCmpRR; 587270c1d64a192341be842f46734054c692bac061eBill Buzbee else if (LOWREG(rDestSrc1)) 5881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbCmpRR; 589270c1d64a192341be842f46734054c692bac061eBill Buzbee else { 590270c1d64a192341be842f46734054c692bac061eBill Buzbee shortForm = false; 5911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbCmpHL; 592270c1d64a192341be842f46734054c692bac061eBill Buzbee } 593270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 594270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 595270c1d64a192341be842f46734054c692bac061eBill Buzbee /* Punt to opRegRegImm - if bad case catch it there */ 596270c1d64a192341be842f46734054c692bac061eBill Buzbee shortForm = false; 597270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 598270c1d64a192341be842f46734054c692bac061eBill Buzbee } 599270c1d64a192341be842f46734054c692bac061eBill Buzbee if (shortForm) 600270c1d64a192341be842f46734054c692bac061eBill Buzbee return newLIR2(cUnit, opCode, rDestSrc1, absValue); 6011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else { 6021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value); 6031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 604270c1d64a192341be842f46734054c692bac061eBill Buzbee} 605270c1d64a192341be842f46734054c692bac061eBill Buzbee 6061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* 6075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Determine whether value can be encoded as a Thumb2 floating point 6085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * immediate. If not, return -1. If so return encoded 8-bit value. 6091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee */ 6105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeImmDoubleHigh(int value) 6111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 6125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int res; 6135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bitA = (value & 0x80000000) >> 31; 6145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int notBitB = (value & 0x40000000) >> 30; 6155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bitB = (value & 0x20000000) >> 29; 6165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bSmear = (value & 0x3fc00000) >> 22; 6175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int slice = (value & 0x003f0000) >> 16; 6185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int zeroes = (value & 0x0000ffff); 6195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (zeroes != 0) 6205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 6215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (bitB) { 6225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if ((notBitB != 0) || (bSmear != 0x1f)) 6235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 6241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 6255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if ((notBitB != 1) || (bSmear != 0x0)) 6265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 6271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 6285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = (bitA << 7) | (bitB << 6) | slice; 6295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 6305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 6311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 6325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeImmDouble(int valLo, int valHi) 6335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 6345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int res = -1; 6355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (valLo == 0) 6365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = encodeImmDoubleHigh(valHi); 6375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 6385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 6391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 6405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadConstantValueWide(CompilationUnit *cUnit, int rDestLo, 6415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int rDestHi, int valLo, int valHi) 6425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 6435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int encodedImm = encodeImmDouble(valLo, valHi); 6445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *res; 6455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (FPREG(rDestLo) && (encodedImm >= 0)) { 6465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = newLIR2(cUnit, kThumb2Vmovd_IMM8, S2D(rDestLo, rDestHi), 6475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng encodedImm); 6481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 6495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = loadConstantValue(cUnit, rDestLo, valLo); 6505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadConstantValue(cUnit, rDestHi, valHi); 6511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 6525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 6531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 6541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 6555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeShift(int code, int amount) { 6565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return ((amount & 0x1f) << 2) | code; 6571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 6581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 6591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase, 6601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rIndex, int rDest, int scale, OpSize size) 6611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 6621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rDest); 6639e45c0b968d63ea38353c99252d233879c2efdafjeffhao ArmLIR *load; 6641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmOpCode opCode = kThumbBkpt; 6651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumbForm = (allLowRegs && (scale == 0)); 6661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int regPtr; 6671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 6681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rDest)) { 6691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(SINGLEREG(rDest)); 6701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((size == kWord) || (size == kSingle)); 6711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2Vldrs; 6721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee size = kSingle; 6731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 6741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (size == kSingle) 6751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee size = kWord; 6761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 6771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 6781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 6791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 680c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee regPtr = dvmCompilerAllocTemp(cUnit); 6811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (scale) { 6821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex, 6831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodeShift(kArmLsl, scale)); 6841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 6851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex); 6861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 6879e45c0b968d63ea38353c99252d233879c2efdafjeffhao load = newLIR3(cUnit, opCode, rDest, regPtr, 0); 6889e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 6899e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 6909e45c0b968d63ea38353c99252d233879c2efdafjeffhao load->branchInsertSV = true; 6919e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 6929e45c0b968d63ea38353c99252d233879c2efdafjeffhao return load; 6931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 6941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbLdrRRR : kThumb2LdrRRR; 695270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 6961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 6971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbLdrhRRR : kThumb2LdrhRRR; 698270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 6991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 7001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbLdrshRRR : kThumb2LdrshRRR; 701270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 7031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbLdrbRRR : kThumb2LdrbRRR; 704270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 7061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbLdrsbRRR : kThumb2LdrsbRRR; 707270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 7091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 7101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumbForm) 7129e45c0b968d63ea38353c99252d233879c2efdafjeffhao load = newLIR3(cUnit, opCode, rDest, rBase, rIndex); 7131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 7149e45c0b968d63ea38353c99252d233879c2efdafjeffhao load = newLIR4(cUnit, opCode, rDest, rBase, rIndex, scale); 7159e45c0b968d63ea38353c99252d233879c2efdafjeffhao 7169e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 7179e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 7189e45c0b968d63ea38353c99252d233879c2efdafjeffhao load->branchInsertSV = true; 7199e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 7209e45c0b968d63ea38353c99252d233879c2efdafjeffhao return load; 7211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 7221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase, 7241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rIndex, int rSrc, int scale, OpSize size) 7251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 7261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rSrc); 7279e45c0b968d63ea38353c99252d233879c2efdafjeffhao ArmLIR *store; 7281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmOpCode opCode = kThumbBkpt; 7291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumbForm = (allLowRegs && (scale == 0)); 7301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int regPtr; 7311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rSrc)) { 7331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(SINGLEREG(rSrc)); 7341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((size == kWord) || (size == kSingle)); 7351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2Vstrs; 7361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee size = kSingle; 7371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 7381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (size == kSingle) 7391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee size = kWord; 7401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 7431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 744c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee regPtr = dvmCompilerAllocTemp(cUnit); 7451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (scale) { 7461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex, 7471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodeShift(kArmLsl, scale)); 7481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 7491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex); 7501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7519e45c0b968d63ea38353c99252d233879c2efdafjeffhao store = newLIR3(cUnit, opCode, rSrc, regPtr, 0); 7529e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 7539e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 7549e45c0b968d63ea38353c99252d233879c2efdafjeffhao store->branchInsertSV = true; 7559e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 7569e45c0b968d63ea38353c99252d233879c2efdafjeffhao return store; 7571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 7581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbStrRRR : kThumb2StrRRR; 759270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 7611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 7621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbStrhRRR : kThumb2StrhRRR; 763270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 7651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 7661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = (thumbForm) ? kThumbStrbRRR : kThumb2StrbRRR; 767270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 7691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 7701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumbForm) 7729e45c0b968d63ea38353c99252d233879c2efdafjeffhao store = newLIR3(cUnit, opCode, rSrc, rBase, rIndex); 7731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 7749e45c0b968d63ea38353c99252d233879c2efdafjeffhao store = newLIR4(cUnit, opCode, rSrc, rBase, rIndex, scale); 7759e45c0b968d63ea38353c99252d233879c2efdafjeffhao 7769e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 7779e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 7789e45c0b968d63ea38353c99252d233879c2efdafjeffhao store->branchInsertSV = true; 7799e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 7809e45c0b968d63ea38353c99252d233879c2efdafjeffhao return store; 7811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 7821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* 7841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * Load value from base + displacement. Optionally perform null check 7851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * on base (which must have an associated sReg and MIR). If not 7861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * performing null check, incoming MIR can be null. 7871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee */ 7881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase, 7891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rDest, int rDestHi, 7905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng OpSize size, int sReg) 7911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 7921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res, *load; 7931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmOpCode opCode = kThumbBkpt; 7941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool shortForm = false; 7951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumb2Form = (displacement < 4092 && displacement >= 0); 7961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int shortMax = 128; 7971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = (LOWREG(rBase) && LOWREG(rDest)); 7981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int encodedDisp = displacement; 7991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 8011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kDouble: 8021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kLong: 8031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rDest)) { 8041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (SINGLEREG(rDest)) { 8051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(FPREG(rDestHi)); 8061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee rDest = S2D(rDest, rDestHi); 8071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2Vldrd; 8091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 8101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 8121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 8141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 8151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, 8165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng -1, kWord, sReg); 8171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee loadBaseDispBody(cUnit, NULL, rBase, displacement + 4, rDestHi, 8185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng -1, kWord, INVALID_SREG); 8191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 8201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 8221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 8231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rDest)) { 8241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2Vldrs; 8251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 8261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 8281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 8301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(rDest) && (rBase == rpc) && 8321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (displacement <= 1020) && (displacement >= 0)) { 8331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 8351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbLdrPcRel; 8361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (LOWREG(rDest) && (rBase == r13) && 8371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (displacement <= 1020) && (displacement >= 0)) { 8381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 8401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbLdrSpRel; 8411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (allLowRegs && displacement < 128 && displacement >= 0) { 8421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x3) == 0); 8431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 8451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbLdrRRI5; 8461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 8471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2LdrRRI12; 8491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 850270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 8511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 8521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 64 && displacement >= 0) { 8531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x1) == 0); 8541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 1; 8561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbLdrhRRI5; 8571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (displacement < 4092 && displacement >= 0) { 8581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2LdrhRRI12; 8601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 861270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 8621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 8631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumb2Form) { 8641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2LdrshRRI12; 8661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 867270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 8681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 8691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 32 && displacement >= 0) { 8701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbLdrbRRI5; 8721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 8731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2LdrbRRI12; 8751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 876270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 8771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 8781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumb2Form) { 8791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2LdrsbRRI12; 8811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 882270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 883270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 884270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 885270c1d64a192341be842f46734054c692bac061eBill Buzbee } 8865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 8871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (shortForm) { 8881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee load = res = newLIR3(cUnit, opCode, rDest, rBase, encodedDisp); 8891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 890c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int regOffset = dvmCompilerAllocTemp(cUnit); 8911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadConstant(cUnit, regOffset, encodedDisp); 8921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee load = loadBaseIndexed(cUnit, rBase, regOffset, rDest, 0, size); 893c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, regOffset); 8941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (rBase == rFP) { 8971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee annotateDalvikRegAccess(load, displacement >> 2, true /* isLoad */); 898270c1d64a192341be842f46734054c692bac061eBill Buzbee } 8999e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 9009e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 9019e45c0b968d63ea38353c99252d233879c2efdafjeffhao load->branchInsertSV = true; 9029e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 9035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 904270c1d64a192341be842f46734054c692bac061eBill Buzbee} 905270c1d64a192341be842f46734054c692bac061eBill Buzbee 9061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase, 9071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rDest, OpSize size, 9085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int sReg) 909270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 9101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1, 9115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng size, sReg); 912270c1d64a192341be842f46734054c692bac061eBill Buzbee} 913270c1d64a192341be842f46734054c692bac061eBill Buzbee 9145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase, 915c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int displacement, int rDestLo, int rDestHi, 916c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int sReg) 917270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 9181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi, 9195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng kLong, sReg); 9201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 921270c1d64a192341be842f46734054c692bac061eBill Buzbee 9221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 9231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase, 924c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int displacement, int rSrc, int rSrcHi, 925c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee OpSize size) 9261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 9271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res, *store; 9281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmOpCode opCode = kThumbBkpt; 9291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool shortForm = false; 9301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumb2Form = (displacement < 4092 && displacement >= 0); 9311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int shortMax = 128; 9321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = (LOWREG(rBase) && LOWREG(rSrc)); 9331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int encodedDisp = displacement; 9341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 9351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 9361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kLong: 9371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kDouble: 9381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (!FPREG(rSrc)) { 9391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = storeBaseDispBody(cUnit, rBase, displacement, rSrc, 9401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee -1, kWord); 9411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee storeBaseDispBody(cUnit, rBase, displacement + 4, rSrcHi, 9421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee -1, kWord); 9431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 944270c1d64a192341be842f46734054c692bac061eBill Buzbee } 9451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (SINGLEREG(rSrc)) { 9461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(FPREG(rSrcHi)); 9471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee rSrc = S2D(rSrc, rSrcHi); 948270c1d64a192341be842f46734054c692bac061eBill Buzbee } 9491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2Vstrd; 9501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 9511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 953270c1d64a192341be842f46734054c692bac061eBill Buzbee } 954270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 9561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 9571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rSrc)) { 9581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(SINGLEREG(rSrc)); 9591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2Vstrs; 9601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 9611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 9631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 964270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 9661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 128 && displacement >= 0) { 9671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x3) == 0); 9681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 9701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbStrRRI5; 9711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 9721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2StrRRI12; 9741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 975270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 9771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 9781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 64 && displacement >= 0) { 9791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x1) == 0); 9801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 1; 9821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbStrhRRI5; 9831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 9841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumb2StrhRRI12; 9861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 987270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 9891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 9901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 32 && displacement >= 0) { 9911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opCode = kThumbStrbRRI5; 9931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 9941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 995964a7b06a9134947b5985c7f712d18d57ed665d2Bill Buzbee opCode = kThumb2StrbRRI12; 9961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 997270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 998270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 999270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 1000270c1d64a192341be842f46734054c692bac061eBill Buzbee } 10011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (shortForm) { 10021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee store = res = newLIR3(cUnit, opCode, rSrc, rBase, encodedDisp); 10031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 1004c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int rScratch = dvmCompilerAllocTemp(cUnit); 10051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadConstant(cUnit, rScratch, encodedDisp); 10061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee store = storeBaseIndexed(cUnit, rBase, rScratch, rSrc, 0, size); 1007c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, rScratch); 10081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 10091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (rBase == rFP) { 10111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee annotateDalvikRegAccess(store, displacement >> 2, false /* isLoad */); 10121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 10139e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 10149e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 10159e45c0b968d63ea38353c99252d233879c2efdafjeffhao store->branchInsertSV = true; 10169e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 10171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 10181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDisp(CompilationUnit *cUnit, int rBase, 10211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rSrc, OpSize size) 10221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size); 10241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase, 10271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rSrcLo, int rSrcHi) 10281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong); 10301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask) 10331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 10351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 10361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(rBase) && ((rMask & 0xff)==rMask)) { 10371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumbLdmia, rBase, rMask); 10381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 10391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumb2Ldmia, rBase, rMask); 10401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 10411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 10421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 10431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask) 10461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 10481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 10491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(rBase) && ((rMask & 0xff)==rMask)) { 10501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumbStmia, rBase, rMask); 10511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 10521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumb2Stmia, rBase, rMask); 10531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 10541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 10551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 10561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic void storePair(CompilationUnit *cUnit, int base, int lowReg, int highReg) 10591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee storeBaseDispWide(cUnit, base, 0, lowReg, highReg); 10611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg) 10641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadBaseDispWide(cUnit, NULL, base, 0, lowReg, highReg, INVALID_SREG); 10661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* 10701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * Perform a "reg cmp imm" operation and jump to the PCR region if condition 10711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * satisfies. 1072a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee */ 10731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *genRegImmCheck(CompilationUnit *cUnit, 1074c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee ArmConditionCode cond, int reg, 1075c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int checkValue, int dOffset, 1076c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee ArmLIR *pcrLabel) 1077a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee{ 10781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *branch; 10791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int modImm; 10801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* 10811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * TODO: re-enable usage of kThumb2Cbz & kThumb2Cbnz once assembler is 10821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * enhanced to allow us to replace code patterns when instructions don't 10831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * reach. Currently, CB[N]Z is causing too many assembler aborts. 10841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * What we want to do is emit the short forms, and then replace them with 10851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * longer versions when needed. 10861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee */ 1087a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee 10881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (0 && (LOWREG(reg)) && (checkValue == 0) && 10891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ((cond == kArmCondEq) || (cond == kArmCondNe))) { 10901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee branch = newLIR2(cUnit, 10911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (cond == kArmCondEq) ? kThumb2Cbz : kThumb2Cbnz, 10921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee reg, 0); 10931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 10941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee modImm = modifiedImmediate(checkValue); 10951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(reg) && ((checkValue & 0xff) == checkValue)) { 10961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR2(cUnit, kThumbCmpRI8, reg, checkValue); 10971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (modImm >= 0) { 10981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR2(cUnit, kThumb2CmpRI8, reg, modImm); 10991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 1100c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int tReg = dvmCompilerAllocTemp(cUnit); 11011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee loadConstant(cUnit, tReg, checkValue); 11021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegReg(cUnit, kOpCmp, reg, tReg); 11031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 11041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee branch = newLIR2(cUnit, kThumbBCond, 0, cond); 11051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 11061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return genCheckCommon(cUnit, dOffset, branch, pcrLabel); 1107a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee} 1108a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee 11095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) 1110270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 11115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR* res = dvmCompilerNew(sizeof(ArmLIR), true); 11125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[0] = rDest; 11135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[1] = rSrc; 11145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rDest == rSrc) { 11155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->isNop = true; 11165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 11175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(DOUBLEREG(rDest) == DOUBLEREG(rSrc)); 11185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (DOUBLEREG(rDest)) { 11195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->opCode = kThumb2Vmovd; 11205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 11215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (SINGLEREG(rDest)) { 11225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->opCode = SINGLEREG(rSrc) ? kThumb2Vmovs : kThumb2Fmsr; 11235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 11245d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(SINGLEREG(rSrc)); 11255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->opCode = kThumb2Fmrs; 11265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 11275d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 11285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[0] = rDest; 11295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[1] = rSrc; 11305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 11315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(res); 11325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1133270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1134270c1d64a192341be842f46734054c692bac061eBill Buzbee 11355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc) 1136270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 11375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR* res; 11385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmOpCode opCode; 11395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (FPREG(rDest) || FPREG(rSrc)) 11405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return fpRegCopy(cUnit, rDest, rSrc); 11415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = dvmCompilerNew(sizeof(ArmLIR), true); 11425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (LOWREG(rDest) && LOWREG(rSrc)) 11435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opCode = kThumbMovRR; 11445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng else if (!LOWREG(rDest) && !LOWREG(rSrc)) 11455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opCode = kThumbMovRR_H2H; 11465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng else if (LOWREG(rDest)) 11475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opCode = kThumbMovRR_H2L; 11485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng else 11495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opCode = kThumbMovRR_L2H; 1150270c1d64a192341be842f46734054c692bac061eBill Buzbee 11515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[0] = rDest; 11525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[1] = rSrc; 11535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->opCode = opCode; 11545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(res); 11555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rDest == rSrc) { 11565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->isNop = true; 11575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 11585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1159270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1160270c1d64a192341be842f46734054c692bac061eBill Buzbee 11615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR* genRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) 1162270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 11635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *res = genRegCopyNoInsert(cUnit, rDest, rSrc); 11645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dvmCompilerAppendLIR(cUnit, (LIR*)res); 11655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1166270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1167270c1d64a192341be842f46734054c692bac061eBill Buzbee 11685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi, 11695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int srcLo, int srcHi) 1170270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 11715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool destFP = FPREG(destLo) && FPREG(destHi); 11725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool srcFP = FPREG(srcLo) && FPREG(srcHi); 11735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(FPREG(srcLo) == FPREG(srcHi)); 11745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(FPREG(destLo) == FPREG(destHi)); 11755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (destFP) { 11765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (srcFP) { 11775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi)); 11785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 11795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, kThumb2Fmdrr, S2D(destLo, destHi), srcLo, srcHi); 11805d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 11815d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 11825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (srcFP) { 11835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, kThumb2Fmrrd, destLo, destHi, S2D(srcLo, srcHi)); 11845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 11855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Handle overlap 11865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (srcHi == destLo) { 11875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destHi, srcHi); 11885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destLo, srcLo); 11895d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 11905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destLo, srcLo); 11915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destHi, srcHi); 11925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 11935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 11945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1195270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1196