target_mips.cc revision b01bf15d18f9b08d77e7a3c6e2897af0e02bf8ca
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 29091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic const RegStorage core_regs_arr[] = 30091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee {rs_rZERO, rs_rAT, rs_rV0, rs_rV1, rs_rA0, rs_rA1, rs_rA2, rs_rA3, rs_rT0, rs_rT1, rs_rT2, 31091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee rs_rT3, rs_rT4, rs_rT5, rs_rT6, rs_rT7, rs_rS0, rs_rS1, rs_rS2, rs_rS3, rs_rS4, rs_rS5, 32091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee rs_rS6, rs_rS7, rs_rT8, rs_rT9, rs_rK0, rs_rK1, rs_rGP, rs_rSP, rs_rFP, rs_rRA}; 33091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic RegStorage sp_regs_arr[] = 34091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee {rs_rF0, rs_rF1, rs_rF2, rs_rF3, rs_rF4, rs_rF5, rs_rF6, rs_rF7, rs_rF8, rs_rF9, rs_rF10, 35091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee rs_rF11, rs_rF12, rs_rF13, rs_rF14, rs_rF15}; 36091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic RegStorage dp_regs_arr[] = 37091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee {rs_rD0, rs_rD1, rs_rD2, rs_rD3, rs_rD4, rs_rD5, rs_rD6, rs_rD7}; 38091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic const RegStorage reserved_regs_arr[] = 39091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee {rs_rZERO, rs_rAT, rs_rS0, rs_rS1, rs_rK0, rs_rK1, rs_rGP, rs_rSP, rs_rRA}; 40091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic RegStorage core_temps_arr[] = 41091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee {rs_rV0, rs_rV1, rs_rA0, rs_rA1, rs_rA2, rs_rA3, rs_rT0, rs_rT1, rs_rT2, rs_rT3, rs_rT4, 42091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee rs_rT5, rs_rT6, rs_rT7, rs_rT8}; 43091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic RegStorage sp_temps_arr[] = 44091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee {rs_rF0, rs_rF1, rs_rF2, rs_rF3, rs_rF4, rs_rF5, rs_rF6, rs_rF7, rs_rF8, rs_rF9, rs_rF10, 45091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee rs_rF11, rs_rF12, rs_rF13, rs_rF14, rs_rF15}; 46091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic RegStorage dp_temps_arr[] = 47091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee {rs_rD0, rs_rD1, rs_rD2, rs_rD3, rs_rD4, rs_rD5, rs_rD6, rs_rD7}; 48091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee 49b01bf15d18f9b08d77e7a3c6e2897af0e02bf8cabuzbeestatic const std::vector<RegStorage> empty_pool; 50091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic const std::vector<RegStorage> core_regs(core_regs_arr, 51091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee core_regs_arr + sizeof(core_regs_arr) / sizeof(core_regs_arr[0])); 52091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic const std::vector<RegStorage> sp_regs(sp_regs_arr, 53091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee sp_regs_arr + sizeof(sp_regs_arr) / sizeof(sp_regs_arr[0])); 54091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic const std::vector<RegStorage> dp_regs(dp_regs_arr, 55091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee dp_regs_arr + sizeof(dp_regs_arr) / sizeof(dp_regs_arr[0])); 56091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic const std::vector<RegStorage> reserved_regs(reserved_regs_arr, 57091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee reserved_regs_arr + sizeof(reserved_regs_arr) / sizeof(reserved_regs_arr[0])); 58091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic const std::vector<RegStorage> core_temps(core_temps_arr, 59091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee core_temps_arr + sizeof(core_temps_arr) / sizeof(core_temps_arr[0])); 60091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic const std::vector<RegStorage> sp_temps(sp_temps_arr, 61091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee sp_temps_arr + sizeof(sp_temps_arr) / sizeof(sp_temps_arr[0])); 62091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeestatic const std::vector<RegStorage> dp_temps(dp_temps_arr, 63091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee dp_temps_arr + sizeof(dp_temps_arr) / sizeof(dp_temps_arr[0])); 64efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 652ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::LocCReturn() { 6600e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return mips_loc_c_return; 67efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 68efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 692ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::LocCReturnWide() { 7000e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return mips_loc_c_return_wide; 71efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 72efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 732ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::LocCReturnFloat() { 7400e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return mips_loc_c_return_float; 75efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 76efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 772ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::LocCReturnDouble() { 7800e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return mips_loc_c_return_double; 79efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 80efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 81efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return a target-dependent special register. 822700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeRegStorage MipsMir2Lir::TargetReg(SpecialTargetRegister reg) { 83091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee RegStorage res_reg; 84efc6369224b036a1fb77849f7ae65b3492c832c0buzbee switch (reg) { 85091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kSelf: res_reg = rs_rMIPS_SELF; break; 86091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kSuspend: res_reg = rs_rMIPS_SUSPEND; break; 87091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kLr: res_reg = rs_rMIPS_LR; break; 88091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kPc: res_reg = rs_rMIPS_PC; break; 89091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kSp: res_reg = rs_rMIPS_SP; break; 90091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kArg0: res_reg = rs_rMIPS_ARG0; break; 91091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kArg1: res_reg = rs_rMIPS_ARG1; break; 92091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kArg2: res_reg = rs_rMIPS_ARG2; break; 93091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kArg3: res_reg = rs_rMIPS_ARG3; break; 94091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kFArg0: res_reg = rs_rMIPS_FARG0; break; 95091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kFArg1: res_reg = rs_rMIPS_FARG1; break; 96091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kFArg2: res_reg = rs_rMIPS_FARG2; break; 97091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kFArg3: res_reg = rs_rMIPS_FARG3; break; 98091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kRet0: res_reg = rs_rMIPS_RET0; break; 99091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kRet1: res_reg = rs_rMIPS_RET1; break; 100091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kInvokeTgt: res_reg = rs_rMIPS_INVOKE_TGT; break; 101091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kHiddenArg: res_reg = rs_rT0; break; 102091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kHiddenFpArg: res_reg = RegStorage::InvalidReg(); break; 103091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kCount: res_reg = rs_rMIPS_COUNT; break; 104efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 105091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee return res_reg; 106efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 107efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 1082700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeRegStorage MipsMir2Lir::GetArgMappingToPhysicalReg(int arg_num) { 1093bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru // For the 32-bit internal ABI, the first 3 arguments are passed in registers. 1103bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru switch (arg_num) { 1113bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru case 0: 1122700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return rs_rMIPS_ARG1; 1133bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru case 1: 1142700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return rs_rMIPS_ARG2; 1153bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru case 2: 1162700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return rs_rMIPS_ARG3; 1173bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru default: 1182700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return RegStorage::InvalidReg(); 1193bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru } 1203bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru} 1213bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 122efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 123efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Decode the register id. 124efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 125091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeeuint64_t MipsMir2Lir::GetRegMaskCommon(RegStorage reg) { 126eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint64_t seed; 127efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int shift; 128091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee int reg_id = reg.GetRegNum(); 129efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Each double register is equal to a pair of single-precision FP registers */ 130091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (reg.IsDouble()) { 131091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee seed = 0x3; 132091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee reg_id = reg_id << 1; 133091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee } else { 134091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee seed = 1; 135091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee } 136091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee /* FP register starts at bit position 32 */ 137091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee shift = reg.IsFloat() ? kMipsFPReg0 : 0; 138efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Expand the double register id into single offset */ 139fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee shift += reg_id; 140efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return (seed << shift); 141efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 142efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 1432ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromuint64_t MipsMir2Lir::GetPCUseDefEncoding() { 144efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return ENCODE_MIPS_REG_PC; 145efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 146efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 147efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 148b48819db07f9a0992a72173380c24249d7fc648abuzbeevoid MipsMir2Lir::SetupTargetResourceMasks(LIR* lir, uint64_t flags) { 1491fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK_EQ(cu_->instruction_set, kMips); 150b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!lir->flags.use_def_invalid); 151efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 152efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Mips-specific resource map setup here. 153efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_DEF_SP) { 154b48819db07f9a0992a72173380c24249d7fc648abuzbee lir->u.m.def_mask |= ENCODE_MIPS_REG_SP; 155efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 156efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 157efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_USE_SP) { 158b48819db07f9a0992a72173380c24249d7fc648abuzbee lir->u.m.use_mask |= ENCODE_MIPS_REG_SP; 159efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 160efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 161efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_DEF_LR) { 162b48819db07f9a0992a72173380c24249d7fc648abuzbee lir->u.m.def_mask |= ENCODE_MIPS_REG_LR; 163efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 1649da5c1013215176f2a4dbe7a804be899e12d5f68buzbee 1659da5c1013215176f2a4dbe7a804be899e12d5f68buzbee if (flags & REG_DEF_HI) { 1669da5c1013215176f2a4dbe7a804be899e12d5f68buzbee lir->u.m.def_mask |= ENCODE_MIPS_REG_HI; 1679da5c1013215176f2a4dbe7a804be899e12d5f68buzbee } 1689da5c1013215176f2a4dbe7a804be899e12d5f68buzbee 1699da5c1013215176f2a4dbe7a804be899e12d5f68buzbee if (flags & REG_DEF_LO) { 1709da5c1013215176f2a4dbe7a804be899e12d5f68buzbee lir->u.m.def_mask |= ENCODE_MIPS_REG_LO; 1719da5c1013215176f2a4dbe7a804be899e12d5f68buzbee } 1729da5c1013215176f2a4dbe7a804be899e12d5f68buzbee 1739da5c1013215176f2a4dbe7a804be899e12d5f68buzbee if (flags & REG_USE_HI) { 1749da5c1013215176f2a4dbe7a804be899e12d5f68buzbee lir->u.m.use_mask |= ENCODE_MIPS_REG_HI; 1759da5c1013215176f2a4dbe7a804be899e12d5f68buzbee } 1769da5c1013215176f2a4dbe7a804be899e12d5f68buzbee 1779da5c1013215176f2a4dbe7a804be899e12d5f68buzbee if (flags & REG_USE_LO) { 1789da5c1013215176f2a4dbe7a804be899e12d5f68buzbee lir->u.m.use_mask |= ENCODE_MIPS_REG_LO; 1799da5c1013215176f2a4dbe7a804be899e12d5f68buzbee } 180efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 181efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 182efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* For dumping instructions */ 183efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#define MIPS_REG_COUNT 32 184fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic const char *mips_reg_name[MIPS_REG_COUNT] = { 185efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 186efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 187efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 188efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" 189efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}; 190efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 191efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 192efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Interpret a format string and build a string no longer than size 193efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * See format key in Assemble.c. 194efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 1952ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromstd::string MipsMir2Lir::BuildInsnString(const char *fmt, LIR *lir, unsigned char* base_addr) { 196efc6369224b036a1fb77849f7ae65b3492c832c0buzbee std::string buf; 197efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int i; 198fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee const char *fmt_end = &fmt[strlen(fmt)]; 199efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char tbuf[256]; 200efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char nc; 201fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (fmt < fmt_end) { 202efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int operand; 203efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (*fmt == '!') { 204efc6369224b036a1fb77849f7ae65b3492c832c0buzbee fmt++; 205fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_LT(fmt, fmt_end); 206efc6369224b036a1fb77849f7ae65b3492c832c0buzbee nc = *fmt++; 20738f85e4892f6504971bde994fec81fd61780ac30Brian Carlstrom if (nc == '!') { 208efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "!"); 209efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 210fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_LT(fmt, fmt_end); 211cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee DCHECK_LT(static_cast<unsigned>(nc-'0'), 4u); 212efc6369224b036a1fb77849f7ae65b3492c832c0buzbee operand = lir->operands[nc-'0']; 213efc6369224b036a1fb77849f7ae65b3492c832c0buzbee switch (*fmt++) { 214efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'b': 215b1eba213afaf7fa6445de863ddc9680ab99762eaBrian Carlstrom strcpy(tbuf, "0000"); 21638f85e4892f6504971bde994fec81fd61780ac30Brian Carlstrom for (i = 3; i >= 0; i--) { 217efc6369224b036a1fb77849f7ae65b3492c832c0buzbee tbuf[i] += operand & 1; 218efc6369224b036a1fb77849f7ae65b3492c832c0buzbee operand >>= 1; 219efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 220efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 221efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 's': 222091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee snprintf(tbuf, arraysize(tbuf), "$f%d", RegStorage::RegNum(operand)); 223efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 224efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'S': 225091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK_EQ(RegStorage::RegNum(operand) & 1, 0); 226091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee snprintf(tbuf, arraysize(tbuf), "$f%d", RegStorage::RegNum(operand)); 227efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 228efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'h': 229988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%04x", operand); 230efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 231efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'M': 232efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'd': 233988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%d", operand); 234efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 235efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'D': 236988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%d", operand+1); 237efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 238efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'E': 239988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%d", operand*4); 240efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 241efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'F': 242988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%d", operand*2); 243efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 244efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 't': 245107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers snprintf(tbuf, arraysize(tbuf), "0x%08" PRIxPTR " (L%p)", 246107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4 + (operand << 1), 247107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers lir->target); 248efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 249efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'T': 250988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "0x%08x", operand << 2); 251efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 252efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'u': { 253efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset_1 = lir->operands[0]; 254efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset_2 = NEXT_LIR(lir)->operands[0]; 255cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee uintptr_t target = 256fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (((reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4) & ~3) + 257efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (offset_1 << 21 >> 9) + (offset_2 << 1)) & 0xfffffffc; 258988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%p", reinterpret_cast<void*>(target)); 259efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 260efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 261efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 262efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Nothing to print for BLX_2 */ 263efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'v': 264efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "see above"); 265efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 266efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'r': 267efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK(operand >= 0 && operand < MIPS_REG_COUNT); 268fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee strcpy(tbuf, mips_reg_name[operand]); 269efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 270efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'N': 271efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Placeholder for delay slot handling 272efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "; nop"); 273efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 274efc6369224b036a1fb77849f7ae65b3492c832c0buzbee default: 275b1eba213afaf7fa6445de863ddc9680ab99762eaBrian Carlstrom strcpy(tbuf, "DecodeError"); 276efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 277efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 278efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf += tbuf; 279efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 280efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 281efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf += *fmt++; 282efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 283efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 284efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return buf; 285efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 286efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 287efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// FIXME: need to redo resource maps for MIPS - fix this at that time 2882ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::DumpResourceMask(LIR *mips_lir, uint64_t mask, const char *prefix) { 289efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char buf[256]; 290efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf[0] = 0; 291efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 292efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask == ENCODE_ALL) { 293efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(buf, "all"); 294efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 295efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char num[8]; 296efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int i; 297efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 298efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (i = 0; i < kMipsRegEnd; i++) { 299efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & (1ULL << i)) { 300988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(num, arraysize(num), "%d ", i); 301efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, num); 302efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 303efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 304efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 305efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_CCODE) { 306efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "cc "); 307efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 308efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_FP_STATUS) { 309efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "fpcc "); 310efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 311efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Memory bits */ 312fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (mips_lir && (mask & ENCODE_DALVIK_REG)) { 313988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(buf + strlen(buf), arraysize(buf) - strlen(buf), "dr%d%s", 314988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers DECODE_ALIAS_INFO_REG(mips_lir->flags.alias_info), 315988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers DECODE_ALIAS_INFO_WIDE(mips_lir->flags.alias_info) ? "(+1)" : ""); 316efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 317efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_LITERAL) { 318efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "lit "); 319efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 320efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 321efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_HEAP_REF) { 322efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "heap "); 323efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 324efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & ENCODE_MUST_NOT_ALIAS) { 325efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "noalias "); 326efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 327efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 328efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (buf[0]) { 329efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(INFO) << prefix << ": " << buf; 330efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 331efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 332efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 333efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 334311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * TUNING: is true leaf? Can't just use METHOD_IS_LEAF to determine as some 335efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * instructions might call out to C/assembly helper functions. Until 336efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * machinery is in place, always spill lr. 337efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 338efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3392ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::AdjustSpillMask() { 340091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee core_spill_mask_ |= (1 << rs_rRA.GetRegNum()); 3411fd3346740dfb7f47be9922312b68a4227fada96buzbee num_core_spills_++; 342efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 343efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 344efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 345efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Mark a callee-save fp register as promoted. Note that 346efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * vpush/vpop uses contiguous register lists so we must 347efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * include any holes in the mask. Associate holes with 348efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Dalvik register INVALID_VREG (0xFFFFU). 349efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 350091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeevoid MipsMir2Lir::MarkPreservedSingle(int s_reg, RegStorage reg) { 351efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(FATAL) << "No support yet for promoted FP regs"; 352efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 353efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 354091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeevoid MipsMir2Lir::MarkPreservedDouble(int s_reg, RegStorage reg) { 355091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LOG(FATAL) << "No support yet for promoted FP regs"; 3562700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee} 3572700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee 358efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Clobber all regs that might be used by an external C call */ 35931c2aac7137b69d5622eea09597500731fbee2efVladimir Markovoid MipsMir2Lir::ClobberCallerSave() { 360091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rZERO); 361091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rAT); 362091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rV0); 363091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rV1); 364091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rA0); 365091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rA1); 366091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rA2); 367091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rA3); 368091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT0); 369091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT1); 370091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT2); 371091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT3); 372091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT4); 373091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT5); 374091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT6); 375091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT7); 376091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT8); 377091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT9); 378091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rK0); 379091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rK1); 380091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rGP); 381091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rFP); 382091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rRA); 383091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF0); 384091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF1); 385091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF2); 386091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF3); 387091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF4); 388091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF5); 389091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF6); 390091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF7); 391091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF8); 392091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF9); 393091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF10); 394091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF11); 395091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF12); 396091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF13); 397091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF14); 398091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF15); 399091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD0); 400091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD1); 401091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD2); 402091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD3); 403091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD4); 404091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD5); 405091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD6); 406091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD7); 4071fd3346740dfb7f47be9922312b68a4227fada96buzbee} 4081fd3346740dfb7f47be9922312b68a4227fada96buzbee 4092ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::GetReturnWideAlt() { 41052a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee UNIMPLEMENTED(FATAL) << "No GetReturnWideAlt for MIPS"; 41152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee RegLocation res = LocCReturnWide(); 412efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 413efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 414efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4152ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::GetReturnAlt() { 41652a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee UNIMPLEMENTED(FATAL) << "No GetReturnAlt for MIPS"; 41752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee RegLocation res = LocCReturn(); 418efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 419efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 420efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 421efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */ 4222ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::LockCallTemps() { 423091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LockTemp(rs_rMIPS_ARG0); 424091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LockTemp(rs_rMIPS_ARG1); 425091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LockTemp(rs_rMIPS_ARG2); 426091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LockTemp(rs_rMIPS_ARG3); 427efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 428efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 429efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */ 4302ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::FreeCallTemps() { 431091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee FreeTemp(rs_rMIPS_ARG0); 432091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee FreeTemp(rs_rMIPS_ARG1); 433091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee FreeTemp(rs_rMIPS_ARG2); 434091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee FreeTemp(rs_rMIPS_ARG3); 435efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 436efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 437b14329f90f725af0f67c45dfcb94933a426d63ceAndreas Gampebool MipsMir2Lir::GenMemBarrier(MemBarrierKind barrier_kind) { 438efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#if ANDROID_SMP != 0 4391fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR1(kMipsSync, 0 /* Only stype currently supported */); 440b14329f90f725af0f67c45dfcb94933a426d63ceAndreas Gampe return true; 441b14329f90f725af0f67c45dfcb94933a426d63ceAndreas Gampe#else 442b14329f90f725af0f67c45dfcb94933a426d63ceAndreas Gampe return false; 443efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif 444efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 445efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4462ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::CompilerInitializeRegAlloc() { 447b01bf15d18f9b08d77e7a3c6e2897af0e02bf8cabuzbee reg_pool_ = new (arena_) RegisterPool(this, arena_, core_regs, empty_pool /* core64 */, sp_regs, 448b01bf15d18f9b08d77e7a3c6e2897af0e02bf8cabuzbee dp_regs, reserved_regs, empty_pool /* reserved64 */, 449b01bf15d18f9b08d77e7a3c6e2897af0e02bf8cabuzbee core_temps, empty_pool /* core64_temps */, sp_temps, 450b01bf15d18f9b08d77e7a3c6e2897af0e02bf8cabuzbee dp_temps); 451091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee 452091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Target-specific adjustments. 453091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee 454091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Alias single precision floats to appropriate half of overlapping double. 455091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee GrowableArray<RegisterInfo*>::Iterator it(®_pool_->sp_regs_); 456091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee for (RegisterInfo* info = it.Next(); info != nullptr; info = it.Next()) { 457091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee int sp_reg_num = info->GetReg().GetRegNum(); 458091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee int dp_reg_num = sp_reg_num >> 1; 459091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee RegStorage dp_reg = RegStorage::Solo64(RegStorage::kFloatingPoint | dp_reg_num); 460091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee RegisterInfo* dp_reg_info = GetRegInfo(dp_reg); 461091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Double precision register's master storage should refer to itself. 462091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK_EQ(dp_reg_info, dp_reg_info->Master()); 463091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Redirect single precision's master storage to master. 464091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee info->SetMaster(dp_reg_info); 465091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Singles should show a single 32-bit mask bit, at first referring to the low half. 466091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK_EQ(info->StorageMask(), 0x1U); 467091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (sp_reg_num & 1) { 468091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // For odd singles, change to user the high word of the backing double. 469091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee info->SetStorageMask(0x2); 470efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 471efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 472091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee 473091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Don't start allocating temps at r0/s0/d0 or you may clobber return regs in early-exit methods. 474091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // TODO: adjust when we roll to hard float calling convention. 475091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee reg_pool_->next_core_reg_ = 2; 476091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee reg_pool_->next_sp_reg_ = 2; 477091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee reg_pool_->next_dp_reg_ = 1; 478efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 479efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 480efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 481efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * In the Arm code a it is typical to use the link register 482efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * to hold the target address. However, for Mips we must 483efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * ensure that all branch instructions can be restarted if 484efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * there is a trap in the shadow. Allocate a temp register. 485efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 486dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersRegStorage MipsMir2Lir::LoadHelper(ThreadOffset<4> offset) { 487695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee // NOTE: native pointer. 4882700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LoadWordDisp(rs_rMIPS_SELF, offset.Int32Value(), rs_rT9); 4892700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return rs_rT9; 490efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 491efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4922f244e9faccfcca68af3c5484c397a01a1c3a342Andreas GampeRegStorage MipsMir2Lir::LoadHelper(ThreadOffset<8> offset) { 4932f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe UNIMPLEMENTED(FATAL) << "Should not be called."; 4942f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe return RegStorage::InvalidReg(); 4952f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe} 4962f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe 497b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave AllisonLIR* MipsMir2Lir::CheckSuspendUsingLoad() { 4982700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage tmp = AllocTemp(); 499695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee // NOTE: native pointer. 500dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers LoadWordDisp(rs_rMIPS_SELF, Thread::ThreadSuspendTriggerOffset<4>().Int32Value(), tmp); 501b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison LIR *inst = LoadWordDisp(tmp, 0, tmp); 502b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison FreeTemp(tmp); 503b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison return inst; 504b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison} 505b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison 5062ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::SpillCoreRegs() { 5071fd3346740dfb7f47be9922312b68a4227fada96buzbee if (num_core_spills_ == 0) { 508efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return; 509efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 5101fd3346740dfb7f47be9922312b68a4227fada96buzbee uint32_t mask = core_spill_mask_; 5111fd3346740dfb7f47be9922312b68a4227fada96buzbee int offset = num_core_spills_ * 4; 5122700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee OpRegImm(kOpSub, rs_rSP, offset); 513efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int reg = 0; mask; mask >>= 1, reg++) { 514efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & 0x1) { 515efc6369224b036a1fb77849f7ae65b3492c832c0buzbee offset -= 4; 516695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee Store32Disp(rs_rMIPS_SP, offset, RegStorage::Solo32(reg)); 517efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 518efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 519efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 520efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5212ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::UnSpillCoreRegs() { 5221fd3346740dfb7f47be9922312b68a4227fada96buzbee if (num_core_spills_ == 0) { 523efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return; 524efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 5251fd3346740dfb7f47be9922312b68a4227fada96buzbee uint32_t mask = core_spill_mask_; 5261fd3346740dfb7f47be9922312b68a4227fada96buzbee int offset = frame_size_; 527efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int reg = 0; mask; mask >>= 1, reg++) { 528efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & 0x1) { 529efc6369224b036a1fb77849f7ae65b3492c832c0buzbee offset -= 4; 530695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee Load32Disp(rs_rMIPS_SP, offset, RegStorage::Solo32(reg)); 531efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 532efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 5332700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee OpRegImm(kOpAdd, rs_rSP, frame_size_); 534efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 535efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5362ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool MipsMir2Lir::IsUnconditionalBranch(LIR* lir) { 537cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee return (lir->opcode == kMipsB); 538efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 539efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 540674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Markobool MipsMir2Lir::SupportsVolatileLoadStore(OpSize size) { 541674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko // No support for 64-bit atomic load/store on mips. 542674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko return size != k64 && size != kDouble; 543674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko} 544674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko 545674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir MarkoRegisterClass MipsMir2Lir::RegClassForFieldLoadStore(OpSize size, bool is_volatile) { 546674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko // No support for 64-bit atomic load/store on mips. 547674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko DCHECK(size != k64 && size != kDouble); 548674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko // TODO: Verify that both core and fp registers are suitable for smaller sizes. 549674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko return RegClassBySize(size); 550674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko} 551674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko 552862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMipsMir2Lir::MipsMir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena) 553862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee : Mir2Lir(cu, mir_graph, arena) { 55402031b185b4653e6c72e21f7a51238b903f6d638buzbee for (int i = 0; i < kMipsLast; i++) { 5551fd3346740dfb7f47be9922312b68a4227fada96buzbee if (MipsMir2Lir::EncodingMap[i].opcode != i) { 5561fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(FATAL) << "Encoding order for " << MipsMir2Lir::EncodingMap[i].name 55702031b185b4653e6c72e21f7a51238b903f6d638buzbee << " is wrong: expecting " << i << ", seeing " 5581fd3346740dfb7f47be9922312b68a4227fada96buzbee << static_cast<int>(MipsMir2Lir::EncodingMap[i].opcode); 559efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 560efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 561efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 562efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 563862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMir2Lir* MipsCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph, 564862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee ArenaAllocator* const arena) { 565862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee return new MipsMir2Lir(cu, mir_graph, arena); 5661fd3346740dfb7f47be9922312b68a4227fada96buzbee} 5671fd3346740dfb7f47be9922312b68a4227fada96buzbee 5682ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromuint64_t MipsMir2Lir::GetTargetInstFlags(int opcode) { 569409fe94ad529d9334587be80b9f6a3d166805508buzbee DCHECK(!IsPseudoLirOp(opcode)); 5701fd3346740dfb7f47be9922312b68a4227fada96buzbee return MipsMir2Lir::EncodingMap[opcode].flags; 5711bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 5721bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 5732ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromconst char* MipsMir2Lir::GetTargetInstName(int opcode) { 574409fe94ad529d9334587be80b9f6a3d166805508buzbee DCHECK(!IsPseudoLirOp(opcode)); 5751fd3346740dfb7f47be9922312b68a4227fada96buzbee return MipsMir2Lir::EncodingMap[opcode].name; 5761bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 5771bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 5782ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromconst char* MipsMir2Lir::GetTargetInstFmt(int opcode) { 579409fe94ad529d9334587be80b9f6a3d166805508buzbee DCHECK(!IsPseudoLirOp(opcode)); 5801fd3346740dfb7f47be9922312b68a4227fada96buzbee return MipsMir2Lir::EncodingMap[opcode].fmt; 5811bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 5821bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 5837934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace art 584