target_mips.cc revision cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8
1efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 2efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Copyright (C) 2012 The Android Open Source Project 3efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * 4efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Licensed under the Apache License, Version 2.0 (the "License"); 5efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * you may not use this file except in compliance with the License. 6efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * You may obtain a copy of the License at 7efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * 8efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * http://www.apache.org/licenses/LICENSE-2.0 9efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * 10efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Unless required by applicable law or agreed to in writing, software 11efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * distributed under the License is distributed on an "AS IS" BASIS, 12efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * See the License for the specific language governing permissions and 14efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * limitations under the License. 15efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 16efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 17efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#include "../../compiler_internals.h" 18efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#include "mips_lir.h" 19eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee#include "../ralloc_util.h" 20eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee#include "../codegen_util.h" 21efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 22efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#include <string> 23efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 24efc6369224b036a1fb77849f7ae65b3492c832c0buzbeenamespace art { 25efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 26efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestatic int coreRegs[] = {r_ZERO, r_AT, r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, 27efc6369224b036a1fb77849f7ae65b3492c832c0buzbee r_T0, r_T1, r_T2, r_T3, r_T4, r_T5, r_T6, r_T7, 28efc6369224b036a1fb77849f7ae65b3492c832c0buzbee r_S0, r_S1, r_S2, r_S3, r_S4, r_S5, r_S6, r_S7, r_T8, 29efc6369224b036a1fb77849f7ae65b3492c832c0buzbee r_T9, r_K0, r_K1, r_GP, r_SP, r_FP, r_RA}; 30efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestatic int reservedRegs[] = {r_ZERO, r_AT, r_S0, r_S1, r_K0, r_K1, r_GP, r_SP, 31efc6369224b036a1fb77849f7ae65b3492c832c0buzbee r_RA}; 32efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestatic int coreTemps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2, 33efc6369224b036a1fb77849f7ae65b3492c832c0buzbee r_T3, r_T4, r_T5, r_T6, r_T7, r_T8}; 34efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#ifdef __mips_hard_float 35efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestatic int fpRegs[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7, 36efc6369224b036a1fb77849f7ae65b3492c832c0buzbee r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15}; 37efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestatic int fpTemps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7, 38efc6369224b036a1fb77849f7ae65b3492c832c0buzbee r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15}; 39efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif 40efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 41efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeRegLocation locCReturn() 42efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 43efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = MIPS_LOC_C_RETURN; 44efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 45efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 46efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 47efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeRegLocation locCReturnWide() 48efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 49efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = MIPS_LOC_C_RETURN_WIDE; 50efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 51efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 52efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 53efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeRegLocation locCReturnFloat() 54efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 55efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = MIPS_LOC_C_RETURN_FLOAT; 56efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 57efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 58efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 59efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeRegLocation locCReturnDouble() 60efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 61efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = MIPS_LOC_C_RETURN_DOUBLE; 62efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 63efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 64efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 65efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return a target-dependent special register. 66efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeint targetReg(SpecialTargetRegister reg) { 67efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int res = INVALID_REG; 68efc6369224b036a1fb77849f7ae65b3492c832c0buzbee switch (reg) { 69efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kSelf: res = rMIPS_SELF; break; 70efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kSuspend: res = rMIPS_SUSPEND; break; 71efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kLr: res = rMIPS_LR; break; 72efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kPc: res = rMIPS_PC; break; 73efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kSp: res = rMIPS_SP; break; 74efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg0: res = rMIPS_ARG0; break; 75efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg1: res = rMIPS_ARG1; break; 76efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg2: res = rMIPS_ARG2; break; 77efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg3: res = rMIPS_ARG3; break; 78efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg0: res = rMIPS_FARG0; break; 79efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg1: res = rMIPS_FARG1; break; 80efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg2: res = rMIPS_FARG2; break; 81efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg3: res = rMIPS_FARG3; break; 82efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kRet0: res = rMIPS_RET0; break; 83efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kRet1: res = rMIPS_RET1; break; 84efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kInvokeTgt: res = rMIPS_INVOKE_TGT; break; 85efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kCount: res = rMIPS_COUNT; break; 86efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 87efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 88efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 89efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 90efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Create a double from a pair of singles. 91efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeint s2d(int lowReg, int highReg) 92efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 93efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_S2D(lowReg, highReg); 94efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 95efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 96efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Is reg a single or double? 97efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool fpReg(int reg) 98efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 99efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_FPREG(reg); 100efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 101efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 102efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Is reg a single? 103efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool singleReg(int reg) 104efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 105efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_SINGLEREG(reg); 106efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 107efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 108efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Is reg a double? 109efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool doubleReg(int reg) 110efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 111efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_DOUBLEREG(reg); 112efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 113efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 114efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return mask to strip off fp reg flags and bias. 115efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeuint32_t fpRegMask() 116efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 117efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_FP_REG_MASK; 118efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 119efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 120efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// True if both regs single, both core or both double. 121efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool sameRegType(int reg1, int reg2) 122efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 123efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return (MIPS_REGTYPE(reg1) == MIPS_REGTYPE(reg2)); 124efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 125efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 126efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 127efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Decode the register id. 128efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 129eaf09bc65f9a10d12befcdb239156938c9bceef2buzbeeuint64_t getRegMaskCommon(CompilationUnit* cUnit, int reg) 130efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 131eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint64_t seed; 132efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int shift; 133efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int regId; 134efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 135efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 136efc6369224b036a1fb77849f7ae65b3492c832c0buzbee regId = reg & 0x1f; 137efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Each double register is equal to a pair of single-precision FP registers */ 138efc6369224b036a1fb77849f7ae65b3492c832c0buzbee seed = MIPS_DOUBLEREG(reg) ? 3 : 1; 139efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* FP register starts at bit position 16 */ 140efc6369224b036a1fb77849f7ae65b3492c832c0buzbee shift = MIPS_FPREG(reg) ? kMipsFPReg0 : 0; 141efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Expand the double register id into single offset */ 142efc6369224b036a1fb77849f7ae65b3492c832c0buzbee shift += regId; 143efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return (seed << shift); 144efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 145efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 146efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeuint64_t getPCUseDefEncoding() 147efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 148efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return ENCODE_MIPS_REG_PC; 149efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 150efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 151efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 152efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir) 153efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 154efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK_EQ(cUnit->instructionSet, kMips); 155efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 156efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Mips-specific resource map setup here. 157efc6369224b036a1fb77849f7ae65b3492c832c0buzbee uint64_t flags = EncodingMap[lir->opcode].flags; 158efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 159efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_DEF_SP) { 160efc6369224b036a1fb77849f7ae65b3492c832c0buzbee lir->defMask |= ENCODE_MIPS_REG_SP; 161efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 162efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 163efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_USE_SP) { 164efc6369224b036a1fb77849f7ae65b3492c832c0buzbee lir->useMask |= ENCODE_MIPS_REG_SP; 165efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 166efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 167efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_DEF_LR) { 168efc6369224b036a1fb77849f7ae65b3492c832c0buzbee lir->defMask |= ENCODE_MIPS_REG_LR; 169efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 170efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 171efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 172efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* For dumping instructions */ 173efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#define MIPS_REG_COUNT 32 174efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestatic const char *mipsRegName[MIPS_REG_COUNT] = { 175efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 176efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 177efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 178efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" 179efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}; 180efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 181efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 182efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Interpret a format string and build a string no longer than size 183efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * See format key in Assemble.c. 184efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 185efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestd::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr) 186efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 187efc6369224b036a1fb77849f7ae65b3492c832c0buzbee std::string buf; 188efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int i; 189efc6369224b036a1fb77849f7ae65b3492c832c0buzbee const char *fmtEnd = &fmt[strlen(fmt)]; 190efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char tbuf[256]; 191efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char nc; 192efc6369224b036a1fb77849f7ae65b3492c832c0buzbee while (fmt < fmtEnd) { 193efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int operand; 194efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (*fmt == '!') { 195efc6369224b036a1fb77849f7ae65b3492c832c0buzbee fmt++; 196efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK_LT(fmt, fmtEnd); 197efc6369224b036a1fb77849f7ae65b3492c832c0buzbee nc = *fmt++; 198efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (nc=='!') { 199efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "!"); 200efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 201efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK_LT(fmt, fmtEnd); 202cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee DCHECK_LT(static_cast<unsigned>(nc-'0'), 4u); 203efc6369224b036a1fb77849f7ae65b3492c832c0buzbee operand = lir->operands[nc-'0']; 204efc6369224b036a1fb77849f7ae65b3492c832c0buzbee switch (*fmt++) { 205efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'b': 206efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf,"0000"); 207efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (i=3; i>= 0; i--) { 208efc6369224b036a1fb77849f7ae65b3492c832c0buzbee tbuf[i] += operand & 1; 209efc6369224b036a1fb77849f7ae65b3492c832c0buzbee operand >>= 1; 210efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 211efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 212efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 's': 213efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK); 214efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 215efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'S': 216efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK_EQ(((operand & MIPS_FP_REG_MASK) & 1), 0); 217efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK); 218efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 219efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'h': 220efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%04x", operand); 221efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 222efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'M': 223efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'd': 224efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%d", operand); 225efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 226efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'D': 227efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%d", operand+1); 228efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 229efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'E': 230efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%d", operand*4); 231efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 232efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'F': 233efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%d", operand*2); 234efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 235efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 't': 236cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee sprintf(tbuf,"0x%08x (L%p)", reinterpret_cast<uintptr_t>(baseAddr) + lir->offset + 4 + 237efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (operand << 2), lir->target); 238efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 239efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'T': 240cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee sprintf(tbuf,"0x%08x", operand << 2); 241efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 242efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'u': { 243efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset_1 = lir->operands[0]; 244efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset_2 = NEXT_LIR(lir)->operands[0]; 245cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee uintptr_t target = 246cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee (((reinterpret_cast<uintptr_t>(baseAddr) + lir->offset + 4) & ~3) + 247efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (offset_1 << 21 >> 9) + (offset_2 << 1)) & 0xfffffffc; 248cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee sprintf(tbuf, "%p", reinterpret_cast<void*>(target)); 249efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 250efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 251efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 252efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Nothing to print for BLX_2 */ 253efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'v': 254efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "see above"); 255efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 256efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'r': 257efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK(operand >= 0 && operand < MIPS_REG_COUNT); 258efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, mipsRegName[operand]); 259efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 260efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'N': 261efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Placeholder for delay slot handling 262efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "; nop"); 263efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 264efc6369224b036a1fb77849f7ae65b3492c832c0buzbee default: 265efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf,"DecodeError"); 266efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 267efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 268efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf += tbuf; 269efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 270efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 271efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf += *fmt++; 272efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 273efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 274efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return buf; 275efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 276efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 277efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// FIXME: need to redo resource maps for MIPS - fix this at that time 278cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbeevoid oatDumpResourceMask(LIR *mipsLIR, uint64_t mask, const char *prefix) 279efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 280efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char buf[256]; 281efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf[0] = 0; 282efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 283efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask == ENCODE_ALL) { 284efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(buf, "all"); 285efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 286efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char num[8]; 287efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int i; 288efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 289efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (i = 0; i < kMipsRegEnd; i++) { 290efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & (1ULL << i)) { 291efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(num, "%d ", i); 292efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, num); 293efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 294efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 295efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 296efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_CCODE) { 297efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "cc "); 298efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 299efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_FP_STATUS) { 300efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "fpcc "); 301efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 302efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Memory bits */ 303efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mipsLIR && (mask & ENCODE_DALVIK_REG)) { 304efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(buf + strlen(buf), "dr%d%s", mipsLIR->aliasInfo & 0xffff, 305efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (mipsLIR->aliasInfo & 0x80000000) ? "(+1)" : ""); 306efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 307efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_LITERAL) { 308efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "lit "); 309efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 310efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 311efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_HEAP_REF) { 312efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "heap "); 313efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 314efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_MUST_NOT_ALIAS) { 315efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "noalias "); 316efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 317efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 318efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (buf[0]) { 319efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(INFO) << prefix << ": " << buf; 320efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 321efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 322efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 323efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 324efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * TUNING: is leaf? Can't just use "hasInvoke" to determine as some 325efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * instructions might call out to C/assembly helper functions. Until 326efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * machinery is in place, always spill lr. 327efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 328efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 329efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid oatAdjustSpillMask(CompilationUnit* cUnit) 330efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 331efc6369224b036a1fb77849f7ae65b3492c832c0buzbee cUnit->coreSpillMask |= (1 << r_RA); 332efc6369224b036a1fb77849f7ae65b3492c832c0buzbee cUnit->numCoreSpills++; 333efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 334efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 335efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 336efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Mark a callee-save fp register as promoted. Note that 337efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * vpush/vpop uses contiguous register lists so we must 338efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * include any holes in the mask. Associate holes with 339efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Dalvik register INVALID_VREG (0xFFFFU). 340efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 341efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid oatMarkPreservedSingle(CompilationUnit* cUnit, int sReg, int reg) 342efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 343efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(FATAL) << "No support yet for promoted FP regs"; 344efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 345efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 346efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2) 347efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 348efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegisterInfo* info1 = oatGetRegInfo(cUnit, reg1); 349efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegisterInfo* info2 = oatGetRegInfo(cUnit, reg2); 350efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK(info1 && info2 && info1->pair && info2->pair && 351efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (info1->partner == info2->reg) && 352efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (info2->partner == info1->reg)); 353efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) { 354efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (!(info1->isTemp && info2->isTemp)) { 355efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Should not happen. If it does, there's a problem in evalLoc */ 356efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(FATAL) << "Long half-temp, half-promoted"; 357efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 358efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 359efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info1->dirty = false; 360efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info2->dirty = false; 361efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (SRegToVReg(cUnit, info2->sReg) < SRegToVReg(cUnit, info1->sReg)) 362efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info1 = info2; 363efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int vReg = SRegToVReg(cUnit, info1->sReg); 364eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee storeBaseDispWide(cUnit, rMIPS_SP, oatVRegOffset(cUnit, vReg), info1->reg, info1->partner); 365efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 366efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 367efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 368efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid oatFlushReg(CompilationUnit* cUnit, int reg) 369efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 370efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegisterInfo* info = oatGetRegInfo(cUnit, reg); 371efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (info->live && info->dirty) { 372efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info->dirty = false; 373efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int vReg = SRegToVReg(cUnit, info->sReg); 374eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee storeBaseDisp(cUnit, rMIPS_SP, oatVRegOffset(cUnit, vReg), reg, kWord); 375efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 376efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 377efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 378efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Give access to the target-dependent FP register encoding to common code */ 379efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool oatIsFpReg(int reg) { 380efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_FPREG(reg); 381efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 382efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 383efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeuint32_t oatFpRegMask() { 384efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_FP_REG_MASK; 385efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 386efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 387efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Clobber all regs that might be used by an external C call */ 388efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeextern void oatClobberCalleeSave(CompilationUnit *cUnit) 389efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 390efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_ZERO); 391efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_AT); 392efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_V0); 393efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_V1); 394efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_A0); 395efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_A1); 396efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_A2); 397efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_A3); 398efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_T0); 399efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_T1); 400efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_T2); 401efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_T3); 402efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_T4); 403efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_T5); 404efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_T6); 405efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_T7); 406efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_T8); 407efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_T9); 408efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_K0); 409efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_K1); 410efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_GP); 411efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_FP); 412efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_RA); 413efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F0); 414efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F1); 415efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F2); 416efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F3); 417efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F4); 418efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F5); 419efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F6); 420efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F7); 421efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F8); 422efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F9); 423efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F10); 424efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F11); 425efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F12); 426efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F13); 427efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F14); 428efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatClobber(cUnit, r_F15); 429efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 430efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 431efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeextern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit) 432efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 433efc6369224b036a1fb77849f7ae65b3492c832c0buzbee UNIMPLEMENTED(FATAL) << "No oatGetReturnWideAlt for MIPS"; 434efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = locCReturnWide(); 435efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 436efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 437efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 438efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeextern RegLocation oatGetReturnAlt(CompilationUnit* cUnit) 439efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 440efc6369224b036a1fb77849f7ae65b3492c832c0buzbee UNIMPLEMENTED(FATAL) << "No oatGetReturnAlt for MIPS"; 441efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = locCReturn(); 442efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 443efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 444efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 445efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeextern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg) 446efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 447efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_FPREG(reg) ? &cUnit->regPool->FPRegs[reg & MIPS_FP_REG_MASK] 448efc6369224b036a1fb77849f7ae65b3492c832c0buzbee : &cUnit->regPool->coreRegs[reg]; 449efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 450efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 451efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */ 452efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeextern void oatLockCallTemps(CompilationUnit* cUnit) 453efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 454efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatLockTemp(cUnit, rMIPS_ARG0); 455efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatLockTemp(cUnit, rMIPS_ARG1); 456efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatLockTemp(cUnit, rMIPS_ARG2); 457efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatLockTemp(cUnit, rMIPS_ARG3); 458efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 459efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 460efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */ 461efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeextern void oatFreeCallTemps(CompilationUnit* cUnit) 462efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 463efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatFreeTemp(cUnit, rMIPS_ARG0); 464efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatFreeTemp(cUnit, rMIPS_ARG1); 465efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatFreeTemp(cUnit, rMIPS_ARG2); 466efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatFreeTemp(cUnit, rMIPS_ARG3); 467efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 468efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 469efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 470efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Determine the initial instruction set to be used for this trace. 471efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Later components may decide to change this. 472efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 473efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeInstructionSet oatInstructionSet() 474efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 475efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return kMips; 476efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 477efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 478efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Architecture-specific initializations and checks go here */ 479efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool oatArchVariantInit(void) 480efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 481efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return true; 482efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 483efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 484efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid oatGenMemBarrier(CompilationUnit *cUnit, int barrierKind) 485efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 486efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#if ANDROID_SMP != 0 487efc6369224b036a1fb77849f7ae65b3492c832c0buzbee newLIR1(cUnit, kMipsSync, barrierKind); 488efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif 489efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 490efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 491efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 492efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Alloc a pair of core registers, or a double. Low reg in low byte, 493efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * high reg in next byte. 494efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 495efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeint oatAllocTypedTempPair(CompilationUnit *cUnit, bool fpHint, 496efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int regClass) 497efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 498efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int highReg; 499efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int lowReg; 500efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int res = 0; 501efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 502efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#ifdef __mips_hard_float 503efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) { 504efc6369224b036a1fb77849f7ae65b3492c832c0buzbee lowReg = oatAllocTempDouble(cUnit); 505efc6369224b036a1fb77849f7ae65b3492c832c0buzbee highReg = lowReg + 1; 506efc6369224b036a1fb77849f7ae65b3492c832c0buzbee res = (lowReg & 0xff) | ((highReg & 0xff) << 8); 507efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 508efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 509efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif 510efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 511efc6369224b036a1fb77849f7ae65b3492c832c0buzbee lowReg = oatAllocTemp(cUnit); 512efc6369224b036a1fb77849f7ae65b3492c832c0buzbee highReg = oatAllocTemp(cUnit); 513efc6369224b036a1fb77849f7ae65b3492c832c0buzbee res = (lowReg & 0xff) | ((highReg & 0xff) << 8); 514efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 515efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 516efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 517efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeint oatAllocTypedTemp(CompilationUnit *cUnit, bool fpHint, int regClass) 518efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 519efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#ifdef __mips_hard_float 520efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) 521efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 522efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return oatAllocTempFloat(cUnit); 523efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 524efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif 525efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return oatAllocTemp(cUnit); 526efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 527efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 528efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid oatInitializeRegAlloc(CompilationUnit* cUnit) 529efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 530efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int numRegs = sizeof(coreRegs)/sizeof(*coreRegs); 531efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int numReserved = sizeof(reservedRegs)/sizeof(*reservedRegs); 532efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int numTemps = sizeof(coreTemps)/sizeof(*coreTemps); 533efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#ifdef __mips_hard_float 534efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs); 535efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps); 536efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#else 537efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int numFPRegs = 0; 538efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int numFPTemps = 0; 539efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif 540cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee RegisterPool *pool = 541cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee static_cast<RegisterPool*>(oatNew(cUnit, sizeof(*pool), true, kAllocRegAlloc)); 542efc6369224b036a1fb77849f7ae65b3492c832c0buzbee cUnit->regPool = pool; 543efc6369224b036a1fb77849f7ae65b3492c832c0buzbee pool->numCoreRegs = numRegs; 544cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee pool->coreRegs = static_cast<RegisterInfo*> 545cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee (oatNew(cUnit, numRegs * sizeof(*cUnit->regPool->coreRegs), true, kAllocRegAlloc)); 546efc6369224b036a1fb77849f7ae65b3492c832c0buzbee pool->numFPRegs = numFPRegs; 547cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee pool->FPRegs = static_cast<RegisterInfo*> 548cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee (oatNew(cUnit, numFPRegs * sizeof(*cUnit->regPool->FPRegs), true, kAllocRegAlloc)); 549efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatInitPool(pool->coreRegs, coreRegs, pool->numCoreRegs); 550efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatInitPool(pool->FPRegs, fpRegs, pool->numFPRegs); 551efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Keep special registers from being allocated 552efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int i = 0; i < numReserved; i++) { 553efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (NO_SUSPEND && (reservedRegs[i] == rMIPS_SUSPEND)) { 554efc6369224b036a1fb77849f7ae65b3492c832c0buzbee //To measure cost of suspend check 555efc6369224b036a1fb77849f7ae65b3492c832c0buzbee continue; 556efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 557efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatMarkInUse(cUnit, reservedRegs[i]); 558efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 559efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Mark temp regs - all others not in use can be used for promotion 560efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int i = 0; i < numTemps; i++) { 561efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatMarkTemp(cUnit, coreTemps[i]); 562efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 563efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int i = 0; i < numFPTemps; i++) { 564efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatMarkTemp(cUnit, fpTemps[i]); 565efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 566efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Construct the alias map. 567cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee cUnit->phiAliasMap = static_cast<int*> 568cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee (oatNew(cUnit, cUnit->numSSARegs * sizeof(cUnit->phiAliasMap[0]), false, kAllocDFInfo)); 569efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int i = 0; i < cUnit->numSSARegs; i++) { 570efc6369224b036a1fb77849f7ae65b3492c832c0buzbee cUnit->phiAliasMap[i] = i; 571efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 572efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (MIR* phi = cUnit->phiList; phi; phi = phi->meta.phiNext) { 573efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int defReg = phi->ssaRep->defs[0]; 574efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int i = 0; i < phi->ssaRep->numUses; i++) { 575efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int j = 0; j < cUnit->numSSARegs; j++) { 576efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (cUnit->phiAliasMap[j] == phi->ssaRep->uses[i]) { 577efc6369224b036a1fb77849f7ae65b3492c832c0buzbee cUnit->phiAliasMap[j] = defReg; 578efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 579efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 580efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 581efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 582efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 583efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 584efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep, 585efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation rlFree) 586efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 587efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if ((rlFree.lowReg != rlKeep.lowReg) && (rlFree.lowReg != rlKeep.highReg) && 588efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (rlFree.highReg != rlKeep.lowReg) && (rlFree.highReg != rlKeep.highReg)) { 589efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // No overlap, free both 590efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatFreeTemp(cUnit, rlFree.lowReg); 591efc6369224b036a1fb77849f7ae65b3492c832c0buzbee oatFreeTemp(cUnit, rlFree.highReg); 592efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 593efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 594efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 595efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * In the Arm code a it is typical to use the link register 596efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * to hold the target address. However, for Mips we must 597efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * ensure that all branch instructions can be restarted if 598efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * there is a trap in the shadow. Allocate a temp register. 599efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 600efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeint loadHelper(CompilationUnit* cUnit, int offset) 601efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 602efc6369224b036a1fb77849f7ae65b3492c832c0buzbee loadWordDisp(cUnit, rMIPS_SELF, offset, r_T9); 603efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return r_T9; 604efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 605efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 606efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid spillCoreRegs(CompilationUnit* cUnit) 607efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 608efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (cUnit->numCoreSpills == 0) { 609efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return; 610efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 611efc6369224b036a1fb77849f7ae65b3492c832c0buzbee uint32_t mask = cUnit->coreSpillMask; 612efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset = cUnit->numCoreSpills * 4; 613efc6369224b036a1fb77849f7ae65b3492c832c0buzbee opRegImm(cUnit, kOpSub, rMIPS_SP, offset); 614efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int reg = 0; mask; mask >>= 1, reg++) { 615efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & 0x1) { 616efc6369224b036a1fb77849f7ae65b3492c832c0buzbee offset -= 4; 617efc6369224b036a1fb77849f7ae65b3492c832c0buzbee storeWordDisp(cUnit, rMIPS_SP, offset, reg); 618efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 619efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 620efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 621efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 622efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid unSpillCoreRegs(CompilationUnit* cUnit) 623efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 624efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (cUnit->numCoreSpills == 0) { 625efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return; 626efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 627efc6369224b036a1fb77849f7ae65b3492c832c0buzbee uint32_t mask = cUnit->coreSpillMask; 628efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset = cUnit->frameSize; 629efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int reg = 0; mask; mask >>= 1, reg++) { 630efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & 0x1) { 631efc6369224b036a1fb77849f7ae65b3492c832c0buzbee offset -= 4; 632efc6369224b036a1fb77849f7ae65b3492c832c0buzbee loadWordDisp(cUnit, rMIPS_SP, offset, reg); 633efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 634efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 635efc6369224b036a1fb77849f7ae65b3492c832c0buzbee opRegImm(cUnit, kOpAdd, rMIPS_SP, cUnit->frameSize); 636efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 637efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 638cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbeebool branchUnconditional(LIR* lir) 639cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee{ 640cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee return (lir->opcode == kMipsB); 641efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 642efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 643efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Common initialization routine for an architecture family */ 644efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool oatArchInit() 645efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 646efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int i; 647efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 648efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (i = 0; i < kMipsLast; i++) { 649efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (EncodingMap[i].opcode != i) { 650efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(FATAL) << "Encoding order for " << EncodingMap[i].name << 651cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee " is wrong: expecting " << i << ", seeing " << static_cast<int>(EncodingMap[i].opcode); 652efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 653efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 654efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 655efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return oatArchVariantInit(); 656efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 657efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 658efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} // namespace art 659