target_mips.cc revision 1fd3346740dfb7f47be9922312b68a4227fada96
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 1702031b185b4653e6c72e21f7a51238b903f6d638buzbee#include "codegen_mips.h" 18395116cae130c983498c0a2f42b89e42f75bb9d0buzbee#include "compiler/dex/compiler_internals.h" 19641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "mips_lir.h" 20efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 21efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#include <string> 22efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 23efc6369224b036a1fb77849f7ae65b3492c832c0buzbeenamespace art { 24efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 25fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int core_regs[] = {r_ZERO, r_AT, r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, 26fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_T0, r_T1, r_T2, r_T3, r_T4, r_T5, r_T6, r_T7, 27fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_S0, r_S1, r_S2, r_S3, r_S4, r_S5, r_S6, r_S7, r_T8, 28fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_T9, r_K0, r_K1, r_GP, r_SP, r_FP, r_RA}; 2952a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbeestatic int ReservedRegs[] = {r_ZERO, r_AT, r_S0, r_S1, r_K0, r_K1, r_GP, r_SP, 30efc6369224b036a1fb77849f7ae65b3492c832c0buzbee r_RA}; 31fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int core_temps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2, 32fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_T3, r_T4, r_T5, r_T6, r_T7, r_T8}; 3352a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbeestatic int FpRegs[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7, 34efc6369224b036a1fb77849f7ae65b3492c832c0buzbee r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15}; 35fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int fp_temps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7, 36fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15}; 37efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 381fd3346740dfb7f47be9922312b68a4227fada96buzbeeRegLocation MipsMir2Lir::LocCReturn() 39efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 40efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = MIPS_LOC_C_RETURN; 41efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 42efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 43efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 441fd3346740dfb7f47be9922312b68a4227fada96buzbeeRegLocation MipsMir2Lir::LocCReturnWide() 45efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 46efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = MIPS_LOC_C_RETURN_WIDE; 47efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 48efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 49efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 501fd3346740dfb7f47be9922312b68a4227fada96buzbeeRegLocation MipsMir2Lir::LocCReturnFloat() 51efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 52efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = MIPS_LOC_C_RETURN_FLOAT; 53efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 54efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 55efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 561fd3346740dfb7f47be9922312b68a4227fada96buzbeeRegLocation MipsMir2Lir::LocCReturnDouble() 57efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 58efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = MIPS_LOC_C_RETURN_DOUBLE; 59efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 60efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 61efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 62efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return a target-dependent special register. 631fd3346740dfb7f47be9922312b68a4227fada96buzbeeint MipsMir2Lir::TargetReg(SpecialTargetRegister reg) { 64efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int res = INVALID_REG; 65efc6369224b036a1fb77849f7ae65b3492c832c0buzbee switch (reg) { 66efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kSelf: res = rMIPS_SELF; break; 67efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kSuspend: res = rMIPS_SUSPEND; break; 68efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kLr: res = rMIPS_LR; break; 69efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kPc: res = rMIPS_PC; break; 70efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kSp: res = rMIPS_SP; break; 71efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg0: res = rMIPS_ARG0; break; 72efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg1: res = rMIPS_ARG1; break; 73efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg2: res = rMIPS_ARG2; break; 74efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg3: res = rMIPS_ARG3; break; 75efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg0: res = rMIPS_FARG0; break; 76efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg1: res = rMIPS_FARG1; break; 77efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg2: res = rMIPS_FARG2; break; 78efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg3: res = rMIPS_FARG3; break; 79efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kRet0: res = rMIPS_RET0; break; 80efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kRet1: res = rMIPS_RET1; break; 81efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kInvokeTgt: res = rMIPS_INVOKE_TGT; break; 82efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kCount: res = rMIPS_COUNT; break; 83efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 84efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 85efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 86efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 87efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Create a double from a pair of singles. 881fd3346740dfb7f47be9922312b68a4227fada96buzbeeint MipsMir2Lir::S2d(int low_reg, int high_reg) 89efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 90fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return MIPS_S2D(low_reg, high_reg); 91efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 92efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 93efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return mask to strip off fp reg flags and bias. 941fd3346740dfb7f47be9922312b68a4227fada96buzbeeuint32_t MipsMir2Lir::FpRegMask() 95efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 96efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_FP_REG_MASK; 97efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 98efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 99efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// True if both regs single, both core or both double. 1001fd3346740dfb7f47be9922312b68a4227fada96buzbeebool MipsMir2Lir::SameRegType(int reg1, int reg2) 101efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 102efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return (MIPS_REGTYPE(reg1) == MIPS_REGTYPE(reg2)); 103efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 104efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 105efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 106efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Decode the register id. 107efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 1081fd3346740dfb7f47be9922312b68a4227fada96buzbeeuint64_t MipsMir2Lir::GetRegMaskCommon(int reg) 109efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 110eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint64_t seed; 111efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int shift; 112fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int reg_id; 113efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 114efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 115fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee reg_id = reg & 0x1f; 116efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Each double register is equal to a pair of single-precision FP registers */ 117efc6369224b036a1fb77849f7ae65b3492c832c0buzbee seed = MIPS_DOUBLEREG(reg) ? 3 : 1; 118efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* FP register starts at bit position 16 */ 119efc6369224b036a1fb77849f7ae65b3492c832c0buzbee shift = MIPS_FPREG(reg) ? kMipsFPReg0 : 0; 120efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Expand the double register id into single offset */ 121fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee shift += reg_id; 122efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return (seed << shift); 123efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 124efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 1251fd3346740dfb7f47be9922312b68a4227fada96buzbeeuint64_t MipsMir2Lir::GetPCUseDefEncoding() 126efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 127efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return ENCODE_MIPS_REG_PC; 128efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 129efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 130efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 1311fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::SetupTargetResourceMasks(LIR* lir) 132efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 1331fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK_EQ(cu_->instruction_set, kMips); 134efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 135efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Mips-specific resource map setup here. 1361fd3346740dfb7f47be9922312b68a4227fada96buzbee uint64_t flags = MipsMir2Lir::EncodingMap[lir->opcode].flags; 137efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 138efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_DEF_SP) { 139fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->def_mask |= ENCODE_MIPS_REG_SP; 140efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 141efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 142efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_USE_SP) { 143fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->use_mask |= ENCODE_MIPS_REG_SP; 144efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 145efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 146efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_DEF_LR) { 147fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->def_mask |= ENCODE_MIPS_REG_LR; 148efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 149efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 150efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 151efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* For dumping instructions */ 152efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#define MIPS_REG_COUNT 32 153fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic const char *mips_reg_name[MIPS_REG_COUNT] = { 154efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 155efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 156efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 157efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" 158efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}; 159efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 160efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 161efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Interpret a format string and build a string no longer than size 162efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * See format key in Assemble.c. 163efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 1641fd3346740dfb7f47be9922312b68a4227fada96buzbeestd::string MipsMir2Lir::BuildInsnString(const char *fmt, LIR *lir, unsigned char* base_addr) 165efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 166efc6369224b036a1fb77849f7ae65b3492c832c0buzbee std::string buf; 167efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int i; 168fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee const char *fmt_end = &fmt[strlen(fmt)]; 169efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char tbuf[256]; 170efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char nc; 171fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (fmt < fmt_end) { 172efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int operand; 173efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (*fmt == '!') { 174efc6369224b036a1fb77849f7ae65b3492c832c0buzbee fmt++; 175fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_LT(fmt, fmt_end); 176efc6369224b036a1fb77849f7ae65b3492c832c0buzbee nc = *fmt++; 177efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (nc=='!') { 178efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "!"); 179efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 180fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_LT(fmt, fmt_end); 181cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee DCHECK_LT(static_cast<unsigned>(nc-'0'), 4u); 182efc6369224b036a1fb77849f7ae65b3492c832c0buzbee operand = lir->operands[nc-'0']; 183efc6369224b036a1fb77849f7ae65b3492c832c0buzbee switch (*fmt++) { 184efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'b': 185efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf,"0000"); 186efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (i=3; i>= 0; i--) { 187efc6369224b036a1fb77849f7ae65b3492c832c0buzbee tbuf[i] += operand & 1; 188efc6369224b036a1fb77849f7ae65b3492c832c0buzbee operand >>= 1; 189efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 190efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 191efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 's': 192efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK); 193efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 194efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'S': 195efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK_EQ(((operand & MIPS_FP_REG_MASK) & 1), 0); 196efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK); 197efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 198efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'h': 199efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%04x", operand); 200efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 201efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'M': 202efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'd': 203efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%d", operand); 204efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 205efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'D': 206efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%d", operand+1); 207efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 208efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'E': 209efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%d", operand*4); 210efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 211efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'F': 212efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%d", operand*2); 213efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 214efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 't': 215fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee sprintf(tbuf,"0x%08x (L%p)", reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4 + 216efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (operand << 2), lir->target); 217efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 218efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'T': 219cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee sprintf(tbuf,"0x%08x", operand << 2); 220efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 221efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'u': { 222efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset_1 = lir->operands[0]; 223efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset_2 = NEXT_LIR(lir)->operands[0]; 224cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee uintptr_t target = 225fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (((reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4) & ~3) + 226efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (offset_1 << 21 >> 9) + (offset_2 << 1)) & 0xfffffffc; 227cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee sprintf(tbuf, "%p", reinterpret_cast<void*>(target)); 228efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 229efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 230efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 231efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Nothing to print for BLX_2 */ 232efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'v': 233efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "see above"); 234efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 235efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'r': 236efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK(operand >= 0 && operand < MIPS_REG_COUNT); 237fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee strcpy(tbuf, mips_reg_name[operand]); 238efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 239efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'N': 240efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Placeholder for delay slot handling 241efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "; nop"); 242efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 243efc6369224b036a1fb77849f7ae65b3492c832c0buzbee default: 244efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf,"DecodeError"); 245efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 246efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 247efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf += tbuf; 248efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 249efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 250efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf += *fmt++; 251efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 252efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 253efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return buf; 254efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 255efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 256efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// FIXME: need to redo resource maps for MIPS - fix this at that time 2571fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::DumpResourceMask(LIR *mips_lir, uint64_t mask, const char *prefix) 258efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 259efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char buf[256]; 260efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf[0] = 0; 261efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 262efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask == ENCODE_ALL) { 263efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(buf, "all"); 264efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 265efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char num[8]; 266efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int i; 267efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 268efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (i = 0; i < kMipsRegEnd; i++) { 269efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & (1ULL << i)) { 270efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(num, "%d ", i); 271efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, num); 272efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 273efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 274efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 275efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_CCODE) { 276efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "cc "); 277efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 278efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_FP_STATUS) { 279efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "fpcc "); 280efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 281efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Memory bits */ 282fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (mips_lir && (mask & ENCODE_DALVIK_REG)) { 283fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee sprintf(buf + strlen(buf), "dr%d%s", mips_lir->alias_info & 0xffff, 284fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (mips_lir->alias_info & 0x80000000) ? "(+1)" : ""); 285efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 286efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_LITERAL) { 287efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "lit "); 288efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 289efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 290efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_HEAP_REF) { 291efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "heap "); 292efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 293efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_MUST_NOT_ALIAS) { 294efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "noalias "); 295efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 296efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 297efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (buf[0]) { 298efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(INFO) << prefix << ": " << buf; 299efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 300efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 301efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 302efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 303311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * TUNING: is true leaf? Can't just use METHOD_IS_LEAF to determine as some 304efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * instructions might call out to C/assembly helper functions. Until 305efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * machinery is in place, always spill lr. 306efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 307efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3081fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::AdjustSpillMask() 309efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 3101fd3346740dfb7f47be9922312b68a4227fada96buzbee core_spill_mask_ |= (1 << r_RA); 3111fd3346740dfb7f47be9922312b68a4227fada96buzbee num_core_spills_++; 312efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 313efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 314efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 315efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Mark a callee-save fp register as promoted. Note that 316efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * vpush/vpop uses contiguous register lists so we must 317efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * include any holes in the mask. Associate holes with 318efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Dalvik register INVALID_VREG (0xFFFFU). 319efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 3201fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::MarkPreservedSingle(int s_reg, int reg) 321efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 322efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(FATAL) << "No support yet for promoted FP regs"; 323efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 324efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3251fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::FlushRegWide(int reg1, int reg2) 326efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 3271fd3346740dfb7f47be9922312b68a4227fada96buzbee RegisterInfo* info1 = GetRegInfo(reg1); 3281fd3346740dfb7f47be9922312b68a4227fada96buzbee RegisterInfo* info2 = GetRegInfo(reg2); 329efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK(info1 && info2 && info1->pair && info2->pair && 330efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (info1->partner == info2->reg) && 331efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (info2->partner == info1->reg)); 332efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) { 333fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!(info1->is_temp && info2->is_temp)) { 334fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee /* Should not happen. If it does, there's a problem in eval_loc */ 335efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(FATAL) << "Long half-temp, half-promoted"; 336efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 337efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 338efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info1->dirty = false; 339efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info2->dirty = false; 3401fd3346740dfb7f47be9922312b68a4227fada96buzbee if (mir_graph_->SRegToVReg(info2->s_reg) < mir_graph_->SRegToVReg(info1->s_reg)) 341efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info1 = info2; 3421fd3346740dfb7f47be9922312b68a4227fada96buzbee int v_reg = mir_graph_->SRegToVReg(info1->s_reg); 3431fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreBaseDispWide(rMIPS_SP, VRegOffset(v_reg), info1->reg, info1->partner); 344efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 345efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 346efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3471fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::FlushReg(int reg) 348efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 3491fd3346740dfb7f47be9922312b68a4227fada96buzbee RegisterInfo* info = GetRegInfo(reg); 350efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (info->live && info->dirty) { 351efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info->dirty = false; 3521fd3346740dfb7f47be9922312b68a4227fada96buzbee int v_reg = mir_graph_->SRegToVReg(info->s_reg); 3531fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreBaseDisp(rMIPS_SP, VRegOffset(v_reg), reg, kWord); 354efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 355efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 356efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 357efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Give access to the target-dependent FP register encoding to common code */ 3581fd3346740dfb7f47be9922312b68a4227fada96buzbeebool MipsMir2Lir::IsFpReg(int reg) { 359efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_FPREG(reg); 360efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 361efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 362efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Clobber all regs that might be used by an external C call */ 3631fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::ClobberCalleeSave() 3641fd3346740dfb7f47be9922312b68a4227fada96buzbee{ 3651fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_ZERO); 3661fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_AT); 3671fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_V0); 3681fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_V1); 3691fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_A0); 3701fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_A1); 3711fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_A2); 3721fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_A3); 3731fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_T0); 3741fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_T1); 3751fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_T2); 3761fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_T3); 3771fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_T4); 3781fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_T5); 3791fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_T6); 3801fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_T7); 3811fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_T8); 3821fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_T9); 3831fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_K0); 3841fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_K1); 3851fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_GP); 3861fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_FP); 3871fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_RA); 3881fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F0); 3891fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F1); 3901fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F2); 3911fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F3); 3921fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F4); 3931fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F5); 3941fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F6); 3951fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F7); 3961fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F8); 3971fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F9); 3981fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F10); 3991fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F11); 4001fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F12); 4011fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F13); 4021fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F14); 4031fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_F15); 4041fd3346740dfb7f47be9922312b68a4227fada96buzbee} 4051fd3346740dfb7f47be9922312b68a4227fada96buzbee 4061fd3346740dfb7f47be9922312b68a4227fada96buzbeeRegLocation MipsMir2Lir::GetReturnWideAlt() 40752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee{ 40852a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee UNIMPLEMENTED(FATAL) << "No GetReturnWideAlt for MIPS"; 40952a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee RegLocation res = LocCReturnWide(); 410efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 411efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 412efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4131fd3346740dfb7f47be9922312b68a4227fada96buzbeeRegLocation MipsMir2Lir::GetReturnAlt() 414efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 41552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee UNIMPLEMENTED(FATAL) << "No GetReturnAlt for MIPS"; 41652a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee RegLocation res = LocCReturn(); 417efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 418efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 419efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4201fd3346740dfb7f47be9922312b68a4227fada96buzbeeMipsMir2Lir::RegisterInfo* MipsMir2Lir::GetRegInfo(int reg) 421efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 4221fd3346740dfb7f47be9922312b68a4227fada96buzbee return MIPS_FPREG(reg) ? ®_pool_->FPRegs[reg & MIPS_FP_REG_MASK] 4231fd3346740dfb7f47be9922312b68a4227fada96buzbee : ®_pool_->core_regs[reg]; 424efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 425efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 426efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */ 4271fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::LockCallTemps() 428efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 4291fd3346740dfb7f47be9922312b68a4227fada96buzbee LockTemp(rMIPS_ARG0); 4301fd3346740dfb7f47be9922312b68a4227fada96buzbee LockTemp(rMIPS_ARG1); 4311fd3346740dfb7f47be9922312b68a4227fada96buzbee LockTemp(rMIPS_ARG2); 4321fd3346740dfb7f47be9922312b68a4227fada96buzbee LockTemp(rMIPS_ARG3); 433efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 434efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 435efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */ 4361fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::FreeCallTemps() 437efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 4381fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(rMIPS_ARG0); 4391fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(rMIPS_ARG1); 4401fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(rMIPS_ARG2); 4411fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(rMIPS_ARG3); 442efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 443efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4441fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::GenMemBarrier(MemBarrierKind barrier_kind) 445efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 446efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#if ANDROID_SMP != 0 4471fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR1(kMipsSync, 0 /* Only stype currently supported */); 448efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif 449efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 450efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 451efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 452efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Alloc a pair of core registers, or a double. Low reg in low byte, 453efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * high reg in next byte. 454efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 4551fd3346740dfb7f47be9922312b68a4227fada96buzbeeint MipsMir2Lir::AllocTypedTempPair(bool fp_hint, 456fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int reg_class) 457efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 458fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int high_reg; 459fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int low_reg; 460efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int res = 0; 461efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 462fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) { 4631fd3346740dfb7f47be9922312b68a4227fada96buzbee low_reg = AllocTempDouble(); 464fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee high_reg = low_reg + 1; 465fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res = (low_reg & 0xff) | ((high_reg & 0xff) << 8); 466efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 467efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 468efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4691fd3346740dfb7f47be9922312b68a4227fada96buzbee low_reg = AllocTemp(); 4701fd3346740dfb7f47be9922312b68a4227fada96buzbee high_reg = AllocTemp(); 471fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res = (low_reg & 0xff) | ((high_reg & 0xff) << 8); 472efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 473efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 474efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4751fd3346740dfb7f47be9922312b68a4227fada96buzbeeint MipsMir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) 476efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 477fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) 478efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 4791fd3346740dfb7f47be9922312b68a4227fada96buzbee return AllocTempFloat(); 480efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 4811fd3346740dfb7f47be9922312b68a4227fada96buzbee return AllocTemp(); 482efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 483efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4841fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::CompilerInitializeRegAlloc() 485efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 486fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_regs = sizeof(core_regs)/sizeof(*core_regs); 487fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_reserved = sizeof(ReservedRegs)/sizeof(*ReservedRegs); 488fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_temps = sizeof(core_temps)/sizeof(*core_temps); 489fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_fp_regs = sizeof(FpRegs)/sizeof(*FpRegs); 490fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_fp_temps = sizeof(fp_temps)/sizeof(*fp_temps); 4911fd3346740dfb7f47be9922312b68a4227fada96buzbee reg_pool_ = static_cast<RegisterPool*>(NewMem(cu_, sizeof(*reg_pool_), true, kAllocRegAlloc)); 4921fd3346740dfb7f47be9922312b68a4227fada96buzbee reg_pool_->num_core_regs = num_regs; 4931fd3346740dfb7f47be9922312b68a4227fada96buzbee reg_pool_->core_regs = static_cast<RegisterInfo*> 4941fd3346740dfb7f47be9922312b68a4227fada96buzbee (NewMem(cu_, num_regs * sizeof(*reg_pool_->core_regs), true, kAllocRegAlloc)); 4951fd3346740dfb7f47be9922312b68a4227fada96buzbee reg_pool_->num_fp_regs = num_fp_regs; 4961fd3346740dfb7f47be9922312b68a4227fada96buzbee reg_pool_->FPRegs = static_cast<RegisterInfo*> 4971fd3346740dfb7f47be9922312b68a4227fada96buzbee (NewMem(cu_, num_fp_regs * sizeof(*reg_pool_->FPRegs), true, kAllocRegAlloc)); 4981fd3346740dfb7f47be9922312b68a4227fada96buzbee CompilerInitPool(reg_pool_->core_regs, core_regs, reg_pool_->num_core_regs); 4991fd3346740dfb7f47be9922312b68a4227fada96buzbee CompilerInitPool(reg_pool_->FPRegs, FpRegs, reg_pool_->num_fp_regs); 500efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Keep special registers from being allocated 501fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_reserved; i++) { 50252a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee if (NO_SUSPEND && (ReservedRegs[i] == rMIPS_SUSPEND)) { 503efc6369224b036a1fb77849f7ae65b3492c832c0buzbee //To measure cost of suspend check 504efc6369224b036a1fb77849f7ae65b3492c832c0buzbee continue; 505efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 5061fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkInUse(ReservedRegs[i]); 507efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 508efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Mark temp regs - all others not in use can be used for promotion 509fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_temps; i++) { 5101fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkTemp(core_temps[i]); 511efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 512fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_fp_temps; i++) { 5131fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkTemp(fp_temps[i]); 514efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 515efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 516efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5171fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free) 518efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 519fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if ((rl_free.low_reg != rl_keep.low_reg) && (rl_free.low_reg != rl_keep.high_reg) && 520fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (rl_free.high_reg != rl_keep.low_reg) && (rl_free.high_reg != rl_keep.high_reg)) { 521efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // No overlap, free both 5221fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(rl_free.low_reg); 5231fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(rl_free.high_reg); 524efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 525efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 526efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 527efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * In the Arm code a it is typical to use the link register 528efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * to hold the target address. However, for Mips we must 529efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * ensure that all branch instructions can be restarted if 530efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * there is a trap in the shadow. Allocate a temp register. 531efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 5321fd3346740dfb7f47be9922312b68a4227fada96buzbeeint MipsMir2Lir::LoadHelper(int offset) 533efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 5341fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadWordDisp(rMIPS_SELF, offset, r_T9); 535efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return r_T9; 536efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 537efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5381fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::SpillCoreRegs() 539efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 5401fd3346740dfb7f47be9922312b68a4227fada96buzbee if (num_core_spills_ == 0) { 541efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return; 542efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 5431fd3346740dfb7f47be9922312b68a4227fada96buzbee uint32_t mask = core_spill_mask_; 5441fd3346740dfb7f47be9922312b68a4227fada96buzbee int offset = num_core_spills_ * 4; 5451fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegImm(kOpSub, rMIPS_SP, offset); 546efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int reg = 0; mask; mask >>= 1, reg++) { 547efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & 0x1) { 548efc6369224b036a1fb77849f7ae65b3492c832c0buzbee offset -= 4; 5491fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreWordDisp(rMIPS_SP, offset, reg); 550efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 551efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 552efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 553efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5541fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::UnSpillCoreRegs() 555efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 5561fd3346740dfb7f47be9922312b68a4227fada96buzbee if (num_core_spills_ == 0) { 557efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return; 558efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 5591fd3346740dfb7f47be9922312b68a4227fada96buzbee uint32_t mask = core_spill_mask_; 5601fd3346740dfb7f47be9922312b68a4227fada96buzbee int offset = frame_size_; 561efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int reg = 0; mask; mask >>= 1, reg++) { 562efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & 0x1) { 563efc6369224b036a1fb77849f7ae65b3492c832c0buzbee offset -= 4; 5641fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadWordDisp(rMIPS_SP, offset, reg); 565efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 566efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 5671fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegImm(kOpAdd, rMIPS_SP, frame_size_); 568efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 569efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5701fd3346740dfb7f47be9922312b68a4227fada96buzbeebool MipsMir2Lir::IsUnconditionalBranch(LIR* lir) 571cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee{ 572cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee return (lir->opcode == kMipsB); 573efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 574efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5751fd3346740dfb7f47be9922312b68a4227fada96buzbeeMipsMir2Lir::MipsMir2Lir(CompilationUnit* cu, MIRGraph* mir_graph) : Mir2Lir(cu, mir_graph) { 57602031b185b4653e6c72e21f7a51238b903f6d638buzbee for (int i = 0; i < kMipsLast; i++) { 5771fd3346740dfb7f47be9922312b68a4227fada96buzbee if (MipsMir2Lir::EncodingMap[i].opcode != i) { 5781fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(FATAL) << "Encoding order for " << MipsMir2Lir::EncodingMap[i].name 57902031b185b4653e6c72e21f7a51238b903f6d638buzbee << " is wrong: expecting " << i << ", seeing " 5801fd3346740dfb7f47be9922312b68a4227fada96buzbee << static_cast<int>(MipsMir2Lir::EncodingMap[i].opcode); 581efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 582efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 583efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 584efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5851fd3346740dfb7f47be9922312b68a4227fada96buzbeeMir2Lir* MipsCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph) { 5861fd3346740dfb7f47be9922312b68a4227fada96buzbee return new MipsMir2Lir(cu, mir_graph); 5871fd3346740dfb7f47be9922312b68a4227fada96buzbee} 5881fd3346740dfb7f47be9922312b68a4227fada96buzbee 5891fd3346740dfb7f47be9922312b68a4227fada96buzbeeuint64_t MipsMir2Lir::GetTargetInstFlags(int opcode) 5901bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee{ 5911fd3346740dfb7f47be9922312b68a4227fada96buzbee return MipsMir2Lir::EncodingMap[opcode].flags; 5921bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 5931bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 5941fd3346740dfb7f47be9922312b68a4227fada96buzbeeconst char* MipsMir2Lir::GetTargetInstName(int opcode) 5951bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee{ 5961fd3346740dfb7f47be9922312b68a4227fada96buzbee return MipsMir2Lir::EncodingMap[opcode].name; 5971bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 5981bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 5991fd3346740dfb7f47be9922312b68a4227fada96buzbeeconst char* MipsMir2Lir::GetTargetInstFmt(int opcode) 6001bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee{ 6011fd3346740dfb7f47be9922312b68a4227fada96buzbee return MipsMir2Lir::EncodingMap[opcode].fmt; 6021bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 6031bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 604efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} // namespace art 605