1a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 2a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Copyright (C) 2009 The Android Open Source Project 3a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 4a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Licensed under the Apache License, Version 2.0 (the "License"); 5a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * you may not use this file except in compliance with the License. 6a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * You may obtain a copy of the License at 7a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 8a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * http://www.apache.org/licenses/LICENSE-2.0 9a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 10a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Unless required by applicable law or agreed to in writing, software 11a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * distributed under the License is distributed on an "AS IS" BASIS, 12a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * See the License for the specific language governing permissions and 14a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * limitations under the License. 15a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 16a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 17a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 18a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * This file contains codegen for the Thumb ISA and is intended to be 19a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * includes by: 20a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 21a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Codegen-$(TARGET_ARCH_VARIANT).c 22a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 23a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 24a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 25a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic int coreTemps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2, 26a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham r_T3, r_T4, r_T5, r_T6, r_T7, r_T8, r_T9, r_S0, r_S4}; 27a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 28a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic int fpTemps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7, 29a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15}; 30a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 31a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 32a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void storePair(CompilationUnit *cUnit, int base, int lowReg, 33a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int highReg); 34a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg); 35a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadWordDisp(CompilationUnit *cUnit, int rBase, int displacement, 36a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rDest); 37a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *storeWordDisp(CompilationUnit *cUnit, int rBase, 38a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int displacement, int rSrc); 39a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *genRegRegCheck(CompilationUnit *cUnit, 40a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsConditionCode cond, 41a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int reg1, int reg2, int dOffset, 42a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *pcrLabel); 43a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value); 44a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 45a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 46a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) 47a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 48a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR* res = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true); 49a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->operands[0] = rDest; 50a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->operands[1] = rSrc; 51a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (rDest == rSrc) { 52a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->flags.isNop = true; 53a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 54a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* must be both DOUBLE or both not DOUBLE */ 55a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(DOUBLEREG(rDest) == DOUBLEREG(rSrc)); 56a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (DOUBLEREG(rDest)) { 57a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->opcode = kMipsFmovd; 58a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 59a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (SINGLEREG(rDest)) { 60a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (SINGLEREG(rSrc)) { 61a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->opcode = kMipsFmovs; 62a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 63a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* note the operands are swapped for the mtc1 instr */ 64a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->opcode = kMipsMtc1; 65a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->operands[0] = rSrc; 66a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->operands[1] = rDest; 67a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 68a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 69a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(SINGLEREG(rSrc)); 70a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->opcode = kMipsMfc1; 71a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 72a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 73a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 74a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham setupResourceMasks(res); 75a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; 76a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 77a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 78a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 79a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 80a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Load a immediate using a shortcut if possible; otherwise 81a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * grab from the per-translation literal pool. If target is 82a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * a high register, build constant into a low register and copy. 83a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 84a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * No additional register clobbering operation performed. Use this version when 85a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 1) rDest is freshly returned from dvmCompilerAllocTemp or 86a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 2) The codegen is under fixed register usage 87a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 88a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest, 89a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int value) 90a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 91a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res; 92a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 93a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 94a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rDestSave = rDest; 95a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int isFpReg = FPREG(rDest); 96a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (isFpReg) { 97a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(SINGLEREG(rDest)); 98a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham rDest = dvmCompilerAllocTemp(cUnit); 99a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 100a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 101a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 102a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* See if the value can be constructed cheaply */ 103a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (value == 0) { 104a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR2(cUnit, kMipsMove, rDest, r_ZERO); 105a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if ((value > 0) && (value <= 65535)) { 106a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR3(cUnit, kMipsOri, rDest, r_ZERO, value); 107a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if ((value < 0) && (value >= -32768)) { 108a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR3(cUnit, kMipsAddiu, rDest, r_ZERO, value); 109a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 110a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR2(cUnit, kMipsLui, rDest, value>>16); 111a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (value & 0xffff) 112a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR3(cUnit, kMipsOri, rDest, rDest, value); 113a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 114a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 115a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 116a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (isFpReg) { 117a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR2(cUnit, kMipsMtc1, rDest, rDestSave); 118a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerFreeTemp(cUnit, rDest); 119a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 120a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 121a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 122a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; 123a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 124a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 125a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 126a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Load an immediate value into a fixed or temp register. Target 127a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * register is clobbered, and marked inUse. 128a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 129a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value) 130a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 131a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (dvmCompilerIsTemp(cUnit, rDest)) { 132a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerClobber(cUnit, rDest); 133a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerMarkInUse(cUnit, rDest); 134a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 135a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return loadConstantNoClobber(cUnit, rDest, value); 136a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 137a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 138a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 139a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Load a class pointer value into a fixed or temp register. Target 140a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * register is clobbered, and marked inUse. 141a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 142a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadClassPointer(CompilationUnit *cUnit, int rDest, int value) 143a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 144a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res; 145a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (dvmCompilerIsTemp(cUnit, rDest)) { 146a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerClobber(cUnit, rDest); 147a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerMarkInUse(cUnit, rDest); 148a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 149a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR2(cUnit, kMipsLui, rDest, value>>16); 150a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (value & 0xffff) 151a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR3(cUnit, kMipsOri, rDest, rDest, value); 152a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; 153a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 154a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 155a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opNone(CompilationUnit *cUnit, OpKind op) 156a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 157a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res; 158a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsOpCode opcode = kMipsNop; 159a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham switch (op) { 160a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpUncondBr: 161a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsB; 162a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 163a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham default: 164fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham ALOGE("Jit: bad case in opNone"); 165a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAbort(cUnit); 166a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 167a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR0(cUnit, opcode); 168a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; 169a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 170a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 171a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opCompareBranch(CompilationUnit *cUnit, MipsOpCode opc, int rs, int rt) 172a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 173a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res; 174a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (rt < 0) { 175a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(opc >= kMipsBeqz && opc <= kMipsBnez); 176a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR1(cUnit, opc, rs); 177a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 178a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(opc == kMipsBeq || opc == kMipsBne); 179a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR2(cUnit, opc, rs, rt); 180a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 181a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; 182a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 183a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 184a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask); 185a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 186a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc) 187a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 188a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsOpCode opcode = kMipsNop; 189a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham switch (op) { 190a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpBlx: 191a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsJalr; 192a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 193a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham default: 194a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(0); 195a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 196a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return newLIR2(cUnit, opcode, r_RA, rDestSrc); 197a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 198a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 199a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest, 200a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rSrc1, int value); 201a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1, 202a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int value) 203a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 204a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res; 205a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool neg = (value < 0); 206a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int absValue = (neg) ? -value : value; 207a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool shortForm = (absValue & 0xff) == absValue; 208a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsOpCode opcode = kMipsNop; 209a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham switch (op) { 210a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpAdd: 211a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value); 212a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 213a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpSub: 214a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value); 215a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 216a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham default: 217fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham ALOGE("Jit: bad case in opRegImm"); 218a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAbort(cUnit); 219a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 220a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 221a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (shortForm) 222a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR2(cUnit, opcode, rDestSrc1, absValue); 223a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham else { 224a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rScratch = dvmCompilerAllocTemp(cUnit); 225a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = loadConstant(cUnit, rScratch, value); 226a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (op == kOpCmp) 227a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR2(cUnit, opcode, rDestSrc1, rScratch); 228a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham else 229a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR3(cUnit, opcode, rDestSrc1, rDestSrc1, rScratch); 230a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 231a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; 232a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 233a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 234a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opRegRegReg(CompilationUnit *cUnit, OpKind op, int rDest, 235a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rSrc1, int rSrc2) 236a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 237a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsOpCode opcode = kMipsNop; 238a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham switch (op) { 239a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpAdd: 240a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsAddu; 241a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 242a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpSub: 243a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSubu; 244a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 245a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpAnd: 246a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsAnd; 247a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 248a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpMul: 249a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsMul; 250a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 251a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpOr: 252a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsOr; 253a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 254a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpXor: 255a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsXor; 256a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 257a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpLsl: 258a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSllv; 259a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 260a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpLsr: 261a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSrlv; 262a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 263a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpAsr: 264a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSrav; 265a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 266a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham default: 267fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham ALOGE("Jit: bad case in opRegRegReg"); 268a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAbort(cUnit); 269a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 270a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 271a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return newLIR3(cUnit, opcode, rDest, rSrc1, rSrc2); 272a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 273a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 274a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest, 275a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rSrc1, int value) 276a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 277a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res; 278a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsOpCode opcode = kMipsNop; 279a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool shortForm = true; 280a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 281a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham switch(op) { 282a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpAdd: 283a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (IS_SIMM16(value)) { 284a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsAddiu; 285a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 286a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham else { 287a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham shortForm = false; 288a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsAddu; 289a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 290a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 291a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpSub: 292a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (IS_SIMM16((-value))) { 293a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham value = -value; 294a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsAddiu; 295a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 296a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham else { 297a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham shortForm = false; 298a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSubu; 299a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 300a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 301a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpLsl: 302a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(value >= 0 && value <= 31); 303a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSll; 304a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 305a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpLsr: 306a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(value >= 0 && value <= 31); 307a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSrl; 308a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 309a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpAsr: 310a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(value >= 0 && value <= 31); 311a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSra; 312a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 313a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpAnd: 314a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (IS_UIMM16((value))) { 315a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsAndi; 316a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 317a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham else { 318a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham shortForm = false; 319a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsAnd; 320a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 321a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 322a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpOr: 323a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (IS_UIMM16((value))) { 324a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsOri; 325a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 326a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham else { 327a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham shortForm = false; 328a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsOr; 329a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 330a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 331a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpXor: 332a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (IS_UIMM16((value))) { 333a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsXori; 334a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 335a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham else { 336a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham shortForm = false; 337a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsXor; 338a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 339a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 340a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpMul: 341a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham shortForm = false; 342a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsMul; 343a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 344a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham default: 345fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham ALOGE("Jit: bad case in opRegRegImm"); 346a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAbort(cUnit); 347a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 348a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 349a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 350a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (shortForm) 351a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR3(cUnit, opcode, rDest, rSrc1, value); 352a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham else { 353a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (rDest != rSrc1) { 354a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = loadConstant(cUnit, rDest, value); 355a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR3(cUnit, opcode, rDest, rSrc1, rDest); 356a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 357a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rScratch = dvmCompilerAllocTemp(cUnit); 358a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = loadConstant(cUnit, rScratch, value); 359a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR3(cUnit, opcode, rDest, rSrc1, rScratch); 360a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 361a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 362a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; 363a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 364a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 365a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1, 366a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rSrc2) 367a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 368a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsOpCode opcode = kMipsNop; 369a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res; 370a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham switch (op) { 371a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpMov: 372a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsMove; 373a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 374a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpMvn: 375a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return newLIR3(cUnit, kMipsNor, rDestSrc1, rSrc2, r_ZERO); 376a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpNeg: 377a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return newLIR3(cUnit, kMipsSubu, rDestSrc1, r_ZERO, rSrc2); 378a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpAdd: 379a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpAnd: 380a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpMul: 381a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpOr: 382a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpSub: 383a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOpXor: 384a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return opRegRegReg(cUnit, op, rDestSrc1, rDestSrc1, rSrc2); 385a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOp2Byte: 386a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if __mips_isa_rev>=2 387a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR2(cUnit, kMipsSeb, rDestSrc1, rSrc2); 388a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#else 389a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = opRegRegImm(cUnit, kOpLsl, rDestSrc1, rSrc2, 24); 390a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opRegRegImm(cUnit, kOpAsr, rDestSrc1, rDestSrc1, 24); 391a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 392a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; 393a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOp2Short: 394a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if __mips_isa_rev>=2 395a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR2(cUnit, kMipsSeh, rDestSrc1, rSrc2); 396a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#else 397a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = opRegRegImm(cUnit, kOpLsl, rDestSrc1, rSrc2, 16); 398a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opRegRegImm(cUnit, kOpAsr, rDestSrc1, rDestSrc1, 16); 399a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 400a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; 401a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kOp2Char: 402a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return newLIR3(cUnit, kMipsAndi, rDestSrc1, rSrc2, 0xFFFF); 403a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham default: 404fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham ALOGE("Jit: bad case in opRegReg"); 405a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAbort(cUnit); 406a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 407a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 408a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return newLIR2(cUnit, opcode, rDestSrc1, rSrc2); 409a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 410a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 411a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadConstantValueWide(CompilationUnit *cUnit, int rDestLo, 412a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rDestHi, int valLo, int valHi) 413a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 414a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res; 415a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = loadConstantNoClobber(cUnit, rDestLo, valLo); 416a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham loadConstantNoClobber(cUnit, rDestHi, valHi); 417a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; 418a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 419a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 420a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* Load value from base + scaled index. */ 421a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase, 422a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rIndex, int rDest, int scale, OpSize size) 423a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 424a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *first = NULL; 425a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res; 426a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsOpCode opcode = kMipsNop; 427a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int tReg = dvmCompilerAllocTemp(cUnit); 428a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 429a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 430a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (FPREG(rDest)) { 431a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(SINGLEREG(rDest)); 432a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert((size == kWord) || (size == kSingle)); 433a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham size = kSingle; 434a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 435a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (size == kSingle) 436a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham size = kWord; 437a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 438a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 439a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 440a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!scale) { 441a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham first = newLIR3(cUnit, kMipsAddu, tReg , rBase, rIndex); 442a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 443a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham first = opRegRegImm(cUnit, kOpLsl, tReg, rIndex, scale); 444a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR3(cUnit, kMipsAddu, tReg , rBase, tReg); 445a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 446a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 447a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham switch (size) { 448a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 449a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kSingle: 450a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsFlwc1; 451a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 452a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 453a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kWord: 454a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsLw; 455a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 456a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kUnsignedHalf: 457a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsLhu; 458a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 459a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kSignedHalf: 460a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsLh; 461a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 462a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kUnsignedByte: 463a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsLbu; 464a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 465a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kSignedByte: 466a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsLb; 467a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 468a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham default: 469fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham ALOGE("Jit: bad case in loadBaseIndexed"); 470a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAbort(cUnit); 471a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 472a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 473a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR3(cUnit, opcode, rDest, 0, tReg); 474a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION) 475a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (cUnit->heapMemOp) 476a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->flags.insertWrapper = true; 477a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 478a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerFreeTemp(cUnit, tReg); 479a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return (first) ? first : res; 480a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 481a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 482a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* store value base base + scaled index. */ 483a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase, 484a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rIndex, int rSrc, int scale, OpSize size) 485a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 486a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *first = NULL; 487a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res; 488a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsOpCode opcode = kMipsNop; 489a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rNewIndex = rIndex; 490a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int tReg = dvmCompilerAllocTemp(cUnit); 491a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 492a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 493a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (FPREG(rSrc)) { 494a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(SINGLEREG(rSrc)); 495a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert((size == kWord) || (size == kSingle)); 496a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham size = kSingle; 497a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 498a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (size == kSingle) 499a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham size = kWord; 500a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 501a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 502a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 503a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!scale) { 504a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham first = newLIR3(cUnit, kMipsAddu, tReg , rBase, rIndex); 505a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 506a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham first = opRegRegImm(cUnit, kOpLsl, tReg, rIndex, scale); 507a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR3(cUnit, kMipsAddu, tReg , rBase, tReg); 508a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 509a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 510a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham switch (size) { 511a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 512a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kSingle: 513a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsFswc1; 514a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 515a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 516a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kWord: 517a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSw; 518a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 519a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kUnsignedHalf: 520a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kSignedHalf: 521a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSh; 522a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 523a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kUnsignedByte: 524a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kSignedByte: 525a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSb; 526a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 527a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham default: 528fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham ALOGE("Jit: bad case in storeBaseIndexed"); 529a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAbort(cUnit); 530a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 531a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = newLIR3(cUnit, opcode, rSrc, 0, tReg); 532a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION) 533a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (cUnit->heapMemOp) 534a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->flags.insertWrapper = true; 535a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 536a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerFreeTemp(cUnit, rNewIndex); 537a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return first; 538a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 539a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 540a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask) 541a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 542a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int i; 543a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int loadCnt = 0; 544a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res = NULL ; 545a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham genBarrier(cUnit); 546a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 547a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (i = 0; i < 8; i++, rMask >>= 1) { 548a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (rMask & 0x1) { /* map r0 to MIPS r_A0 */ 549a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR3(cUnit, kMipsLw, i+r_A0, loadCnt*4, rBase); 550a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham loadCnt++; 551a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 552a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 553a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 554a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (loadCnt) {/* increment after */ 555a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR3(cUnit, kMipsAddiu, rBase, rBase, loadCnt*4); 556a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 557a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 558a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION) 559a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (cUnit->heapMemOp) 560a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->flags.insertWrapper = true; 561a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 562a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham genBarrier(cUnit); 563a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; /* NULL always returned which should be ok since no callers use it */ 564a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 565a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 566a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask) 567a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 568a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int i; 569a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int storeCnt = 0; 570a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res = NULL ; 571a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham genBarrier(cUnit); 572a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 573a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (i = 0; i < 8; i++, rMask >>= 1) { 574a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (rMask & 0x1) { /* map r0 to MIPS r_A0 */ 575a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR3(cUnit, kMipsSw, i+r_A0, storeCnt*4, rBase); 576a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham storeCnt++; 577a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 578a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 579a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 580a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (storeCnt) { /* increment after */ 581a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR3(cUnit, kMipsAddiu, rBase, rBase, storeCnt*4); 582a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 583a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 584a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION) 585a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (cUnit->heapMemOp) 586a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->flags.insertWrapper = true; 587a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 588a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham genBarrier(cUnit); 589a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; /* NULL always returned which should be ok since no callers use it */ 590a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 591a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 592a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase, 593a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int displacement, int rDest, int rDestHi, 594a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham OpSize size, int sReg) 595a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 596a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Load value from base + displacement. Optionally perform null check 597a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * on base (which must have an associated sReg and MIR). If not 598a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * performing null check, incoming MIR can be null. IMPORTANT: this 599a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * code must not allocate any new temps. If a new register is needed 600a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * and base and dest are the same, spill some other register to 601a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * rlp and then restore. 602a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 603a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 604a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res; 605a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *load = NULL; 606a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *load2 = NULL; 607a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsOpCode opcode = kMipsNop; 608a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool shortForm = IS_SIMM16(displacement); 609a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool pair = false; 610a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 611a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham switch (size) { 612a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kLong: 613a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kDouble: 614a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham pair = true; 615a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsLw; 616a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 617a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (FPREG(rDest)) { 618a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsFlwc1; 619a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (DOUBLEREG(rDest)) { 620a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham rDest = rDest - FP_DOUBLE; 621a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 622a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(FPREG(rDestHi)); 623a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(rDest == (rDestHi - 1)); 624a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 625a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham rDestHi = rDest + 1; 626a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 627a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 628a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham shortForm = IS_SIMM16_2WORD(displacement); 629a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert((displacement & 0x3) == 0); 630a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 631a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kWord: 632a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kSingle: 633a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsLw; 634a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 635a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (FPREG(rDest)) { 636a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsFlwc1; 637a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(SINGLEREG(rDest)); 638a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 639a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 640a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert((displacement & 0x3) == 0); 641a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 642a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kUnsignedHalf: 643a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsLhu; 644a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert((displacement & 0x1) == 0); 645a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 646a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kSignedHalf: 647a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsLh; 648a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert((displacement & 0x1) == 0); 649a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 650a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kUnsignedByte: 651a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsLbu; 652a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 653a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kSignedByte: 654a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsLb; 655a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 656a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham default: 657fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham ALOGE("Jit: bad case in loadBaseIndexedBody"); 658a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAbort(cUnit); 659a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 660a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 661a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (shortForm) { 662a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!pair) { 663a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham load = res = newLIR3(cUnit, opcode, rDest, displacement, rBase); 664a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 665a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham load = res = newLIR3(cUnit, opcode, rDest, displacement + LOWORD_OFFSET, rBase); 666a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham load2 = newLIR3(cUnit, opcode, rDestHi, displacement + HIWORD_OFFSET, rBase); 667a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 668a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 669a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (pair) { 670a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rTmp = dvmCompilerAllocFreeTemp(cUnit); 671a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = opRegRegImm(cUnit, kOpAdd, rTmp, rBase, displacement); 672a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham load = newLIR3(cUnit, opcode, rDest, LOWORD_OFFSET, rTmp); 673a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham load2 = newLIR3(cUnit, opcode, rDestHi, HIWORD_OFFSET, rTmp); 674a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerFreeTemp(cUnit, rTmp); 675a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 676a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rTmp = (rBase == rDest) ? dvmCompilerAllocFreeTemp(cUnit) 677a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham : rDest; 678a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = loadConstant(cUnit, rTmp, displacement); 679a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham load = newLIR3(cUnit, opcode, rDest, rBase, rTmp); 680a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (rTmp != rDest) 681a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerFreeTemp(cUnit, rTmp); 682a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 683a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 684a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 685a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (rBase == rFP) { 686a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (load != NULL) 687a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham annotateDalvikRegAccess(load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, 688a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham true /* isLoad */); 689a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (load2 != NULL) 690a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham annotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2, 691a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham true /* isLoad */); 692a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 693a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION) 694a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (load != NULL && cUnit->heapMemOp) 695a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham load->flags.insertWrapper = true; 696a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (load2 != NULL && cUnit->heapMemOp) 697a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham load2->flags.insertWrapper = true; 698a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 699a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return load; 700a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 701a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 702a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase, 703a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int displacement, int rDest, OpSize size, 704a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int sReg) 705a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 706a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1, 707a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham size, sReg); 708a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 709a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 710a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase, 711a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int displacement, int rDestLo, int rDestHi, 712a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int sReg) 713a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 714a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi, 715a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham kLong, sReg); 716a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 717a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 718a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase, 719a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int displacement, int rSrc, int rSrcHi, 720a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham OpSize size) 721a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 722a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res; 723a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *store = NULL; 724a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *store2 = NULL; 725a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsOpCode opcode = kMipsNop; 726a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool shortForm = IS_SIMM16(displacement); 727a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool pair = false; 728a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 729a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham switch (size) { 730a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kLong: 731a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kDouble: 732a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham pair = true; 733a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSw; 734a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 735a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (FPREG(rSrc)) { 736a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsFswc1; 737a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (DOUBLEREG(rSrc)) { 738a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham rSrc = rSrc - FP_DOUBLE; 739a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 740a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(FPREG(rSrcHi)); 741a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(rSrc == (rSrcHi - 1)); 742a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 743a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham rSrcHi = rSrc + 1; 744a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 745a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 746a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham shortForm = IS_SIMM16_2WORD(displacement); 747a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert((displacement & 0x3) == 0); 748a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 749a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kWord: 750a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kSingle: 751a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSw; 752a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 753a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (FPREG(rSrc)) { 754a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsFswc1; 755a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(SINGLEREG(rSrc)); 756a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 757a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 758a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert((displacement & 0x3) == 0); 759a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 760a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kUnsignedHalf: 761a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kSignedHalf: 762a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSh; 763a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert((displacement & 0x1) == 0); 764a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 765a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kUnsignedByte: 766a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham case kSignedByte: 767a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsSb; 768a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 769a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham default: 770fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham ALOGE("Jit: bad case in storeBaseIndexedBody"); 771a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAbort(cUnit); 772a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 773a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 774a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (shortForm) { 775a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!pair) { 776a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham store = res = newLIR3(cUnit, opcode, rSrc, displacement, rBase); 777a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 778a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham store = res = newLIR3(cUnit, opcode, rSrc, displacement + LOWORD_OFFSET, rBase); 779a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham store2 = newLIR3(cUnit, opcode, rSrcHi, displacement + HIWORD_OFFSET, rBase); 780a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 781a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 782a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int rScratch = dvmCompilerAllocTemp(cUnit); 783a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = opRegRegImm(cUnit, kOpAdd, rScratch, rBase, displacement); 784a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!pair) { 785a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham store = newLIR3(cUnit, opcode, rSrc, 0, rScratch); 786a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 787a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham store = newLIR3(cUnit, opcode, rSrc, LOWORD_OFFSET, rScratch); 788a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham store2 = newLIR3(cUnit, opcode, rSrcHi, HIWORD_OFFSET, rScratch); 789a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 790a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerFreeTemp(cUnit, rScratch); 791a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 792a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 793a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (rBase == rFP) { 794a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (store != NULL) 795a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham annotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, 796a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham false /* isLoad */); 797a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (store2 != NULL) 798a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham annotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2, 799a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham false /* isLoad */); 800a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 801a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 802a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION) 803a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (store != NULL && cUnit->heapMemOp) 804a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham store->flags.insertWrapper = true; 805a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (store2 != NULL && cUnit->heapMemOp) 806a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham store2->flags.insertWrapper = true; 807a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 808a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; 809a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 810a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 811a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *storeBaseDisp(CompilationUnit *cUnit, int rBase, 812a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int displacement, int rSrc, OpSize size) 813a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 814a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size); 815a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 816a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 817a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase, 818a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int displacement, int rSrcLo, int rSrcHi) 819a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 820a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong); 821a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 822a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 823a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void storePair(CompilationUnit *cUnit, int base, int lowReg, int highReg) 824a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 825a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham storeWordDisp(cUnit, base, LOWORD_OFFSET, lowReg); 826a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham storeWordDisp(cUnit, base, HIWORD_OFFSET, highReg); 827a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 828a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 829a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg) 830a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 831a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham loadWordDisp(cUnit, base, LOWORD_OFFSET , lowReg); 832a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham loadWordDisp(cUnit, base, HIWORD_OFFSET , highReg); 833a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 834a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 835a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc) 836a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 837a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR* res; 838a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsOpCode opcode; 839a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 840a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (FPREG(rDest) || FPREG(rSrc)) 841a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return fpRegCopy(cUnit, rDest, rSrc); 842a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 843a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true); 844a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opcode = kMipsMove; 845a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(LOWREG(rDest) && LOWREG(rSrc)); 846a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->operands[0] = rDest; 847a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->operands[1] = rSrc; 848a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->opcode = opcode; 849a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham setupResourceMasks(res); 850a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (rDest == rSrc) { 851a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham res->flags.isNop = true; 852a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 853a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; 854a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 855a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 856a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR* genRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) 857a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 858a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *res = genRegCopyNoInsert(cUnit, rDest, rSrc); 859a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAppendLIR(cUnit, (LIR*)res); 860a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return res; 861a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 862a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 863a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi, 864a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int srcLo, int srcHi) 865a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 866a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 867a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool destFP = FPREG(destLo) && FPREG(destHi); 868a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool srcFP = FPREG(srcLo) && FPREG(srcHi); 869a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(FPREG(srcLo) == FPREG(srcHi)); 870a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(FPREG(destLo) == FPREG(destHi)); 871a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (destFP) { 872a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (srcFP) { 873a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham genRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi)); 874a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 875a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* note the operands are swapped for the mtc1 instr */ 876a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR2(cUnit, kMipsMtc1, srcLo, destLo); 877a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR2(cUnit, kMipsMtc1, srcHi, destHi); 878a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 879a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 880a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (srcFP) { 881a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR2(cUnit, kMipsMfc1, destLo, srcLo); 882a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR2(cUnit, kMipsMfc1, destHi, srcHi); 883a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 884a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham // Handle overlap 885a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (srcHi == destLo) { 886a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham genRegCopy(cUnit, destHi, srcHi); 887a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham genRegCopy(cUnit, destLo, srcLo); 888a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 889a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham genRegCopy(cUnit, destLo, srcLo); 890a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham genRegCopy(cUnit, destHi, srcHi); 891a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 892a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 893a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 894a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#else 895a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham // Handle overlap 896a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (srcHi == destLo) { 897a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham genRegCopy(cUnit, destHi, srcHi); 898a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham genRegCopy(cUnit, destLo, srcLo); 899a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 900a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham genRegCopy(cUnit, destLo, srcLo); 901a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham genRegCopy(cUnit, destHi, srcHi); 902a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 903a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 904a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 905a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 906a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic inline MipsLIR *genRegImmCheck(CompilationUnit *cUnit, 907a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsConditionCode cond, int reg, 908a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int checkValue, int dOffset, 909a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *pcrLabel) 910a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 911a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *branch = NULL; 912a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 913a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (checkValue == 0) { 914a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsOpCode opc = kMipsNop; 915a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (cond == kMipsCondEq) { 916a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opc = kMipsBeqz; 917a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (cond == kMipsCondNe) { 918a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opc = kMipsBnez; 919a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (cond == kMipsCondLt || cond == kMipsCondMi) { 920a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opc = kMipsBltz; 921a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (cond == kMipsCondLe) { 922a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opc = kMipsBlez; 923a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (cond == kMipsCondGt) { 924a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opc = kMipsBgtz; 925a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (cond == kMipsCondGe) { 926a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham opc = kMipsBgez; 927a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 928fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham ALOGE("Jit: bad case in genRegImmCheck"); 929a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAbort(cUnit); 930a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 931a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham branch = opCompareBranch(cUnit, opc, reg, -1); 932a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (IS_SIMM16(checkValue)) { 933a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (cond == kMipsCondLt) { 934a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int tReg = dvmCompilerAllocTemp(cUnit); 935a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR3(cUnit, kMipsSlti, tReg, reg, checkValue); 936a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham branch = opCompareBranch(cUnit, kMipsBne, tReg, r_ZERO); 937a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerFreeTemp(cUnit, tReg); 938a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 939fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham ALOGE("Jit: bad case in genRegImmCheck"); 940a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAbort(cUnit); 941a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 942a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 943fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham ALOGE("Jit: bad case in genRegImmCheck"); 944a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAbort(cUnit); 945a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 946a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 947a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (cUnit->jitMode == kJitMethod) { 948a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham BasicBlock *bb = cUnit->curBlock; 949a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (bb->taken) { 950a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *exceptionLabel = (MipsLIR *) cUnit->blockLabelList; 951a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham exceptionLabel += bb->taken->id; 952a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham branch->generic.target = (LIR *) exceptionLabel; 953a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return exceptionLabel; 954a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 955fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham ALOGE("Catch blocks not handled yet"); 956a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmAbort(); 957a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return NULL; 958a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 959a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 960a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return genCheckCommon(cUnit, dOffset, branch, pcrLabel); 961a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 962a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 963a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 964a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION) 965a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void genSelfVerificationPreBranch(CompilationUnit *cUnit, 966a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *origLIR) { 967a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham// DOUGLAS - this still needs to be implemented for MIPS. 968a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if 0 969a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 970a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * We need two separate pushes, since we want r5 to be pushed first. 971a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Store multiple will push LR first. 972a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 973a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *pushFP = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true); 974a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham pushFP->opcode = kThumbPush; 975a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham pushFP->operands[0] = 1 << r5FP; 976a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham setupResourceMasks(pushFP); 977a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerInsertLIRBefore((LIR *) origLIR, (LIR *) pushFP); 978a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 979a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *pushLR = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true); 980a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham pushLR->opcode = kThumbPush; 981a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Thumb push can handle LR, but is encoded differently at bit 8 */ 982a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham pushLR->operands[0] = 1 << 8; 983a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham setupResourceMasks(pushLR); 984a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerInsertLIRBefore((LIR *) origLIR, (LIR *) pushLR); 985a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 986a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 987a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 988a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void genSelfVerificationPostBranch(CompilationUnit *cUnit, 989a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *origLIR) { 990a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham// DOUGLAS - this still needs to be implemented for MIPS. 991a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if 0 992a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 993a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Since Thumb cannot pop memory content into LR, we have to pop LR 994a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * to a temp first (r5 in this case). Then we move r5 to LR, then pop the 995a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * original r5 from stack. 996a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 997a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Pop memory content(LR) into r5 first */ 998a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *popForLR = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true); 999a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham popForLR->opcode = kThumbPop; 1000a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham popForLR->operands[0] = 1 << r5FP; 1001a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham setupResourceMasks(popForLR); 1002a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerInsertLIRAfter((LIR *) origLIR, (LIR *) popForLR); 1003a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 1004a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *copy = genRegCopyNoInsert(cUnit, r14lr, r5FP); 1005a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerInsertLIRAfter((LIR *) popForLR, (LIR *) copy); 1006a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 1007a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Now restore the original r5 */ 1008a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *popFP = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true); 1009a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham popFP->opcode = kThumbPop; 1010a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham popFP->operands[0] = 1 << r5FP; 1011a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham setupResourceMasks(popFP); 1012a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerInsertLIRAfter((LIR *) copy, (LIR *) popFP); 1013a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 1014a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 1015a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 1016