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 29089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr 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}; 33089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr 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}; 36089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr RegStorage dp_regs_arr[] = 37091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee {rs_rD0, rs_rD1, rs_rD2, rs_rD3, rs_rD4, rs_rD5, rs_rD6, rs_rD7}; 38089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr RegStorage reserved_regs_arr[] = 39091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee {rs_rZERO, rs_rAT, rs_rS0, rs_rS1, rs_rK0, rs_rK1, rs_rGP, rs_rSP, rs_rRA}; 40089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr 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}; 43089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr 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}; 46089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr RegStorage dp_temps_arr[] = 47091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee {rs_rD0, rs_rD1, rs_rD2, rs_rD3, rs_rD4, rs_rD5, rs_rD6, rs_rD7}; 48091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee 49089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr ArrayRef<const RegStorage> empty_pool; 50089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr ArrayRef<const RegStorage> core_regs(core_regs_arr); 51089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr ArrayRef<const RegStorage> sp_regs(sp_regs_arr); 52089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr ArrayRef<const RegStorage> dp_regs(dp_regs_arr); 53089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr ArrayRef<const RegStorage> reserved_regs(reserved_regs_arr); 54089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr ArrayRef<const RegStorage> core_temps(core_temps_arr); 55089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr ArrayRef<const RegStorage> sp_temps(sp_temps_arr); 56089142cf1d0c028b5a7c703baf0b97f4a4ada3f7Vladimir Markostatic constexpr ArrayRef<const RegStorage> dp_temps(dp_temps_arr); 57efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 582ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::LocCReturn() { 5900e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return mips_loc_c_return; 60efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 61efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 62a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbeeRegLocation MipsMir2Lir::LocCReturnRef() { 63a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee return mips_loc_c_return; 64a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee} 65a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee 662ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::LocCReturnWide() { 6700e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return mips_loc_c_return_wide; 68efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 69efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 702ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::LocCReturnFloat() { 7100e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return mips_loc_c_return_float; 72efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 73efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 742ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::LocCReturnDouble() { 7500e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee return mips_loc_c_return_double; 76efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 77efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 782db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung// Convert k64BitSolo into k64BitPair 792db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas LeungRegStorage MipsMir2Lir::Solo64ToPair64(RegStorage reg) { 802db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung DCHECK(reg.IsDouble()); 812db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung int reg_num = (reg.GetRegNum() & ~1) | RegStorage::kFloatingPoint; 822db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung return RegStorage(RegStorage::k64BitPair, reg_num, reg_num + 1); 832db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung} 842db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung 85efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return a target-dependent special register. 862700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeRegStorage MipsMir2Lir::TargetReg(SpecialTargetRegister reg) { 87091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee RegStorage res_reg; 88efc6369224b036a1fb77849f7ae65b3492c832c0buzbee switch (reg) { 89091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kSelf: res_reg = rs_rMIPS_SELF; break; 90091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kSuspend: res_reg = rs_rMIPS_SUSPEND; break; 91091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kLr: res_reg = rs_rMIPS_LR; break; 92091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kPc: res_reg = rs_rMIPS_PC; break; 93091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kSp: res_reg = rs_rMIPS_SP; break; 94091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kArg0: res_reg = rs_rMIPS_ARG0; break; 95091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kArg1: res_reg = rs_rMIPS_ARG1; break; 96091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kArg2: res_reg = rs_rMIPS_ARG2; break; 97091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kArg3: res_reg = rs_rMIPS_ARG3; break; 98091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kFArg0: res_reg = rs_rMIPS_FARG0; break; 99091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kFArg1: res_reg = rs_rMIPS_FARG1; break; 100091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kFArg2: res_reg = rs_rMIPS_FARG2; break; 101091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kFArg3: res_reg = rs_rMIPS_FARG3; break; 102091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kRet0: res_reg = rs_rMIPS_RET0; break; 103091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kRet1: res_reg = rs_rMIPS_RET1; break; 104091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kInvokeTgt: res_reg = rs_rMIPS_INVOKE_TGT; break; 105091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kHiddenArg: res_reg = rs_rT0; break; 106091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kHiddenFpArg: res_reg = RegStorage::InvalidReg(); break; 107091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee case kCount: res_reg = rs_rMIPS_COUNT; break; 10858994cdb00b323339bd83828eddc53976048006fDmitry Petrochenko default: res_reg = RegStorage::InvalidReg(); 109efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 110091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee return res_reg; 111efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 112efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 1132700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeRegStorage MipsMir2Lir::GetArgMappingToPhysicalReg(int arg_num) { 1143bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru // For the 32-bit internal ABI, the first 3 arguments are passed in registers. 1153bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru switch (arg_num) { 1163bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru case 0: 1172700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return rs_rMIPS_ARG1; 1183bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru case 1: 1192700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return rs_rMIPS_ARG2; 1203bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru case 2: 1212700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return rs_rMIPS_ARG3; 1223bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru default: 1232700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return RegStorage::InvalidReg(); 1243bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru } 1253bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru} 1263bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 127efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 128efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Decode the register id. 129efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 1308dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir MarkoResourceMask MipsMir2Lir::GetRegMaskCommon(const RegStorage& reg) const { 1318dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko return reg.IsDouble() 1328dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko /* Each double register is equal to a pair of single-precision FP registers */ 1332db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung#if (FR_BIT == 0) 1342db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung ? ResourceMask::TwoBits((reg.GetRegNum() & ~1) + kMipsFPReg0) 1352db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung#else 1368dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko ? ResourceMask::TwoBits(reg.GetRegNum() * 2 + kMipsFPReg0) 1372db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung#endif 1388dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko : ResourceMask::Bit(reg.IsSingle() ? reg.GetRegNum() + kMipsFPReg0 : reg.GetRegNum()); 139efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 140efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 1418dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir MarkoResourceMask MipsMir2Lir::GetPCUseDefEncoding() const { 1428dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko return ResourceMask::Bit(kMipsRegPC); 143efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 144efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 145efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 1468dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Markovoid MipsMir2Lir::SetupTargetResourceMasks(LIR* lir, uint64_t flags, 1478dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko ResourceMask* use_mask, ResourceMask* def_mask) { 1481fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK_EQ(cu_->instruction_set, kMips); 149b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!lir->flags.use_def_invalid); 150efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 151efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Mips-specific resource map setup here. 152efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_DEF_SP) { 1538dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko def_mask->SetBit(kMipsRegSP); 154efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 155efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 156efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_USE_SP) { 1578dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko use_mask->SetBit(kMipsRegSP); 158efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 159efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 160efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (flags & REG_DEF_LR) { 1618dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko def_mask->SetBit(kMipsRegLR); 162efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 1639da5c1013215176f2a4dbe7a804be899e12d5f68buzbee 1649da5c1013215176f2a4dbe7a804be899e12d5f68buzbee if (flags & REG_DEF_HI) { 1658dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko def_mask->SetBit(kMipsRegHI); 1669da5c1013215176f2a4dbe7a804be899e12d5f68buzbee } 1679da5c1013215176f2a4dbe7a804be899e12d5f68buzbee 1689da5c1013215176f2a4dbe7a804be899e12d5f68buzbee if (flags & REG_DEF_LO) { 1698dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko def_mask->SetBit(kMipsRegLO); 1709da5c1013215176f2a4dbe7a804be899e12d5f68buzbee } 1719da5c1013215176f2a4dbe7a804be899e12d5f68buzbee 1729da5c1013215176f2a4dbe7a804be899e12d5f68buzbee if (flags & REG_USE_HI) { 1738dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko use_mask->SetBit(kMipsRegHI); 1749da5c1013215176f2a4dbe7a804be899e12d5f68buzbee } 1759da5c1013215176f2a4dbe7a804be899e12d5f68buzbee 1769da5c1013215176f2a4dbe7a804be899e12d5f68buzbee if (flags & REG_USE_LO) { 1778dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko use_mask->SetBit(kMipsRegLO); 1789da5c1013215176f2a4dbe7a804be899e12d5f68buzbee } 179efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 180efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 181efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* For dumping instructions */ 182efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#define MIPS_REG_COUNT 32 183fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic const char *mips_reg_name[MIPS_REG_COUNT] = { 184efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 185efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 186efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 187efc6369224b036a1fb77849f7ae65b3492c832c0buzbee "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" 188efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}; 189efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 190efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 191efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Interpret a format string and build a string no longer than size 192efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * See format key in Assemble.c. 193efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 1942ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromstd::string MipsMir2Lir::BuildInsnString(const char *fmt, LIR *lir, unsigned char* base_addr) { 195efc6369224b036a1fb77849f7ae65b3492c832c0buzbee std::string buf; 196efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int i; 197fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee const char *fmt_end = &fmt[strlen(fmt)]; 198efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char tbuf[256]; 199efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char nc; 200fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (fmt < fmt_end) { 201efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int operand; 202efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (*fmt == '!') { 203efc6369224b036a1fb77849f7ae65b3492c832c0buzbee fmt++; 204fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_LT(fmt, fmt_end); 205efc6369224b036a1fb77849f7ae65b3492c832c0buzbee nc = *fmt++; 20638f85e4892f6504971bde994fec81fd61780ac30Brian Carlstrom if (nc == '!') { 207efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "!"); 208efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 209fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_LT(fmt, fmt_end); 210cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee DCHECK_LT(static_cast<unsigned>(nc-'0'), 4u); 211efc6369224b036a1fb77849f7ae65b3492c832c0buzbee operand = lir->operands[nc-'0']; 212efc6369224b036a1fb77849f7ae65b3492c832c0buzbee switch (*fmt++) { 213efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'b': 214b1eba213afaf7fa6445de863ddc9680ab99762eaBrian Carlstrom strcpy(tbuf, "0000"); 21538f85e4892f6504971bde994fec81fd61780ac30Brian Carlstrom for (i = 3; i >= 0; i--) { 216efc6369224b036a1fb77849f7ae65b3492c832c0buzbee tbuf[i] += operand & 1; 217efc6369224b036a1fb77849f7ae65b3492c832c0buzbee operand >>= 1; 218efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 219efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 220efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 's': 221091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee snprintf(tbuf, arraysize(tbuf), "$f%d", RegStorage::RegNum(operand)); 222efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 223efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'S': 224091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK_EQ(RegStorage::RegNum(operand) & 1, 0); 225091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee snprintf(tbuf, arraysize(tbuf), "$f%d", RegStorage::RegNum(operand)); 226efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 227efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'h': 228988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%04x", operand); 229efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 230efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'M': 231efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'd': 232988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%d", operand); 233efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 234efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'D': 235988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%d", operand+1); 236efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 237efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'E': 238988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%d", operand*4); 239efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 240efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'F': 241988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%d", operand*2); 242efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 243efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 't': 244107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers snprintf(tbuf, arraysize(tbuf), "0x%08" PRIxPTR " (L%p)", 245107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4 + (operand << 1), 246107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers lir->target); 247efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 248efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'T': 249988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "0x%08x", operand << 2); 250efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 251efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'u': { 252efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset_1 = lir->operands[0]; 253efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int offset_2 = NEXT_LIR(lir)->operands[0]; 254cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee uintptr_t target = 255fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (((reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4) & ~3) + 256efc6369224b036a1fb77849f7ae65b3492c832c0buzbee (offset_1 << 21 >> 9) + (offset_2 << 1)) & 0xfffffffc; 257988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(tbuf, arraysize(tbuf), "%p", reinterpret_cast<void*>(target)); 258efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 259efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 260efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 261efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Nothing to print for BLX_2 */ 262efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'v': 263efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "see above"); 264efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 265efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'r': 266efc6369224b036a1fb77849f7ae65b3492c832c0buzbee DCHECK(operand >= 0 && operand < MIPS_REG_COUNT); 267fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee strcpy(tbuf, mips_reg_name[operand]); 268efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 269efc6369224b036a1fb77849f7ae65b3492c832c0buzbee case 'N': 270efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Placeholder for delay slot handling 271efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(tbuf, "; nop"); 272efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 273efc6369224b036a1fb77849f7ae65b3492c832c0buzbee default: 274b1eba213afaf7fa6445de863ddc9680ab99762eaBrian Carlstrom strcpy(tbuf, "DecodeError"); 275efc6369224b036a1fb77849f7ae65b3492c832c0buzbee break; 276efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 277efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf += tbuf; 278efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 279efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 280efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf += *fmt++; 281efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 282efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 283efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return buf; 284efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 285efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 286efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// FIXME: need to redo resource maps for MIPS - fix this at that time 2878dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Markovoid MipsMir2Lir::DumpResourceMask(LIR *mips_lir, const ResourceMask& mask, const char *prefix) { 288efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char buf[256]; 289efc6369224b036a1fb77849f7ae65b3492c832c0buzbee buf[0] = 0; 290efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 2918dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mask.Equals(kEncodeAll)) { 292efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcpy(buf, "all"); 293efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 294efc6369224b036a1fb77849f7ae65b3492c832c0buzbee char num[8]; 295efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int i; 296efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 297efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (i = 0; i < kMipsRegEnd; i++) { 2988dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mask.HasBit(i)) { 299988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(num, arraysize(num), "%d ", i); 300efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, num); 301efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 302efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 303efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3048dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mask.HasBit(ResourceMask::kCCode)) { 305efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "cc "); 306efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 3078dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mask.HasBit(ResourceMask::kFPStatus)) { 308efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "fpcc "); 309efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 310efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Memory bits */ 3118dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mips_lir && (mask.HasBit(ResourceMask::kDalvikReg))) { 312988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers snprintf(buf + strlen(buf), arraysize(buf) - strlen(buf), "dr%d%s", 313988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers DECODE_ALIAS_INFO_REG(mips_lir->flags.alias_info), 314988e6ea9ac66edf1e205851df9bb53de3f3763f3Ian Rogers DECODE_ALIAS_INFO_WIDE(mips_lir->flags.alias_info) ? "(+1)" : ""); 315efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 3168dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mask.HasBit(ResourceMask::kLiteral)) { 317efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "lit "); 318efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 319efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3208dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mask.HasBit(ResourceMask::kHeapRef)) { 321efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "heap "); 322efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 3238dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mask.HasBit(ResourceMask::kMustNotAlias)) { 324efc6369224b036a1fb77849f7ae65b3492c832c0buzbee strcat(buf, "noalias "); 325efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 326efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 327efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (buf[0]) { 328efc6369224b036a1fb77849f7ae65b3492c832c0buzbee LOG(INFO) << prefix << ": " << buf; 329efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 330efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 331efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 332efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 333311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * TUNING: is true leaf? Can't just use METHOD_IS_LEAF to determine as some 334efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * instructions might call out to C/assembly helper functions. Until 335efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * machinery is in place, always spill lr. 336efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 337efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 3382ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::AdjustSpillMask() { 339091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee core_spill_mask_ |= (1 << rs_rRA.GetRegNum()); 3401fd3346740dfb7f47be9922312b68a4227fada96buzbee num_core_spills_++; 341efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 342efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 343efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Clobber all regs that might be used by an external C call */ 34431c2aac7137b69d5622eea09597500731fbee2efVladimir Markovoid MipsMir2Lir::ClobberCallerSave() { 345091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rZERO); 346091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rAT); 347091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rV0); 348091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rV1); 349091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rA0); 350091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rA1); 351091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rA2); 352091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rA3); 353091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT0); 354091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT1); 355091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT2); 356091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT3); 357091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT4); 358091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT5); 359091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT6); 360091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT7); 361091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT8); 362091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rT9); 363091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rK0); 364091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rK1); 365091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rGP); 366091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rFP); 367091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rRA); 368091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF0); 369091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF1); 370091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF2); 371091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF3); 372091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF4); 373091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF5); 374091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF6); 375091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF7); 376091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF8); 377091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF9); 378091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF10); 379091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF11); 380091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF12); 381091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF13); 382091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF14); 383091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rF15); 384091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD0); 385091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD1); 386091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD2); 387091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD3); 388091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD4); 389091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD5); 390091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD6); 391091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rs_rD7); 3921fd3346740dfb7f47be9922312b68a4227fada96buzbee} 3931fd3346740dfb7f47be9922312b68a4227fada96buzbee 3942ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::GetReturnWideAlt() { 39552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee UNIMPLEMENTED(FATAL) << "No GetReturnWideAlt for MIPS"; 39652a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee RegLocation res = LocCReturnWide(); 397efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 398efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 399efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4002ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation MipsMir2Lir::GetReturnAlt() { 40152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee UNIMPLEMENTED(FATAL) << "No GetReturnAlt for MIPS"; 40252a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee RegLocation res = LocCReturn(); 403efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return res; 404efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 405efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 406efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */ 4072ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::LockCallTemps() { 408091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LockTemp(rs_rMIPS_ARG0); 409091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LockTemp(rs_rMIPS_ARG1); 410091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LockTemp(rs_rMIPS_ARG2); 411091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LockTemp(rs_rMIPS_ARG3); 412efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 413efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 414efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */ 4152ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::FreeCallTemps() { 416091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee FreeTemp(rs_rMIPS_ARG0); 417091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee FreeTemp(rs_rMIPS_ARG1); 418091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee FreeTemp(rs_rMIPS_ARG2); 419091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee FreeTemp(rs_rMIPS_ARG3); 420efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 421efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 422b14329f90f725af0f67c45dfcb94933a426d63ceAndreas Gampebool MipsMir2Lir::GenMemBarrier(MemBarrierKind barrier_kind) { 423efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#if ANDROID_SMP != 0 4241fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR1(kMipsSync, 0 /* Only stype currently supported */); 425b14329f90f725af0f67c45dfcb94933a426d63ceAndreas Gampe return true; 426b14329f90f725af0f67c45dfcb94933a426d63ceAndreas Gampe#else 427b14329f90f725af0f67c45dfcb94933a426d63ceAndreas Gampe return false; 428efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif 429efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 430efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 4312ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::CompilerInitializeRegAlloc() { 432b01bf15d18f9b08d77e7a3c6e2897af0e02bf8cabuzbee reg_pool_ = new (arena_) RegisterPool(this, arena_, core_regs, empty_pool /* core64 */, sp_regs, 433b01bf15d18f9b08d77e7a3c6e2897af0e02bf8cabuzbee dp_regs, reserved_regs, empty_pool /* reserved64 */, 434b01bf15d18f9b08d77e7a3c6e2897af0e02bf8cabuzbee core_temps, empty_pool /* core64_temps */, sp_temps, 435b01bf15d18f9b08d77e7a3c6e2897af0e02bf8cabuzbee dp_temps); 436091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee 437091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Target-specific adjustments. 438091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee 439091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Alias single precision floats to appropriate half of overlapping double. 440091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee GrowableArray<RegisterInfo*>::Iterator it(®_pool_->sp_regs_); 441091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee for (RegisterInfo* info = it.Next(); info != nullptr; info = it.Next()) { 442091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee int sp_reg_num = info->GetReg().GetRegNum(); 4432db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung#if (FR_BIT == 0) 4442db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung int dp_reg_num = sp_reg_num & ~1; 4452db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung#else 446091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee int dp_reg_num = sp_reg_num >> 1; 4472db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung#endif 448091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee RegStorage dp_reg = RegStorage::Solo64(RegStorage::kFloatingPoint | dp_reg_num); 449091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee RegisterInfo* dp_reg_info = GetRegInfo(dp_reg); 450091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Double precision register's master storage should refer to itself. 451091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK_EQ(dp_reg_info, dp_reg_info->Master()); 452091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Redirect single precision's master storage to master. 453091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee info->SetMaster(dp_reg_info); 454091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Singles should show a single 32-bit mask bit, at first referring to the low half. 455091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK_EQ(info->StorageMask(), 0x1U); 456091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (sp_reg_num & 1) { 457091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // For odd singles, change to user the high word of the backing double. 458091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee info->SetStorageMask(0x2); 459efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 460efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 461091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee 462091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Don't start allocating temps at r0/s0/d0 or you may clobber return regs in early-exit methods. 463091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // TODO: adjust when we roll to hard float calling convention. 464091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee reg_pool_->next_core_reg_ = 2; 465091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee reg_pool_->next_sp_reg_ = 2; 4662db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung#if (FR_BIT == 0) 4672db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung reg_pool_->next_dp_reg_ = 2; 4682db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung#else 469091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee reg_pool_->next_dp_reg_ = 1; 4702db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung#endif 471efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 472efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 473efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 474efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * In the Arm code a it is typical to use the link register 475efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * to hold the target address. However, for Mips we must 476efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * ensure that all branch instructions can be restarted if 477efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * there is a trap in the shadow. Allocate a temp register. 478efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 479984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas GampeRegStorage MipsMir2Lir::LoadHelper(QuickEntrypointEnum trampoline) { 480695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee // NOTE: native pointer. 481984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe LoadWordDisp(rs_rMIPS_SELF, GetThreadOffset<4>(trampoline).Int32Value(), rs_rT9); 4822700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return rs_rT9; 483efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 484efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 485b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave AllisonLIR* MipsMir2Lir::CheckSuspendUsingLoad() { 4862700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage tmp = AllocTemp(); 487695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee // NOTE: native pointer. 488dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers LoadWordDisp(rs_rMIPS_SELF, Thread::ThreadSuspendTriggerOffset<4>().Int32Value(), tmp); 489b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison LIR *inst = LoadWordDisp(tmp, 0, tmp); 490b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison FreeTemp(tmp); 491b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison return inst; 492b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison} 493b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison 494d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas LeungLIR* MipsMir2Lir::GenAtomic64Load(RegStorage r_base, int displacement, RegStorage r_dest) { 495d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung DCHECK(!r_dest.IsFloat()); // See RegClassForFieldLoadStore(). 496d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung DCHECK(r_dest.IsPair()); 497d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung ClobberCallerSave(); 498d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung LockCallTemps(); // Using fixed registers 499d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung RegStorage reg_ptr = TargetReg(kArg0); 500d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung OpRegRegImm(kOpAdd, reg_ptr, r_base, displacement); 501984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe RegStorage r_tgt = LoadHelper(kQuickA64Load); 502d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung LIR *ret = OpReg(kOpBlx, r_tgt); 503d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung RegStorage reg_ret = RegStorage::MakeRegPair(TargetReg(kRet0), TargetReg(kRet1)); 504d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung OpRegCopyWide(r_dest, reg_ret); 505d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung return ret; 506d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung} 507d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung 508d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas LeungLIR* MipsMir2Lir::GenAtomic64Store(RegStorage r_base, int displacement, RegStorage r_src) { 509d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung DCHECK(!r_src.IsFloat()); // See RegClassForFieldLoadStore(). 510d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung DCHECK(r_src.IsPair()); 511d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung ClobberCallerSave(); 512d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung LockCallTemps(); // Using fixed registers 513d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung RegStorage temp_ptr = AllocTemp(); 514d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung OpRegRegImm(kOpAdd, temp_ptr, r_base, displacement); 515d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung RegStorage temp_value = AllocTempWide(); 516d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung OpRegCopyWide(temp_value, r_src); 517d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung RegStorage reg_ptr = TargetReg(kArg0); 518d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung OpRegCopy(reg_ptr, temp_ptr); 519d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung RegStorage reg_value = RegStorage::MakeRegPair(TargetReg(kArg2), TargetReg(kArg3)); 520d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung OpRegCopyWide(reg_value, temp_value); 521d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung FreeTemp(temp_ptr); 522d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung FreeTemp(temp_value); 523984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe RegStorage r_tgt = LoadHelper(kQuickA64Store); 524d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung return OpReg(kOpBlx, r_tgt); 525d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung} 526d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung 5272ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::SpillCoreRegs() { 5281fd3346740dfb7f47be9922312b68a4227fada96buzbee if (num_core_spills_ == 0) { 529efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return; 530efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 5311fd3346740dfb7f47be9922312b68a4227fada96buzbee uint32_t mask = core_spill_mask_; 5321fd3346740dfb7f47be9922312b68a4227fada96buzbee int offset = num_core_spills_ * 4; 5332700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee OpRegImm(kOpSub, rs_rSP, offset); 534efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int reg = 0; mask; mask >>= 1, reg++) { 535efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & 0x1) { 536efc6369224b036a1fb77849f7ae65b3492c832c0buzbee offset -= 4; 537695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee Store32Disp(rs_rMIPS_SP, offset, RegStorage::Solo32(reg)); 538efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 539efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 540efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 541efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5422ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MipsMir2Lir::UnSpillCoreRegs() { 5431fd3346740dfb7f47be9922312b68a4227fada96buzbee if (num_core_spills_ == 0) { 544efc6369224b036a1fb77849f7ae65b3492c832c0buzbee return; 545efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 5461fd3346740dfb7f47be9922312b68a4227fada96buzbee uint32_t mask = core_spill_mask_; 5471fd3346740dfb7f47be9922312b68a4227fada96buzbee int offset = frame_size_; 548efc6369224b036a1fb77849f7ae65b3492c832c0buzbee for (int reg = 0; mask; mask >>= 1, reg++) { 549efc6369224b036a1fb77849f7ae65b3492c832c0buzbee if (mask & 0x1) { 550efc6369224b036a1fb77849f7ae65b3492c832c0buzbee offset -= 4; 551695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee Load32Disp(rs_rMIPS_SP, offset, RegStorage::Solo32(reg)); 552efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 553efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 5542700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee OpRegImm(kOpAdd, rs_rSP, frame_size_); 555efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 556efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 5572ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool MipsMir2Lir::IsUnconditionalBranch(LIR* lir) { 558cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee return (lir->opcode == kMipsB); 559efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 560efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 561674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir MarkoRegisterClass MipsMir2Lir::RegClassForFieldLoadStore(OpSize size, bool is_volatile) { 5622db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung if (UNLIKELY(is_volatile)) { 563d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung // On Mips, atomic 64-bit load/store requires a core register. 5642db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung // Smaller aligned load/store is atomic for both core and fp registers. 5652db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung if (size == k64 || size == kDouble) { 566d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung return kCoreReg; 5672db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung } 5682db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung } 569674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko // TODO: Verify that both core and fp registers are suitable for smaller sizes. 570674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko return RegClassBySize(size); 571674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko} 572674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko 573862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMipsMir2Lir::MipsMir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena) 574862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee : Mir2Lir(cu, mir_graph, arena) { 57502031b185b4653e6c72e21f7a51238b903f6d638buzbee for (int i = 0; i < kMipsLast; i++) { 5761fd3346740dfb7f47be9922312b68a4227fada96buzbee if (MipsMir2Lir::EncodingMap[i].opcode != i) { 5771fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(FATAL) << "Encoding order for " << MipsMir2Lir::EncodingMap[i].name 57802031b185b4653e6c72e21f7a51238b903f6d638buzbee << " is wrong: expecting " << i << ", seeing " 5791fd3346740dfb7f47be9922312b68a4227fada96buzbee << static_cast<int>(MipsMir2Lir::EncodingMap[i].opcode); 580efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 581efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 582efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 583efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 584862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMir2Lir* MipsCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph, 585862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee ArenaAllocator* const arena) { 586862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee return new MipsMir2Lir(cu, mir_graph, arena); 5871fd3346740dfb7f47be9922312b68a4227fada96buzbee} 5881fd3346740dfb7f47be9922312b68a4227fada96buzbee 5892ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromuint64_t MipsMir2Lir::GetTargetInstFlags(int opcode) { 590409fe94ad529d9334587be80b9f6a3d166805508buzbee DCHECK(!IsPseudoLirOp(opcode)); 5911fd3346740dfb7f47be9922312b68a4227fada96buzbee return MipsMir2Lir::EncodingMap[opcode].flags; 5921bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 5931bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 5942ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromconst char* MipsMir2Lir::GetTargetInstName(int opcode) { 595409fe94ad529d9334587be80b9f6a3d166805508buzbee DCHECK(!IsPseudoLirOp(opcode)); 5961fd3346740dfb7f47be9922312b68a4227fada96buzbee return MipsMir2Lir::EncodingMap[opcode].name; 5971bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 5981bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 5992ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromconst char* MipsMir2Lir::GetTargetInstFmt(int opcode) { 600409fe94ad529d9334587be80b9f6a3d166805508buzbee DCHECK(!IsPseudoLirOp(opcode)); 6011fd3346740dfb7f47be9922312b68a4227fada96buzbee return MipsMir2Lir::EncodingMap[opcode].fmt; 6021bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee} 6031bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 6047934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace art 605