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 fpTemps[] = {fr16, fr17, fr18, fr19, fr20, fr21, fr22, fr23, 27c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee fr24, fr25, fr26, fr27, fr28, fr29, fr30, fr31}; 285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeImmSingle(int value) 305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int res; 325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bitA = (value & 0x80000000) >> 31; 335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int notBitB = (value & 0x40000000) >> 30; 345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bitB = (value & 0x20000000) >> 29; 355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bSmear = (value & 0x3e000000) >> 25; 365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int slice = (value & 0x01f80000) >> 19; 375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int zeroes = (value & 0x0007ffff); 385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (zeroes != 0) 395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (bitB) { 415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if ((notBitB != 0) || (bSmear != 0x1f)) 425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if ((notBitB != 1) || (bSmear != 0x0)) 455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = (bitA << 7) | (bitB << 6) | slice; 485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadFPConstantValue(CompilationUnit *cUnit, int rDest, 525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int value) 535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int encodedImm = encodeImmSingle(value); 555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(SINGLEREG(rDest)); 56c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee if (value == 0) { 57c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee // TODO: we need better info about the target CPU. a vector exclusive or 58c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee // would probably be better here if we could rely on its existance. 59c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee // Load an immediate +2.0 (which encodes to 0) 60c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee newLIR2(cUnit, kThumb2Vmovs_IMM8, rDest, 0); 61c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee // +0.0 = +2.0 - +2.0 62c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee return newLIR3(cUnit, kThumb2Vsubs, rDest, rDest, rDest); 63c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee } else if (encodedImm >= 0) { 645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return newLIR2(cUnit, kThumb2Vmovs_IMM8, rDest, encodedImm); 655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 66385828e36ea70effe9aa18a954d008b1f7dc1d63Ben Cheng ArmLIR *dataTarget = scanLiteralPool(cUnit->literalList, value, 0); 675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (dataTarget == NULL) { 68385828e36ea70effe9aa18a954d008b1f7dc1d63Ben Cheng dataTarget = addWordData(cUnit, &cUnit->literalList, value); 695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 70fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro ArmLIR *loadPcRel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 719a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein loadPcRel->opcode = kThumb2Vldrs; 725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->generic.target = (LIR *) dataTarget; 735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->operands[0] = rDest; 7420d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng loadPcRel->operands[1] = r15pc; 755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(loadPcRel); 76d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng setMemRefType(loadPcRel, true, kLiteral); 771f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee loadPcRel->aliasInfo = dataTarget->operands[0]; 785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel); 795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return loadPcRel; 805d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic int leadingZeros(u4 val) 831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee u4 alt; 851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int n; 861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int count; 871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee count = 16; 891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee n = 32; 901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee do { 911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee alt = val >> count; 921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (alt != 0) { 931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee n = n - count; 941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee val = alt; 951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee count >>= 1; 971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } while (count); 981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return n - val; 991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 1009bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 1019bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee/* 1021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * Determine whether value can be encoded as a Thumb2 modified 1031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * immediate. If not, return -1. If so, return i:imm3:a:bcdefgh form. 1049bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee */ 1051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic int modifiedImmediate(u4 value) 1061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 1071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int zLeading; 1081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int zTrailing; 1091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee u4 b0 = value & 0xff; 1101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 1111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* Note: case of value==0 must use 0:000:0:0000000 encoding */ 1121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (value <= 0xFF) 1131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return b0; // 0:000:a:bcdefgh 1141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (value == ((b0 << 16) | b0)) 1151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return (0x1 << 8) | b0; /* 0:001:a:bcdefgh */ 1161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (value == ((b0 << 24) | (b0 << 16) | (b0 << 8) | b0)) 1171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return (0x3 << 8) | b0; /* 0:011:a:bcdefgh */ 1181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee b0 = (value >> 8) & 0xff; 1191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (value == ((b0 << 24) | (b0 << 8))) 1201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return (0x2 << 8) | b0; /* 0:010:a:bcdefgh */ 1211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* Can we do it with rotation? */ 1221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee zLeading = leadingZeros(value); 1231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee zTrailing = 32 - leadingZeros(~value & (value - 1)); 1241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* A run of eight or fewer active bits? */ 1251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if ((zLeading + zTrailing) < 24) 1261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return -1; /* No - bail */ 1271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* left-justify the constant, discarding msb (known to be 1) */ 1281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee value <<= zLeading + 1; 1291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* Create bcdefgh */ 1301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee value >>= 25; 1311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* Put it all together */ 1321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return value | ((0x8 + zLeading) << 7); /* [01000..11111]:bcdefgh */ 1331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 1349bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 1359bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee/* 1365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Load a immediate using a shortcut if possible; otherwise 1375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * grab from the per-translation literal pool. 138bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng * 139bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng * No additional register clobbering operation performed. Use this version when 140bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng * 1) rDest is freshly returned from dvmCompilerAllocTemp or 141bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng * 2) The codegen is under fixed register usage 1429bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee */ 143bd1326d0e6b82a24ee80d50921e62152ea919151Ben Chengstatic ArmLIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest, 144bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng int value) 1459bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{ 1465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *res; 1475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int modImm; 1489bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 1495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (FPREG(rDest)) { 1505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return loadFPConstantValue(cUnit, rDest, value); 1511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1529bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 1535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* See if the value can be constructed cheaply */ 1545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (LOWREG(rDest) && (value >= 0) && (value <= 255)) { 1555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return newLIR2(cUnit, kThumbMovImm, rDest, value); 1561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* Check Modified immediate special cases */ 1585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng modImm = modifiedImmediate(value); 1595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (modImm >= 0) { 1605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = newLIR2(cUnit, kThumb2MovImmShift, rDest, modImm); 1615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1629bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee } 1635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng modImm = modifiedImmediate(~value); 1645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (modImm >= 0) { 1655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = newLIR2(cUnit, kThumb2MvnImmShift, rDest, modImm); 1665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 167a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee } 1685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* 16-bit immediate? */ 1695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if ((value & 0xffff) == value) { 1705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = newLIR2(cUnit, kThumb2MovImm16, rDest, value); 1715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 172270c1d64a192341be842f46734054c692bac061eBill Buzbee } 1735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* No shortcut - go ahead and use literal pool */ 174385828e36ea70effe9aa18a954d008b1f7dc1d63Ben Cheng ArmLIR *dataTarget = scanLiteralPool(cUnit->literalList, value, 0); 1755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (dataTarget == NULL) { 176385828e36ea70effe9aa18a954d008b1f7dc1d63Ben Cheng dataTarget = addWordData(cUnit, &cUnit->literalList, value); 1775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 178fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro ArmLIR *loadPcRel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 1799a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein loadPcRel->opcode = kThumb2LdrPcRel12; 1805d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->generic.target = (LIR *) dataTarget; 1815d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->operands[0] = rDest; 1825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(loadPcRel); 183d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng setMemRefType(loadPcRel, true, kLiteral); 1841f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee loadPcRel->aliasInfo = dataTarget->operands[0]; 1855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = loadPcRel; 1865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel); 187270c1d64a192341be842f46734054c692bac061eBill Buzbee 1885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* 1895d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * To save space in the constant pool, we use the ADD_RRI8 instruction to 1905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * add up to 255 to an existing constant value. 1915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 1925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (dataTarget->operands[0] != value) { 1935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opRegImm(cUnit, kOpAdd, rDest, value - dataTarget->operands[0]); 1947ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee } 1957ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return res; 1967ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee} 1977ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee 1985d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* 1995d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Load an immediate value into a fixed or temp register. Target 2005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * register is clobbered, and marked inUse. 2015d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 2025d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value) 2039bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{ 204c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee if (dvmCompilerIsTemp(cUnit, rDest)) { 205c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rDest); 2066a55513b0d268bc0721834050a3698316854fa0aElliott Hughes dvmCompilerMarkInUse(cUnit, rDest); 2075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 208bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng return loadConstantNoClobber(cUnit, rDest, value); 2099bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee} 2109bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 211fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng/* 212fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng * Load a class pointer value into a fixed or temp register. Target 213fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng * register is clobbered, and marked inUse. 214fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng */ 215fe108f779db4fb3bc720a92e69e58177983088c1Ben Chengstatic ArmLIR *loadClassPointer(CompilationUnit *cUnit, int rDest, int value) 216fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng{ 217fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng ArmLIR *res; 218fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng cUnit->hasClassLiterals = true; 219fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng if (dvmCompilerIsTemp(cUnit, rDest)) { 220fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng dvmCompilerClobber(cUnit, rDest); 221fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng dvmCompilerMarkInUse(cUnit, rDest); 222fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng } 223fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng ArmLIR *dataTarget = scanLiteralPool(cUnit->classPointerList, value, 0); 224fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng if (dataTarget == NULL) { 225fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng dataTarget = addWordData(cUnit, &cUnit->classPointerList, value); 226fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng /* Counts the number of class pointers in this translation */ 227fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng cUnit->numClassPointers++; 228fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng } 229fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng ArmLIR *loadPcRel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 230fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng loadPcRel->opcode = kThumb2LdrPcRel12; 231fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng loadPcRel->generic.target = (LIR *) dataTarget; 232fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng loadPcRel->operands[0] = rDest; 233fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng setupResourceMasks(loadPcRel); 234fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng setMemRefType(loadPcRel, true, kLiteral); 235fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng loadPcRel->aliasInfo = dataTarget->operands[0]; 236fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng res = loadPcRel; 237fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel); 238fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng return res; 239fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng} 240fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng 2411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opNone(CompilationUnit *cUnit, OpKind op) 2429bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{ 2439a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 2441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (op) { 2451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpUncondBr: 2469a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbBUncond; 247270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 248270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 249270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 250270c1d64a192341be842f46734054c692bac061eBill Buzbee } 2519a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR0(cUnit, opcode); 2529bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee} 2539bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 2541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opCondBranch(CompilationUnit *cUnit, ArmConditionCode cc) 2559bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{ 256bff121aa3e5d3c34caf837227cb00a46bf3f1966buzbee return newLIR2(cUnit, kThumb2BCond, 0 /* offset to be patched */, cc); 2571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 2581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 2591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opImm(CompilationUnit *cUnit, OpKind op, int value) 2601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 2619a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 2621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (op) { 26318c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng case kOpPush: { 26418c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng if ((value & 0xff00) == 0) { 26518c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng opcode = kThumbPush; 26620d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng } else if ((value & 0xff00) == (1 << r14lr)) { 26718c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng /* Thumb push can handle lr, which is encoded by bit 8 */ 26818c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng opcode = kThumbPush; 26918c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng value = (value & 0xff) | (1<<8); 27018c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } else { 27118c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng opcode = kThumb2Push; 27218c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } 273270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 27418c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } 27518c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng case kOpPop: { 27618c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng if ((value & 0xff00) == 0) { 27718c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng opcode = kThumbPop; 27820d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng } else if ((value & 0xff00) == (1 << r15pc)) { 27918c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng /* Thumb pop can handle pc, which is encoded by bit 8 */ 28018c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng opcode = kThumbPop; 28118c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng value = (value & 0xff) | (1<<8); 28218c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } else { 28318c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng opcode = kThumb2Pop; 28418c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } 285270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 28618c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } 287270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 288270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 2899bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee } 2909a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR1(cUnit, opcode, value); 291d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng} 292d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 2931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc) 294d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng{ 2959a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 2961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (op) { 2971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpBlx: 2989a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbBlxR; 2991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 3001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 3011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 302d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 3039a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR1(cUnit, opcode, rDestSrc); 304d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng} 305d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 3061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegShift(CompilationUnit *cUnit, OpKind op, int rDestSrc1, 3071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rSrc2, int shift) 308270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 309270c1d64a192341be842f46734054c692bac061eBill Buzbee bool thumbForm = ((shift == 0) && LOWREG(rDestSrc1) && LOWREG(rSrc2)); 3109a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 311270c1d64a192341be842f46734054c692bac061eBill Buzbee switch (op) { 3121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdc: 3139a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbAdcRR : kThumb2AdcRRR; 314270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAnd: 3169a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbAndRR : kThumb2AndRRR; 317270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpBic: 3199a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbBicRR : kThumb2BicRRR; 320270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpCmn: 322270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3239a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbCmnRR : kThumb2CmnRR; 324270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpCmp: 326270c1d64a192341be842f46734054c692bac061eBill Buzbee if (thumbForm) 3279a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbCmpRR; 328270c1d64a192341be842f46734054c692bac061eBill Buzbee else if ((shift == 0) && !LOWREG(rDestSrc1) && !LOWREG(rSrc2)) 3299a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbCmpHH; 330270c1d64a192341be842f46734054c692bac061eBill Buzbee else if ((shift == 0) && LOWREG(rDestSrc1)) 3319a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbCmpLH; 332270c1d64a192341be842f46734054c692bac061eBill Buzbee else if (shift == 0) 3339a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbCmpHL; 334dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng else 3359a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2CmpRR; 336270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpXor: 3389a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbEorRR : kThumb2EorRRR; 339270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMov: 341270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 342270c1d64a192341be842f46734054c692bac061eBill Buzbee if (LOWREG(rDestSrc1) && LOWREG(rSrc2)) 3439a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR; 344270c1d64a192341be842f46734054c692bac061eBill Buzbee else if (!LOWREG(rDestSrc1) && !LOWREG(rSrc2)) 3459a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_H2H; 346270c1d64a192341be842f46734054c692bac061eBill Buzbee else if (LOWREG(rDestSrc1)) 3479a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_H2L; 348270c1d64a192341be842f46734054c692bac061eBill Buzbee else 3499a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_L2H; 350270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMul: 352270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3539a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbMul : kThumb2MulRRR; 354270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMvn: 3569a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbMvn : kThumb2MnvRR; 357270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpNeg: 359270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3609a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbNeg : kThumb2NegRR; 361270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpOr: 3639a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbOrr : kThumb2OrrRRR; 364270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSbc: 3669a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbSbc : kThumb2SbcRRR; 367270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpTst: 3699a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbTst : kThumb2TstRR; 370270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsl: 372270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3739a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLslRR : kThumb2LslRRR; 374270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsr: 376270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3779a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLsrRR : kThumb2LsrRRR; 378270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAsr: 380270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3819a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbAsrRR : kThumb2AsrRRR; 382270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpRor: 384270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3859a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbRorRR : kThumb2RorRRR; 386270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdd: 3889a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR; 389270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSub: 3919a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR; 392270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOp2Byte: 394270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 8); 3961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOp2Short: 397270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 16); 3991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOp2Char: 400270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 4011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR4(cUnit, kThumb2Ubfx, rDestSrc1, rSrc2, 0, 16); 402270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 403270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 404270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 405270c1d64a192341be842f46734054c692bac061eBill Buzbee } 4069a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein assert(opcode >= 0); 4079a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein if (EncodingMap[opcode].flags & IS_BINARY_OP) 4089a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR2(cUnit, opcode, rDestSrc1, rSrc2); 4099a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein else if (EncodingMap[opcode].flags & IS_TERTIARY_OP) { 4109a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein if (EncodingMap[opcode].fieldLoc[2].kind == kFmtShift) 4119a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR3(cUnit, opcode, rDestSrc1, rSrc2, shift); 412270c1d64a192341be842f46734054c692bac061eBill Buzbee else 4139a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR3(cUnit, opcode, rDestSrc1, rDestSrc1, rSrc2); 4149a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein } else if (EncodingMap[opcode].flags & IS_QUAD_OP) 4159a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR4(cUnit, opcode, rDestSrc1, rDestSrc1, rSrc2, shift); 416270c1d64a192341be842f46734054c692bac061eBill Buzbee else { 417270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 418270c1d64a192341be842f46734054c692bac061eBill Buzbee return NULL; 419270c1d64a192341be842f46734054c692bac061eBill Buzbee } 420270c1d64a192341be842f46734054c692bac061eBill Buzbee} 421270c1d64a192341be842f46734054c692bac061eBill Buzbee 422270c1d64a192341be842f46734054c692bac061eBill Buzbeestatic ArmLIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1, 423270c1d64a192341be842f46734054c692bac061eBill Buzbee int rSrc2) 424270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 425270c1d64a192341be842f46734054c692bac061eBill Buzbee return opRegRegShift(cUnit, op, rDestSrc1, rSrc2, 0); 426270c1d64a192341be842f46734054c692bac061eBill Buzbee} 427270c1d64a192341be842f46734054c692bac061eBill Buzbee 4281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegRegShift(CompilationUnit *cUnit, OpKind op, 4291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rDest, int rSrc1, int rSrc2, int shift) 4301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 4319a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 4321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumbForm = (shift == 0) && LOWREG(rDest) && LOWREG(rSrc1) && 4331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee LOWREG(rSrc2); 4341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (op) { 4351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdd: 4369a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR; 4371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSub: 4399a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR; 4401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdc: 4429a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2AdcRRR; 4431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAnd: 4459a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2AndRRR; 4461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpBic: 4489a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2BicRRR; 4491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpXor: 4519a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2EorRRR; 4521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMul: 4541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4559a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2MulRRR; 4561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpOr: 4589a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2OrrRRR; 4591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSbc: 4619a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2SbcRRR; 4621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsl: 4641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4659a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LslRRR; 4661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsr: 4681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4699a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LsrRRR; 4701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAsr: 4721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4739a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2AsrRRR; 4741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpRor: 4761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4779a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2RorRRR; 4781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 4801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 4811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 4839a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein assert(opcode >= 0); 4849a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein if (EncodingMap[opcode].flags & IS_QUAD_OP) 4859a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR4(cUnit, opcode, rDest, rSrc1, rSrc2, shift); 4861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else { 4879a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein assert(EncodingMap[opcode].flags & IS_TERTIARY_OP); 4889a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR3(cUnit, opcode, rDest, rSrc1, rSrc2); 4891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 4901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 4911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 4921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegReg(CompilationUnit *cUnit, OpKind op, int rDest, 4931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rSrc1, int rSrc2) 4941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 4951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return opRegRegRegShift(cUnit, op, rDest, rSrc1, rSrc2, 0); 4961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 4971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 4981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest, 4991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rSrc1, int value) 5001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 5011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 5021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool neg = (value < 0); 5031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int absValue = (neg) ? -value : value; 5049a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 5059a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode altOpcode = kThumbBkpt; 5061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = (LOWREG(rDest) && LOWREG(rSrc1)); 5071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int modImm = modifiedImmediate(value); 5081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int modImmNeg = modifiedImmediate(-value); 5091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 5101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch(op) { 5111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsl: 5121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs) 5131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbLslRRI5, rDest, rSrc1, value); 5141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 5151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumb2LslRRI5, rDest, rSrc1, value); 5161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsr: 5171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs) 5181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbLsrRRI5, rDest, rSrc1, value); 5191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 5201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumb2LsrRRI5, rDest, rSrc1, value); 5211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAsr: 5221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs) 5231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbAsrRRI5, rDest, rSrc1, value); 5241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 5251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumb2AsrRRI5, rDest, rSrc1, value); 5261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpRor: 5271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumb2RorRRI5, rDest, rSrc1, value); 5281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdd: 52920d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng if (LOWREG(rDest) && (rSrc1 == r13sp) && 5301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (value <= 1020) && ((value & 0x3)==0)) { 5311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbAddSpRel, rDest, rSrc1, 5321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee value >> 2); 53320d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng } else if (LOWREG(rDest) && (rSrc1 == r15pc) && 5341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (value <= 1020) && ((value & 0x3)==0)) { 5351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbAddPcRel, rDest, rSrc1, 5361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee value >> 2); 5371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5389a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2AddRRI8; 5399a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2AddRRR; 5401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee // Note: intentional fallthrough 5411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSub: 5421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && ((absValue & 0x7) == absValue)) { 5431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (op == kOpAdd) 5449a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (neg) ? kThumbSubRRI3 : kThumbAddRRI3; 5451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 5469a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (neg) ? kThumbAddRRI3 : kThumbSubRRI3; 5479a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR3(cUnit, opcode, rDest, rSrc1, absValue); 5481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if ((absValue & 0xff) == absValue) { 5491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (op == kOpAdd) 5509a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (neg) ? kThumb2SubRRI12 : kThumb2AddRRI12; 5511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 5529a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (neg) ? kThumb2AddRRI12 : kThumb2SubRRI12; 5539a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR3(cUnit, opcode, rDest, rSrc1, absValue); 5541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (modImmNeg >= 0) { 5561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee op = (op == kOpAdd) ? kOpSub : kOpAdd; 5571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee modImm = modImmNeg; 5581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (op == kOpSub) { 5609a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2SubRRI8; 5619a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2SubRRR; 5621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdc: 5659a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2AdcRRI8; 5669a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2AdcRRR; 5671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSbc: 5699a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2SbcRRI8; 5709a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2SbcRRR; 5711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpOr: 5739a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2OrrRRI8; 5749a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2OrrRRR; 5751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAnd: 5779a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2AndRRI8; 5789a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2AndRRR; 5791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpXor: 5819a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2EorRRI8; 5829a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2EorRRR; 5831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMul: 5851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee //TUNING: power of 2, shift & add 5861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee modImm = -1; 5879a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2MulRRR; 5881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpCmp: { 5901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int modImm = modifiedImmediate(value); 5911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 5921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (modImm >= 0) { 5931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumb2CmpRI8, rSrc1, modImm); 5941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 595c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int rTmp = dvmCompilerAllocTemp(cUnit); 5961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadConstant(cUnit, rTmp, value); 5971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegReg(cUnit, kOpCmp, rSrc1, rTmp); 598c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, rTmp); 5991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 6001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 6011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 6021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 6031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 6041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 6051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 6061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (modImm >= 0) { 6079a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR3(cUnit, opcode, rDest, rSrc1, modImm); 6081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 609c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int rScratch = dvmCompilerAllocTemp(cUnit); 6101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee loadConstant(cUnit, rScratch, value); 6119a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein if (EncodingMap[altOpcode].flags & IS_QUAD_OP) 6129a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res = newLIR4(cUnit, altOpcode, rDest, rSrc1, rScratch, 0); 6131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 6149a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res = newLIR3(cUnit, altOpcode, rDest, rSrc1, rScratch); 615c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, rScratch); 6161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 6171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 6181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 6191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 620270c1d64a192341be842f46734054c692bac061eBill Buzbee/* Handle Thumb-only variants here - otherwise punt to opRegRegImm */ 621270c1d64a192341be842f46734054c692bac061eBill Buzbeestatic ArmLIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1, 6221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int value) 623270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 624270c1d64a192341be842f46734054c692bac061eBill Buzbee bool neg = (value < 0); 625270c1d64a192341be842f46734054c692bac061eBill Buzbee int absValue = (neg) ? -value : value; 626270c1d64a192341be842f46734054c692bac061eBill Buzbee bool shortForm = (((absValue & 0xff) == absValue) && LOWREG(rDestSrc1)); 6279a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 628270c1d64a192341be842f46734054c692bac061eBill Buzbee switch (op) { 6291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdd: 63020d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng if ( !neg && (rDestSrc1 == r13sp) && (value <= 508)) { /* sp */ 631270c1d64a192341be842f46734054c692bac061eBill Buzbee assert((value & 0x3) == 0); 6321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR1(cUnit, kThumbAddSpI7, value >> 2); 633270c1d64a192341be842f46734054c692bac061eBill Buzbee } else if (shortForm) { 6349a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (neg) ? kThumbSubRI8 : kThumbAddRI8; 635270c1d64a192341be842f46734054c692bac061eBill Buzbee } 636270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 6371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSub: 63820d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng if (!neg && (rDestSrc1 == r13sp) && (value <= 508)) { /* sp */ 639270c1d64a192341be842f46734054c692bac061eBill Buzbee assert((value & 0x3) == 0); 6401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR1(cUnit, kThumbSubSpI7, value >> 2); 641270c1d64a192341be842f46734054c692bac061eBill Buzbee } else if (shortForm) { 6429a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (neg) ? kThumbAddRI8 : kThumbSubRI8; 643270c1d64a192341be842f46734054c692bac061eBill Buzbee } 644270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 6451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpCmp: 646270c1d64a192341be842f46734054c692bac061eBill Buzbee if (LOWREG(rDestSrc1) && shortForm) 6479a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (shortForm) ? kThumbCmpRI8 : kThumbCmpRR; 648270c1d64a192341be842f46734054c692bac061eBill Buzbee else if (LOWREG(rDestSrc1)) 6499a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbCmpRR; 650270c1d64a192341be842f46734054c692bac061eBill Buzbee else { 651270c1d64a192341be842f46734054c692bac061eBill Buzbee shortForm = false; 6529a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbCmpHL; 653270c1d64a192341be842f46734054c692bac061eBill Buzbee } 654270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 655270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 656270c1d64a192341be842f46734054c692bac061eBill Buzbee /* Punt to opRegRegImm - if bad case catch it there */ 657270c1d64a192341be842f46734054c692bac061eBill Buzbee shortForm = false; 658270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 659270c1d64a192341be842f46734054c692bac061eBill Buzbee } 660270c1d64a192341be842f46734054c692bac061eBill Buzbee if (shortForm) 6619a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR2(cUnit, opcode, rDestSrc1, absValue); 6621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else { 6631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value); 6641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 665270c1d64a192341be842f46734054c692bac061eBill Buzbee} 666270c1d64a192341be842f46734054c692bac061eBill Buzbee 6671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* 6685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Determine whether value can be encoded as a Thumb2 floating point 6695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * immediate. If not, return -1. If so return encoded 8-bit value. 6701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee */ 6715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeImmDoubleHigh(int value) 6721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 6735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int res; 6745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bitA = (value & 0x80000000) >> 31; 6755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int notBitB = (value & 0x40000000) >> 30; 6765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bitB = (value & 0x20000000) >> 29; 6775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bSmear = (value & 0x3fc00000) >> 22; 6785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int slice = (value & 0x003f0000) >> 16; 6795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int zeroes = (value & 0x0000ffff); 6805d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (zeroes != 0) 6815d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 6825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (bitB) { 6835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if ((notBitB != 0) || (bSmear != 0x1f)) 6845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 6851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 6865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if ((notBitB != 1) || (bSmear != 0x0)) 6875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 6881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 6895d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = (bitA << 7) | (bitB << 6) | slice; 6905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 6915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 6921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 6935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeImmDouble(int valLo, int valHi) 6945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 6955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int res = -1; 6965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (valLo == 0) 6975d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = encodeImmDoubleHigh(valHi); 6985d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 6995d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 7001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7015d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadConstantValueWide(CompilationUnit *cUnit, int rDestLo, 7025d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int rDestHi, int valLo, int valHi) 7035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 7045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int encodedImm = encodeImmDouble(valLo, valHi); 7055d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *res; 706c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee int targetReg = S2D(rDestLo, rDestHi); 707c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee if (FPREG(rDestLo)) { 708c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee if ((valLo == 0) && (valHi == 0)) { 709c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee // TODO: we need better info about the target CPU. a vector 710c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee // exclusive or would probably be better here if we could rely on 711c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee // its existance. 712c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee // Load an immediate +2.0 (which encodes to 0) 713c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee newLIR2(cUnit, kThumb2Vmovd_IMM8, targetReg, 0); 714c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee // +0.0 = +2.0 - +2.0 715c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee res = newLIR3(cUnit, kThumb2Vsubd, targetReg, targetReg, targetReg); 716c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee } else if (encodedImm >= 0) { 717c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee res = newLIR2(cUnit, kThumb2Vmovd_IMM8, targetReg, encodedImm); 718c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee } else { 719c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee ArmLIR* dataTarget = scanLiteralPoolWide(cUnit->literalList, valLo, valHi); 720c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee if (dataTarget == NULL) { 721c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee dataTarget = addWideData(cUnit, &cUnit->literalList, valLo, valHi); 722c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee } 723c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee ArmLIR *loadPcRel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 724c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee loadPcRel->opcode = kThumb2Vldrd; 725c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee loadPcRel->generic.target = (LIR *) dataTarget; 726c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee loadPcRel->operands[0] = targetReg; 727c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee loadPcRel->operands[1] = r15pc; 728c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee setupResourceMasks(loadPcRel); 729c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee setMemRefType(loadPcRel, true, kLiteral); 730c1757a6deab0ca0bfd42c38612d92b2f26c41dbebuzbee // TODO: rework literal load disambiguation to more cleanly handle 64-bit loads 731c1757a6deab0ca0bfd42c38612d92b2f26c41dbebuzbee loadPcRel->aliasInfo = (uintptr_t)dataTarget; 732c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel); 733c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee res = loadPcRel; 734c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee } 7351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 736bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng res = loadConstantNoClobber(cUnit, rDestLo, valLo); 737bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng loadConstantNoClobber(cUnit, rDestHi, valHi); 7381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 7401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 7411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeShift(int code, int amount) { 7435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return ((amount & 0x1f) << 2) | code; 7441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 7451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase, 7471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rIndex, int rDest, int scale, OpSize size) 7481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 7491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rDest); 7509e45c0b968d63ea38353c99252d233879c2efdafjeffhao ArmLIR *load; 7519a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 7521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumbForm = (allLowRegs && (scale == 0)); 7531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int regPtr; 7541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rDest)) { 7561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(SINGLEREG(rDest)); 7571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((size == kWord) || (size == kSingle)); 7589a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vldrs; 7591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee size = kSingle; 7601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 7611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (size == kSingle) 7621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee size = kWord; 7631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 7661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 767c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee regPtr = dvmCompilerAllocTemp(cUnit); 7681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (scale) { 7691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex, 7701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodeShift(kArmLsl, scale)); 7711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 7721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex); 7731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7749a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein load = newLIR3(cUnit, opcode, rDest, regPtr, 0); 7759e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 7769e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 777d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng load->flags.insertWrapper = true; 7789e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 7799e45c0b968d63ea38353c99252d233879c2efdafjeffhao return load; 7801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 7819a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrRRR : kThumb2LdrRRR; 782270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 7849a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrhRRR : kThumb2LdrhRRR; 785270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 7879a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrshRRR : kThumb2LdrshRRR; 788270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 7909a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrbRRR : kThumb2LdrbRRR; 791270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 7939a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrsbRRR : kThumb2LdrsbRRR; 794270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 7961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 7971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumbForm) 7999a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein load = newLIR3(cUnit, opcode, rDest, rBase, rIndex); 8001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 8019a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein load = newLIR4(cUnit, opcode, rDest, rBase, rIndex, scale); 8029e45c0b968d63ea38353c99252d233879c2efdafjeffhao 8039e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 8049e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 805d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng load->flags.insertWrapper = true; 8069e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 8079e45c0b968d63ea38353c99252d233879c2efdafjeffhao return load; 8081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 8091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase, 8111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rIndex, int rSrc, int scale, OpSize size) 8121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 8131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rSrc); 8149e45c0b968d63ea38353c99252d233879c2efdafjeffhao ArmLIR *store; 8159a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 8161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumbForm = (allLowRegs && (scale == 0)); 8171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int regPtr; 8181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rSrc)) { 8201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(SINGLEREG(rSrc)); 821749e8162846b9dec5418d4d8f2334e683af81d52Bill Buzbee assert((size == kWord) || (size == kSingle)); 8229a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vstrs; 823749e8162846b9dec5418d4d8f2334e683af81d52Bill Buzbee size = kSingle; 8241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 8251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (size == kSingle) 8261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee size = kWord; 8271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 8301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 831c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee regPtr = dvmCompilerAllocTemp(cUnit); 8321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (scale) { 8331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex, 8341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodeShift(kArmLsl, scale)); 8351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 8361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex); 8371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8389a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein store = newLIR3(cUnit, opcode, rSrc, regPtr, 0); 8399e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 8409e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 841d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng store->flags.insertWrapper = true; 8429e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 8439e45c0b968d63ea38353c99252d233879c2efdafjeffhao return store; 8441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 8459a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbStrRRR : kThumb2StrRRR; 846270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 8471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 8481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 8499a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbStrhRRR : kThumb2StrhRRR; 850270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 8511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 8521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 8539a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbStrbRRR : kThumb2StrbRRR; 854270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 8551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 8561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 8571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumbForm) 8599a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein store = newLIR3(cUnit, opcode, rSrc, rBase, rIndex); 8601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 8619a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein store = newLIR4(cUnit, opcode, rSrc, rBase, rIndex, scale); 8629e45c0b968d63ea38353c99252d233879c2efdafjeffhao 8639e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 8649e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 865d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng store->flags.insertWrapper = true; 8669e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 8679e45c0b968d63ea38353c99252d233879c2efdafjeffhao return store; 8681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 8691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* 8711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * Load value from base + displacement. Optionally perform null check 8721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * on base (which must have an associated sReg and MIR). If not 8731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * performing null check, incoming MIR can be null. 8741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee */ 8751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase, 8761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rDest, int rDestHi, 8775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng OpSize size, int sReg) 8781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 8791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res, *load; 8809a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 8811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool shortForm = false; 8821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumb2Form = (displacement < 4092 && displacement >= 0); 8831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = (LOWREG(rBase) && LOWREG(rDest)); 8841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int encodedDisp = displacement; 8851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 8871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kDouble: 8881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kLong: 8891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rDest)) { 8901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (SINGLEREG(rDest)) { 8911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(FPREG(rDestHi)); 8921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee rDest = S2D(rDest, rDestHi); 8931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8949a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vldrd; 8951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 8961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 8981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 9001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 9011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, 9025d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng -1, kWord, sReg); 9031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee loadBaseDispBody(cUnit, NULL, rBase, displacement + 4, rDestHi, 9045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng -1, kWord, INVALID_SREG); 9051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 9061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 9071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 9081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 9091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rDest)) { 9109a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vldrs; 9111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 9121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 9141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 9151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 9161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 91720d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng if (LOWREG(rDest) && (rBase == r15pc) && 9181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (displacement <= 1020) && (displacement >= 0)) { 9191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 9219a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrPcRel; 92220d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng } else if (LOWREG(rDest) && (rBase == r13sp) && 9231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (displacement <= 1020) && (displacement >= 0)) { 9241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 9269a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrSpRel; 9271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (allLowRegs && displacement < 128 && displacement >= 0) { 9281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x3) == 0); 9291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 9319a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrRRI5; 9321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 9331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9349a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrRRI12; 9351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 936270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 9381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 64 && displacement >= 0) { 9391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x1) == 0); 9401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 1; 9429a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrhRRI5; 9431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (displacement < 4092 && displacement >= 0) { 9441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9459a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrhRRI12; 9461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 947270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 9491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumb2Form) { 9501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9519a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrshRRI12; 9521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 953270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 9551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 32 && displacement >= 0) { 9561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9579a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrbRRI5; 9581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 9591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9609a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrbRRI12; 9611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 962270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 9641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumb2Form) { 9651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9669a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrsbRRI12; 9671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 968270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 969270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 970270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 971270c1d64a192341be842f46734054c692bac061eBill Buzbee } 9725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 9731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (shortForm) { 9749a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein load = res = newLIR3(cUnit, opcode, rDest, rBase, encodedDisp); 9751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 976c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int regOffset = dvmCompilerAllocTemp(cUnit); 9771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadConstant(cUnit, regOffset, encodedDisp); 9781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee load = loadBaseIndexed(cUnit, rBase, regOffset, rDest, 0, size); 979c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, regOffset); 9801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 9811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 98220d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng if (rBase == r5FP) { 9831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee annotateDalvikRegAccess(load, displacement >> 2, true /* isLoad */); 984270c1d64a192341be842f46734054c692bac061eBill Buzbee } 9859e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 9869e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 987d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng load->flags.insertWrapper = true; 9889e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 989fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng return load; 990270c1d64a192341be842f46734054c692bac061eBill Buzbee} 991270c1d64a192341be842f46734054c692bac061eBill Buzbee 9921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase, 9931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rDest, OpSize size, 9945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int sReg) 995270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 9961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1, 9975d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng size, sReg); 998270c1d64a192341be842f46734054c692bac061eBill Buzbee} 999270c1d64a192341be842f46734054c692bac061eBill Buzbee 10005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase, 1001c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int displacement, int rDestLo, int rDestHi, 1002c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int sReg) 1003270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 10041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi, 10055d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng kLong, sReg); 10061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 1007270c1d64a192341be842f46734054c692bac061eBill Buzbee 10081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase, 1010c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int displacement, int rSrc, int rSrcHi, 1011c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee OpSize size) 10121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res, *store; 10149a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 10151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool shortForm = false; 10161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumb2Form = (displacement < 4092 && displacement >= 0); 10171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = (LOWREG(rBase) && LOWREG(rSrc)); 10181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int encodedDisp = displacement; 10191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 10211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kLong: 10221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kDouble: 10231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (!FPREG(rSrc)) { 10241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = storeBaseDispBody(cUnit, rBase, displacement, rSrc, 10251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee -1, kWord); 10261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee storeBaseDispBody(cUnit, rBase, displacement + 4, rSrcHi, 10271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee -1, kWord); 10281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 1029270c1d64a192341be842f46734054c692bac061eBill Buzbee } 10301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (SINGLEREG(rSrc)) { 10311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(FPREG(rSrcHi)); 10321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee rSrc = S2D(rSrc, rSrcHi); 1033270c1d64a192341be842f46734054c692bac061eBill Buzbee } 10349a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vstrd; 10351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 10361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 1038270c1d64a192341be842f46734054c692bac061eBill Buzbee } 1039270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 10401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 10411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 10421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rSrc)) { 10431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(SINGLEREG(rSrc)); 10449a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vstrs; 10451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 10461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 10481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1049270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 10501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 10511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 128 && displacement >= 0) { 10521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x3) == 0); 10531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 10559a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbStrRRI5; 10561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 10571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10589a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2StrRRI12; 10591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1060270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 10611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 10621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 10631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 64 && displacement >= 0) { 10641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x1) == 0); 10651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 1; 10679a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbStrhRRI5; 10681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 10691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10709a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2StrhRRI12; 10711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1072270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 10731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 10741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 10751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 32 && displacement >= 0) { 10761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10779a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbStrbRRI5; 10781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 10791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10809a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2StrbRRI12; 10811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1082270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 1083270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 1084270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 1085270c1d64a192341be842f46734054c692bac061eBill Buzbee } 10861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (shortForm) { 10879a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein store = res = newLIR3(cUnit, opcode, rSrc, rBase, encodedDisp); 10881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 1089c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int rScratch = dvmCompilerAllocTemp(cUnit); 10901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadConstant(cUnit, rScratch, encodedDisp); 10911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee store = storeBaseIndexed(cUnit, rBase, rScratch, rSrc, 0, size); 1092c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, rScratch); 10931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 10941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 109520d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng if (rBase == r5FP) { 10961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee annotateDalvikRegAccess(store, displacement >> 2, false /* isLoad */); 10971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 10989e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 10999e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 1100d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng store->flags.insertWrapper = true; 11019e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 11021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 11031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDisp(CompilationUnit *cUnit, int rBase, 11061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rSrc, OpSize size) 11071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 11081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size); 11091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase, 11121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rSrcLo, int rSrcHi) 11131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 11141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong); 11151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask) 11181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 11191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 11201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 11211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(rBase) && ((rMask & 0xff)==rMask)) { 11221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumbLdmia, rBase, rMask); 11231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 11241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumb2Ldmia, rBase, rMask); 11251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1126121ea790080b5a6bb713a07452c19f87d209de48jeffhao#if defined(WITH_SELF_VERIFICATION) 1127121ea790080b5a6bb713a07452c19f87d209de48jeffhao if (cUnit->heapMemOp) 1128d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng res->flags.insertWrapper = true; 1129121ea790080b5a6bb713a07452c19f87d209de48jeffhao#endif 11301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 11311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 11321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask) 11351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 11361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 11371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 11381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(rBase) && ((rMask & 0xff)==rMask)) { 11391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumbStmia, rBase, rMask); 11401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 11411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumb2Stmia, rBase, rMask); 11421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1143121ea790080b5a6bb713a07452c19f87d209de48jeffhao#if defined(WITH_SELF_VERIFICATION) 1144121ea790080b5a6bb713a07452c19f87d209de48jeffhao if (cUnit->heapMemOp) 1145d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng res->flags.insertWrapper = true; 1146121ea790080b5a6bb713a07452c19f87d209de48jeffhao#endif 11471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 11481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 11491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic void storePair(CompilationUnit *cUnit, int base, int lowReg, int highReg) 11521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 11531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee storeBaseDispWide(cUnit, base, 0, lowReg, highReg); 11541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg) 11571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 11585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadBaseDispWide(cUnit, NULL, base, 0, lowReg, highReg, INVALID_SREG); 11591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* 11628f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbee * Generate a register comparison to an immediate and branch. Caller 11638f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbee * is responsible for setting branch target field. 1164a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee */ 11658f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbeestatic ArmLIR *genCmpImmBranch(CompilationUnit *cUnit, 1166c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee ArmConditionCode cond, int reg, 11678f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbee int checkValue) 1168a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee{ 11691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *branch; 11701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int modImm; 1171bff121aa3e5d3c34caf837227cb00a46bf3f1966buzbee if ((LOWREG(reg)) && (checkValue == 0) && 11721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ((cond == kArmCondEq) || (cond == kArmCondNe))) { 11731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee branch = newLIR2(cUnit, 11741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (cond == kArmCondEq) ? kThumb2Cbz : kThumb2Cbnz, 11751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee reg, 0); 11761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 11771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee modImm = modifiedImmediate(checkValue); 11781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(reg) && ((checkValue & 0xff) == checkValue)) { 11791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR2(cUnit, kThumbCmpRI8, reg, checkValue); 11801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (modImm >= 0) { 11811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR2(cUnit, kThumb2CmpRI8, reg, modImm); 11821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 1183c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int tReg = dvmCompilerAllocTemp(cUnit); 11841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee loadConstant(cUnit, tReg, checkValue); 11851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegReg(cUnit, kOpCmp, reg, tReg); 11861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 11871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee branch = newLIR2(cUnit, kThumbBCond, 0, cond); 11881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 11898f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbee return branch; 1190a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee} 1191a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee 11925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) 1193270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 1194fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro ArmLIR* res = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 11955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[0] = rDest; 11965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[1] = rSrc; 11975d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rDest == rSrc) { 1198d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng res->flags.isNop = true; 11995d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(DOUBLEREG(rDest) == DOUBLEREG(rSrc)); 12015d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (DOUBLEREG(rDest)) { 12029a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res->opcode = kThumb2Vmovd; 12035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (SINGLEREG(rDest)) { 12059a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res->opcode = SINGLEREG(rSrc) ? kThumb2Vmovs : kThumb2Fmsr; 12065d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(SINGLEREG(rSrc)); 12089a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res->opcode = kThumb2Fmrs; 12095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[0] = rDest; 12125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[1] = rSrc; 12135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(res); 12155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1216270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1217270c1d64a192341be842f46734054c692bac061eBill Buzbee 12185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc) 1219270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 12205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR* res; 12219a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode; 12225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (FPREG(rDest) || FPREG(rSrc)) 12235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return fpRegCopy(cUnit, rDest, rSrc); 1224fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro res = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 12255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (LOWREG(rDest) && LOWREG(rSrc)) 12269a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR; 12275d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng else if (!LOWREG(rDest) && !LOWREG(rSrc)) 12289a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_H2H; 12295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng else if (LOWREG(rDest)) 12309a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_H2L; 12315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng else 12329a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_L2H; 1233270c1d64a192341be842f46734054c692bac061eBill Buzbee 12345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[0] = rDest; 12355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[1] = rSrc; 12369a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res->opcode = opcode; 12375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(res); 12385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rDest == rSrc) { 1239d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng res->flags.isNop = true; 12405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1242270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1243270c1d64a192341be842f46734054c692bac061eBill Buzbee 12445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR* genRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) 1245270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 12465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *res = genRegCopyNoInsert(cUnit, rDest, rSrc); 12475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dvmCompilerAppendLIR(cUnit, (LIR*)res); 12485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1249270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1250270c1d64a192341be842f46734054c692bac061eBill Buzbee 12515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi, 12525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int srcLo, int srcHi) 1253270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 12545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool destFP = FPREG(destLo) && FPREG(destHi); 12555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool srcFP = FPREG(srcLo) && FPREG(srcHi); 12565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(FPREG(srcLo) == FPREG(srcHi)); 12575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(FPREG(destLo) == FPREG(destHi)); 12585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (destFP) { 12595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (srcFP) { 12605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi)); 12615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, kThumb2Fmdrr, S2D(destLo, destHi), srcLo, srcHi); 12635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (srcFP) { 12665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, kThumb2Fmrrd, destLo, destHi, S2D(srcLo, srcHi)); 12675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Handle overlap 12695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (srcHi == destLo) { 12705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destHi, srcHi); 12715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destLo, srcLo); 12725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destLo, srcLo); 12745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destHi, srcHi); 12755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1278270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1279d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng 1280d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng#if defined(WITH_SELF_VERIFICATION) 1281d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Chengstatic void genSelfVerificationPreBranch(CompilationUnit *cUnit, 1282d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng ArmLIR *origLIR) { 1283d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng ArmLIR *push = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 1284d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng push->opcode = kThumbPush; 1285d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng /* Thumb push can handle LR (encoded at bit 8) */ 128620d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng push->operands[0] = (1 << r5FP | 1 << 8); 1287d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng setupResourceMasks(push); 1288d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng dvmCompilerInsertLIRBefore((LIR *) origLIR, (LIR *) push); 1289d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng} 1290d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng 1291d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Chengstatic void genSelfVerificationPostBranch(CompilationUnit *cUnit, 1292d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng ArmLIR *origLIR) { 1293d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng ArmLIR *pop = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 1294d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng /* Thumb pop cannot store into LR - use Thumb2 here */ 1295d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng pop->opcode = kThumb2Pop; 129620d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng pop->operands[0] = (1 << r5FP | 1 << r14lr); 1297d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng setupResourceMasks(pop); 1298d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng dvmCompilerInsertLIRAfter((LIR *) origLIR, (LIR *) pop); 1299d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng} 1300d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng#endif 1301