Factory.cpp revision d72564ca7aa66c6d95b6ca34299258b65ecfd1cb
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)); 565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (encodedImm >= 0) { 575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return newLIR2(cUnit, kThumb2Vmovs_IMM8, rDest, encodedImm); 585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *dataTarget = scanLiteralPool(cUnit, value, 0); 605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (dataTarget == NULL) { 615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dataTarget = addWordData(cUnit, value, false); 625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 63fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro ArmLIR *loadPcRel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 649a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein loadPcRel->opcode = kThumb2Vldrs; 655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->generic.target = (LIR *) dataTarget; 665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->operands[0] = rDest; 675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->operands[1] = rpc; 685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(loadPcRel); 69d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng setMemRefType(loadPcRel, true, kLiteral); 701f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee loadPcRel->aliasInfo = dataTarget->operands[0]; 715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel); 725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return loadPcRel; 735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic int leadingZeros(u4 val) 761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee u4 alt; 781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int n; 791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int count; 801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee count = 16; 821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee n = 32; 831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee do { 841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee alt = val >> count; 851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (alt != 0) { 861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee n = n - count; 871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee val = alt; 881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee count >>= 1; 901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } while (count); 911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return n - val; 921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 939bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 949bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee/* 951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * Determine whether value can be encoded as a Thumb2 modified 961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * immediate. If not, return -1. If so, return i:imm3:a:bcdefgh form. 979bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee */ 981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic int modifiedImmediate(u4 value) 991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 1001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int zLeading; 1011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int zTrailing; 1021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee u4 b0 = value & 0xff; 1031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 1041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* Note: case of value==0 must use 0:000:0:0000000 encoding */ 1051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (value <= 0xFF) 1061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return b0; // 0:000:a:bcdefgh 1071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (value == ((b0 << 16) | b0)) 1081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return (0x1 << 8) | b0; /* 0:001:a:bcdefgh */ 1091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (value == ((b0 << 24) | (b0 << 16) | (b0 << 8) | b0)) 1101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return (0x3 << 8) | b0; /* 0:011:a:bcdefgh */ 1111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee b0 = (value >> 8) & 0xff; 1121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (value == ((b0 << 24) | (b0 << 8))) 1131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return (0x2 << 8) | b0; /* 0:010:a:bcdefgh */ 1141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* Can we do it with rotation? */ 1151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee zLeading = leadingZeros(value); 1161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee zTrailing = 32 - leadingZeros(~value & (value - 1)); 1171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* A run of eight or fewer active bits? */ 1181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if ((zLeading + zTrailing) < 24) 1191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return -1; /* No - bail */ 1201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* left-justify the constant, discarding msb (known to be 1) */ 1211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee value <<= zLeading + 1; 1221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* Create bcdefgh */ 1231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee value >>= 25; 1241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee /* Put it all together */ 1251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return value | ((0x8 + zLeading) << 7); /* [01000..11111]:bcdefgh */ 1261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 1279bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 1289bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee/* 1295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Load a immediate using a shortcut if possible; otherwise 1305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * grab from the per-translation literal pool. 131bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng * 132bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng * No additional register clobbering operation performed. Use this version when 133bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng * 1) rDest is freshly returned from dvmCompilerAllocTemp or 134bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng * 2) The codegen is under fixed register usage 1359bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee */ 136bd1326d0e6b82a24ee80d50921e62152ea919151Ben Chengstatic ArmLIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest, 137bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng int value) 1389bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{ 1395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *res; 1405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int modImm; 1419bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 1425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (FPREG(rDest)) { 1435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return loadFPConstantValue(cUnit, rDest, value); 1441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1459bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 1465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* See if the value can be constructed cheaply */ 1475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (LOWREG(rDest) && (value >= 0) && (value <= 255)) { 1485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return newLIR2(cUnit, kThumbMovImm, rDest, value); 1491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* Check Modified immediate special cases */ 1515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng modImm = modifiedImmediate(value); 1525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (modImm >= 0) { 1535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = newLIR2(cUnit, kThumb2MovImmShift, rDest, modImm); 1545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1559bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee } 1565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng modImm = modifiedImmediate(~value); 1575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (modImm >= 0) { 1585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = newLIR2(cUnit, kThumb2MvnImmShift, rDest, modImm); 1595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 160a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee } 1615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* 16-bit immediate? */ 1625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if ((value & 0xffff) == value) { 1635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = newLIR2(cUnit, kThumb2MovImm16, rDest, value); 1645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 165270c1d64a192341be842f46734054c692bac061eBill Buzbee } 1665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* No shortcut - go ahead and use literal pool */ 167fc519dc8f4444f6d93806ec15ce7445b322070fdBill Buzbee ArmLIR *dataTarget = scanLiteralPool(cUnit, value, 0); 1685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (dataTarget == NULL) { 1695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dataTarget = addWordData(cUnit, value, false); 1705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 171fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro ArmLIR *loadPcRel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 1729a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein loadPcRel->opcode = kThumb2LdrPcRel12; 1735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->generic.target = (LIR *) dataTarget; 1745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadPcRel->operands[0] = rDest; 1755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(loadPcRel); 176d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng setMemRefType(loadPcRel, true, kLiteral); 1771f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee loadPcRel->aliasInfo = dataTarget->operands[0]; 1785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = loadPcRel; 1795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel); 180270c1d64a192341be842f46734054c692bac061eBill Buzbee 1815d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng /* 1825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * To save space in the constant pool, we use the ADD_RRI8 instruction to 1835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * add up to 255 to an existing constant value. 1845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 1855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (dataTarget->operands[0] != value) { 1865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opRegImm(cUnit, kOpAdd, rDest, value - dataTarget->operands[0]); 1877ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee } 1887ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return res; 1897ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee} 1907ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee 1915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* 1925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Load an immediate value into a fixed or temp register. Target 1935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * register is clobbered, and marked inUse. 1945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 1955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value) 1969bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{ 197c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee if (dvmCompilerIsTemp(cUnit, rDest)) { 198c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rDest); 1996a55513b0d268bc0721834050a3698316854fa0aElliott Hughes dvmCompilerMarkInUse(cUnit, rDest); 2005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 201bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng return loadConstantNoClobber(cUnit, rDest, value); 2029bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee} 2039bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 2041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opNone(CompilationUnit *cUnit, OpKind op) 2059bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{ 2069a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 2071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (op) { 2081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpUncondBr: 2099a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbBUncond; 210270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 211270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 212270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 213270c1d64a192341be842f46734054c692bac061eBill Buzbee } 2149a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR0(cUnit, opcode); 2159bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee} 2169bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee 2171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opCondBranch(CompilationUnit *cUnit, ArmConditionCode cc) 2189bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{ 219bff121aa3e5d3c34caf837227cb00a46bf3f1966buzbee return newLIR2(cUnit, kThumb2BCond, 0 /* offset to be patched */, cc); 2201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 2211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 2221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opImm(CompilationUnit *cUnit, OpKind op, int value) 2231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 2249a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 2251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (op) { 22618c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng case kOpPush: { 22718c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng if ((value & 0xff00) == 0) { 22818c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng opcode = kThumbPush; 22918c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } else if ((value & 0xff00) == (1 << rlr)) { 23018c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng /* Thumb push can handle lr, which is encoded by bit 8 */ 23118c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng opcode = kThumbPush; 23218c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng value = (value & 0xff) | (1<<8); 23318c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } else { 23418c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng opcode = kThumb2Push; 23518c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } 236270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 23718c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } 23818c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng case kOpPop: { 23918c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng if ((value & 0xff00) == 0) { 24018c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng opcode = kThumbPop; 24118c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } else if ((value & 0xff00) == (1 << rpc)) { 24218c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng /* Thumb pop can handle pc, which is encoded by bit 8 */ 24318c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng opcode = kThumbPop; 24418c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng value = (value & 0xff) | (1<<8); 24518c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } else { 24618c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng opcode = kThumb2Pop; 24718c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } 248270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 24918c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } 250270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 251270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 2529bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee } 2539a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR1(cUnit, opcode, value); 254d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng} 255d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 2561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc) 257d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng{ 2589a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 2591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (op) { 2601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpBlx: 2619a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbBlxR; 2621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 2631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 2641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 265d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 2669a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR1(cUnit, opcode, rDestSrc); 267d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng} 268d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 2691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegShift(CompilationUnit *cUnit, OpKind op, int rDestSrc1, 2701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rSrc2, int shift) 271270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 272270c1d64a192341be842f46734054c692bac061eBill Buzbee bool thumbForm = ((shift == 0) && LOWREG(rDestSrc1) && LOWREG(rSrc2)); 2739a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 274270c1d64a192341be842f46734054c692bac061eBill Buzbee switch (op) { 2751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdc: 2769a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbAdcRR : kThumb2AdcRRR; 277270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAnd: 2799a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbAndRR : kThumb2AndRRR; 280270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpBic: 2829a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbBicRR : kThumb2BicRRR; 283270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpCmn: 285270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 2869a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbCmnRR : kThumb2CmnRR; 287270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 2881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpCmp: 289270c1d64a192341be842f46734054c692bac061eBill Buzbee if (thumbForm) 2909a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbCmpRR; 291270c1d64a192341be842f46734054c692bac061eBill Buzbee else if ((shift == 0) && !LOWREG(rDestSrc1) && !LOWREG(rSrc2)) 2929a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbCmpHH; 293270c1d64a192341be842f46734054c692bac061eBill Buzbee else if ((shift == 0) && LOWREG(rDestSrc1)) 2949a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbCmpLH; 295270c1d64a192341be842f46734054c692bac061eBill Buzbee else if (shift == 0) 2969a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbCmpHL; 297dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng else 2989a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2CmpRR; 299270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpXor: 3019a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbEorRR : kThumb2EorRRR; 302270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMov: 304270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 305270c1d64a192341be842f46734054c692bac061eBill Buzbee if (LOWREG(rDestSrc1) && LOWREG(rSrc2)) 3069a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR; 307270c1d64a192341be842f46734054c692bac061eBill Buzbee else if (!LOWREG(rDestSrc1) && !LOWREG(rSrc2)) 3089a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_H2H; 309270c1d64a192341be842f46734054c692bac061eBill Buzbee else if (LOWREG(rDestSrc1)) 3109a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_H2L; 311270c1d64a192341be842f46734054c692bac061eBill Buzbee else 3129a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_L2H; 313270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMul: 315270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3169a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbMul : kThumb2MulRRR; 317270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMvn: 3199a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbMvn : kThumb2MnvRR; 320270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpNeg: 322270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3239a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbNeg : kThumb2NegRR; 324270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpOr: 3269a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbOrr : kThumb2OrrRRR; 327270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSbc: 3299a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbSbc : kThumb2SbcRRR; 330270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpTst: 3329a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbTst : kThumb2TstRR; 333270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsl: 335270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3369a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLslRR : kThumb2LslRRR; 337270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsr: 339270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3409a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLsrRR : kThumb2LsrRRR; 341270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAsr: 343270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3449a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbAsrRR : kThumb2AsrRRR; 345270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpRor: 347270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3489a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbRorRR : kThumb2RorRRR; 349270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdd: 3519a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR; 352270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSub: 3549a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR; 355270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 3561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOp2Byte: 357270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 8); 3591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOp2Short: 360270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 16); 3621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOp2Char: 363270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(shift == 0); 3641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR4(cUnit, kThumb2Ubfx, rDestSrc1, rSrc2, 0, 16); 365270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 366270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 367270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 368270c1d64a192341be842f46734054c692bac061eBill Buzbee } 3699a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein assert(opcode >= 0); 3709a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein if (EncodingMap[opcode].flags & IS_BINARY_OP) 3719a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR2(cUnit, opcode, rDestSrc1, rSrc2); 3729a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein else if (EncodingMap[opcode].flags & IS_TERTIARY_OP) { 3739a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein if (EncodingMap[opcode].fieldLoc[2].kind == kFmtShift) 3749a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR3(cUnit, opcode, rDestSrc1, rSrc2, shift); 375270c1d64a192341be842f46734054c692bac061eBill Buzbee else 3769a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR3(cUnit, opcode, rDestSrc1, rDestSrc1, rSrc2); 3779a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein } else if (EncodingMap[opcode].flags & IS_QUAD_OP) 3789a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR4(cUnit, opcode, rDestSrc1, rDestSrc1, rSrc2, shift); 379270c1d64a192341be842f46734054c692bac061eBill Buzbee else { 380270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 381270c1d64a192341be842f46734054c692bac061eBill Buzbee return NULL; 382270c1d64a192341be842f46734054c692bac061eBill Buzbee } 383270c1d64a192341be842f46734054c692bac061eBill Buzbee} 384270c1d64a192341be842f46734054c692bac061eBill Buzbee 385270c1d64a192341be842f46734054c692bac061eBill Buzbeestatic ArmLIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1, 386270c1d64a192341be842f46734054c692bac061eBill Buzbee int rSrc2) 387270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 388270c1d64a192341be842f46734054c692bac061eBill Buzbee return opRegRegShift(cUnit, op, rDestSrc1, rSrc2, 0); 389270c1d64a192341be842f46734054c692bac061eBill Buzbee} 390270c1d64a192341be842f46734054c692bac061eBill Buzbee 3911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegRegShift(CompilationUnit *cUnit, OpKind op, 3921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rDest, int rSrc1, int rSrc2, int shift) 3931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 3949a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 3951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumbForm = (shift == 0) && LOWREG(rDest) && LOWREG(rSrc1) && 3961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee LOWREG(rSrc2); 3971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (op) { 3981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdd: 3999a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR; 4001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSub: 4029a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR; 4031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdc: 4059a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2AdcRRR; 4061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAnd: 4089a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2AndRRR; 4091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpBic: 4119a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2BicRRR; 4121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpXor: 4149a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2EorRRR; 4151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMul: 4171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4189a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2MulRRR; 4191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpOr: 4219a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2OrrRRR; 4221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSbc: 4249a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2SbcRRR; 4251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsl: 4271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4289a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LslRRR; 4291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsr: 4311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4329a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LsrRRR; 4331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAsr: 4351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4369a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2AsrRRR; 4371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpRor: 4391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(shift == 0); 4409a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2RorRRR; 4411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 4431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 4441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 4451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 4469a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein assert(opcode >= 0); 4479a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein if (EncodingMap[opcode].flags & IS_QUAD_OP) 4489a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR4(cUnit, opcode, rDest, rSrc1, rSrc2, shift); 4491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else { 4509a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein assert(EncodingMap[opcode].flags & IS_TERTIARY_OP); 4519a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR3(cUnit, opcode, rDest, rSrc1, rSrc2); 4521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 4531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 4541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 4551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegReg(CompilationUnit *cUnit, OpKind op, int rDest, 4561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rSrc1, int rSrc2) 4571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 4581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return opRegRegRegShift(cUnit, op, rDest, rSrc1, rSrc2, 0); 4591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 4601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 4611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest, 4621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rSrc1, int value) 4631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 4641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 4651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool neg = (value < 0); 4661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int absValue = (neg) ? -value : value; 4679a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 4689a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode altOpcode = kThumbBkpt; 4691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = (LOWREG(rDest) && LOWREG(rSrc1)); 4701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int modImm = modifiedImmediate(value); 4711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int modImmNeg = modifiedImmediate(-value); 4721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 4731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch(op) { 4741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsl: 4751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs) 4761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbLslRRI5, rDest, rSrc1, value); 4771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 4781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumb2LslRRI5, rDest, rSrc1, value); 4791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpLsr: 4801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs) 4811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbLsrRRI5, rDest, rSrc1, value); 4821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 4831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumb2LsrRRI5, rDest, rSrc1, value); 4841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAsr: 4851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs) 4861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbAsrRRI5, rDest, rSrc1, value); 4871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 4881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumb2AsrRRI5, rDest, rSrc1, value); 4891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpRor: 4901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumb2RorRRI5, rDest, rSrc1, value); 4911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdd: 4921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(rDest) && (rSrc1 == 13) && 4931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (value <= 1020) && ((value & 0x3)==0)) { 4941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbAddSpRel, rDest, rSrc1, 4951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee value >> 2); 4961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (LOWREG(rDest) && (rSrc1 == rpc) && 4971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (value <= 1020) && ((value & 0x3)==0)) { 4981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR3(cUnit, kThumbAddPcRel, rDest, rSrc1, 4991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee value >> 2); 5001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5019a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2AddRRI8; 5029a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2AddRRR; 5031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee // Note: intentional fallthrough 5041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSub: 5051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && ((absValue & 0x7) == absValue)) { 5061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (op == kOpAdd) 5079a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (neg) ? kThumbSubRRI3 : kThumbAddRRI3; 5081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 5099a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (neg) ? kThumbAddRRI3 : kThumbSubRRI3; 5109a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR3(cUnit, opcode, rDest, rSrc1, absValue); 5111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if ((absValue & 0xff) == absValue) { 5121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (op == kOpAdd) 5139a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (neg) ? kThumb2SubRRI12 : kThumb2AddRRI12; 5141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 5159a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (neg) ? kThumb2AddRRI12 : kThumb2SubRRI12; 5169a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR3(cUnit, opcode, rDest, rSrc1, absValue); 5171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (modImmNeg >= 0) { 5191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee op = (op == kOpAdd) ? kOpSub : kOpAdd; 5201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee modImm = modImmNeg; 5211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (op == kOpSub) { 5239a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2SubRRI8; 5249a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2SubRRR; 5251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdc: 5289a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2AdcRRI8; 5299a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2AdcRRR; 5301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSbc: 5329a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2SbcRRI8; 5339a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2SbcRRR; 5341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpOr: 5369a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2OrrRRI8; 5379a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2OrrRRR; 5381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAnd: 5409a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2AndRRI8; 5419a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2AndRRR; 5421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpXor: 5449a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2EorRRI8; 5459a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2EorRRR; 5461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpMul: 5481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee //TUNING: power of 2, shift & add 5491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee modImm = -1; 5509a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein altOpcode = kThumb2MulRRR; 5511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 5521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpCmp: { 5531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int modImm = modifiedImmediate(value); 5541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 5551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (modImm >= 0) { 5561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumb2CmpRI8, rSrc1, modImm); 5571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 558c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int rTmp = dvmCompilerAllocTemp(cUnit); 5591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadConstant(cUnit, rTmp, value); 5601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegReg(cUnit, kOpCmp, rSrc1, rTmp); 561c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, rTmp); 5621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 5641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 5661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 5671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 5691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (modImm >= 0) { 5709a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR3(cUnit, opcode, rDest, rSrc1, modImm); 5711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 572c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int rScratch = dvmCompilerAllocTemp(cUnit); 5731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee loadConstant(cUnit, rScratch, value); 5749a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein if (EncodingMap[altOpcode].flags & IS_QUAD_OP) 5759a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res = newLIR4(cUnit, altOpcode, rDest, rSrc1, rScratch, 0); 5761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 5779a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res = newLIR3(cUnit, altOpcode, rDest, rSrc1, rScratch); 578c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, rScratch); 5791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 5801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 5811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 5821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 583270c1d64a192341be842f46734054c692bac061eBill Buzbee/* Handle Thumb-only variants here - otherwise punt to opRegRegImm */ 584270c1d64a192341be842f46734054c692bac061eBill Buzbeestatic ArmLIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1, 5851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int value) 586270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 587270c1d64a192341be842f46734054c692bac061eBill Buzbee bool neg = (value < 0); 588270c1d64a192341be842f46734054c692bac061eBill Buzbee int absValue = (neg) ? -value : value; 589270c1d64a192341be842f46734054c692bac061eBill Buzbee bool shortForm = (((absValue & 0xff) == absValue) && LOWREG(rDestSrc1)); 5909a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 591270c1d64a192341be842f46734054c692bac061eBill Buzbee switch (op) { 5921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpAdd: 593270c1d64a192341be842f46734054c692bac061eBill Buzbee if ( !neg && (rDestSrc1 == 13) && (value <= 508)) { /* sp */ 594270c1d64a192341be842f46734054c692bac061eBill Buzbee assert((value & 0x3) == 0); 5951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR1(cUnit, kThumbAddSpI7, value >> 2); 596270c1d64a192341be842f46734054c692bac061eBill Buzbee } else if (shortForm) { 5979a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (neg) ? kThumbSubRI8 : kThumbAddRI8; 598270c1d64a192341be842f46734054c692bac061eBill Buzbee } 599270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 6001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpSub: 601270c1d64a192341be842f46734054c692bac061eBill Buzbee if (!neg && (rDestSrc1 == 13) && (value <= 508)) { /* sp */ 602270c1d64a192341be842f46734054c692bac061eBill Buzbee assert((value & 0x3) == 0); 6031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return newLIR1(cUnit, kThumbSubSpI7, value >> 2); 604270c1d64a192341be842f46734054c692bac061eBill Buzbee } else if (shortForm) { 6059a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (neg) ? kThumbAddRI8 : kThumbSubRI8; 606270c1d64a192341be842f46734054c692bac061eBill Buzbee } 607270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 6081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kOpCmp: 609270c1d64a192341be842f46734054c692bac061eBill Buzbee if (LOWREG(rDestSrc1) && shortForm) 6109a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (shortForm) ? kThumbCmpRI8 : kThumbCmpRR; 611270c1d64a192341be842f46734054c692bac061eBill Buzbee else if (LOWREG(rDestSrc1)) 6129a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbCmpRR; 613270c1d64a192341be842f46734054c692bac061eBill Buzbee else { 614270c1d64a192341be842f46734054c692bac061eBill Buzbee shortForm = false; 6159a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbCmpHL; 616270c1d64a192341be842f46734054c692bac061eBill Buzbee } 617270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 618270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 619270c1d64a192341be842f46734054c692bac061eBill Buzbee /* Punt to opRegRegImm - if bad case catch it there */ 620270c1d64a192341be842f46734054c692bac061eBill Buzbee shortForm = false; 621270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 622270c1d64a192341be842f46734054c692bac061eBill Buzbee } 623270c1d64a192341be842f46734054c692bac061eBill Buzbee if (shortForm) 6249a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein return newLIR2(cUnit, opcode, rDestSrc1, absValue); 6251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else { 6261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value); 6271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 628270c1d64a192341be842f46734054c692bac061eBill Buzbee} 629270c1d64a192341be842f46734054c692bac061eBill Buzbee 6301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* 6315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Determine whether value can be encoded as a Thumb2 floating point 6325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * immediate. If not, return -1. If so return encoded 8-bit value. 6331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee */ 6345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeImmDoubleHigh(int value) 6351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 6365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int res; 6375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bitA = (value & 0x80000000) >> 31; 6385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int notBitB = (value & 0x40000000) >> 30; 6395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bitB = (value & 0x20000000) >> 29; 6405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int bSmear = (value & 0x3fc00000) >> 22; 6415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int slice = (value & 0x003f0000) >> 16; 6425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int zeroes = (value & 0x0000ffff); 6435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (zeroes != 0) 6445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 6455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (bitB) { 6465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if ((notBitB != 0) || (bSmear != 0x1f)) 6475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 6481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 6495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if ((notBitB != 1) || (bSmear != 0x0)) 6505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return -1; 6511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 6525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = (bitA << 7) | (bitB << 6) | slice; 6535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 6545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 6551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 6565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeImmDouble(int valLo, int valHi) 6575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 6585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int res = -1; 6595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (valLo == 0) 6605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = encodeImmDoubleHigh(valHi); 6615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 6625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 6631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 6645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadConstantValueWide(CompilationUnit *cUnit, int rDestLo, 6655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int rDestHi, int valLo, int valHi) 6665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 6675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int encodedImm = encodeImmDouble(valLo, valHi); 6685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *res; 6695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (FPREG(rDestLo) && (encodedImm >= 0)) { 6705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = newLIR2(cUnit, kThumb2Vmovd_IMM8, S2D(rDestLo, rDestHi), 6715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng encodedImm); 6721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 673bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng res = loadConstantNoClobber(cUnit, rDestLo, valLo); 674bd1326d0e6b82a24ee80d50921e62152ea919151Ben Cheng loadConstantNoClobber(cUnit, rDestHi, valHi); 6751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 6765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 6771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 6781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 6795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeShift(int code, int amount) { 6805d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return ((amount & 0x1f) << 2) | code; 6811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 6821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 6831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase, 6841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rIndex, int rDest, int scale, OpSize size) 6851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 6861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rDest); 6879e45c0b968d63ea38353c99252d233879c2efdafjeffhao ArmLIR *load; 6889a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 6891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumbForm = (allLowRegs && (scale == 0)); 6901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int regPtr; 6911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 6921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rDest)) { 6931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(SINGLEREG(rDest)); 6941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((size == kWord) || (size == kSingle)); 6959a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vldrs; 6961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee size = kSingle; 6971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 6981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (size == kSingle) 6991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee size = kWord; 7001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 7031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 704c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee regPtr = dvmCompilerAllocTemp(cUnit); 7051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (scale) { 7061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex, 7071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodeShift(kArmLsl, scale)); 7081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 7091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex); 7101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7119a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein load = newLIR3(cUnit, opcode, rDest, regPtr, 0); 7129e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 7139e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 714d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng load->flags.insertWrapper = true; 7159e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 7169e45c0b968d63ea38353c99252d233879c2efdafjeffhao return load; 7171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 7189a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrRRR : kThumb2LdrRRR; 719270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 7219a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrhRRR : kThumb2LdrhRRR; 722270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 7249a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrshRRR : kThumb2LdrshRRR; 725270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 7279a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrbRRR : kThumb2LdrbRRR; 728270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 7309a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbLdrsbRRR : kThumb2LdrsbRRR; 731270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 7331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 7341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumbForm) 7369a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein load = newLIR3(cUnit, opcode, rDest, rBase, rIndex); 7371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 7389a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein load = newLIR4(cUnit, opcode, rDest, rBase, rIndex, scale); 7399e45c0b968d63ea38353c99252d233879c2efdafjeffhao 7409e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 7419e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 742d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng load->flags.insertWrapper = true; 7439e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 7449e45c0b968d63ea38353c99252d233879c2efdafjeffhao return load; 7451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 7461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase, 7481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int rIndex, int rSrc, int scale, OpSize size) 7491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 7501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rSrc); 7519e45c0b968d63ea38353c99252d233879c2efdafjeffhao ArmLIR *store; 7529a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 7531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumbForm = (allLowRegs && (scale == 0)); 7541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int regPtr; 7551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rSrc)) { 7571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(SINGLEREG(rSrc)); 758749e8162846b9dec5418d4d8f2334e683af81d52Bill Buzbee assert((size == kWord) || (size == kSingle)); 7599a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vstrs; 760749e8162846b9dec5418d4d8f2334e683af81d52Bill Buzbee size = kSingle; 7611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 7621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (size == kSingle) 7631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee size = kWord; 7641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 7661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 7671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 768c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee regPtr = dvmCompilerAllocTemp(cUnit); 7691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (scale) { 7701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex, 7711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodeShift(kArmLsl, scale)); 7721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 7731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex); 7741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7759a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein store = newLIR3(cUnit, opcode, rSrc, regPtr, 0); 7769e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 7779e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 778d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng store->flags.insertWrapper = true; 7799e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 7809e45c0b968d63ea38353c99252d233879c2efdafjeffhao return store; 7811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 7829a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbStrRRR : kThumb2StrRRR; 783270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 7851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 7869a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbStrhRRR : kThumb2StrhRRR; 787270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 7891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 7909a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = (thumbForm) ? kThumbStrbRRR : kThumb2StrbRRR; 791270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 7921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee default: 7931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(0); 7941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 7951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumbForm) 7969a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein store = newLIR3(cUnit, opcode, rSrc, rBase, rIndex); 7971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee else 7989a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein store = newLIR4(cUnit, opcode, rSrc, rBase, rIndex, scale); 7999e45c0b968d63ea38353c99252d233879c2efdafjeffhao 8009e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 8019e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 802d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng store->flags.insertWrapper = true; 8039e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 8049e45c0b968d63ea38353c99252d233879c2efdafjeffhao return store; 8051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 8061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* 8081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * Load value from base + displacement. Optionally perform null check 8091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * on base (which must have an associated sReg and MIR). If not 8101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * performing null check, incoming MIR can be null. 8111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee */ 8121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase, 8131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rDest, int rDestHi, 8145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng OpSize size, int sReg) 8151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 8161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res, *load; 8179a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 8181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool shortForm = false; 8191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumb2Form = (displacement < 4092 && displacement >= 0); 8201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = (LOWREG(rBase) && LOWREG(rDest)); 8211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int encodedDisp = displacement; 8221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 8231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 8241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kDouble: 8251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kLong: 8261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rDest)) { 8271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (SINGLEREG(rDest)) { 8281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(FPREG(rDestHi)); 8291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee rDest = S2D(rDest, rDestHi); 8301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8319a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vldrd; 8321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 8331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 8351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 8371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 8381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, 8395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng -1, kWord, sReg); 8401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee loadBaseDispBody(cUnit, NULL, rBase, displacement + 4, rDestHi, 8415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng -1, kWord, INVALID_SREG); 8421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 8431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 8451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 8461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rDest)) { 8479a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vldrs; 8481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 8491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 8511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee break; 8531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 8541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(rDest) && (rBase == rpc) && 8551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (displacement <= 1020) && (displacement >= 0)) { 8561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 8589a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrPcRel; 8591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (LOWREG(rDest) && (rBase == r13) && 8601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (displacement <= 1020) && (displacement >= 0)) { 8611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 8639a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrSpRel; 8641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (allLowRegs && displacement < 128 && displacement >= 0) { 8651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x3) == 0); 8661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 8689a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrRRI5; 8691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 8701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8719a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrRRI12; 8721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 873270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 8741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 8751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 64 && displacement >= 0) { 8761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x1) == 0); 8771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 1; 8799a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrhRRI5; 8801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (displacement < 4092 && displacement >= 0) { 8811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8829a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrhRRI12; 8831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 884270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 8851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 8861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumb2Form) { 8871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8889a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrshRRI12; 8891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 890270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 8911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 8921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 32 && displacement >= 0) { 8931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8949a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbLdrbRRI5; 8951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 8961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 8979a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrbRRI12; 8981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 899270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 9011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (thumb2Form) { 9021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9039a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2LdrsbRRI12; 9041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 905270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 906270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 907270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 908270c1d64a192341be842f46734054c692bac061eBill Buzbee } 9095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 9101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (shortForm) { 9119a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein load = res = newLIR3(cUnit, opcode, rDest, rBase, encodedDisp); 9121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 913c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int regOffset = dvmCompilerAllocTemp(cUnit); 9141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadConstant(cUnit, regOffset, encodedDisp); 9151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee load = loadBaseIndexed(cUnit, rBase, regOffset, rDest, 0, size); 916c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, regOffset); 9171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 9181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 9191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (rBase == rFP) { 9201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee annotateDalvikRegAccess(load, displacement >> 2, true /* isLoad */); 921270c1d64a192341be842f46734054c692bac061eBill Buzbee } 9229e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 9239e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 924d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng load->flags.insertWrapper = true; 9259e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 9265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 927270c1d64a192341be842f46734054c692bac061eBill Buzbee} 928270c1d64a192341be842f46734054c692bac061eBill Buzbee 9291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase, 9301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rDest, OpSize size, 9315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int sReg) 932270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 9331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1, 9345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng size, sReg); 935270c1d64a192341be842f46734054c692bac061eBill Buzbee} 936270c1d64a192341be842f46734054c692bac061eBill Buzbee 9375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase, 938c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int displacement, int rDestLo, int rDestHi, 939c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int sReg) 940270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 9411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi, 9425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng kLong, sReg); 9431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 944270c1d64a192341be842f46734054c692bac061eBill Buzbee 9451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 9461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase, 947c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int displacement, int rSrc, int rSrcHi, 948c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee OpSize size) 9491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 9501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res, *store; 9519a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode = kThumbBkpt; 9521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool shortForm = false; 9531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool thumb2Form = (displacement < 4092 && displacement >= 0); 9541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee bool allLowRegs = (LOWREG(rBase) && LOWREG(rSrc)); 9551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int encodedDisp = displacement; 9561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 9571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee switch (size) { 9581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kLong: 9591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kDouble: 9601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (!FPREG(rSrc)) { 9611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = storeBaseDispBody(cUnit, rBase, displacement, rSrc, 9621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee -1, kWord); 9631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee storeBaseDispBody(cUnit, rBase, displacement + 4, rSrcHi, 9641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee -1, kWord); 9651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 966270c1d64a192341be842f46734054c692bac061eBill Buzbee } 9671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (SINGLEREG(rSrc)) { 9681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(FPREG(rSrcHi)); 9691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee rSrc = S2D(rSrc, rSrcHi); 970270c1d64a192341be842f46734054c692bac061eBill Buzbee } 9719a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vstrd; 9721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 9731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 975270c1d64a192341be842f46734054c692bac061eBill Buzbee } 976270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSingle: 9781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kWord: 9791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (FPREG(rSrc)) { 9801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(SINGLEREG(rSrc)); 9819a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2Vstrs; 9821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (displacement <= 1020) { 9831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 9851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 986270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 9881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 128 && displacement >= 0) { 9891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x3) == 0); 9901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 2; 9929a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbStrRRI5; 9931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 9941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 9959a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2StrRRI12; 9961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 997270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 9981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedHalf: 9991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedHalf: 10001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 64 && displacement >= 0) { 10011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert((displacement & 0x1) == 0); 10021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee encodedDisp >>= 1; 10049a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbStrhRRI5; 10051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 10061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10079a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2StrhRRI12; 10081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1009270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 10101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kUnsignedByte: 10111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kSignedByte: 10121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (allLowRegs && displacement < 32 && displacement >= 0) { 10131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10149a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbStrbRRI5; 10151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (thumb2Form) { 10161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee shortForm = true; 10179a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumb2StrbRRI12; 10181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1019270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 1020270c1d64a192341be842f46734054c692bac061eBill Buzbee default: 1021270c1d64a192341be842f46734054c692bac061eBill Buzbee assert(0); 1022270c1d64a192341be842f46734054c692bac061eBill Buzbee } 10231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (shortForm) { 10249a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein store = res = newLIR3(cUnit, opcode, rSrc, rBase, encodedDisp); 10251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 1026c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int rScratch = dvmCompilerAllocTemp(cUnit); 10271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = loadConstant(cUnit, rScratch, encodedDisp); 10281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee store = storeBaseIndexed(cUnit, rBase, rScratch, rSrc, 0, size); 1029c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, rScratch); 10301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 10311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (rBase == rFP) { 10331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee annotateDalvikRegAccess(store, displacement >> 2, false /* isLoad */); 10341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 10359e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION) 10369e45c0b968d63ea38353c99252d233879c2efdafjeffhao if (cUnit->heapMemOp) 1037d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng store->flags.insertWrapper = true; 10389e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif 10391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 10401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDisp(CompilationUnit *cUnit, int rBase, 10431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rSrc, OpSize size) 10441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size); 10461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase, 10491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int displacement, int rSrcLo, int rSrcHi) 10501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong); 10521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask) 10551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 10571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 10581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(rBase) && ((rMask & 0xff)==rMask)) { 10591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumbLdmia, rBase, rMask); 10601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 10611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumb2Ldmia, rBase, rMask); 10621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1063121ea790080b5a6bb713a07452c19f87d209de48jeffhao#if defined(WITH_SELF_VERIFICATION) 1064121ea790080b5a6bb713a07452c19f87d209de48jeffhao if (cUnit->heapMemOp) 1065d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng res->flags.insertWrapper = true; 1066121ea790080b5a6bb713a07452c19f87d209de48jeffhao#endif 10671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 10681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 10691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask) 10721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *res; 10741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 10751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(rBase) && ((rMask & 0xff)==rMask)) { 10761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumbStmia, rBase, rMask); 10771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 10781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee res = newLIR2(cUnit, kThumb2Stmia, rBase, rMask); 10791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 1080121ea790080b5a6bb713a07452c19f87d209de48jeffhao#if defined(WITH_SELF_VERIFICATION) 1081121ea790080b5a6bb713a07452c19f87d209de48jeffhao if (cUnit->heapMemOp) 1082d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng res->flags.insertWrapper = true; 1083121ea790080b5a6bb713a07452c19f87d209de48jeffhao#endif 10841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee genBarrier(cUnit); 10851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee return res; 10861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic void storePair(CompilationUnit *cUnit, int base, int lowReg, int highReg) 10891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee storeBaseDispWide(cUnit, base, 0, lowReg, highReg); 10911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg) 10941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{ 10955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadBaseDispWide(cUnit, NULL, base, 0, lowReg, highReg, INVALID_SREG); 10961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee} 10971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee 10981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* 10998f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbee * Generate a register comparison to an immediate and branch. Caller 11008f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbee * is responsible for setting branch target field. 1101a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee */ 11028f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbeestatic ArmLIR *genCmpImmBranch(CompilationUnit *cUnit, 1103c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee ArmConditionCode cond, int reg, 11048f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbee int checkValue) 1105a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee{ 11061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ArmLIR *branch; 11071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee int modImm; 1108bff121aa3e5d3c34caf837227cb00a46bf3f1966buzbee if ((LOWREG(reg)) && (checkValue == 0) && 11091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee ((cond == kArmCondEq) || (cond == kArmCondNe))) { 11101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee branch = newLIR2(cUnit, 11111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee (cond == kArmCondEq) ? kThumb2Cbz : kThumb2Cbnz, 11121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee reg, 0); 11131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 11141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee modImm = modifiedImmediate(checkValue); 11151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee if (LOWREG(reg) && ((checkValue & 0xff) == checkValue)) { 11161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR2(cUnit, kThumbCmpRI8, reg, checkValue); 11171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else if (modImm >= 0) { 11181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee newLIR2(cUnit, kThumb2CmpRI8, reg, modImm); 11191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } else { 1120c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int tReg = dvmCompilerAllocTemp(cUnit); 11211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee loadConstant(cUnit, tReg, checkValue); 11221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee opRegReg(cUnit, kOpCmp, reg, tReg); 11231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 11241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee branch = newLIR2(cUnit, kThumbBCond, 0, cond); 11251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee } 11268f8109ade5c32c8c94fa6b7c058045733c8c5ad1buzbee return branch; 1127a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee} 1128a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee 11295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) 1130270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 1131fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro ArmLIR* res = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 11325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[0] = rDest; 11335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[1] = rSrc; 11345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rDest == rSrc) { 1135d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng res->flags.isNop = true; 11365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 11375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(DOUBLEREG(rDest) == DOUBLEREG(rSrc)); 11385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (DOUBLEREG(rDest)) { 11399a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res->opcode = kThumb2Vmovd; 11405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 11415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (SINGLEREG(rDest)) { 11429a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res->opcode = SINGLEREG(rSrc) ? kThumb2Vmovs : kThumb2Fmsr; 11435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 11445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(SINGLEREG(rSrc)); 11459a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res->opcode = kThumb2Fmrs; 11465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 11475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 11485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[0] = rDest; 11495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[1] = rSrc; 11505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 11515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(res); 11525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1153270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1154270c1d64a192341be842f46734054c692bac061eBill Buzbee 11555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc) 1156270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 11575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR* res; 11589a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein ArmOpcode opcode; 11595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (FPREG(rDest) || FPREG(rSrc)) 11605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return fpRegCopy(cUnit, rDest, rSrc); 1161fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro res = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 11625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (LOWREG(rDest) && LOWREG(rSrc)) 11639a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR; 11645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng else if (!LOWREG(rDest) && !LOWREG(rSrc)) 11659a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_H2H; 11665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng else if (LOWREG(rDest)) 11679a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_H2L; 11685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng else 11699a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein opcode = kThumbMovRR_L2H; 1170270c1d64a192341be842f46734054c692bac061eBill Buzbee 11715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[0] = rDest; 11725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res->operands[1] = rSrc; 11739a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein res->opcode = opcode; 11745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng setupResourceMasks(res); 11755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rDest == rSrc) { 1176d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng res->flags.isNop = true; 11775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 11785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1179270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1180270c1d64a192341be842f46734054c692bac061eBill Buzbee 11815d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR* genRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) 1182270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 11835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *res = genRegCopyNoInsert(cUnit, rDest, rSrc); 11845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dvmCompilerAppendLIR(cUnit, (LIR*)res); 11855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1186270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1187270c1d64a192341be842f46734054c692bac061eBill Buzbee 11885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi, 11895d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int srcLo, int srcHi) 1190270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 11915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool destFP = FPREG(destLo) && FPREG(destHi); 11925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng bool srcFP = FPREG(srcLo) && FPREG(srcHi); 11935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(FPREG(srcLo) == FPREG(srcHi)); 11945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(FPREG(destLo) == FPREG(destHi)); 11955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (destFP) { 11965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (srcFP) { 11975d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi)); 11985d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 11995d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, kThumb2Fmdrr, S2D(destLo, destHi), srcLo, srcHi); 12005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12015d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12025d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (srcFP) { 12035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR3(cUnit, kThumb2Fmrrd, destLo, destHi, S2D(srcLo, srcHi)); 12045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12055d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Handle overlap 12065d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (srcHi == destLo) { 12075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destHi, srcHi); 12085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destLo, srcLo); 12095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 12105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destLo, srcLo); 12115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, destHi, srcHi); 12125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 12145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1215270c1d64a192341be842f46734054c692bac061eBill Buzbee} 1216d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng 1217d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng#if defined(WITH_SELF_VERIFICATION) 1218d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Chengstatic void genSelfVerificationPreBranch(CompilationUnit *cUnit, 1219d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng ArmLIR *origLIR) { 1220d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng ArmLIR *push = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 1221d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng push->opcode = kThumbPush; 1222d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng /* Thumb push can handle LR (encoded at bit 8) */ 1223d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng push->operands[0] = (1 << rFP | 1 << 8); 1224d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng setupResourceMasks(push); 1225d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng dvmCompilerInsertLIRBefore((LIR *) origLIR, (LIR *) push); 1226d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng} 1227d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng 1228d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Chengstatic void genSelfVerificationPostBranch(CompilationUnit *cUnit, 1229d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng ArmLIR *origLIR) { 1230d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng ArmLIR *pop = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 1231d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng /* Thumb pop cannot store into LR - use Thumb2 here */ 1232d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng pop->opcode = kThumb2Pop; 1233d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng pop->operands[0] = (1 << rFP | 1 << rlr); 1234d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng setupResourceMasks(pop); 1235d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng dvmCompilerInsertLIRAfter((LIR *) origLIR, (LIR *) pop); 1236d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng} 1237d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng#endif 1238