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