Factory.cpp revision c8129911e598ad0ca8d7b31012444ab6ce8bce45
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); 730c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee loadPcRel->aliasInfo = dataTarget->operands[0]; 731c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel); 732c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee res = loadPcRel; 733c8129911e598ad0ca8d7b31012444ab6ce8bce45buzbee } 7341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 735bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng res = loadConstantNoClobber(cUnit, rDestLo, valLo); 736bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng loadConstantNoClobber(cUnit, rDestHi, valHi); 7371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 7391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 7401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeShift(int code, int amount) { 7425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return ((amount & 0x1f) << 2) | code; 7431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 7441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase, 7461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rIndex, int rDest, int scale, OpSize size) 7471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 7481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rDest); 7499e45c0b968d63ea38353c99252d233879c2efdafjeffhao ArmLIR *load; 7509a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 7511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumbForm = (allLowRegs && (scale == 0)); 7521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int regPtr; 7531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rDest)) { 7551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(SINGLEREG(rDest)); 7561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((size == kWord) || (size == kSingle)); 7579a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vldrs; 7581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee size = kSingle; 7591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 7601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (size == kSingle) 7611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee size = kWord; 7621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 7651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 766c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee regPtr = dvmCompilerAllocTemp(cUnit); 7671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (scale) { 7681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex, 7691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodeShift(kArmLsl, scale)); 7701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 7711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex); 7721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7739a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein load = newLIR3(cUnit, opcode, rDest, regPtr, 0); 7749e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 7759e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 776d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng load->flags.insertWrapper = true; 7779e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 7789e45c0b968d63ea38353c99252d233879c2efdafjeffhao return load; 7791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 7809a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrRRR : kThumb2LdrRRR; 781270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 7839a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrhRRR : kThumb2LdrhRRR; 784270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 7869a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrshRRR : kThumb2LdrshRRR; 787270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 7899a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrbRRR : kThumb2LdrbRRR; 790270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 7929a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrsbRRR : kThumb2LdrsbRRR; 793270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 7951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 7961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumbForm) 7989a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein load = newLIR3(cUnit, opcode, rDest, rBase, rIndex); 7991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 8009a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein load = newLIR4(cUnit, opcode, rDest, rBase, rIndex, scale); 8019e45c0b968d63ea38353c99252d233879c2efdafjeffhao 8029e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 8039e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 804d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng load->flags.insertWrapper = true; 8059e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 8069e45c0b968d63ea38353c99252d233879c2efdafjeffhao return load; 8071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 8081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase, 8101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rIndex, int rSrc, int scale, OpSize size) 8111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 8121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rSrc); 8139e45c0b968d63ea38353c99252d233879c2efdafjeffhao ArmLIR *store; 8149a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 8151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumbForm = (allLowRegs && (scale == 0)); 8161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int regPtr; 8171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rSrc)) { 8191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(SINGLEREG(rSrc)); 820749e8162846b9dec5418d4d8f2334e683af81d52Bill Buzbee assert((size == kWord) || (size == kSingle)); 8219a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vstrs; 822749e8162846b9dec5418d4d8f2334e683af81d52Bill Buzbee size = kSingle; 8231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 8241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (size == kSingle) 8251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee size = kWord; 8261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 8291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 830c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee regPtr = dvmCompilerAllocTemp(cUnit); 8311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (scale) { 8321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex, 8331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodeShift(kArmLsl, scale)); 8341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 8351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex); 8361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8379a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein store = newLIR3(cUnit, opcode, rSrc, regPtr, 0); 8389e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 8399e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 840d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng store->flags.insertWrapper = true; 8419e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 8429e45c0b968d63ea38353c99252d233879c2efdafjeffhao return store; 8431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 8449a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbStrRRR : kThumb2StrRRR; 845270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 8461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 8471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 8489a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbStrhRRR : kThumb2StrhRRR; 849270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 8501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 8511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 8529a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbStrbRRR : kThumb2StrbRRR; 853270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 8541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 8551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 8561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumbForm) 8589a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein store = newLIR3(cUnit, opcode, rSrc, rBase, rIndex); 8591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 8609a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein store = newLIR4(cUnit, opcode, rSrc, rBase, rIndex, scale); 8619e45c0b968d63ea38353c99252d233879c2efdafjeffhao 8629e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 8639e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 864d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng store->flags.insertWrapper = true; 8659e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 8669e45c0b968d63ea38353c99252d233879c2efdafjeffhao return store; 8671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 8681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* 8701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * Load value from base + displacement. Optionally perform null check 8711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * on base (which must have an associated sReg and MIR). If not 8721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * performing null check, incoming MIR can be null. 8731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee */ 8741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase, 8751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rDest, int rDestHi, 8765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng OpSize size, int sReg) 8771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 8781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res, *load; 8799a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 8801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool shortForm = false; 8811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumb2Form = (displacement < 4092 && displacement >= 0); 8821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = (LOWREG(rBase) && LOWREG(rDest)); 8831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int encodedDisp = displacement; 8841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 8861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kDouble: 8871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kLong: 8881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rDest)) { 8891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (SINGLEREG(rDest)) { 8901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(FPREG(rDestHi)); 8911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee rDest = S2D(rDest, rDestHi); 8921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8939a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vldrd; 8941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 8951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 8971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 8991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 9001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, 9015d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng -1, kWord, sReg); 9021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee loadBaseDispBody(cUnit, NULL, rBase, displacement + 4, rDestHi, 9035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng -1, kWord, INVALID_SREG); 9041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 9051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 9061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 9071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 9081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rDest)) { 9099a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vldrs; 9101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 9111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 9131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 9141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 9151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 91620d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng if (LOWREG(rDest) && (rBase == r15pc) && 9171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (displacement <= 1020) && (displacement >= 0)) { 9181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 9209a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrPcRel; 92120d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng } else if (LOWREG(rDest) && (rBase == r13sp) && 9221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (displacement <= 1020) && (displacement >= 0)) { 9231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 9259a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrSpRel; 9261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (allLowRegs && displacement < 128 && displacement >= 0) { 9271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x3) == 0); 9281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 9309a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrRRI5; 9311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 9321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9339a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrRRI12; 9341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 935270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 9371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 64 && displacement >= 0) { 9381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x1) == 0); 9391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 1; 9419a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrhRRI5; 9421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (displacement < 4092 && displacement >= 0) { 9431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9449a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrhRRI12; 9451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 946270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 9481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumb2Form) { 9491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9509a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrshRRI12; 9511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 952270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 9541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 32 && displacement >= 0) { 9551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9569a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrbRRI5; 9571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 9581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9599a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrbRRI12; 9601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 961270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 9631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumb2Form) { 9641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9659a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrsbRRI12; 9661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 967270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 968270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 969270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 970270c1d64a192341be842f46734054c692bac061eBill Buzbee } 9715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 9721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (shortForm) { 9739a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein load = res = newLIR3(cUnit, opcode, rDest, rBase, encodedDisp); 9741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 975c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int regOffset = dvmCompilerAllocTemp(cUnit); 9761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadConstant(cUnit, regOffset, encodedDisp); 9771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee load = loadBaseIndexed(cUnit, rBase, regOffset, rDest, 0, size); 978c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, regOffset); 9791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 9801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 98120d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng if (rBase == r5FP) { 9821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee annotateDalvikRegAccess(load, displacement >> 2, true /* isLoad */); 983270c1d64a192341be842f46734054c692bac061eBill Buzbee } 9849e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 9859e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 986d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng load->flags.insertWrapper = true; 9879e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 988fe108f779db4fb3bc720a92e69e58177983088c1Ben Cheng return load; 989270c1d64a192341be842f46734054c692bac061eBill Buzbee} 990270c1d64a192341be842f46734054c692bac061eBill Buzbee 9911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase, 9921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rDest, OpSize size, 9935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int sReg) 994270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 9951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1, 9965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng size, sReg); 997270c1d64a192341be842f46734054c692bac061eBill Buzbee} 998270c1d64a192341be842f46734054c692bac061eBill Buzbee 9995d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase, 1000c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int displacement, int rDestLo, int rDestHi, 1001c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int sReg) 1002270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 10031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi, 10045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng kLong, sReg); 10051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 1006270c1d64a192341be842f46734054c692bac061eBill Buzbee 10071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase, 1009c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int displacement, int rSrc, int rSrcHi, 1010c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee OpSize size) 10111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res, *store; 10139a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 10141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool shortForm = false; 10151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumb2Form = (displacement < 4092 && displacement >= 0); 10161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = (LOWREG(rBase) && LOWREG(rSrc)); 10171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int encodedDisp = displacement; 10181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 10201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kLong: 10211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kDouble: 10221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (!FPREG(rSrc)) { 10231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = storeBaseDispBody(cUnit, rBase, displacement, rSrc, 10241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee -1, kWord); 10251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee storeBaseDispBody(cUnit, rBase, displacement + 4, rSrcHi, 10261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee -1, kWord); 10271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 1028270c1d64a192341be842f46734054c692bac061eBill Buzbee } 10291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (SINGLEREG(rSrc)) { 10301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(FPREG(rSrcHi)); 10311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee rSrc = S2D(rSrc, rSrcHi); 1032270c1d64a192341be842f46734054c692bac061eBill Buzbee } 10339a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vstrd; 10341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 10351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 1037270c1d64a192341be842f46734054c692bac061eBill Buzbee } 1038270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 10391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 10401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 10411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rSrc)) { 10421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(SINGLEREG(rSrc)); 10439a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vstrs; 10441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 10451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 10471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1048270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 10491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 10501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 128 && displacement >= 0) { 10511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x3) == 0); 10521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 10549a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbStrRRI5; 10551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 10561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10579a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2StrRRI12; 10581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1059270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 10601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 10611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 10621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 64 && displacement >= 0) { 10631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x1) == 0); 10641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 1; 10669a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbStrhRRI5; 10671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 10681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10699a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2StrhRRI12; 10701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1071270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 10721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 10731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 10741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 32 && displacement >= 0) { 10751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10769a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbStrbRRI5; 10771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 10781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10799a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2StrbRRI12; 10801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1081270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 1082270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 1083270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 1084270c1d64a192341be842f46734054c692bac061eBill Buzbee } 10851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (shortForm) { 10869a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein store = res = newLIR3(cUnit, opcode, rSrc, rBase, encodedDisp); 10871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 1088c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int rScratch = dvmCompilerAllocTemp(cUnit); 10891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadConstant(cUnit, rScratch, encodedDisp); 10901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee store = storeBaseIndexed(cUnit, rBase, rScratch, rSrc, 0, size); 1091c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, rScratch); 10921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 10931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 109420d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng if (rBase == r5FP) { 10951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee annotateDalvikRegAccess(store, displacement >> 2, false /* isLoad */); 10961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 10979e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 10989e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 1099d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng store->flags.insertWrapper = true; 11009e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 11011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 11021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDisp(CompilationUnit *cUnit, int rBase, 11051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rSrc, OpSize size) 11061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 11071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size); 11081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase, 11111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rSrcLo, int rSrcHi) 11121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 11131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong); 11141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask) 11171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 11181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 11191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 11201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(rBase) && ((rMask & 0xff)==rMask)) { 11211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumbLdmia, rBase, rMask); 11221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 11231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumb2Ldmia, rBase, rMask); 11241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1125121ea790080b5a6bb713a07452c19f87d209de48jeffhao#if defined(WITH_SELF_VERIFICATION) 1126121ea790080b5a6bb713a07452c19f87d209de48jeffhao if (cUnit->heapMemOp) 1127d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng res->flags.insertWrapper = true; 1128121ea790080b5a6bb713a07452c19f87d209de48jeffhao#endif 11291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 11301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 11311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask) 11341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 11351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 11361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 11371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(rBase) && ((rMask & 0xff)==rMask)) { 11381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumbStmia, rBase, rMask); 11391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 11401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumb2Stmia, rBase, rMask); 11411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1142121ea790080b5a6bb713a07452c19f87d209de48jeffhao#if defined(WITH_SELF_VERIFICATION) 1143121ea790080b5a6bb713a07452c19f87d209de48jeffhao if (cUnit->heapMemOp) 1144d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng res->flags.insertWrapper = true; 1145121ea790080b5a6bb713a07452c19f87d209de48jeffhao#endif 11461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 11471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 11481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic void storePair(CompilationUnit *cUnit, int base, int lowReg, int highReg) 11511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 11521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee storeBaseDispWide(cUnit, base, 0, lowReg, highReg); 11531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg) 11561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 11575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadBaseDispWide(cUnit, NULL, base, 0, lowReg, highReg, INVALID_SREG); 11581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 11591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 11601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* 11618f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbee * Generate a register comparison to an immediate and branch. Caller 11628f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbee * is responsible for setting branch target field. 1163a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee */ 11648f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbeestatic ArmLIR *genCmpImmBranch(CompilationUnit *cUnit, 1165c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee ArmConditionCode cond, int reg, 11668f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbee int checkValue) 1167a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee{ 11681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *branch; 11691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int modImm; 1170bff121aa3e5d3c34caf837227cb00a46bf3f1966buzbee if ((LOWREG(reg)) && (checkValue == 0) && 11711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ((cond == kArmCondEq) || (cond == kArmCondNe))) { 11721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee branch = newLIR2(cUnit, 11731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (cond == kArmCondEq) ? kThumb2Cbz : kThumb2Cbnz, 11741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee reg, 0); 11751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 11761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee modImm = modifiedImmediate(checkValue); 11771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(reg) && ((checkValue & 0xff) == checkValue)) { 11781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR2(cUnit, kThumbCmpRI8, reg, checkValue); 11791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (modImm >= 0) { 11801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR2(cUnit, kThumb2CmpRI8, reg, modImm); 11811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 1182c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int tReg = dvmCompilerAllocTemp(cUnit); 11831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee loadConstant(cUnit, tReg, checkValue); 11841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegReg(cUnit, kOpCmp, reg, tReg); 11851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 11861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee branch = newLIR2(cUnit, kThumbBCond, 0, cond); 11871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 11888f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbee return branch; 1189a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee} 1190a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee 11915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) 1192270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 1193fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro ArmLIR* res = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 11945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[0] = rDest; 11955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[1] = rSrc; 11965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rDest == rSrc) { 1197d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng res->flags.isNop = true; 11985d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 11995d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(DOUBLEREG(rDest) == DOUBLEREG(rSrc)); 12005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (DOUBLEREG(rDest)) { 12019a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res->opcode = kThumb2Vmovd; 12025d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (SINGLEREG(rDest)) { 12049a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res->opcode = SINGLEREG(rSrc) ? kThumb2Vmovs : kThumb2Fmsr; 12055d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12065d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(SINGLEREG(rSrc)); 12079a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res->opcode = kThumb2Fmrs; 12085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[0] = rDest; 12115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[1] = rSrc; 12125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(res); 12145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1215270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1216270c1d64a192341be842f46734054c692bac061eBill Buzbee 12175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc) 1218270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 12195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR* res; 12209a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode; 12215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (FPREG(rDest) || FPREG(rSrc)) 12225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return fpRegCopy(cUnit, rDest, rSrc); 1223fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro res = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 12245d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (LOWREG(rDest) && LOWREG(rSrc)) 12259a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR; 12265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng else if (!LOWREG(rDest) && !LOWREG(rSrc)) 12279a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_H2H; 12285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng else if (LOWREG(rDest)) 12299a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_H2L; 12305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng else 12319a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_L2H; 1232270c1d64a192341be842f46734054c692bac061eBill Buzbee 12335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[0] = rDest; 12345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[1] = rSrc; 12359a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res->opcode = opcode; 12365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(res); 12375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rDest == rSrc) { 1238d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng res->flags.isNop = true; 12395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1241270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1242270c1d64a192341be842f46734054c692bac061eBill Buzbee 12435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR* genRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) 1244270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 12455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *res = genRegCopyNoInsert(cUnit, rDest, rSrc); 12465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dvmCompilerAppendLIR(cUnit, (LIR*)res); 12475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1248270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1249270c1d64a192341be842f46734054c692bac061eBill Buzbee 12505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi, 12515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int srcLo, int srcHi) 1252270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 12535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool destFP = FPREG(destLo) && FPREG(destHi); 12545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool srcFP = FPREG(srcLo) && FPREG(srcHi); 12555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(FPREG(srcLo) == FPREG(srcHi)); 12565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(FPREG(destLo) == FPREG(destHi)); 12575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (destFP) { 12585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (srcFP) { 12595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi)); 12605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, kThumb2Fmdrr, S2D(destLo, destHi), srcLo, srcHi); 12625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (srcFP) { 12655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, kThumb2Fmrrd, destLo, destHi, S2D(srcLo, srcHi)); 12665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Handle overlap 12685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (srcHi == destLo) { 12695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destHi, srcHi); 12705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destLo, srcLo); 12715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destLo, srcLo); 12735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destHi, srcHi); 12745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1277270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1278d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng 1279d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng#if defined(WITH_SELF_VERIFICATION) 1280d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Chengstatic void genSelfVerificationPreBranch(CompilationUnit *cUnit, 1281d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng ArmLIR *origLIR) { 1282d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng ArmLIR *push = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 1283d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng push->opcode = kThumbPush; 1284d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng /* Thumb push can handle LR (encoded at bit 8) */ 128520d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng push->operands[0] = (1 << r5FP | 1 << 8); 1286d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng setupResourceMasks(push); 1287d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng dvmCompilerInsertLIRBefore((LIR *) origLIR, (LIR *) push); 1288d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng} 1289d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng 1290d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Chengstatic void genSelfVerificationPostBranch(CompilationUnit *cUnit, 1291d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng ArmLIR *origLIR) { 1292d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng ArmLIR *pop = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 1293d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng /* Thumb pop cannot store into LR - use Thumb2 here */ 1294d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng pop->opcode = kThumb2Pop; 129520d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng pop->operands[0] = (1 << r5FP | 1 << r14lr); 1296d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng setupResourceMasks(pop); 1297d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng dvmCompilerInsertLIRAfter((LIR *) origLIR, (LIR *) pop); 1298d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng} 1299d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng#endif 1300