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(&reg_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