15d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* 25d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Copyright (C) 2009 The Android Open Source Project 35d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * 45d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 55d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * you may not use this file except in compliance with the License. 65d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * You may obtain a copy of the License at 75d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * 85d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * http://www.apache.org/licenses/LICENSE-2.0 95d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * 105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Unless required by applicable law or agreed to in writing, software 115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * distributed under the License is distributed on an "AS IS" BASIS, 125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * See the License for the specific language governing permissions and 145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * limitations under the License. 155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* 185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * This file contains codegen for the Thumb ISA and is intended to be 195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * includes by: 205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * 215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Codegen-$(TARGET_ARCH_VARIANT).c 225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * 235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 245d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* 262e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * Reserve 6 bytes at the beginning of the trace 272e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * +----------------------------+ 282e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * | prof count addr (4 bytes) | 292e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * +----------------------------+ 302e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * | chain cell offset (2 bytes)| 312e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * +----------------------------+ 322e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * 332e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * ...and then code to increment the execution 342e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * 352e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * For continuous profiling (12 bytes): 362e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * 372e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * mov r0, pc @ move adr of "mov r0,pc" + 4 to r0 382e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * sub r0, #10 @ back up to addr prof count pointer 392e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * ldr r0, [r0] @ get address of counter 402e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * ldr r1, [r0] 412e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * add r1, #1 422e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * str r1, [r0] 432e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * 442e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * For periodic profiling (4 bytes): 452e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * call TEMPLATE_PERIODIC_PROFILING 462e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * 472e152baec01433de9c63633ebc6f4adf1cea3a87buzbee * and return the size (in bytes) of the generated code. 482e152baec01433de9c63633ebc6f4adf1cea3a87buzbee */ 492e152baec01433de9c63633ebc6f4adf1cea3a87buzbee 502e152baec01433de9c63633ebc6f4adf1cea3a87buzbeestatic int genTraceProfileEntry(CompilationUnit *cUnit) 512e152baec01433de9c63633ebc6f4adf1cea3a87buzbee{ 522e152baec01433de9c63633ebc6f4adf1cea3a87buzbee intptr_t addr = (intptr_t)dvmJitNextTraceCounter(); 532e152baec01433de9c63633ebc6f4adf1cea3a87buzbee assert(__BYTE_ORDER == __LITTLE_ENDIAN); 542e152baec01433de9c63633ebc6f4adf1cea3a87buzbee newLIR1(cUnit, kArm16BitData, addr & 0xffff); 552e152baec01433de9c63633ebc6f4adf1cea3a87buzbee newLIR1(cUnit, kArm16BitData, (addr >> 16) & 0xffff); 562e152baec01433de9c63633ebc6f4adf1cea3a87buzbee cUnit->chainCellOffsetLIR = 572e152baec01433de9c63633ebc6f4adf1cea3a87buzbee (LIR *) newLIR1(cUnit, kArm16BitData, CHAIN_CELL_OFFSET_TAG); 582e152baec01433de9c63633ebc6f4adf1cea3a87buzbee cUnit->headerSize = 6; 592e152baec01433de9c63633ebc6f4adf1cea3a87buzbee if ((gDvmJit.profileMode == kTraceProfilingContinuous) || 602e152baec01433de9c63633ebc6f4adf1cea3a87buzbee (gDvmJit.profileMode == kTraceProfilingDisabled)) { 612e152baec01433de9c63633ebc6f4adf1cea3a87buzbee /* Thumb instruction used directly here to ensure correct size */ 6220d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng newLIR2(cUnit, kThumbMovRR_H2L, r0, r15pc); 632e152baec01433de9c63633ebc6f4adf1cea3a87buzbee newLIR2(cUnit, kThumbSubRI8, r0, 10); 642e152baec01433de9c63633ebc6f4adf1cea3a87buzbee newLIR3(cUnit, kThumbLdrRRI5, r0, r0, 0); 652e152baec01433de9c63633ebc6f4adf1cea3a87buzbee newLIR3(cUnit, kThumbLdrRRI5, r1, r0, 0); 662e152baec01433de9c63633ebc6f4adf1cea3a87buzbee newLIR2(cUnit, kThumbAddRI8, r1, 1); 672e152baec01433de9c63633ebc6f4adf1cea3a87buzbee newLIR3(cUnit, kThumbStrRRI5, r1, r0, 0); 682e152baec01433de9c63633ebc6f4adf1cea3a87buzbee return 12; 692e152baec01433de9c63633ebc6f4adf1cea3a87buzbee } else { 702e152baec01433de9c63633ebc6f4adf1cea3a87buzbee int opcode = TEMPLATE_PERIODIC_PROFILING; 712e152baec01433de9c63633ebc6f4adf1cea3a87buzbee newLIR2(cUnit, kThumbBlx1, 722e152baec01433de9c63633ebc6f4adf1cea3a87buzbee (int) gDvmJit.codeCache + templateEntryOffsets[opcode], 732e152baec01433de9c63633ebc6f4adf1cea3a87buzbee (int) gDvmJit.codeCache + templateEntryOffsets[opcode]); 742e152baec01433de9c63633ebc6f4adf1cea3a87buzbee newLIR2(cUnit, kThumbBlx2, 752e152baec01433de9c63633ebc6f4adf1cea3a87buzbee (int) gDvmJit.codeCache + templateEntryOffsets[opcode], 762e152baec01433de9c63633ebc6f4adf1cea3a87buzbee (int) gDvmJit.codeCache + templateEntryOffsets[opcode]); 772e152baec01433de9c63633ebc6f4adf1cea3a87buzbee return 4; 782e152baec01433de9c63633ebc6f4adf1cea3a87buzbee } 792e152baec01433de9c63633ebc6f4adf1cea3a87buzbee} 802e152baec01433de9c63633ebc6f4adf1cea3a87buzbee 812e152baec01433de9c63633ebc6f4adf1cea3a87buzbee/* 825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Perform a "reg cmp imm" operation and jump to the PCR region if condition 835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * satisfies. 845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void genNegFloat(CompilationUnit *cUnit, RegLocation rlDest, 865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlSrc) 875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlResult; 895d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc = loadValue(cUnit, rlSrc, kCoreReg); 90c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true); 915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opRegRegImm(cUnit, kOpAdd, rlResult.lowReg, 925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc.lowReg, 0x80000000); 935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValue(cUnit, rlDest, rlResult); 945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void genNegDouble(CompilationUnit *cUnit, RegLocation rlDest, 97c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee RegLocation rlSrc) 985d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 995d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlResult; 1005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg); 101c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true); 1025d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opRegRegImm(cUnit, kOpAdd, rlResult.highReg, rlSrc.highReg, 1035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 0x80000000); 1045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg); 1055d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValueWide(cUnit, rlDest, rlResult); 1065d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 1075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void genMulLong(CompilationUnit *cUnit, RegLocation rlDest, 1095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlSrc1, RegLocation rlSrc2) 1105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 1115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlResult; 1125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1); 1135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3); 1145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genDispatchToHandler(cUnit, TEMPLATE_MUL_LONG); 115c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerGetReturnWide(cUnit); 1165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValueWide(cUnit, rlDest, rlResult); 1175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 1185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 119434bae646046871c334b95bd9123a78da66c27c3Bill Buzbeestatic bool partialOverlap(int sreg1, int sreg2) 12080cef8675b2ce54faa31e837b79db9f66d8e652cBill Buzbee{ 12180cef8675b2ce54faa31e837b79db9f66d8e652cBill Buzbee return abs(sreg1 - sreg2) == 1; 12280cef8675b2ce54faa31e837b79db9f66d8e652cBill Buzbee} 12380cef8675b2ce54faa31e837b79db9f66d8e652cBill Buzbee 12480cef8675b2ce54faa31e837b79db9f66d8e652cBill Buzbeestatic void genLong3Addr(CompilationUnit *cUnit, MIR *mir, OpKind firstOp, 1255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng OpKind secondOp, RegLocation rlDest, 1265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlSrc1, RegLocation rlSrc2) 1275d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 1285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlResult; 12980cef8675b2ce54faa31e837b79db9f66d8e652cBill Buzbee if (partialOverlap(rlSrc1.sRegLow,rlSrc2.sRegLow) || 13080cef8675b2ce54faa31e837b79db9f66d8e652cBill Buzbee partialOverlap(rlSrc1.sRegLow,rlDest.sRegLow) || 13180cef8675b2ce54faa31e837b79db9f66d8e652cBill Buzbee partialOverlap(rlSrc2.sRegLow,rlDest.sRegLow)) { 13280cef8675b2ce54faa31e837b79db9f66d8e652cBill Buzbee // Rare case - not enough registers to properly handle 13380cef8675b2ce54faa31e837b79db9f66d8e652cBill Buzbee genInterpSingleStep(cUnit, mir); 13480cef8675b2ce54faa31e837b79db9f66d8e652cBill Buzbee } else if (rlDest.sRegLow == rlSrc1.sRegLow) { 1355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Already 2-operand 1365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlResult = loadValueWide(cUnit, rlDest, kCoreReg); 1375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg); 1385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opRegReg(cUnit, firstOp, rlResult.lowReg, rlSrc2.lowReg); 1395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opRegReg(cUnit, secondOp, rlResult.highReg, rlSrc2.highReg); 1405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValueWide(cUnit, rlDest, rlResult); 1415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else if (rlDest.sRegLow == rlSrc2.sRegLow) { 1425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Bad case - must use/clobber Src1 and reassign Dest 1435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg); 1445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlResult = loadValueWide(cUnit, rlDest, kCoreReg); 1455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opRegReg(cUnit, firstOp, rlSrc1.lowReg, rlResult.lowReg); 1465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opRegReg(cUnit, secondOp, rlSrc1.highReg, rlResult.highReg); 1475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Old reg assignments are now invalid 148c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rlResult.lowReg); 149c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rlResult.highReg); 150c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rlSrc1.lowReg); 151c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rlSrc1.highReg); 1525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlDest.location = kLocDalvikFrame; 1535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlSrc1.location == kLocPhysReg); 1545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Reassign registers - rlDest will now get rlSrc1's old regs 1555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValueWide(cUnit, rlDest, rlSrc1); 1565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 1575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Copy Src1 to Dest 1585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg); 159c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, false); 1605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadValueDirectWide(cUnit, rlSrc1, rlResult.lowReg, 1615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlResult.highReg); 1625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlResult.location = kLocPhysReg; 1635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opRegReg(cUnit, firstOp, rlResult.lowReg, rlSrc2.lowReg); 1645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng opRegReg(cUnit, secondOp, rlResult.highReg, rlSrc2.highReg); 1655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValueWide(cUnit, rlDest, rlResult); 1665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 1685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengvoid dvmCompilerInitializeRegAlloc(CompilationUnit *cUnit) 1705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 1715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int numTemps = sizeof(coreTemps)/sizeof(int); 172a118989d1b33e1513f08863e58308e7e3a68a18aBen Cheng RegisterPool *pool = (RegisterPool *) dvmCompilerNew(sizeof(*pool), true); 1735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng cUnit->regPool = pool; 1745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng pool->numCoreTemps = numTemps; 175a118989d1b33e1513f08863e58308e7e3a68a18aBen Cheng pool->coreTemps = (RegisterInfo *) 1765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dvmCompilerNew(numTemps * sizeof(*pool->coreTemps), true); 1775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng pool->numFPTemps = 0; 1785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng pool->FPTemps = NULL; 179c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerInitPool(pool->coreTemps, coreTemps, pool->numCoreTemps); 180c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerInitPool(pool->FPTemps, NULL, 0); 1815d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng pool->nullCheckedRegs = 1825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng dvmCompilerAllocBitVector(cUnit->numSSARegs, false); 1835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 1845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* Export the Dalvik PC assicated with an instruction to the StackSave area */ 1865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *genExportPC(CompilationUnit *cUnit, MIR *mir) 1875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 1885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *res; 189c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int rDPC = dvmCompilerAllocTemp(cUnit); 190c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int rAddr = dvmCompilerAllocTemp(cUnit); 1915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int offset = offsetof(StackSaveArea, xtra.currentPc); 1925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng res = loadConstant(cUnit, rDPC, (int) (cUnit->method->insns + mir->offset)); 19320d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng newLIR2(cUnit, kThumbMovRR, rAddr, r5FP); 1945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumbSubRI8, rAddr, sizeof(StackSaveArea) - offset); 1955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeWordDisp( cUnit, rAddr, 0, rDPC); 1965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return res; 1975d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 1985d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1995d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void genMonitor(CompilationUnit *cUnit, MIR *mir) 2005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 2015d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genMonitorPortable(cUnit, mir); 2025d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 2035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 2045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void genCmpLong(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest, 2055d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlSrc1, RegLocation rlSrc2) 2065d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 2075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlResult; 2085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1); 2095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3); 2105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genDispatchToHandler(cUnit, TEMPLATE_CMP_LONG); 211c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlResult = dvmCompilerGetReturn(cUnit); 2125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeValue(cUnit, rlDest, rlResult); 2135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 2145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 2155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genInlinedAbsFloat(CompilationUnit *cUnit, MIR *mir) 2165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 217cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee int offset = offsetof(Thread, interpSave.retval); 218c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee RegLocation rlSrc = dvmCompilerGetSrc(cUnit, mir, 0); 2195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int reg0 = loadValue(cUnit, rlSrc, kCoreReg).lowReg; 220c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int signMask = dvmCompilerAllocTemp(cUnit); 2215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadConstant(cUnit, signMask, 0x7fffffff); 2225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumbAndRR, reg0, signMask); 223c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, signMask); 22420d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng storeWordDisp(cUnit, r6SELF, offset, reg0); 2251f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee //TUNING: rewrite this to not clobber 226c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, reg0); 2277e914f110323165e7f683eece444ef83a499596dElliott Hughes return false; 2285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 2295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 2305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genInlinedAbsDouble(CompilationUnit *cUnit, MIR *mir) 2315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 232cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee int offset = offsetof(Thread, interpSave.retval); 233c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee RegLocation rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1); 2345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation regSrc = loadValueWide(cUnit, rlSrc, kCoreReg); 2355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int reglo = regSrc.lowReg; 2365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int reghi = regSrc.highReg; 237c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int signMask = dvmCompilerAllocTemp(cUnit); 2385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadConstant(cUnit, signMask, 0x7fffffff); 23920d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng storeWordDisp(cUnit, r6SELF, offset, reglo); 2405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumbAndRR, reghi, signMask); 241c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerFreeTemp(cUnit, signMask); 24220d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng storeWordDisp(cUnit, r6SELF, offset + 4, reghi); 2431f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee //TUNING: rewrite this to not clobber 244c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, reghi); 2457e914f110323165e7f683eece444ef83a499596dElliott Hughes return false; 2465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 2475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 2485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* No select in thumb, so we need to branch. Thumb2 will do better */ 2495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic bool genInlinedMinMaxInt(CompilationUnit *cUnit, MIR *mir, bool isMin) 2505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 251cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee int offset = offsetof(Thread, interpSave.retval); 252c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee RegLocation rlSrc1 = dvmCompilerGetSrc(cUnit, mir, 0); 253c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee RegLocation rlSrc2 = dvmCompilerGetSrc(cUnit, mir, 1); 2545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int reg0 = loadValue(cUnit, rlSrc1, kCoreReg).lowReg; 2555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int reg1 = loadValue(cUnit, rlSrc2, kCoreReg).lowReg; 2565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumbCmpRR, reg0, reg1); 2575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *branch1 = newLIR2(cUnit, kThumbBCond, 2, 2585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng isMin ? kArmCondLt : kArmCondGt); 2595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng newLIR2(cUnit, kThumbMovRR, reg0, reg1); 2605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel); 2615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng target->defMask = ENCODE_ALL; 26220d7e6c67af128d5bf7cc003564a8122c4101c84Ben Cheng newLIR3(cUnit, kThumbStrRRI5, reg0, r6SELF, offset >> 2); 2635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng branch1->generic.target = (LIR *)target; 2641f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee //TUNING: rewrite this to not clobber 265c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit,reg0); 2665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return false; 2675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 2685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 269b4c05977c28c38d2f81b48d0cb15559dc3d05564Elliott Hughesstatic void genMultiplyByTwoBitMultiplier(CompilationUnit *cUnit, 270b4c05977c28c38d2f81b48d0cb15559dc3d05564Elliott Hughes RegLocation rlSrc, RegLocation rlResult, int lit, 271b4c05977c28c38d2f81b48d0cb15559dc3d05564Elliott Hughes int firstBit, int secondBit) 272b4c05977c28c38d2f81b48d0cb15559dc3d05564Elliott Hughes{ 273b4c05977c28c38d2f81b48d0cb15559dc3d05564Elliott Hughes // We can't implement "add src, src, src, lsl#shift" on Thumb, so we have 274b4c05977c28c38d2f81b48d0cb15559dc3d05564Elliott Hughes // to do a regular multiply. 275b4c05977c28c38d2f81b48d0cb15559dc3d05564Elliott Hughes opRegRegImm(cUnit, kOpMul, rlResult.lowReg, rlSrc.lowReg, lit); 276b4c05977c28c38d2f81b48d0cb15559dc3d05564Elliott Hughes} 27720111d635e9210bdd105219eceb263607ec4d5c5Anders O Nilsson 27820111d635e9210bdd105219eceb263607ec4d5c5Anders O Nilssonstatic void genMultiplyByShiftAndReverseSubtract(CompilationUnit *cUnit, 27920111d635e9210bdd105219eceb263607ec4d5c5Anders O Nilsson RegLocation rlSrc, RegLocation rlResult, int lit) 28020111d635e9210bdd105219eceb263607ec4d5c5Anders O Nilsson{ 28120111d635e9210bdd105219eceb263607ec4d5c5Anders O Nilsson int tReg = dvmCompilerAllocTemp(cUnit); 28220111d635e9210bdd105219eceb263607ec4d5c5Anders O Nilsson opRegRegImm(cUnit, kOpLsl, tReg, rlSrc.lowReg, lit); 28320111d635e9210bdd105219eceb263607ec4d5c5Anders O Nilsson opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg, rlSrc.lowReg); 28420111d635e9210bdd105219eceb263607ec4d5c5Anders O Nilsson} 285