target_mips.cc revision 641ce0371c2f0dc95d26be02d8366124c8b66653
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"
18641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "compiler/codegen/codegen_util.h"
19641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "compiler/compiler_internals.h"
20641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "compiler/codegen/ralloc_util.h"
21641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "mips_lir.h"
22efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
23efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#include <string>
24efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
25efc6369224b036a1fb77849f7ae65b3492c832c0buzbeenamespace art {
26efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
27fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int core_regs[] = {r_ZERO, r_AT, r_V0, r_V1, r_A0, r_A1, r_A2, r_A3,
28fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                          r_T0, r_T1, r_T2, r_T3, r_T4, r_T5, r_T6, r_T7,
29fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                          r_S0, r_S1, r_S2, r_S3, r_S4, r_S5, r_S6, r_S7, r_T8,
30fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                          r_T9, r_K0, r_K1, r_GP, r_SP, r_FP, r_RA};
3152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbeestatic int ReservedRegs[] = {r_ZERO, r_AT, r_S0, r_S1, r_K0, r_K1, r_GP, r_SP,
32efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                             r_RA};
33fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int core_temps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2,
34fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                           r_T3, r_T4, r_T5, r_T6, r_T7, r_T8};
3552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbeestatic int FpRegs[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
36efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                       r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
37fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic int fp_temps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
38fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                         r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
39efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
4002031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegLocation MipsCodegen::LocCReturn()
41efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
42efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = MIPS_LOC_C_RETURN;
43efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
44efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
45efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
4602031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegLocation MipsCodegen::LocCReturnWide()
47efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
48efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = MIPS_LOC_C_RETURN_WIDE;
49efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
50efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
51efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
5202031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegLocation MipsCodegen::LocCReturnFloat()
53efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
54efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = MIPS_LOC_C_RETURN_FLOAT;
55efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
56efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
57efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
5802031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegLocation MipsCodegen::LocCReturnDouble()
59efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
60efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = MIPS_LOC_C_RETURN_DOUBLE;
61efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
62efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
63efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
64efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return a target-dependent special register.
6502031b185b4653e6c72e21f7a51238b903f6d638buzbeeint MipsCodegen::TargetReg(SpecialTargetRegister reg) {
66efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int res = INVALID_REG;
67efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  switch (reg) {
68efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kSelf: res = rMIPS_SELF; break;
69efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kSuspend: res =  rMIPS_SUSPEND; break;
70efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kLr: res =  rMIPS_LR; break;
71efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kPc: res =  rMIPS_PC; break;
72efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kSp: res =  rMIPS_SP; break;
73efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kArg0: res = rMIPS_ARG0; break;
74efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kArg1: res = rMIPS_ARG1; break;
75efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kArg2: res = rMIPS_ARG2; break;
76efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kArg3: res = rMIPS_ARG3; break;
77efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kFArg0: res = rMIPS_FARG0; break;
78efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kFArg1: res = rMIPS_FARG1; break;
79efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kFArg2: res = rMIPS_FARG2; break;
80efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kFArg3: res = rMIPS_FARG3; break;
81efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kRet0: res = rMIPS_RET0; break;
82efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kRet1: res = rMIPS_RET1; break;
83efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kInvokeTgt: res = rMIPS_INVOKE_TGT; break;
84efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kCount: res = rMIPS_COUNT; break;
85efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
86efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
87efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
88efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
89efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Create a double from a pair of singles.
9002031b185b4653e6c72e21f7a51238b903f6d638buzbeeint MipsCodegen::S2d(int low_reg, int high_reg)
91efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
92fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  return MIPS_S2D(low_reg, high_reg);
93efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
94efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
95efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return mask to strip off fp reg flags and bias.
9602031b185b4653e6c72e21f7a51238b903f6d638buzbeeuint32_t MipsCodegen::FpRegMask()
97efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
98efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return MIPS_FP_REG_MASK;
99efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
100efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
101efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// True if both regs single, both core or both double.
10202031b185b4653e6c72e21f7a51238b903f6d638buzbeebool MipsCodegen::SameRegType(int reg1, int reg2)
103efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
104efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return (MIPS_REGTYPE(reg1) == MIPS_REGTYPE(reg2));
105efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
106efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
107efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
108efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Decode the register id.
109efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
11002031b185b4653e6c72e21f7a51238b903f6d638buzbeeuint64_t MipsCodegen::GetRegMaskCommon(CompilationUnit* cu, int reg)
111efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
112eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee  uint64_t seed;
113efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int shift;
114fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int reg_id;
115efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
116efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
117fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  reg_id = reg & 0x1f;
118efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  /* Each double register is equal to a pair of single-precision FP registers */
119efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  seed = MIPS_DOUBLEREG(reg) ? 3 : 1;
120efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  /* FP register starts at bit position 16 */
121efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  shift = MIPS_FPREG(reg) ? kMipsFPReg0 : 0;
122efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  /* Expand the double register id into single offset */
123fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  shift += reg_id;
124efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return (seed << shift);
125efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
126efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
12702031b185b4653e6c72e21f7a51238b903f6d638buzbeeuint64_t MipsCodegen::GetPCUseDefEncoding()
128efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
129efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return ENCODE_MIPS_REG_PC;
130efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
131efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
132efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
13302031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::SetupTargetResourceMasks(CompilationUnit* cu, LIR* lir)
134efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
135fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK_EQ(cu->instruction_set, kMips);
136efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
137efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  // Mips-specific resource map setup here.
13802031b185b4653e6c72e21f7a51238b903f6d638buzbee  uint64_t flags = MipsCodegen::EncodingMap[lir->opcode].flags;
139efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
140efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (flags & REG_DEF_SP) {
141fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    lir->def_mask |= ENCODE_MIPS_REG_SP;
142efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
143efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
144efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (flags & REG_USE_SP) {
145fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    lir->use_mask |= ENCODE_MIPS_REG_SP;
146efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
147efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
148efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (flags & REG_DEF_LR) {
149fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    lir->def_mask |= ENCODE_MIPS_REG_LR;
150efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
151efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
152efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
153efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* For dumping instructions */
154efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#define MIPS_REG_COUNT 32
155fa57c47f1b72916371a9c2d5c1389219bce655b4buzbeestatic const char *mips_reg_name[MIPS_REG_COUNT] = {
156efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
157efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
158efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
159efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
160efc6369224b036a1fb77849f7ae65b3492c832c0buzbee};
161efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
162efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
163efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Interpret a format string and build a string no longer than size
164efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * See format key in Assemble.c.
165efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
16602031b185b4653e6c72e21f7a51238b903f6d638buzbeestd::string MipsCodegen::BuildInsnString(const char *fmt, LIR *lir, unsigned char* base_addr)
167efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
168efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  std::string buf;
169efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int i;
170fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  const char *fmt_end = &fmt[strlen(fmt)];
171efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  char tbuf[256];
172efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  char nc;
173fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (fmt < fmt_end) {
174efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    int operand;
175efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (*fmt == '!') {
176efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      fmt++;
177fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      DCHECK_LT(fmt, fmt_end);
178efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      nc = *fmt++;
179efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      if (nc=='!') {
180efc6369224b036a1fb77849f7ae65b3492c832c0buzbee        strcpy(tbuf, "!");
181efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      } else {
182fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee         DCHECK_LT(fmt, fmt_end);
183cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee         DCHECK_LT(static_cast<unsigned>(nc-'0'), 4u);
184efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         operand = lir->operands[nc-'0'];
185efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         switch (*fmt++) {
186efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'b':
187efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             strcpy(tbuf,"0000");
188efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             for (i=3; i>= 0; i--) {
189efc6369224b036a1fb77849f7ae65b3492c832c0buzbee               tbuf[i] += operand & 1;
190efc6369224b036a1fb77849f7ae65b3492c832c0buzbee               operand >>= 1;
191efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             }
192efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
193efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 's':
194efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK);
195efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
196efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'S':
197efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             DCHECK_EQ(((operand & MIPS_FP_REG_MASK) & 1), 0);
198efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK);
199efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
200efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'h':
201efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%04x", operand);
202efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
203efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'M':
204efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'd':
205efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%d", operand);
206efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
207efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'D':
208efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%d", operand+1);
209efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
210efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'E':
211efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%d", operand*4);
212efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
213efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'F':
214efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%d", operand*2);
215efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
216efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 't':
217fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee             sprintf(tbuf,"0x%08x (L%p)", reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4 +
218efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                     (operand << 2), lir->target);
219efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
220efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'T':
221cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee             sprintf(tbuf,"0x%08x", operand << 2);
222efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
223efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'u': {
224efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             int offset_1 = lir->operands[0];
225efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             int offset_2 = NEXT_LIR(lir)->operands[0];
226cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee             uintptr_t target =
227fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                 (((reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4) & ~3) +
228efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                 (offset_1 << 21 >> 9) + (offset_2 << 1)) & 0xfffffffc;
229cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee             sprintf(tbuf, "%p", reinterpret_cast<void*>(target));
230efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
231efc6369224b036a1fb77849f7ae65b3492c832c0buzbee          }
232efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
233efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           /* Nothing to print for BLX_2 */
234efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'v':
235efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             strcpy(tbuf, "see above");
236efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
237efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'r':
238efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             DCHECK(operand >= 0 && operand < MIPS_REG_COUNT);
239fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee             strcpy(tbuf, mips_reg_name[operand]);
240efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
241efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'N':
242efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             // Placeholder for delay slot handling
243efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             strcpy(tbuf, ";  nop");
244efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
245efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           default:
246efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             strcpy(tbuf,"DecodeError");
247efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
248efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         }
249efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         buf += tbuf;
250efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      }
251efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    } else {
252efc6369224b036a1fb77849f7ae65b3492c832c0buzbee       buf += *fmt++;
253efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
254efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
255efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return buf;
256efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
257efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
258efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// FIXME: need to redo resource maps for MIPS - fix this at that time
25902031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::DumpResourceMask(LIR *mips_lir, uint64_t mask, const char *prefix)
260efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
261efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  char buf[256];
262efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  buf[0] = 0;
263efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
264efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (mask == ENCODE_ALL) {
265efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    strcpy(buf, "all");
266efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  } else {
267efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    char num[8];
268efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    int i;
269efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
270efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    for (i = 0; i < kMipsRegEnd; i++) {
271efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      if (mask & (1ULL << i)) {
272efc6369224b036a1fb77849f7ae65b3492c832c0buzbee        sprintf(num, "%d ", i);
273efc6369224b036a1fb77849f7ae65b3492c832c0buzbee        strcat(buf, num);
274efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      }
275efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
276efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
277efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_CCODE) {
278efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "cc ");
279efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
280efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_FP_STATUS) {
281efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "fpcc ");
282efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
283efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    /* Memory bits */
284fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (mips_lir && (mask & ENCODE_DALVIK_REG)) {
285fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      sprintf(buf + strlen(buf), "dr%d%s", mips_lir->alias_info & 0xffff,
286fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee              (mips_lir->alias_info & 0x80000000) ? "(+1)" : "");
287efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
288efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_LITERAL) {
289efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "lit ");
290efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
291efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
292efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_HEAP_REF) {
293efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "heap ");
294efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
295efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_MUST_NOT_ALIAS) {
296efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "noalias ");
297efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
298efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
299efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (buf[0]) {
300efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    LOG(INFO) << prefix << ": " <<  buf;
301efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
302efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
303efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
304efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
305fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * TUNING: is leaf?  Can't just use "has_invoke" to determine as some
306efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * instructions might call out to C/assembly helper functions.  Until
307efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * machinery is in place, always spill lr.
308efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
309efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
31002031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::AdjustSpillMask(CompilationUnit* cu)
311efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
312fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  cu->core_spill_mask |= (1 << r_RA);
313fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  cu->num_core_spills++;
314efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
315efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
316efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
317efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Mark a callee-save fp register as promoted.  Note that
318efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * vpush/vpop uses contiguous register lists so we must
319efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * include any holes in the mask.  Associate holes with
320efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Dalvik register INVALID_VREG (0xFFFFU).
321efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
32202031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::MarkPreservedSingle(CompilationUnit* cu, int s_reg, int reg)
323efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
324efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  LOG(FATAL) << "No support yet for promoted FP regs";
325efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
326efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
32702031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::FlushRegWide(CompilationUnit* cu, int reg1, int reg2)
328efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
329fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  RegisterInfo* info1 = GetRegInfo(cu, reg1);
330fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  RegisterInfo* info2 = GetRegInfo(cu, 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;
342fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (SRegToVReg(cu, info2->s_reg) < SRegToVReg(cu, info1->s_reg))
343efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      info1 = info2;
344fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    int v_reg = SRegToVReg(cu, info1->s_reg);
345fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    StoreBaseDispWide(cu, rMIPS_SP, VRegOffset(cu, v_reg), info1->reg, info1->partner);
346efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
347efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
348efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
34902031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::FlushReg(CompilationUnit* cu, int reg)
350efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
351fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  RegisterInfo* info = GetRegInfo(cu, reg);
352efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (info->live && info->dirty) {
353efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    info->dirty = false;
354fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    int v_reg = SRegToVReg(cu, info->s_reg);
355fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    StoreBaseDisp(cu, rMIPS_SP, VRegOffset(cu, v_reg), reg, kWord);
356efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
357efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
358efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
359efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Give access to the target-dependent FP register encoding to common code */
36002031b185b4653e6c72e21f7a51238b903f6d638buzbeebool MipsCodegen::IsFpReg(int reg) {
361efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return MIPS_FPREG(reg);
362efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
363efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
364efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Clobber all regs that might be used by an external C call */
36502031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::ClobberCalleeSave(CompilationUnit *cu)
366fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee{
367fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_ZERO);
368fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_AT);
369fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_V0);
370fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_V1);
371fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_A0);
372fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_A1);
373fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_A2);
374fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_A3);
375fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_T0);
376fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_T1);
377fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_T2);
378fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_T3);
379fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_T4);
380fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_T5);
381fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_T6);
382fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_T7);
383fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_T8);
384fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_T9);
385fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_K0);
386fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_K1);
387fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_GP);
388fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_FP);
389fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_RA);
390fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F0);
391fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F1);
392fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F2);
393fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F3);
394fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F4);
395fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F5);
396fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F6);
397fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F7);
398fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F8);
399fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F9);
400fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F10);
401fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F11);
402fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F12);
403fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F13);
404fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F14);
405fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  Clobber(cu, r_F15);
406fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee}
407fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee
40802031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegLocation MipsCodegen::GetReturnWideAlt(CompilationUnit* cu)
40952a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee{
41052a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee  UNIMPLEMENTED(FATAL) << "No GetReturnWideAlt for MIPS";
41152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee  RegLocation res = LocCReturnWide();
412efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
413efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
414efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
41502031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegLocation MipsCodegen::GetReturnAlt(CompilationUnit* cu)
416efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
41752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee  UNIMPLEMENTED(FATAL) << "No GetReturnAlt for MIPS";
41852a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee  RegLocation res = LocCReturn();
419efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
420efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
421efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
42202031b185b4653e6c72e21f7a51238b903f6d638buzbeeRegisterInfo* MipsCodegen::GetRegInfo(CompilationUnit* cu, int reg)
423efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
424fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  return MIPS_FPREG(reg) ? &cu->reg_pool->FPRegs[reg & MIPS_FP_REG_MASK]
425fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee            : &cu->reg_pool->core_regs[reg];
426efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
427efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
428efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */
42902031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::LockCallTemps(CompilationUnit* cu)
430efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
431fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LockTemp(cu, rMIPS_ARG0);
432fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LockTemp(cu, rMIPS_ARG1);
433fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LockTemp(cu, rMIPS_ARG2);
434fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LockTemp(cu, rMIPS_ARG3);
435efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
436efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
437efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */
43802031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::FreeCallTemps(CompilationUnit* cu)
439efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
440fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  FreeTemp(cu, rMIPS_ARG0);
441fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  FreeTemp(cu, rMIPS_ARG1);
442fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  FreeTemp(cu, rMIPS_ARG2);
443fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  FreeTemp(cu, rMIPS_ARG3);
444efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
445efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
44602031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::GenMemBarrier(CompilationUnit *cu, MemBarrierKind barrier_kind)
447efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
448efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#if ANDROID_SMP != 0
449fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  NewLIR1(cu, kMipsSync, 0 /* Only stype currently supported */);
450efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif
451efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
452efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
453efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
454efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Alloc a pair of core registers, or a double.  Low reg in low byte,
455efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * high reg in next byte.
456efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
45702031b185b4653e6c72e21f7a51238b903f6d638buzbeeint MipsCodegen::AllocTypedTempPair(CompilationUnit *cu, bool fp_hint,
458fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                  int reg_class)
459efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
460fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int high_reg;
461fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int low_reg;
462efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int res = 0;
463efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
464fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
465fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    low_reg = AllocTempDouble(cu);
466fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    high_reg = low_reg + 1;
467fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    res = (low_reg & 0xff) | ((high_reg & 0xff) << 8);
468efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    return res;
469efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
470efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
471fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  low_reg = AllocTemp(cu);
472fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  high_reg = AllocTemp(cu);
473fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  res = (low_reg & 0xff) | ((high_reg & 0xff) << 8);
474efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
475efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
476efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
47702031b185b4653e6c72e21f7a51238b903f6d638buzbeeint MipsCodegen::AllocTypedTemp(CompilationUnit *cu, bool fp_hint, int reg_class)
478efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
479fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg))
480efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
481fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    return AllocTempFloat(cu);
482efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
483fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  return AllocTemp(cu);
484efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
485efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
48602031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::CompilerInitializeRegAlloc(CompilationUnit* cu)
487efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
488fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int num_regs = sizeof(core_regs)/sizeof(*core_regs);
489fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int num_reserved = sizeof(ReservedRegs)/sizeof(*ReservedRegs);
490fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int num_temps = sizeof(core_temps)/sizeof(*core_temps);
491fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int num_fp_regs = sizeof(FpRegs)/sizeof(*FpRegs);
492fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int num_fp_temps = sizeof(fp_temps)/sizeof(*fp_temps);
493cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee  RegisterPool *pool =
494fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      static_cast<RegisterPool*>(NewMem(cu, sizeof(*pool), true, kAllocRegAlloc));
495fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  cu->reg_pool = pool;
496fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  pool->num_core_regs = num_regs;
497fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  pool->core_regs = static_cast<RegisterInfo*>
498fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee     (NewMem(cu, num_regs * sizeof(*cu->reg_pool->core_regs), true, kAllocRegAlloc));
499fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  pool->num_fp_regs = num_fp_regs;
500cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee  pool->FPRegs = static_cast<RegisterInfo*>
501fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      (NewMem(cu, num_fp_regs * sizeof(*cu->reg_pool->FPRegs), true, kAllocRegAlloc));
502fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  CompilerInitPool(pool->core_regs, core_regs, pool->num_core_regs);
503fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  CompilerInitPool(pool->FPRegs, FpRegs, pool->num_fp_regs);
504efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  // Keep special registers from being allocated
505fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  for (int i = 0; i < num_reserved; i++) {
50652a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee    if (NO_SUSPEND && (ReservedRegs[i] == rMIPS_SUSPEND)) {
507efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      //To measure cost of suspend check
508efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      continue;
509efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
510fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    MarkInUse(cu, ReservedRegs[i]);
511efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
512efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  // Mark temp regs - all others not in use can be used for promotion
513fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  for (int i = 0; i < num_temps; i++) {
514fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    MarkTemp(cu, core_temps[i]);
515efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
516fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  for (int i = 0; i < num_fp_temps; i++) {
517fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    MarkTemp(cu, fp_temps[i]);
518efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
519efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
520efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
52102031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::FreeRegLocTemps(CompilationUnit* cu, RegLocation rl_keep, RegLocation rl_free)
522efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
523fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if ((rl_free.low_reg != rl_keep.low_reg) && (rl_free.low_reg != rl_keep.high_reg) &&
524fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    (rl_free.high_reg != rl_keep.low_reg) && (rl_free.high_reg != rl_keep.high_reg)) {
525efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    // No overlap, free both
526fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    FreeTemp(cu, rl_free.low_reg);
527fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    FreeTemp(cu, rl_free.high_reg);
528efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
529efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
530efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
531efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * In the Arm code a it is typical to use the link register
532efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * to hold the target address.  However, for Mips we must
533efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * ensure that all branch instructions can be restarted if
534efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * there is a trap in the shadow.  Allocate a temp register.
535efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
53602031b185b4653e6c72e21f7a51238b903f6d638buzbeeint MipsCodegen::LoadHelper(CompilationUnit* cu, int offset)
537efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
538fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LoadWordDisp(cu, rMIPS_SELF, offset, r_T9);
539efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return r_T9;
540efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
541efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
54202031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::SpillCoreRegs(CompilationUnit* cu)
543efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
544fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (cu->num_core_spills == 0) {
545efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    return;
546efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
547fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  uint32_t mask = cu->core_spill_mask;
548fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int offset = cu->num_core_spills * 4;
549fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  OpRegImm(cu, kOpSub, rMIPS_SP, offset);
550efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  for (int reg = 0; mask; mask >>= 1, reg++) {
551efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & 0x1) {
552efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      offset -= 4;
553fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      StoreWordDisp(cu, rMIPS_SP, offset, reg);
554efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
555efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
556efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
557efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
55802031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid MipsCodegen::UnSpillCoreRegs(CompilationUnit* cu)
559efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
560fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (cu->num_core_spills == 0) {
561efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    return;
562efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
563fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  uint32_t mask = cu->core_spill_mask;
564fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int offset = cu->frame_size;
565efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  for (int reg = 0; mask; mask >>= 1, reg++) {
566efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & 0x1) {
567efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      offset -= 4;
568fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LoadWordDisp(cu, rMIPS_SP, offset, reg);
569efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
570efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
571fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  OpRegImm(cu, kOpAdd, rMIPS_SP, cu->frame_size);
572efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
573efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
57402031b185b4653e6c72e21f7a51238b903f6d638buzbeebool MipsCodegen::IsUnconditionalBranch(LIR* lir)
575cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee{
576cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee  return (lir->opcode == kMipsB);
577efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
578efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
579efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Common initialization routine for an architecture family */
58002031b185b4653e6c72e21f7a51238b903f6d638buzbeebool InitMipsCodegen(CompilationUnit* cu)
58102031b185b4653e6c72e21f7a51238b903f6d638buzbee{
58202031b185b4653e6c72e21f7a51238b903f6d638buzbee  cu->cg.reset(new MipsCodegen());
58302031b185b4653e6c72e21f7a51238b903f6d638buzbee  for (int i = 0; i < kMipsLast; i++) {
58402031b185b4653e6c72e21f7a51238b903f6d638buzbee    if (MipsCodegen::EncodingMap[i].opcode != i) {
58502031b185b4653e6c72e21f7a51238b903f6d638buzbee      LOG(FATAL) << "Encoding order for " << MipsCodegen::EncodingMap[i].name
58602031b185b4653e6c72e21f7a51238b903f6d638buzbee                 << " is wrong: expecting " << i << ", seeing "
58702031b185b4653e6c72e21f7a51238b903f6d638buzbee                 << static_cast<int>(MipsCodegen::EncodingMap[i].opcode);
588efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
589efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
59002031b185b4653e6c72e21f7a51238b903f6d638buzbee  return true;
591efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
592efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
59302031b185b4653e6c72e21f7a51238b903f6d638buzbeeuint64_t MipsCodegen::GetTargetInstFlags(int opcode)
5941bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee{
59502031b185b4653e6c72e21f7a51238b903f6d638buzbee  return MipsCodegen::EncodingMap[opcode].flags;
5961bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee}
5971bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee
59802031b185b4653e6c72e21f7a51238b903f6d638buzbeeconst char* MipsCodegen::GetTargetInstName(int opcode)
5991bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee{
60002031b185b4653e6c72e21f7a51238b903f6d638buzbee  return MipsCodegen::EncodingMap[opcode].name;
6011bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee}
6021bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee
60302031b185b4653e6c72e21f7a51238b903f6d638buzbeeconst char* MipsCodegen::GetTargetInstFmt(int opcode)
6041bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee{
60502031b185b4653e6c72e21f7a51238b903f6d638buzbee  return MipsCodegen::EncodingMap[opcode].fmt;
6061bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee}
6071bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee
608efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} // namespace art
609