target_mips.cc revision 00e1ec6581b5b7b46ca4c314c2854e9caa647dd2
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" 18107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers 19107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers#include <inttypes.h> 20107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers 21107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers#include <string> 22107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers 237940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/compiler_internals.h" 247940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/quick/mir_to_lir-inl.h" 25641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "mips_lir.h" 26efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 27efc6369224b036a1fb77849f7ae65b3492c832c0buzbeenamespace art { 28efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 29fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int core_regs[] = {r_ZERO, r_AT, r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, 30fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_T0, r_T1, r_T2, r_T3, r_T4, r_T5, r_T6, r_T7, 31fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_S0, r_S1, r_S2, r_S3, r_S4, r_S5, r_S6, r_S7, r_T8, 32fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_T9, r_K0, r_K1, r_GP, r_SP, r_FP, r_RA}; 3352a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbeestatic int ReservedRegs[] = {r_ZERO, r_AT, r_S0, r_S1, r_K0, r_K1, r_GP, r_SP, 34efc6369224b036a1fb77849f7ae65b3492c832c0buzbee r_RA}; 35fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int core_temps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2, 36fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_T3, r_T4, r_T5, r_T6, r_T7, r_T8}; 3752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbeestatic int FpRegs[] = {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}; 39fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int fp_temps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7, 40fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15}; 41efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 422ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::LocCReturn() { 4300e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return mips_loc_c_return; 44efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 45efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 462ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::LocCReturnWide() { 4700e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return mips_loc_c_return_wide; 48efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 49efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 502ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::LocCReturnFloat() { 5100e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return mips_loc_c_return_float; 52efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 53efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 542ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::LocCReturnDouble() { 5500e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return mips_loc_c_return_double; 56efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 57efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 58efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return a target-dependent special register. 591fd3346740dfb7f47be9922312b68a4227fada96buzbeeint MipsMir2Lir::TargetReg(SpecialTargetRegister reg) { 60efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int res = INVALID_REG; 61efc6369224b036a1fb77849f7ae65b3492c832c0buzbee switch (reg) { 62efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kSelf: res = rMIPS_SELF; break; 63efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kSuspend: res = rMIPS_SUSPEND; break; 64efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kLr: res = rMIPS_LR; break; 65efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kPc: res = rMIPS_PC; break; 66efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kSp: res = rMIPS_SP; break; 67efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg0: res = rMIPS_ARG0; break; 68efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg1: res = rMIPS_ARG1; break; 69efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg2: res = rMIPS_ARG2; break; 70efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kArg3: res = rMIPS_ARG3; break; 71efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg0: res = rMIPS_FARG0; break; 72efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg1: res = rMIPS_FARG1; break; 73efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg2: res = rMIPS_FARG2; break; 74efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kFArg3: res = rMIPS_FARG3; break; 75efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kRet0: res = rMIPS_RET0; break; 76efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kRet1: res = rMIPS_RET1; break; 77efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kInvokeTgt: res = rMIPS_INVOKE_TGT; break; 7888474b416eb257078e590bf9bc7957cee604a186Jeff Hao case kHiddenArg: res = r_T0; break; 7988474b416eb257078e590bf9bc7957cee604a186Jeff Hao case kHiddenFpArg: res = INVALID_REG; break; 80efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case kCount: res = rMIPS_COUNT; break; 81efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 82efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 83efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 84efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 853bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoruint MipsMir2Lir::GetArgMappingToPhysicalReg(int arg_num) { 863bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru // For the 32-bit internal ABI, the first 3 arguments are passed in registers. 873bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru switch (arg_num) { 883bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru case 0: 893bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru return rMIPS_ARG1; 903bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru case 1: 913bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru return rMIPS_ARG2; 923bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru case 2: 933bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru return rMIPS_ARG3; 943bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru default: 953bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru return INVALID_REG; 963bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru } 973bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru} 983bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 99efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Create a double from a pair of singles. 1002ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromint MipsMir2Lir::S2d(int low_reg, int high_reg) { 101fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return MIPS_S2D(low_reg, high_reg); 102efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 103efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 104efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return mask to strip off fp reg flags and bias. 1052ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromuint32_t MipsMir2Lir::FpRegMask() { 106efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_FP_REG_MASK; 107efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 108efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 109efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// True if both regs single, both core or both double. 1102ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool MipsMir2Lir::SameRegType(int reg1, int reg2) { 111efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return (MIPS_REGTYPE(reg1) == MIPS_REGTYPE(reg2)); 112efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 113efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 114efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 115efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Decode the register id. 116efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 1172ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromuint64_t MipsMir2Lir::GetRegMaskCommon(int reg) { 118eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint64_t seed; 119efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int shift; 120fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int reg_id; 121efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 122efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 123fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee reg_id = reg & 0x1f; 124efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Each double register is equal to a pair of single-precision FP registers */ 125efc6369224b036a1fb77849f7ae65b3492c832c0buzbee seed = MIPS_DOUBLEREG(reg) ? 3 : 1; 126efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* FP register starts at bit position 16 */ 127efc6369224b036a1fb77849f7ae65b3492c832c0buzbee shift = MIPS_FPREG(reg) ? kMipsFPReg0 : 0; 128efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Expand the double register id into single offset */ 129fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee shift += reg_id; 130efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return (seed << shift); 131efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 132efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 1332ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromuint64_t MipsMir2Lir::GetPCUseDefEncoding() { 134efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return ENCODE_MIPS_REG_PC; 135efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 136efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 137efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 138b48819db07f9a0992a72173380c24249d7fc648abuzbeevoid MipsMir2Lir::SetupTargetResourceMasks(LIR* lir, uint64_t flags) { 1391fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK_EQ(cu_->instruction_set, kMips); 140b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!lir->flags.use_def_invalid); 141efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 142efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Mips-specific resource map setup here. 143efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_DEF_SP) { 144b48819db07f9a0992a72173380c24249d7fc648abuzbee lir->u.m.def_mask |= ENCODE_MIPS_REG_SP; 145efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 146efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 147efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_USE_SP) { 148b48819db07f9a0992a72173380c24249d7fc648abuzbee lir->u.m.use_mask |= ENCODE_MIPS_REG_SP; 149efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 150efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 151efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_DEF_LR) { 152b48819db07f9a0992a72173380c24249d7fc648abuzbee lir->u.m.def_mask |= ENCODE_MIPS_REG_LR; 153efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 154efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 155efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 156efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* For dumping instructions */ 157efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#define MIPS_REG_COUNT 32 158fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic const char *mips_reg_name[MIPS_REG_COUNT] = { 159efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 160efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 161efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 162efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" 163efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}; 164efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 165efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 166efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Interpret a format string and build a string no longer than size 167efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * See format key in Assemble.c. 168efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 1692ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromstd::string MipsMir2Lir::BuildInsnString(const char *fmt, LIR *lir, unsigned char* base_addr) { 170efc6369224b036a1fb77849f7ae65b3492c832c0buzbee std::string buf; 171efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int i; 172fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee const char *fmt_end = &fmt[strlen(fmt)]; 173efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char tbuf[256]; 174efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char nc; 175fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (fmt < fmt_end) { 176efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int operand; 177efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (*fmt == '!') { 178efc6369224b036a1fb77849f7ae65b3492c832c0buzbee fmt++; 179fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_LT(fmt, fmt_end); 180efc6369224b036a1fb77849f7ae65b3492c832c0buzbee nc = *fmt++; 18138f85e4892f6504971bde994fec81fd61780ac30Brian Carlstrom if (nc == '!') { 182efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "!"); 183efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 184fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_LT(fmt, fmt_end); 185cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee DCHECK_LT(static_cast<unsigned>(nc-'0'), 4u); 186efc6369224b036a1fb77849f7ae65b3492c832c0buzbee operand = lir->operands[nc-'0']; 187efc6369224b036a1fb77849f7ae65b3492c832c0buzbee switch (*fmt++) { 188efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'b': 189b1eba213afaf7fa6445de863ddc9680ab99762eaBrian Carlstrom strcpy(tbuf, "0000"); 19038f85e4892f6504971bde994fec81fd61780ac30Brian Carlstrom for (i = 3; i >= 0; i--) { 191efc6369224b036a1fb77849f7ae65b3492c832c0buzbee tbuf[i] += operand & 1; 192efc6369224b036a1fb77849f7ae65b3492c832c0buzbee operand >>= 1; 193efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 194efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 195efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 's': 196988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "$f%d", operand & MIPS_FP_REG_MASK); 197efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 198efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'S': 199efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK_EQ(((operand & MIPS_FP_REG_MASK) & 1), 0); 200988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "$f%d", operand & MIPS_FP_REG_MASK); 201efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 202efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'h': 203988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%04x", operand); 204efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 205efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'M': 206efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'd': 207988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%d", operand); 208efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 209efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'D': 210988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%d", operand+1); 211efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 212efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'E': 213988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%d", operand*4); 214efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 215efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'F': 216988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%d", operand*2); 217efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 218efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 't': 219107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers snprintf(tbuf, arraysize(tbuf), "0x%08" PRIxPTR " (L%p)", 220107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4 + (operand << 1), 221107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers lir->target); 222efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 223efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'T': 224988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "0x%08x", operand << 2); 225efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 226efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'u': { 227efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset_1 = lir->operands[0]; 228efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset_2 = NEXT_LIR(lir)->operands[0]; 229cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee uintptr_t target = 230fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (((reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4) & ~3) + 231efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (offset_1 << 21 >> 9) + (offset_2 << 1)) & 0xfffffffc; 232988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%p", reinterpret_cast<void*>(target)); 233efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 234efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 235efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 236efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Nothing to print for BLX_2 */ 237efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'v': 238efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "see above"); 239efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 240efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'r': 241efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK(operand >= 0 && operand < MIPS_REG_COUNT); 242fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee strcpy(tbuf, mips_reg_name[operand]); 243efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 244efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'N': 245efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Placeholder for delay slot handling 246efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "; nop"); 247efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 248efc6369224b036a1fb77849f7ae65b3492c832c0buzbee default: 249b1eba213afaf7fa6445de863ddc9680ab99762eaBrian Carlstrom strcpy(tbuf, "DecodeError"); 250efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 251efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 252efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf += tbuf; 253efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 254efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 255efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf += *fmt++; 256efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 257efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 258efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return buf; 259efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 260efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 261efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// FIXME: need to redo resource maps for MIPS - fix this at that time 2622ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::DumpResourceMask(LIR *mips_lir, uint64_t mask, const char *prefix) { 263efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char buf[256]; 264efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf[0] = 0; 265efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 266efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask == ENCODE_ALL) { 267efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(buf, "all"); 268efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 269efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char num[8]; 270efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int i; 271efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 272efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (i = 0; i < kMipsRegEnd; i++) { 273efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & (1ULL << i)) { 274988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(num, arraysize(num), "%d ", i); 275efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, num); 276efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 277efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 278efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 279efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_CCODE) { 280efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "cc "); 281efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 282efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_FP_STATUS) { 283efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "fpcc "); 284efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 285efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Memory bits */ 286fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (mips_lir && (mask & ENCODE_DALVIK_REG)) { 287988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(buf + strlen(buf), arraysize(buf) - strlen(buf), "dr%d%s", 288988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers DECODE_ALIAS_INFO_REG(mips_lir->flags.alias_info), 289988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers DECODE_ALIAS_INFO_WIDE(mips_lir->flags.alias_info) ? "(+1)" : ""); 290efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 291efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_LITERAL) { 292efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "lit "); 293efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 294efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 295efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_HEAP_REF) { 296efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "heap "); 297efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 298efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_MUST_NOT_ALIAS) { 299efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "noalias "); 300efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 301efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 302efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (buf[0]) { 303efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(INFO) << prefix << ": " << buf; 304efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 305efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 306efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 307efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 308311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * TUNING: is true leaf? Can't just use METHOD_IS_LEAF to determine as some 309efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * instructions might call out to C/assembly helper functions. Until 310efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * machinery is in place, always spill lr. 311efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 312efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3132ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::AdjustSpillMask() { 3141fd3346740dfb7f47be9922312b68a4227fada96buzbee core_spill_mask_ |= (1 << r_RA); 3151fd3346740dfb7f47be9922312b68a4227fada96buzbee num_core_spills_++; 316efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 317efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 318efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 319efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Mark a callee-save fp register as promoted. Note that 320efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * vpush/vpop uses contiguous register lists so we must 321efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * include any holes in the mask. Associate holes with 322efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Dalvik register INVALID_VREG (0xFFFFU). 323efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 3242ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::MarkPreservedSingle(int s_reg, int reg) { 325efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(FATAL) << "No support yet for promoted FP regs"; 326efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 327efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3282ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::FlushRegWide(int reg1, int reg2) { 3291fd3346740dfb7f47be9922312b68a4227fada96buzbee RegisterInfo* info1 = GetRegInfo(reg1); 3301fd3346740dfb7f47be9922312b68a4227fada96buzbee RegisterInfo* info2 = GetRegInfo(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; 3421fd3346740dfb7f47be9922312b68a4227fada96buzbee if (mir_graph_->SRegToVReg(info2->s_reg) < mir_graph_->SRegToVReg(info1->s_reg)) 343efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info1 = info2; 3441fd3346740dfb7f47be9922312b68a4227fada96buzbee int v_reg = mir_graph_->SRegToVReg(info1->s_reg); 3451fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreBaseDispWide(rMIPS_SP, VRegOffset(v_reg), info1->reg, info1->partner); 346efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 347efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 348efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3492ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::FlushReg(int reg) { 3501fd3346740dfb7f47be9922312b68a4227fada96buzbee RegisterInfo* info = GetRegInfo(reg); 351efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (info->live && info->dirty) { 352efc6369224b036a1fb77849f7ae65b3492c832c0buzbee info->dirty = false; 3531fd3346740dfb7f47be9922312b68a4227fada96buzbee int v_reg = mir_graph_->SRegToVReg(info->s_reg); 3541fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreBaseDisp(rMIPS_SP, VRegOffset(v_reg), reg, kWord); 355efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 356efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 357efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 358efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Give access to the target-dependent FP register encoding to common code */ 3591fd3346740dfb7f47be9922312b68a4227fada96buzbeebool MipsMir2Lir::IsFpReg(int reg) { 360efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return MIPS_FPREG(reg); 361efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 362efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 363efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Clobber all regs that might be used by an external C call */ 36431c2aac7137b69d5622eea09597500731fbee2efVladimir Markovoid MipsMir2Lir::ClobberCallerSave() { 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 4062ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::GetReturnWideAlt() { 40752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee UNIMPLEMENTED(FATAL) << "No GetReturnWideAlt for MIPS"; 40852a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee RegLocation res = LocCReturnWide(); 409efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 410efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 411efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4122ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::GetReturnAlt() { 41352a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee UNIMPLEMENTED(FATAL) << "No GetReturnAlt for MIPS"; 41452a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee RegLocation res = LocCReturn(); 415efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 416efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 417efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 418efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */ 4192ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::LockCallTemps() { 4201fd3346740dfb7f47be9922312b68a4227fada96buzbee LockTemp(rMIPS_ARG0); 4211fd3346740dfb7f47be9922312b68a4227fada96buzbee LockTemp(rMIPS_ARG1); 4221fd3346740dfb7f47be9922312b68a4227fada96buzbee LockTemp(rMIPS_ARG2); 4231fd3346740dfb7f47be9922312b68a4227fada96buzbee LockTemp(rMIPS_ARG3); 424efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 425efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 426efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */ 4272ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::FreeCallTemps() { 4281fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(rMIPS_ARG0); 4291fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(rMIPS_ARG1); 4301fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(rMIPS_ARG2); 4311fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(rMIPS_ARG3); 432efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 433efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4342ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::GenMemBarrier(MemBarrierKind barrier_kind) { 435efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#if ANDROID_SMP != 0 4361fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR1(kMipsSync, 0 /* Only stype currently supported */); 437efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif 438efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 439efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 44000e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee// Alloc a pair of core registers, or a double. 44100e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill BuzbeeRegStorage MipsMir2Lir::AllocTypedTempWide(bool fp_hint, int reg_class) { 442fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int high_reg; 443fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int low_reg; 444efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 445fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) { 4461fd3346740dfb7f47be9922312b68a4227fada96buzbee low_reg = AllocTempDouble(); 447fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee high_reg = low_reg + 1; 44800e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return RegStorage(RegStorage::k64BitPair, low_reg, high_reg); 449efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 450efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4511fd3346740dfb7f47be9922312b68a4227fada96buzbee low_reg = AllocTemp(); 4521fd3346740dfb7f47be9922312b68a4227fada96buzbee high_reg = AllocTemp(); 45300e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return RegStorage(RegStorage::k64BitPair, low_reg, high_reg); 454efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 455efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4562ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromint MipsMir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) { 4572ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) { 4581fd3346740dfb7f47be9922312b68a4227fada96buzbee return AllocTempFloat(); 459efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 4601fd3346740dfb7f47be9922312b68a4227fada96buzbee return AllocTemp(); 461efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 462efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4632ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::CompilerInitializeRegAlloc() { 464fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_regs = sizeof(core_regs)/sizeof(*core_regs); 465fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_reserved = sizeof(ReservedRegs)/sizeof(*ReservedRegs); 466fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_temps = sizeof(core_temps)/sizeof(*core_temps); 467fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_fp_regs = sizeof(FpRegs)/sizeof(*FpRegs); 468fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_fp_temps = sizeof(fp_temps)/sizeof(*fp_temps); 469f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier reg_pool_ = static_cast<RegisterPool*>(arena_->Alloc(sizeof(*reg_pool_), 470f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier ArenaAllocator::kAllocRegAlloc)); 4711fd3346740dfb7f47be9922312b68a4227fada96buzbee reg_pool_->num_core_regs = num_regs; 4721fd3346740dfb7f47be9922312b68a4227fada96buzbee reg_pool_->core_regs = static_cast<RegisterInfo*> 473f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier (arena_->Alloc(num_regs * sizeof(*reg_pool_->core_regs), ArenaAllocator::kAllocRegAlloc)); 4741fd3346740dfb7f47be9922312b68a4227fada96buzbee reg_pool_->num_fp_regs = num_fp_regs; 4751fd3346740dfb7f47be9922312b68a4227fada96buzbee reg_pool_->FPRegs = static_cast<RegisterInfo*> 476f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier (arena_->Alloc(num_fp_regs * sizeof(*reg_pool_->FPRegs), ArenaAllocator::kAllocRegAlloc)); 4771fd3346740dfb7f47be9922312b68a4227fada96buzbee CompilerInitPool(reg_pool_->core_regs, core_regs, reg_pool_->num_core_regs); 4781fd3346740dfb7f47be9922312b68a4227fada96buzbee CompilerInitPool(reg_pool_->FPRegs, FpRegs, reg_pool_->num_fp_regs); 479efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Keep special registers from being allocated 480fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_reserved; i++) { 48152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee if (NO_SUSPEND && (ReservedRegs[i] == rMIPS_SUSPEND)) { 4827934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom // To measure cost of suspend check 483efc6369224b036a1fb77849f7ae65b3492c832c0buzbee continue; 484efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 4851fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkInUse(ReservedRegs[i]); 486efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 487efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Mark temp regs - all others not in use can be used for promotion 488fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_temps; i++) { 4891fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkTemp(core_temps[i]); 490efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 491fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_fp_temps; i++) { 4921fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkTemp(fp_temps[i]); 493efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 494efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 495efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4962ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free) { 49700e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee if ((rl_free.reg.GetReg() != rl_keep.reg.GetReg()) && (rl_free.reg.GetReg() != rl_keep.reg.GetHighReg()) && 49800e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee (rl_free.reg.GetHighReg() != rl_keep.reg.GetReg()) && (rl_free.reg.GetHighReg() != rl_keep.reg.GetHighReg())) { 499efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // No overlap, free both 50000e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee FreeTemp(rl_free.reg.GetReg()); 50100e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee FreeTemp(rl_free.reg.GetHighReg()); 502efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 503efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 504efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 505efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * In the Arm code a it is typical to use the link register 506efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * to hold the target address. However, for Mips we must 507efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * ensure that all branch instructions can be restarted if 508efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * there is a trap in the shadow. Allocate a temp register. 509efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 510468532ea115657709bc32ee498e701a4c71762d4Ian Rogersint MipsMir2Lir::LoadHelper(ThreadOffset offset) { 511468532ea115657709bc32ee498e701a4c71762d4Ian Rogers LoadWordDisp(rMIPS_SELF, offset.Int32Value(), r_T9); 512efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return r_T9; 513efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 514efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5152ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::SpillCoreRegs() { 5161fd3346740dfb7f47be9922312b68a4227fada96buzbee if (num_core_spills_ == 0) { 517efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return; 518efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 5191fd3346740dfb7f47be9922312b68a4227fada96buzbee uint32_t mask = core_spill_mask_; 5201fd3346740dfb7f47be9922312b68a4227fada96buzbee int offset = num_core_spills_ * 4; 5211fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegImm(kOpSub, rMIPS_SP, offset); 522efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int reg = 0; mask; mask >>= 1, reg++) { 523efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & 0x1) { 524efc6369224b036a1fb77849f7ae65b3492c832c0buzbee offset -= 4; 5251fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreWordDisp(rMIPS_SP, offset, reg); 526efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 527efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 528efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 529efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5302ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::UnSpillCoreRegs() { 5311fd3346740dfb7f47be9922312b68a4227fada96buzbee if (num_core_spills_ == 0) { 532efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return; 533efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 5341fd3346740dfb7f47be9922312b68a4227fada96buzbee uint32_t mask = core_spill_mask_; 5351fd3346740dfb7f47be9922312b68a4227fada96buzbee int offset = frame_size_; 536efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int reg = 0; mask; mask >>= 1, reg++) { 537efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & 0x1) { 538efc6369224b036a1fb77849f7ae65b3492c832c0buzbee offset -= 4; 5391fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadWordDisp(rMIPS_SP, offset, reg); 540efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 541efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 5421fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegImm(kOpAdd, rMIPS_SP, frame_size_); 543efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 544efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5452ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool MipsMir2Lir::IsUnconditionalBranch(LIR* lir) { 546cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee return (lir->opcode == kMipsB); 547efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 548efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 549862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMipsMir2Lir::MipsMir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena) 550862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee : Mir2Lir(cu, mir_graph, arena) { 55102031b185b4653e6c72e21f7a51238b903f6d638buzbee for (int i = 0; i < kMipsLast; i++) { 5521fd3346740dfb7f47be9922312b68a4227fada96buzbee if (MipsMir2Lir::EncodingMap[i].opcode != i) { 5531fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(FATAL) << "Encoding order for " << MipsMir2Lir::EncodingMap[i].name 55402031b185b4653e6c72e21f7a51238b903f6d638buzbee << " is wrong: expecting " << i << ", seeing " 5551fd3346740dfb7f47be9922312b68a4227fada96buzbee << static_cast<int>(MipsMir2Lir::EncodingMap[i].opcode); 556efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 557efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 558efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 559efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 560862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMir2Lir* MipsCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph, 561862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee ArenaAllocator* const arena) { 562862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee return new MipsMir2Lir(cu, mir_graph, arena); 5631fd3346740dfb7f47be9922312b68a4227fada96buzbee} 5641fd3346740dfb7f47be9922312b68a4227fada96buzbee 5652ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromuint64_t MipsMir2Lir::GetTargetInstFlags(int opcode) { 566409fe94ad529d9334587be80b9f6a3d166805508buzbee DCHECK(!IsPseudoLirOp(opcode)); 5671fd3346740dfb7f47be9922312b68a4227fada96buzbee return MipsMir2Lir::EncodingMap[opcode].flags; 5681bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 5691bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 5702ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromconst char* MipsMir2Lir::GetTargetInstName(int opcode) { 571409fe94ad529d9334587be80b9f6a3d166805508buzbee DCHECK(!IsPseudoLirOp(opcode)); 5721fd3346740dfb7f47be9922312b68a4227fada96buzbee return MipsMir2Lir::EncodingMap[opcode].name; 5731bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 5741bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 5752ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromconst char* MipsMir2Lir::GetTargetInstFmt(int opcode) { 576409fe94ad529d9334587be80b9f6a3d166805508buzbee DCHECK(!IsPseudoLirOp(opcode)); 5771fd3346740dfb7f47be9922312b68a4227fada96buzbee return MipsMir2Lir::EncodingMap[opcode].fmt; 5781bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 5791bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 5807934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace art 581