target_mips.cc revision 1fd3346740dfb7f47be9922312b68a4227fada96
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"
18395116cae130c983498c0a2f42b89e42f75bb9d0buzbee#include "compiler/dex/compiler_internals.h"
19641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "mips_lir.h"
20efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
21efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#include <string>
22efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
23efc6369224b036a1fb77849f7ae65b3492c832c0buzbeenamespace art {
24efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
25fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int core_regs[] = {r_ZERO, r_AT, r_V0, r_V1, r_A0, r_A1, r_A2, r_A3,
26fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                          r_T0, r_T1, r_T2, r_T3, r_T4, r_T5, r_T6, r_T7,
27fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                          r_S0, r_S1, r_S2, r_S3, r_S4, r_S5, r_S6, r_S7, r_T8,
28fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                          r_T9, r_K0, r_K1, r_GP, r_SP, r_FP, r_RA};
2952a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbeestatic int ReservedRegs[] = {r_ZERO, r_AT, r_S0, r_S1, r_K0, r_K1, r_GP, r_SP,
30efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                             r_RA};
31fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int core_temps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2,
32fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                           r_T3, r_T4, r_T5, r_T6, r_T7, r_T8};
3352a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbeestatic int FpRegs[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
34efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                       r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
35fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int fp_temps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
36fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                         r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
37efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
381fd3346740dfb7f47be9922312b68a4227fada96buzbeeRegLocation MipsMir2Lir::LocCReturn()
39efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
40efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = MIPS_LOC_C_RETURN;
41efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
42efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
43efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
441fd3346740dfb7f47be9922312b68a4227fada96buzbeeRegLocation MipsMir2Lir::LocCReturnWide()
45efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
46efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = MIPS_LOC_C_RETURN_WIDE;
47efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
48efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
49efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
501fd3346740dfb7f47be9922312b68a4227fada96buzbeeRegLocation MipsMir2Lir::LocCReturnFloat()
51efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
52efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = MIPS_LOC_C_RETURN_FLOAT;
53efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
54efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
55efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
561fd3346740dfb7f47be9922312b68a4227fada96buzbeeRegLocation MipsMir2Lir::LocCReturnDouble()
57efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
58efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = MIPS_LOC_C_RETURN_DOUBLE;
59efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
60efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
61efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
62efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return a target-dependent special register.
631fd3346740dfb7f47be9922312b68a4227fada96buzbeeint MipsMir2Lir::TargetReg(SpecialTargetRegister reg) {
64efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int res = INVALID_REG;
65efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  switch (reg) {
66efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kSelf: res = rMIPS_SELF; break;
67efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kSuspend: res =  rMIPS_SUSPEND; break;
68efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kLr: res =  rMIPS_LR; break;
69efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kPc: res =  rMIPS_PC; break;
70efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kSp: res =  rMIPS_SP; break;
71efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kArg0: res = rMIPS_ARG0; break;
72efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kArg1: res = rMIPS_ARG1; break;
73efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kArg2: res = rMIPS_ARG2; break;
74efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kArg3: res = rMIPS_ARG3; break;
75efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kFArg0: res = rMIPS_FARG0; break;
76efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kFArg1: res = rMIPS_FARG1; break;
77efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kFArg2: res = rMIPS_FARG2; break;
78efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kFArg3: res = rMIPS_FARG3; break;
79efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kRet0: res = rMIPS_RET0; break;
80efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kRet1: res = rMIPS_RET1; break;
81efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kInvokeTgt: res = rMIPS_INVOKE_TGT; break;
82efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kCount: res = rMIPS_COUNT; break;
83efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
84efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
85efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
86efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
87efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Create a double from a pair of singles.
881fd3346740dfb7f47be9922312b68a4227fada96buzbeeint MipsMir2Lir::S2d(int low_reg, int high_reg)
89efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
90fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  return MIPS_S2D(low_reg, high_reg);
91efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
92efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
93efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return mask to strip off fp reg flags and bias.
941fd3346740dfb7f47be9922312b68a4227fada96buzbeeuint32_t MipsMir2Lir::FpRegMask()
95efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
96efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return MIPS_FP_REG_MASK;
97efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
98efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
99efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// True if both regs single, both core or both double.
1001fd3346740dfb7f47be9922312b68a4227fada96buzbeebool MipsMir2Lir::SameRegType(int reg1, int reg2)
101efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
102efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return (MIPS_REGTYPE(reg1) == MIPS_REGTYPE(reg2));
103efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
104efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
105efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
106efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Decode the register id.
107efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
1081fd3346740dfb7f47be9922312b68a4227fada96buzbeeuint64_t MipsMir2Lir::GetRegMaskCommon(int reg)
109efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
110eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee  uint64_t seed;
111efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int shift;
112fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int reg_id;
113efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
114efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
115fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  reg_id = reg & 0x1f;
116efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  /* Each double register is equal to a pair of single-precision FP registers */
117efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  seed = MIPS_DOUBLEREG(reg) ? 3 : 1;
118efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  /* FP register starts at bit position 16 */
119efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  shift = MIPS_FPREG(reg) ? kMipsFPReg0 : 0;
120efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  /* Expand the double register id into single offset */
121fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  shift += reg_id;
122efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return (seed << shift);
123efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
124efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
1251fd3346740dfb7f47be9922312b68a4227fada96buzbeeuint64_t MipsMir2Lir::GetPCUseDefEncoding()
126efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
127efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return ENCODE_MIPS_REG_PC;
128efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
129efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
130efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
1311fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::SetupTargetResourceMasks(LIR* lir)
132efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
1331fd3346740dfb7f47be9922312b68a4227fada96buzbee  DCHECK_EQ(cu_->instruction_set, kMips);
134efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
135efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  // Mips-specific resource map setup here.
1361fd3346740dfb7f47be9922312b68a4227fada96buzbee  uint64_t flags = MipsMir2Lir::EncodingMap[lir->opcode].flags;
137efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
138efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (flags & REG_DEF_SP) {
139fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    lir->def_mask |= ENCODE_MIPS_REG_SP;
140efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
141efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
142efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (flags & REG_USE_SP) {
143fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    lir->use_mask |= ENCODE_MIPS_REG_SP;
144efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
145efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
146efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (flags & REG_DEF_LR) {
147fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    lir->def_mask |= ENCODE_MIPS_REG_LR;
148efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
149efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
150efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
151efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* For dumping instructions */
152efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#define MIPS_REG_COUNT 32
153fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic const char *mips_reg_name[MIPS_REG_COUNT] = {
154efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
155efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
156efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
157efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
158efc6369224b036a1fb77849f7ae65b3492c832c0buzbee};
159efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
160efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
161efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Interpret a format string and build a string no longer than size
162efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * See format key in Assemble.c.
163efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
1641fd3346740dfb7f47be9922312b68a4227fada96buzbeestd::string MipsMir2Lir::BuildInsnString(const char *fmt, LIR *lir, unsigned char* base_addr)
165efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
166efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  std::string buf;
167efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int i;
168fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  const char *fmt_end = &fmt[strlen(fmt)];
169efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  char tbuf[256];
170efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  char nc;
171fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (fmt < fmt_end) {
172efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    int operand;
173efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (*fmt == '!') {
174efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      fmt++;
175fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      DCHECK_LT(fmt, fmt_end);
176efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      nc = *fmt++;
177efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      if (nc=='!') {
178efc6369224b036a1fb77849f7ae65b3492c832c0buzbee        strcpy(tbuf, "!");
179efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      } else {
180fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee         DCHECK_LT(fmt, fmt_end);
181cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee         DCHECK_LT(static_cast<unsigned>(nc-'0'), 4u);
182efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         operand = lir->operands[nc-'0'];
183efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         switch (*fmt++) {
184efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'b':
185efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             strcpy(tbuf,"0000");
186efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             for (i=3; i>= 0; i--) {
187efc6369224b036a1fb77849f7ae65b3492c832c0buzbee               tbuf[i] += operand & 1;
188efc6369224b036a1fb77849f7ae65b3492c832c0buzbee               operand >>= 1;
189efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             }
190efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
191efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 's':
192efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK);
193efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
194efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'S':
195efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             DCHECK_EQ(((operand & MIPS_FP_REG_MASK) & 1), 0);
196efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK);
197efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
198efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'h':
199efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%04x", operand);
200efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
201efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'M':
202efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'd':
203efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%d", operand);
204efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
205efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'D':
206efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%d", operand+1);
207efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
208efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'E':
209efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%d", operand*4);
210efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
211efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'F':
212efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%d", operand*2);
213efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
214efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 't':
215fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee             sprintf(tbuf,"0x%08x (L%p)", reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4 +
216efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                     (operand << 2), lir->target);
217efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
218efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'T':
219cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee             sprintf(tbuf,"0x%08x", operand << 2);
220efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
221efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'u': {
222efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             int offset_1 = lir->operands[0];
223efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             int offset_2 = NEXT_LIR(lir)->operands[0];
224cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee             uintptr_t target =
225fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                 (((reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4) & ~3) +
226efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                 (offset_1 << 21 >> 9) + (offset_2 << 1)) & 0xfffffffc;
227cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee             sprintf(tbuf, "%p", reinterpret_cast<void*>(target));
228efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
229efc6369224b036a1fb77849f7ae65b3492c832c0buzbee          }
230efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
231efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           /* Nothing to print for BLX_2 */
232efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'v':
233efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             strcpy(tbuf, "see above");
234efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
235efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'r':
236efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             DCHECK(operand >= 0 && operand < MIPS_REG_COUNT);
237fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee             strcpy(tbuf, mips_reg_name[operand]);
238efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
239efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'N':
240efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             // Placeholder for delay slot handling
241efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             strcpy(tbuf, ";  nop");
242efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
243efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           default:
244efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             strcpy(tbuf,"DecodeError");
245efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
246efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         }
247efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         buf += tbuf;
248efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      }
249efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    } else {
250efc6369224b036a1fb77849f7ae65b3492c832c0buzbee       buf += *fmt++;
251efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
252efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
253efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return buf;
254efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
255efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
256efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// FIXME: need to redo resource maps for MIPS - fix this at that time
2571fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::DumpResourceMask(LIR *mips_lir, uint64_t mask, const char *prefix)
258efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
259efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  char buf[256];
260efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  buf[0] = 0;
261efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
262efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (mask == ENCODE_ALL) {
263efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    strcpy(buf, "all");
264efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  } else {
265efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    char num[8];
266efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    int i;
267efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
268efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    for (i = 0; i < kMipsRegEnd; i++) {
269efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      if (mask & (1ULL << i)) {
270efc6369224b036a1fb77849f7ae65b3492c832c0buzbee        sprintf(num, "%d ", i);
271efc6369224b036a1fb77849f7ae65b3492c832c0buzbee        strcat(buf, num);
272efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      }
273efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
274efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
275efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_CCODE) {
276efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "cc ");
277efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
278efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_FP_STATUS) {
279efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "fpcc ");
280efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
281efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    /* Memory bits */
282fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (mips_lir && (mask & ENCODE_DALVIK_REG)) {
283fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      sprintf(buf + strlen(buf), "dr%d%s", mips_lir->alias_info & 0xffff,
284fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee              (mips_lir->alias_info & 0x80000000) ? "(+1)" : "");
285efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
286efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_LITERAL) {
287efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "lit ");
288efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
289efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
290efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_HEAP_REF) {
291efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "heap ");
292efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
293efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_MUST_NOT_ALIAS) {
294efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "noalias ");
295efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
296efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
297efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (buf[0]) {
298efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    LOG(INFO) << prefix << ": " <<  buf;
299efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
300efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
301efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
302efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
303311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * TUNING: is true leaf?  Can't just use METHOD_IS_LEAF to determine as some
304efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * instructions might call out to C/assembly helper functions.  Until
305efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * machinery is in place, always spill lr.
306efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
307efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
3081fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::AdjustSpillMask()
309efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
3101fd3346740dfb7f47be9922312b68a4227fada96buzbee  core_spill_mask_ |= (1 << r_RA);
3111fd3346740dfb7f47be9922312b68a4227fada96buzbee  num_core_spills_++;
312efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
313efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
314efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
315efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Mark a callee-save fp register as promoted.  Note that
316efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * vpush/vpop uses contiguous register lists so we must
317efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * include any holes in the mask.  Associate holes with
318efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Dalvik register INVALID_VREG (0xFFFFU).
319efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
3201fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::MarkPreservedSingle(int s_reg, int reg)
321efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
322efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  LOG(FATAL) << "No support yet for promoted FP regs";
323efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
324efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
3251fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::FlushRegWide(int reg1, int reg2)
326efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
3271fd3346740dfb7f47be9922312b68a4227fada96buzbee  RegisterInfo* info1 = GetRegInfo(reg1);
3281fd3346740dfb7f47be9922312b68a4227fada96buzbee  RegisterInfo* info2 = GetRegInfo(reg2);
329efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  DCHECK(info1 && info2 && info1->pair && info2->pair &&
330efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         (info1->partner == info2->reg) &&
331efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         (info2->partner == info1->reg));
332efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) {
333fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (!(info1->is_temp && info2->is_temp)) {
334fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      /* Should not happen.  If it does, there's a problem in eval_loc */
335efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      LOG(FATAL) << "Long half-temp, half-promoted";
336efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
337efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
338efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    info1->dirty = false;
339efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    info2->dirty = false;
3401fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (mir_graph_->SRegToVReg(info2->s_reg) < mir_graph_->SRegToVReg(info1->s_reg))
341efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      info1 = info2;
3421fd3346740dfb7f47be9922312b68a4227fada96buzbee    int v_reg = mir_graph_->SRegToVReg(info1->s_reg);
3431fd3346740dfb7f47be9922312b68a4227fada96buzbee    StoreBaseDispWide(rMIPS_SP, VRegOffset(v_reg), info1->reg, info1->partner);
344efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
345efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
346efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
3471fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::FlushReg(int reg)
348efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
3491fd3346740dfb7f47be9922312b68a4227fada96buzbee  RegisterInfo* info = GetRegInfo(reg);
350efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (info->live && info->dirty) {
351efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    info->dirty = false;
3521fd3346740dfb7f47be9922312b68a4227fada96buzbee    int v_reg = mir_graph_->SRegToVReg(info->s_reg);
3531fd3346740dfb7f47be9922312b68a4227fada96buzbee    StoreBaseDisp(rMIPS_SP, VRegOffset(v_reg), reg, kWord);
354efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
355efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
356efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
357efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Give access to the target-dependent FP register encoding to common code */
3581fd3346740dfb7f47be9922312b68a4227fada96buzbeebool MipsMir2Lir::IsFpReg(int reg) {
359efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return MIPS_FPREG(reg);
360efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
361efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
362efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Clobber all regs that might be used by an external C call */
3631fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::ClobberCalleeSave()
3641fd3346740dfb7f47be9922312b68a4227fada96buzbee{
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
4061fd3346740dfb7f47be9922312b68a4227fada96buzbeeRegLocation MipsMir2Lir::GetReturnWideAlt()
40752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee{
40852a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee  UNIMPLEMENTED(FATAL) << "No GetReturnWideAlt for MIPS";
40952a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee  RegLocation res = LocCReturnWide();
410efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
411efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
412efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
4131fd3346740dfb7f47be9922312b68a4227fada96buzbeeRegLocation MipsMir2Lir::GetReturnAlt()
414efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
41552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee  UNIMPLEMENTED(FATAL) << "No GetReturnAlt for MIPS";
41652a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee  RegLocation res = LocCReturn();
417efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
418efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
419efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
4201fd3346740dfb7f47be9922312b68a4227fada96buzbeeMipsMir2Lir::RegisterInfo* MipsMir2Lir::GetRegInfo(int reg)
421efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
4221fd3346740dfb7f47be9922312b68a4227fada96buzbee  return MIPS_FPREG(reg) ? &reg_pool_->FPRegs[reg & MIPS_FP_REG_MASK]
4231fd3346740dfb7f47be9922312b68a4227fada96buzbee            : &reg_pool_->core_regs[reg];
424efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
425efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
426efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */
4271fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::LockCallTemps()
428efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
4291fd3346740dfb7f47be9922312b68a4227fada96buzbee  LockTemp(rMIPS_ARG0);
4301fd3346740dfb7f47be9922312b68a4227fada96buzbee  LockTemp(rMIPS_ARG1);
4311fd3346740dfb7f47be9922312b68a4227fada96buzbee  LockTemp(rMIPS_ARG2);
4321fd3346740dfb7f47be9922312b68a4227fada96buzbee  LockTemp(rMIPS_ARG3);
433efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
434efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
435efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */
4361fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::FreeCallTemps()
437efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
4381fd3346740dfb7f47be9922312b68a4227fada96buzbee  FreeTemp(rMIPS_ARG0);
4391fd3346740dfb7f47be9922312b68a4227fada96buzbee  FreeTemp(rMIPS_ARG1);
4401fd3346740dfb7f47be9922312b68a4227fada96buzbee  FreeTemp(rMIPS_ARG2);
4411fd3346740dfb7f47be9922312b68a4227fada96buzbee  FreeTemp(rMIPS_ARG3);
442efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
443efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
4441fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::GenMemBarrier(MemBarrierKind barrier_kind)
445efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
446efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#if ANDROID_SMP != 0
4471fd3346740dfb7f47be9922312b68a4227fada96buzbee  NewLIR1(kMipsSync, 0 /* Only stype currently supported */);
448efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif
449efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
450efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
451efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
452efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Alloc a pair of core registers, or a double.  Low reg in low byte,
453efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * high reg in next byte.
454efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
4551fd3346740dfb7f47be9922312b68a4227fada96buzbeeint MipsMir2Lir::AllocTypedTempPair(bool fp_hint,
456fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                  int reg_class)
457efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
458fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int high_reg;
459fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int low_reg;
460efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int res = 0;
461efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
462fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
4631fd3346740dfb7f47be9922312b68a4227fada96buzbee    low_reg = AllocTempDouble();
464fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    high_reg = low_reg + 1;
465fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    res = (low_reg & 0xff) | ((high_reg & 0xff) << 8);
466efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    return res;
467efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
468efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
4691fd3346740dfb7f47be9922312b68a4227fada96buzbee  low_reg = AllocTemp();
4701fd3346740dfb7f47be9922312b68a4227fada96buzbee  high_reg = AllocTemp();
471fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  res = (low_reg & 0xff) | ((high_reg & 0xff) << 8);
472efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
473efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
474efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
4751fd3346740dfb7f47be9922312b68a4227fada96buzbeeint MipsMir2Lir::AllocTypedTemp(bool fp_hint, int reg_class)
476efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
477fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg))
478efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
4791fd3346740dfb7f47be9922312b68a4227fada96buzbee    return AllocTempFloat();
480efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
4811fd3346740dfb7f47be9922312b68a4227fada96buzbee  return AllocTemp();
482efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
483efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
4841fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::CompilerInitializeRegAlloc()
485efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
486fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int num_regs = sizeof(core_regs)/sizeof(*core_regs);
487fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int num_reserved = sizeof(ReservedRegs)/sizeof(*ReservedRegs);
488fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int num_temps = sizeof(core_temps)/sizeof(*core_temps);
489fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int num_fp_regs = sizeof(FpRegs)/sizeof(*FpRegs);
490fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int num_fp_temps = sizeof(fp_temps)/sizeof(*fp_temps);
4911fd3346740dfb7f47be9922312b68a4227fada96buzbee  reg_pool_ = static_cast<RegisterPool*>(NewMem(cu_, sizeof(*reg_pool_), true, kAllocRegAlloc));
4921fd3346740dfb7f47be9922312b68a4227fada96buzbee  reg_pool_->num_core_regs = num_regs;
4931fd3346740dfb7f47be9922312b68a4227fada96buzbee  reg_pool_->core_regs = static_cast<RegisterInfo*>
4941fd3346740dfb7f47be9922312b68a4227fada96buzbee     (NewMem(cu_, num_regs * sizeof(*reg_pool_->core_regs), true, kAllocRegAlloc));
4951fd3346740dfb7f47be9922312b68a4227fada96buzbee  reg_pool_->num_fp_regs = num_fp_regs;
4961fd3346740dfb7f47be9922312b68a4227fada96buzbee  reg_pool_->FPRegs = static_cast<RegisterInfo*>
4971fd3346740dfb7f47be9922312b68a4227fada96buzbee      (NewMem(cu_, num_fp_regs * sizeof(*reg_pool_->FPRegs), true, kAllocRegAlloc));
4981fd3346740dfb7f47be9922312b68a4227fada96buzbee  CompilerInitPool(reg_pool_->core_regs, core_regs, reg_pool_->num_core_regs);
4991fd3346740dfb7f47be9922312b68a4227fada96buzbee  CompilerInitPool(reg_pool_->FPRegs, FpRegs, reg_pool_->num_fp_regs);
500efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  // Keep special registers from being allocated
501fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  for (int i = 0; i < num_reserved; i++) {
50252a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee    if (NO_SUSPEND && (ReservedRegs[i] == rMIPS_SUSPEND)) {
503efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      //To measure cost of suspend check
504efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      continue;
505efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
5061fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkInUse(ReservedRegs[i]);
507efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
508efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  // Mark temp regs - all others not in use can be used for promotion
509fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  for (int i = 0; i < num_temps; i++) {
5101fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkTemp(core_temps[i]);
511efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
512fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  for (int i = 0; i < num_fp_temps; i++) {
5131fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkTemp(fp_temps[i]);
514efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
515efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
516efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
5171fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free)
518efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
519fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if ((rl_free.low_reg != rl_keep.low_reg) && (rl_free.low_reg != rl_keep.high_reg) &&
520fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    (rl_free.high_reg != rl_keep.low_reg) && (rl_free.high_reg != rl_keep.high_reg)) {
521efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    // No overlap, free both
5221fd3346740dfb7f47be9922312b68a4227fada96buzbee    FreeTemp(rl_free.low_reg);
5231fd3346740dfb7f47be9922312b68a4227fada96buzbee    FreeTemp(rl_free.high_reg);
524efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
525efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
526efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
527efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * In the Arm code a it is typical to use the link register
528efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * to hold the target address.  However, for Mips we must
529efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * ensure that all branch instructions can be restarted if
530efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * there is a trap in the shadow.  Allocate a temp register.
531efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
5321fd3346740dfb7f47be9922312b68a4227fada96buzbeeint MipsMir2Lir::LoadHelper(int offset)
533efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
5341fd3346740dfb7f47be9922312b68a4227fada96buzbee  LoadWordDisp(rMIPS_SELF, offset, r_T9);
535efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return r_T9;
536efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
537efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
5381fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::SpillCoreRegs()
539efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
5401fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (num_core_spills_ == 0) {
541efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    return;
542efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
5431fd3346740dfb7f47be9922312b68a4227fada96buzbee  uint32_t mask = core_spill_mask_;
5441fd3346740dfb7f47be9922312b68a4227fada96buzbee  int offset = num_core_spills_ * 4;
5451fd3346740dfb7f47be9922312b68a4227fada96buzbee  OpRegImm(kOpSub, rMIPS_SP, offset);
546efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  for (int reg = 0; mask; mask >>= 1, reg++) {
547efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & 0x1) {
548efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      offset -= 4;
5491fd3346740dfb7f47be9922312b68a4227fada96buzbee      StoreWordDisp(rMIPS_SP, offset, reg);
550efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
551efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
552efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
553efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
5541fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid MipsMir2Lir::UnSpillCoreRegs()
555efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
5561fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (num_core_spills_ == 0) {
557efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    return;
558efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
5591fd3346740dfb7f47be9922312b68a4227fada96buzbee  uint32_t mask = core_spill_mask_;
5601fd3346740dfb7f47be9922312b68a4227fada96buzbee  int offset = frame_size_;
561efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  for (int reg = 0; mask; mask >>= 1, reg++) {
562efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & 0x1) {
563efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      offset -= 4;
5641fd3346740dfb7f47be9922312b68a4227fada96buzbee      LoadWordDisp(rMIPS_SP, offset, reg);
565efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
566efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
5671fd3346740dfb7f47be9922312b68a4227fada96buzbee  OpRegImm(kOpAdd, rMIPS_SP, frame_size_);
568efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
569efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
5701fd3346740dfb7f47be9922312b68a4227fada96buzbeebool MipsMir2Lir::IsUnconditionalBranch(LIR* lir)
571cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee{
572cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee  return (lir->opcode == kMipsB);
573efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
574efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
5751fd3346740dfb7f47be9922312b68a4227fada96buzbeeMipsMir2Lir::MipsMir2Lir(CompilationUnit* cu, MIRGraph* mir_graph) : Mir2Lir(cu, mir_graph) {
57602031b185b4653e6c72e21f7a51238b903f6d638buzbee  for (int i = 0; i < kMipsLast; i++) {
5771fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (MipsMir2Lir::EncodingMap[i].opcode != i) {
5781fd3346740dfb7f47be9922312b68a4227fada96buzbee      LOG(FATAL) << "Encoding order for " << MipsMir2Lir::EncodingMap[i].name
57902031b185b4653e6c72e21f7a51238b903f6d638buzbee                 << " is wrong: expecting " << i << ", seeing "
5801fd3346740dfb7f47be9922312b68a4227fada96buzbee                 << static_cast<int>(MipsMir2Lir::EncodingMap[i].opcode);
581efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
582efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
583efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
584efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
5851fd3346740dfb7f47be9922312b68a4227fada96buzbeeMir2Lir* MipsCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph) {
5861fd3346740dfb7f47be9922312b68a4227fada96buzbee  return new MipsMir2Lir(cu, mir_graph);
5871fd3346740dfb7f47be9922312b68a4227fada96buzbee}
5881fd3346740dfb7f47be9922312b68a4227fada96buzbee
5891fd3346740dfb7f47be9922312b68a4227fada96buzbeeuint64_t MipsMir2Lir::GetTargetInstFlags(int opcode)
5901bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee{
5911fd3346740dfb7f47be9922312b68a4227fada96buzbee  return MipsMir2Lir::EncodingMap[opcode].flags;
5921bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee}
5931bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee
5941fd3346740dfb7f47be9922312b68a4227fada96buzbeeconst char* MipsMir2Lir::GetTargetInstName(int opcode)
5951bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee{
5961fd3346740dfb7f47be9922312b68a4227fada96buzbee  return MipsMir2Lir::EncodingMap[opcode].name;
5971bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee}
5981bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee
5991fd3346740dfb7f47be9922312b68a4227fada96buzbeeconst char* MipsMir2Lir::GetTargetInstFmt(int opcode)
6001bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee{
6011fd3346740dfb7f47be9922312b68a4227fada96buzbee  return MipsMir2Lir::EncodingMap[opcode].fmt;
6021bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee}
6031bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee
604efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} // namespace art
605