target_mips.cc revision 641ce0371c2f0dc95d26be02d8366124c8b66653
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" 18641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "compiler/codegen/codegen_util.h" 19641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "compiler/compiler_internals.h" 20641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "compiler/codegen/ralloc_util.h" 21641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "mips_lir.h" 22efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 23efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#include <string> 24efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 25efc6369224b036a1fb77849f7ae65b3492c832c0buzbeenamespace art { 26efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 27fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int core_regs[] = {r_ZERO, r_AT, r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, 28fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_T0, r_T1, r_T2, r_T3, r_T4, r_T5, r_T6, r_T7, 29fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_S0, r_S1, r_S2, r_S3, r_S4, r_S5, r_S6, r_S7, r_T8, 30fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_T9, r_K0, r_K1, r_GP, r_SP, r_FP, r_RA}; 3152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbeestatic int ReservedRegs[] = {r_ZERO, r_AT, r_S0, r_S1, r_K0, r_K1, r_GP, r_SP, 32efc6369224b036a1fb77849f7ae65b3492c832c0buzbee r_RA}; 33fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int core_temps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2, 34fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_T3, r_T4, r_T5, r_T6, r_T7, r_T8}; 3552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbeestatic 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}; 37fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int fp_temps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7, 38fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15}; 39efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4002031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegLocation MipsCodegen::LocCReturn() 41efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 42efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = MIPS_LOC_C_RETURN; 43efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 44efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 45efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4602031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegLocation MipsCodegen::LocCReturnWide() 47efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 48efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = MIPS_LOC_C_RETURN_WIDE; 49efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 50efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 51efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5202031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegLocation MipsCodegen::LocCReturnFloat() 53efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 54efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = MIPS_LOC_C_RETURN_FLOAT; 55efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 56efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 57efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5802031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegLocation MipsCodegen::LocCReturnDouble() 59efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 60efc6369224b036a1fb77849f7ae65b3492c832c0buzbee RegLocation res = MIPS_LOC_C_RETURN_DOUBLE; 61efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 62efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 63efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 64efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return a target-dependent special register. 6502031b185b4653e6c72e21f7a51238b903f6d638buzbeeint MipsCodegen::TargetReg(SpecialTargetRegister reg) { 66efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int res = INVALID_REG; 67efc6369224b036a1fb77849f7ae65b3492c832c0buzbee switch (reg) { 68efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kSelf: res = rMIPS_SELF; break; 69efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kSuspend: res = rMIPS_SUSPEND; break; 70efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kLr: res = rMIPS_LR; break; 71efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kPc: res = rMIPS_PC; break; 72efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kSp: res = rMIPS_SP; break; 73efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg0: res = rMIPS_ARG0; break; 74efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg1: res = rMIPS_ARG1; break; 75efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg2: res = rMIPS_ARG2; break; 76efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg3: res = rMIPS_ARG3; break; 77efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg0: res = rMIPS_FARG0; break; 78efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg1: res = rMIPS_FARG1; break; 79efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg2: res = rMIPS_FARG2; break; 80efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg3: res = rMIPS_FARG3; break; 81efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kRet0: res = rMIPS_RET0; break; 82efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kRet1: res = rMIPS_RET1; break; 83efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kInvokeTgt: res = rMIPS_INVOKE_TGT; break; 84efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kCount: res = rMIPS_COUNT; break; 85efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 86efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 87efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 88efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 89efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Create a double from a pair of singles. 9002031b185b4653e6c72e21f7a51238b903f6d638buzbeeint MipsCodegen::S2d(int low_reg, int high_reg) 91efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 92fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return MIPS_S2D(low_reg, high_reg); 93efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 94efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 95efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return mask to strip off fp reg flags and bias. 9602031b185b4653e6c72e21f7a51238b903f6d638buzbeeuint32_t MipsCodegen::FpRegMask() 97efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 98efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_FP_REG_MASK; 99efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 100efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 101efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// True if both regs single, both core or both double. 10202031b185b4653e6c72e21f7a51238b903f6d638buzbeebool MipsCodegen::SameRegType(int reg1, int reg2) 103efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 104efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return (MIPS_REGTYPE(reg1) == MIPS_REGTYPE(reg2)); 105efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 106efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 107efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 108efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Decode the register id. 109efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 11002031b185b4653e6c72e21f7a51238b903f6d638buzbeeuint64_t MipsCodegen::GetRegMaskCommon(CompilationUnit* cu, int reg) 111efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 112eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint64_t seed; 113efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int shift; 114fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int reg_id; 115efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 116efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 117fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee reg_id = reg & 0x1f; 118efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Each double register is equal to a pair of single-precision FP registers */ 119efc6369224b036a1fb77849f7ae65b3492c832c0buzbee seed = MIPS_DOUBLEREG(reg) ? 3 : 1; 120efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* FP register starts at bit position 16 */ 121efc6369224b036a1fb77849f7ae65b3492c832c0buzbee shift = MIPS_FPREG(reg) ? kMipsFPReg0 : 0; 122efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Expand the double register id into single offset */ 123fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee shift += reg_id; 124efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return (seed << shift); 125efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 126efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 12702031b185b4653e6c72e21f7a51238b903f6d638buzbeeuint64_t MipsCodegen::GetPCUseDefEncoding() 128efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 129efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return ENCODE_MIPS_REG_PC; 130efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 131efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 132efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 13302031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::SetupTargetResourceMasks(CompilationUnit* cu, LIR* lir) 134efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 135fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(cu->instruction_set, kMips); 136efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 137efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Mips-specific resource map setup here. 13802031b185b4653e6c72e21f7a51238b903f6d638buzbee uint64_t flags = MipsCodegen::EncodingMap[lir->opcode].flags; 139efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 140efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_DEF_SP) { 141fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->def_mask |= ENCODE_MIPS_REG_SP; 142efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 143efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 144efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_USE_SP) { 145fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->use_mask |= ENCODE_MIPS_REG_SP; 146efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 147efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 148efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_DEF_LR) { 149fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->def_mask |= ENCODE_MIPS_REG_LR; 150efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 151efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 152efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 153efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* For dumping instructions */ 154efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#define MIPS_REG_COUNT 32 155fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic const char *mips_reg_name[MIPS_REG_COUNT] = { 156efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 157efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 158efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 159efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" 160efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}; 161efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 162efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 163efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Interpret a format string and build a string no longer than size 164efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * See format key in Assemble.c. 165efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 16602031b185b4653e6c72e21f7a51238b903f6d638buzbeestd::string MipsCodegen::BuildInsnString(const char *fmt, LIR *lir, unsigned char* base_addr) 167efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 168efc6369224b036a1fb77849f7ae65b3492c832c0buzbee std::string buf; 169efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int i; 170fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee const char *fmt_end = &fmt[strlen(fmt)]; 171efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char tbuf[256]; 172efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char nc; 173fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (fmt < fmt_end) { 174efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int operand; 175efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (*fmt == '!') { 176efc6369224b036a1fb77849f7ae65b3492c832c0buzbee fmt++; 177fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_LT(fmt, fmt_end); 178efc6369224b036a1fb77849f7ae65b3492c832c0buzbee nc = *fmt++; 179efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (nc=='!') { 180efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "!"); 181efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 182fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_LT(fmt, fmt_end); 183cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee DCHECK_LT(static_cast<unsigned>(nc-'0'), 4u); 184efc6369224b036a1fb77849f7ae65b3492c832c0buzbee operand = lir->operands[nc-'0']; 185efc6369224b036a1fb77849f7ae65b3492c832c0buzbee switch (*fmt++) { 186efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'b': 187efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf,"0000"); 188efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (i=3; i>= 0; i--) { 189efc6369224b036a1fb77849f7ae65b3492c832c0buzbee tbuf[i] += operand & 1; 190efc6369224b036a1fb77849f7ae65b3492c832c0buzbee operand >>= 1; 191efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 192efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 193efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 's': 194efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK); 195efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 196efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'S': 197efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK_EQ(((operand & MIPS_FP_REG_MASK) & 1), 0); 198efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK); 199efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 200efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'h': 201efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%04x", operand); 202efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 203efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'M': 204efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'd': 205efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%d", operand); 206efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 207efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'D': 208efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%d", operand+1); 209efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 210efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'E': 211efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%d", operand*4); 212efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 213efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'F': 214efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(tbuf,"%d", operand*2); 215efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 216efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 't': 217fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee sprintf(tbuf,"0x%08x (L%p)", reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4 + 218efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (operand << 2), lir->target); 219efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 220efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'T': 221cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee sprintf(tbuf,"0x%08x", operand << 2); 222efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 223efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'u': { 224efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset_1 = lir->operands[0]; 225efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset_2 = NEXT_LIR(lir)->operands[0]; 226cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee uintptr_t target = 227fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (((reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4) & ~3) + 228efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (offset_1 << 21 >> 9) + (offset_2 << 1)) & 0xfffffffc; 229cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee sprintf(tbuf, "%p", reinterpret_cast<void*>(target)); 230efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 231efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 232efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 233efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Nothing to print for BLX_2 */ 234efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'v': 235efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "see above"); 236efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 237efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'r': 238efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK(operand >= 0 && operand < MIPS_REG_COUNT); 239fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee strcpy(tbuf, mips_reg_name[operand]); 240efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 241efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'N': 242efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Placeholder for delay slot handling 243efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "; nop"); 244efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 245efc6369224b036a1fb77849f7ae65b3492c832c0buzbee default: 246efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf,"DecodeError"); 247efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 248efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 249efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf += tbuf; 250efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 251efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 252efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf += *fmt++; 253efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 254efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 255efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return buf; 256efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 257efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 258efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// FIXME: need to redo resource maps for MIPS - fix this at that time 25902031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::DumpResourceMask(LIR *mips_lir, uint64_t mask, const char *prefix) 260efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 261efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char buf[256]; 262efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf[0] = 0; 263efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 264efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask == ENCODE_ALL) { 265efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(buf, "all"); 266efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 267efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char num[8]; 268efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int i; 269efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 270efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (i = 0; i < kMipsRegEnd; i++) { 271efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & (1ULL << i)) { 272efc6369224b036a1fb77849f7ae65b3492c832c0buzbee sprintf(num, "%d ", i); 273efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, num); 274efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 275efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 276efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 277efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_CCODE) { 278efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "cc "); 279efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 280efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_FP_STATUS) { 281efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "fpcc "); 282efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 283efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Memory bits */ 284fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (mips_lir && (mask & ENCODE_DALVIK_REG)) { 285fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee sprintf(buf + strlen(buf), "dr%d%s", mips_lir->alias_info & 0xffff, 286fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (mips_lir->alias_info & 0x80000000) ? "(+1)" : ""); 287efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 288efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_LITERAL) { 289efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "lit "); 290efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 291efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 292efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_HEAP_REF) { 293efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "heap "); 294efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 295efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_MUST_NOT_ALIAS) { 296efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "noalias "); 297efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 298efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 299efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (buf[0]) { 300efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(INFO) << prefix << ": " << buf; 301efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 302efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 303efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 304efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 305fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * TUNING: is leaf? Can't just use "has_invoke" to determine as some 306efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * instructions might call out to C/assembly helper functions. Until 307efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * machinery is in place, always spill lr. 308efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 309efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 31002031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::AdjustSpillMask(CompilationUnit* cu) 311efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 312fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee cu->core_spill_mask |= (1 << r_RA); 313fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee cu->num_core_spills++; 314efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 315efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 316efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 317efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Mark a callee-save fp register as promoted. Note that 318efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * vpush/vpop uses contiguous register lists so we must 319efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * include any holes in the mask. Associate holes with 320efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Dalvik register INVALID_VREG (0xFFFFU). 321efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 32202031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::MarkPreservedSingle(CompilationUnit* cu, int s_reg, int reg) 323efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 324efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(FATAL) << "No support yet for promoted FP regs"; 325efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 326efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 32702031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::FlushRegWide(CompilationUnit* cu, int reg1, int reg2) 328efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 329fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegisterInfo* info1 = GetRegInfo(cu, reg1); 330fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegisterInfo* info2 = GetRegInfo(cu, reg2); 331efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK(info1 && info2 && info1->pair && info2->pair && 332efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (info1->partner == info2->reg) && 333efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (info2->partner == info1->reg)); 334efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) { 335fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!(info1->is_temp && info2->is_temp)) { 336fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee /* Should not happen. If it does, there's a problem in eval_loc */ 337efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(FATAL) << "Long half-temp, half-promoted"; 338efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 339efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 340efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info1->dirty = false; 341efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info2->dirty = false; 342fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (SRegToVReg(cu, info2->s_reg) < SRegToVReg(cu, info1->s_reg)) 343efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info1 = info2; 344fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int v_reg = SRegToVReg(cu, info1->s_reg); 345fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee StoreBaseDispWide(cu, rMIPS_SP, VRegOffset(cu, v_reg), info1->reg, info1->partner); 346efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 347efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 348efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 34902031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::FlushReg(CompilationUnit* cu, int reg) 350efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 351fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee RegisterInfo* info = GetRegInfo(cu, reg); 352efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (info->live && info->dirty) { 353efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info->dirty = false; 354fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int v_reg = SRegToVReg(cu, info->s_reg); 355fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee StoreBaseDisp(cu, rMIPS_SP, VRegOffset(cu, v_reg), reg, kWord); 356efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 357efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 358efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 359efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Give access to the target-dependent FP register encoding to common code */ 36002031b185b4653e6c72e21f7a51238b903f6d638buzbeebool MipsCodegen::IsFpReg(int reg) { 361efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_FPREG(reg); 362efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 363efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 364efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Clobber all regs that might be used by an external C call */ 36502031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::ClobberCalleeSave(CompilationUnit *cu) 366fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee{ 367fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_ZERO); 368fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_AT); 369fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_V0); 370fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_V1); 371fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_A0); 372fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_A1); 373fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_A2); 374fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_A3); 375fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_T0); 376fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_T1); 377fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_T2); 378fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_T3); 379fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_T4); 380fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_T5); 381fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_T6); 382fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_T7); 383fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_T8); 384fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_T9); 385fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_K0); 386fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_K1); 387fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_GP); 388fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_FP); 389fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_RA); 390fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F0); 391fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F1); 392fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F2); 393fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F3); 394fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F4); 395fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F5); 396fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F6); 397fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F7); 398fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F8); 399fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F9); 400fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F10); 401fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F11); 402fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F12); 403fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F13); 404fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F14); 405fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee Clobber(cu, r_F15); 406fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee} 407fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee 40802031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegLocation MipsCodegen::GetReturnWideAlt(CompilationUnit* cu) 40952a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee{ 41052a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee UNIMPLEMENTED(FATAL) << "No GetReturnWideAlt for MIPS"; 41152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee RegLocation res = LocCReturnWide(); 412efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 413efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 414efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 41502031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegLocation MipsCodegen::GetReturnAlt(CompilationUnit* cu) 416efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 41752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee UNIMPLEMENTED(FATAL) << "No GetReturnAlt for MIPS"; 41852a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee RegLocation res = LocCReturn(); 419efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 420efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 421efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 42202031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegisterInfo* MipsCodegen::GetRegInfo(CompilationUnit* cu, int reg) 423efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 424fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return MIPS_FPREG(reg) ? &cu->reg_pool->FPRegs[reg & MIPS_FP_REG_MASK] 425fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee : &cu->reg_pool->core_regs[reg]; 426efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 427efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 428efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */ 42902031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::LockCallTemps(CompilationUnit* cu) 430efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 431fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LockTemp(cu, rMIPS_ARG0); 432fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LockTemp(cu, rMIPS_ARG1); 433fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LockTemp(cu, rMIPS_ARG2); 434fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LockTemp(cu, rMIPS_ARG3); 435efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 436efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 437efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */ 43802031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::FreeCallTemps(CompilationUnit* cu) 439efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 440fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee FreeTemp(cu, rMIPS_ARG0); 441fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee FreeTemp(cu, rMIPS_ARG1); 442fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee FreeTemp(cu, rMIPS_ARG2); 443fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee FreeTemp(cu, rMIPS_ARG3); 444efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 445efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 44602031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::GenMemBarrier(CompilationUnit *cu, MemBarrierKind barrier_kind) 447efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 448efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#if ANDROID_SMP != 0 449fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR1(cu, kMipsSync, 0 /* Only stype currently supported */); 450efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif 451efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 452efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 453efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 454efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Alloc a pair of core registers, or a double. Low reg in low byte, 455efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * high reg in next byte. 456efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 45702031b185b4653e6c72e21f7a51238b903f6d638buzbeeint MipsCodegen::AllocTypedTempPair(CompilationUnit *cu, bool fp_hint, 458fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int reg_class) 459efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 460fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int high_reg; 461fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int low_reg; 462efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int res = 0; 463efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 464fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) { 465fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee low_reg = AllocTempDouble(cu); 466fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee high_reg = low_reg + 1; 467fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res = (low_reg & 0xff) | ((high_reg & 0xff) << 8); 468efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 469efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 470efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 471fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee low_reg = AllocTemp(cu); 472fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee high_reg = AllocTemp(cu); 473fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res = (low_reg & 0xff) | ((high_reg & 0xff) << 8); 474efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 475efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 476efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 47702031b185b4653e6c72e21f7a51238b903f6d638buzbeeint MipsCodegen::AllocTypedTemp(CompilationUnit *cu, bool fp_hint, int reg_class) 478efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 479fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) 480efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 481fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return AllocTempFloat(cu); 482efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 483fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return AllocTemp(cu); 484efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 485efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 48602031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::CompilerInitializeRegAlloc(CompilationUnit* cu) 487efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 488fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_regs = sizeof(core_regs)/sizeof(*core_regs); 489fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_reserved = sizeof(ReservedRegs)/sizeof(*ReservedRegs); 490fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_temps = sizeof(core_temps)/sizeof(*core_temps); 491fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_fp_regs = sizeof(FpRegs)/sizeof(*FpRegs); 492fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_fp_temps = sizeof(fp_temps)/sizeof(*fp_temps); 493cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee RegisterPool *pool = 494fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee static_cast<RegisterPool*>(NewMem(cu, sizeof(*pool), true, kAllocRegAlloc)); 495fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee cu->reg_pool = pool; 496fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee pool->num_core_regs = num_regs; 497fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee pool->core_regs = static_cast<RegisterInfo*> 498fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (NewMem(cu, num_regs * sizeof(*cu->reg_pool->core_regs), true, kAllocRegAlloc)); 499fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee pool->num_fp_regs = num_fp_regs; 500cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee pool->FPRegs = static_cast<RegisterInfo*> 501fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (NewMem(cu, num_fp_regs * sizeof(*cu->reg_pool->FPRegs), true, kAllocRegAlloc)); 502fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee CompilerInitPool(pool->core_regs, core_regs, pool->num_core_regs); 503fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee CompilerInitPool(pool->FPRegs, FpRegs, pool->num_fp_regs); 504efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Keep special registers from being allocated 505fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_reserved; i++) { 50652a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee if (NO_SUSPEND && (ReservedRegs[i] == rMIPS_SUSPEND)) { 507efc6369224b036a1fb77849f7ae65b3492c832c0buzbee //To measure cost of suspend check 508efc6369224b036a1fb77849f7ae65b3492c832c0buzbee continue; 509efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 510fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee MarkInUse(cu, ReservedRegs[i]); 511efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 512efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Mark temp regs - all others not in use can be used for promotion 513fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_temps; i++) { 514fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee MarkTemp(cu, core_temps[i]); 515efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 516fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_fp_temps; i++) { 517fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee MarkTemp(cu, fp_temps[i]); 518efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 519efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 520efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 52102031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::FreeRegLocTemps(CompilationUnit* cu, RegLocation rl_keep, RegLocation rl_free) 522efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 523fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if ((rl_free.low_reg != rl_keep.low_reg) && (rl_free.low_reg != rl_keep.high_reg) && 524fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (rl_free.high_reg != rl_keep.low_reg) && (rl_free.high_reg != rl_keep.high_reg)) { 525efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // No overlap, free both 526fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee FreeTemp(cu, rl_free.low_reg); 527fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee FreeTemp(cu, rl_free.high_reg); 528efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 529efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 530efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 531efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * In the Arm code a it is typical to use the link register 532efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * to hold the target address. However, for Mips we must 533efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * ensure that all branch instructions can be restarted if 534efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * there is a trap in the shadow. Allocate a temp register. 535efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 53602031b185b4653e6c72e21f7a51238b903f6d638buzbeeint MipsCodegen::LoadHelper(CompilationUnit* cu, int offset) 537efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 538fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LoadWordDisp(cu, rMIPS_SELF, offset, r_T9); 539efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return r_T9; 540efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 541efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 54202031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::SpillCoreRegs(CompilationUnit* cu) 543efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 544fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (cu->num_core_spills == 0) { 545efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return; 546efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 547fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee uint32_t mask = cu->core_spill_mask; 548fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int offset = cu->num_core_spills * 4; 549fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee OpRegImm(cu, kOpSub, rMIPS_SP, offset); 550efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int reg = 0; mask; mask >>= 1, reg++) { 551efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & 0x1) { 552efc6369224b036a1fb77849f7ae65b3492c832c0buzbee offset -= 4; 553fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee StoreWordDisp(cu, rMIPS_SP, offset, reg); 554efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 555efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 556efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 557efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 55802031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::UnSpillCoreRegs(CompilationUnit* cu) 559efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{ 560fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (cu->num_core_spills == 0) { 561efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return; 562efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 563fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee uint32_t mask = cu->core_spill_mask; 564fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int offset = cu->frame_size; 565efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int reg = 0; mask; mask >>= 1, reg++) { 566efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & 0x1) { 567efc6369224b036a1fb77849f7ae65b3492c832c0buzbee offset -= 4; 568fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LoadWordDisp(cu, rMIPS_SP, offset, reg); 569efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 570efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 571fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee OpRegImm(cu, kOpAdd, rMIPS_SP, cu->frame_size); 572efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 573efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 57402031b185b4653e6c72e21f7a51238b903f6d638buzbeebool MipsCodegen::IsUnconditionalBranch(LIR* lir) 575cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee{ 576cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee return (lir->opcode == kMipsB); 577efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 578efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 579efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Common initialization routine for an architecture family */ 58002031b185b4653e6c72e21f7a51238b903f6d638buzbeebool InitMipsCodegen(CompilationUnit* cu) 58102031b185b4653e6c72e21f7a51238b903f6d638buzbee{ 58202031b185b4653e6c72e21f7a51238b903f6d638buzbee cu->cg.reset(new MipsCodegen()); 58302031b185b4653e6c72e21f7a51238b903f6d638buzbee for (int i = 0; i < kMipsLast; i++) { 58402031b185b4653e6c72e21f7a51238b903f6d638buzbee if (MipsCodegen::EncodingMap[i].opcode != i) { 58502031b185b4653e6c72e21f7a51238b903f6d638buzbee LOG(FATAL) << "Encoding order for " << MipsCodegen::EncodingMap[i].name 58602031b185b4653e6c72e21f7a51238b903f6d638buzbee << " is wrong: expecting " << i << ", seeing " 58702031b185b4653e6c72e21f7a51238b903f6d638buzbee << static_cast<int>(MipsCodegen::EncodingMap[i].opcode); 588efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 589efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 59002031b185b4653e6c72e21f7a51238b903f6d638buzbee return true; 591efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 592efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 59302031b185b4653e6c72e21f7a51238b903f6d638buzbeeuint64_t MipsCodegen::GetTargetInstFlags(int opcode) 5941bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee{ 59502031b185b4653e6c72e21f7a51238b903f6d638buzbee return MipsCodegen::EncodingMap[opcode].flags; 5961bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 5971bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 59802031b185b4653e6c72e21f7a51238b903f6d638buzbeeconst char* MipsCodegen::GetTargetInstName(int opcode) 5991bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee{ 60002031b185b4653e6c72e21f7a51238b903f6d638buzbee return MipsCodegen::EncodingMap[opcode].name; 6011bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 6021bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 60302031b185b4653e6c72e21f7a51238b903f6d638buzbeeconst char* MipsCodegen::GetTargetInstFmt(int opcode) 6041bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee{ 60502031b185b4653e6c72e21f7a51238b903f6d638buzbee return MipsCodegen::EncodingMap[opcode].fmt; 6061bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 6071bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 608efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} // namespace art 609