target_mips.cc revision cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8
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
17efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#include "../../compiler_internals.h"
18efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#include "mips_lir.h"
19eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee#include "../ralloc_util.h"
20eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee#include "../codegen_util.h"
21efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
22efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#include <string>
23efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
24efc6369224b036a1fb77849f7ae65b3492c832c0buzbeenamespace art {
25efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
26efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestatic int coreRegs[] = {r_ZERO, r_AT, r_V0, r_V1, r_A0, r_A1, r_A2, r_A3,
27efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                         r_T0, r_T1, r_T2, r_T3, r_T4, r_T5, r_T6, r_T7,
28efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                         r_S0, r_S1, r_S2, r_S3, r_S4, r_S5, r_S6, r_S7, r_T8,
29efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                         r_T9, r_K0, r_K1, r_GP, r_SP, r_FP, r_RA};
30efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestatic int reservedRegs[] = {r_ZERO, r_AT, r_S0, r_S1, r_K0, r_K1, r_GP, r_SP,
31efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                             r_RA};
32efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestatic int coreTemps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2,
33efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                          r_T3, r_T4, r_T5, r_T6, r_T7, r_T8};
34efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#ifdef __mips_hard_float
35efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestatic 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};
37efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestatic int fpTemps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
38efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                        r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
39efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif
40efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
41efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeRegLocation locCReturn()
42efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
43efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = MIPS_LOC_C_RETURN;
44efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
45efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
46efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
47efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeRegLocation locCReturnWide()
48efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
49efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = MIPS_LOC_C_RETURN_WIDE;
50efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
51efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
52efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
53efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeRegLocation locCReturnFloat()
54efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
55efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = MIPS_LOC_C_RETURN_FLOAT;
56efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
57efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
58efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
59efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeRegLocation locCReturnDouble()
60efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
61efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = MIPS_LOC_C_RETURN_DOUBLE;
62efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
63efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
64efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
65efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return a target-dependent special register.
66efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeint targetReg(SpecialTargetRegister reg) {
67efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int res = INVALID_REG;
68efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  switch (reg) {
69efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kSelf: res = rMIPS_SELF; break;
70efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kSuspend: res =  rMIPS_SUSPEND; break;
71efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kLr: res =  rMIPS_LR; break;
72efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kPc: res =  rMIPS_PC; break;
73efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kSp: res =  rMIPS_SP; break;
74efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kArg0: res = rMIPS_ARG0; break;
75efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kArg1: res = rMIPS_ARG1; break;
76efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kArg2: res = rMIPS_ARG2; break;
77efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kArg3: res = rMIPS_ARG3; break;
78efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kFArg0: res = rMIPS_FARG0; break;
79efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kFArg1: res = rMIPS_FARG1; break;
80efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kFArg2: res = rMIPS_FARG2; break;
81efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kFArg3: res = rMIPS_FARG3; break;
82efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kRet0: res = rMIPS_RET0; break;
83efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kRet1: res = rMIPS_RET1; break;
84efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kInvokeTgt: res = rMIPS_INVOKE_TGT; break;
85efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    case kCount: res = rMIPS_COUNT; break;
86efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
87efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
88efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
89efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
90efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Create a double from a pair of singles.
91efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeint s2d(int lowReg, int highReg)
92efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
93efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return MIPS_S2D(lowReg, highReg);
94efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
95efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
96efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Is reg a single or double?
97efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool fpReg(int reg)
98efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
99efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return MIPS_FPREG(reg);
100efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
101efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
102efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Is reg a single?
103efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool singleReg(int reg)
104efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
105efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return MIPS_SINGLEREG(reg);
106efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
107efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
108efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Is reg a double?
109efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool doubleReg(int reg)
110efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
111efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return MIPS_DOUBLEREG(reg);
112efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
113efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
114efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// Return mask to strip off fp reg flags and bias.
115efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeuint32_t fpRegMask()
116efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
117efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return MIPS_FP_REG_MASK;
118efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
119efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
120efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// True if both regs single, both core or both double.
121efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool sameRegType(int reg1, int reg2)
122efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
123efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return (MIPS_REGTYPE(reg1) == MIPS_REGTYPE(reg2));
124efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
125efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
126efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
127efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Decode the register id.
128efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
129eaf09bc65f9a10d12befcdb239156938c9bceef2buzbeeuint64_t getRegMaskCommon(CompilationUnit* cUnit, int reg)
130efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
131eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee  uint64_t seed;
132efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int shift;
133efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int regId;
134efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
135efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
136efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  regId = reg & 0x1f;
137efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  /* Each double register is equal to a pair of single-precision FP registers */
138efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  seed = MIPS_DOUBLEREG(reg) ? 3 : 1;
139efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  /* FP register starts at bit position 16 */
140efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  shift = MIPS_FPREG(reg) ? kMipsFPReg0 : 0;
141efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  /* Expand the double register id into single offset */
142efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  shift += regId;
143efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return (seed << shift);
144efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
145efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
146efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeuint64_t getPCUseDefEncoding()
147efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
148efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return ENCODE_MIPS_REG_PC;
149efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
150efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
151efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
152efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir)
153efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
154efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  DCHECK_EQ(cUnit->instructionSet, kMips);
155efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
156efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  // Mips-specific resource map setup here.
157efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  uint64_t flags = EncodingMap[lir->opcode].flags;
158efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
159efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (flags & REG_DEF_SP) {
160efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    lir->defMask |= ENCODE_MIPS_REG_SP;
161efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
162efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
163efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (flags & REG_USE_SP) {
164efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    lir->useMask |= ENCODE_MIPS_REG_SP;
165efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
166efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
167efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (flags & REG_DEF_LR) {
168efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    lir->defMask |= ENCODE_MIPS_REG_LR;
169efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
170efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
171efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
172efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* For dumping instructions */
173efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#define MIPS_REG_COUNT 32
174efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestatic const char *mipsRegName[MIPS_REG_COUNT] = {
175efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
176efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
177efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
178efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
179efc6369224b036a1fb77849f7ae65b3492c832c0buzbee};
180efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
181efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
182efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Interpret a format string and build a string no longer than size
183efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * See format key in Assemble.c.
184efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
185efc6369224b036a1fb77849f7ae65b3492c832c0buzbeestd::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr)
186efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
187efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  std::string buf;
188efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int i;
189efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  const char *fmtEnd = &fmt[strlen(fmt)];
190efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  char tbuf[256];
191efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  char nc;
192efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  while (fmt < fmtEnd) {
193efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    int operand;
194efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (*fmt == '!') {
195efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      fmt++;
196efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      DCHECK_LT(fmt, fmtEnd);
197efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      nc = *fmt++;
198efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      if (nc=='!') {
199efc6369224b036a1fb77849f7ae65b3492c832c0buzbee        strcpy(tbuf, "!");
200efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      } else {
201efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         DCHECK_LT(fmt, fmtEnd);
202cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee         DCHECK_LT(static_cast<unsigned>(nc-'0'), 4u);
203efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         operand = lir->operands[nc-'0'];
204efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         switch (*fmt++) {
205efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'b':
206efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             strcpy(tbuf,"0000");
207efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             for (i=3; i>= 0; i--) {
208efc6369224b036a1fb77849f7ae65b3492c832c0buzbee               tbuf[i] += operand & 1;
209efc6369224b036a1fb77849f7ae65b3492c832c0buzbee               operand >>= 1;
210efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             }
211efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
212efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 's':
213efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK);
214efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
215efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'S':
216efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             DCHECK_EQ(((operand & MIPS_FP_REG_MASK) & 1), 0);
217efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK);
218efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
219efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'h':
220efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%04x", operand);
221efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
222efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'M':
223efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'd':
224efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%d", operand);
225efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
226efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'D':
227efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%d", operand+1);
228efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
229efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'E':
230efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%d", operand*4);
231efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
232efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'F':
233efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             sprintf(tbuf,"%d", operand*2);
234efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
235efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 't':
236cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee             sprintf(tbuf,"0x%08x (L%p)", reinterpret_cast<uintptr_t>(baseAddr) + lir->offset + 4 +
237efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                     (operand << 2), lir->target);
238efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
239efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'T':
240cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee             sprintf(tbuf,"0x%08x", operand << 2);
241efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
242efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'u': {
243efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             int offset_1 = lir->operands[0];
244efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             int offset_2 = NEXT_LIR(lir)->operands[0];
245cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee             uintptr_t target =
246cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee                 (((reinterpret_cast<uintptr_t>(baseAddr) + lir->offset + 4) & ~3) +
247efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                 (offset_1 << 21 >> 9) + (offset_2 << 1)) & 0xfffffffc;
248cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee             sprintf(tbuf, "%p", reinterpret_cast<void*>(target));
249efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
250efc6369224b036a1fb77849f7ae65b3492c832c0buzbee          }
251efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
252efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           /* Nothing to print for BLX_2 */
253efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'v':
254efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             strcpy(tbuf, "see above");
255efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
256efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'r':
257efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             DCHECK(operand >= 0 && operand < MIPS_REG_COUNT);
258efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             strcpy(tbuf, mipsRegName[operand]);
259efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
260efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           case 'N':
261efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             // Placeholder for delay slot handling
262efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             strcpy(tbuf, ";  nop");
263efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
264efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           default:
265efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             strcpy(tbuf,"DecodeError");
266efc6369224b036a1fb77849f7ae65b3492c832c0buzbee             break;
267efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         }
268efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         buf += tbuf;
269efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      }
270efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    } else {
271efc6369224b036a1fb77849f7ae65b3492c832c0buzbee       buf += *fmt++;
272efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
273efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
274efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return buf;
275efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
276efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
277efc6369224b036a1fb77849f7ae65b3492c832c0buzbee// FIXME: need to redo resource maps for MIPS - fix this at that time
278cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbeevoid oatDumpResourceMask(LIR *mipsLIR, uint64_t mask, const char *prefix)
279efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
280efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  char buf[256];
281efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  buf[0] = 0;
282efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
283efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (mask == ENCODE_ALL) {
284efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    strcpy(buf, "all");
285efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  } else {
286efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    char num[8];
287efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    int i;
288efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
289efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    for (i = 0; i < kMipsRegEnd; i++) {
290efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      if (mask & (1ULL << i)) {
291efc6369224b036a1fb77849f7ae65b3492c832c0buzbee        sprintf(num, "%d ", i);
292efc6369224b036a1fb77849f7ae65b3492c832c0buzbee        strcat(buf, num);
293efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      }
294efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
295efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
296efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_CCODE) {
297efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "cc ");
298efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
299efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_FP_STATUS) {
300efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "fpcc ");
301efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
302efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    /* Memory bits */
303efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mipsLIR && (mask & ENCODE_DALVIK_REG)) {
304efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      sprintf(buf + strlen(buf), "dr%d%s", mipsLIR->aliasInfo & 0xffff,
305efc6369224b036a1fb77849f7ae65b3492c832c0buzbee              (mipsLIR->aliasInfo & 0x80000000) ? "(+1)" : "");
306efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
307efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_LITERAL) {
308efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "lit ");
309efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
310efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
311efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_HEAP_REF) {
312efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "heap ");
313efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
314efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & ENCODE_MUST_NOT_ALIAS) {
315efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      strcat(buf, "noalias ");
316efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
317efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
318efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (buf[0]) {
319efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    LOG(INFO) << prefix << ": " <<  buf;
320efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
321efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
322efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
323efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
324efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * TUNING: is leaf?  Can't just use "hasInvoke" to determine as some
325efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * instructions might call out to C/assembly helper functions.  Until
326efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * machinery is in place, always spill lr.
327efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
328efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
329efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid oatAdjustSpillMask(CompilationUnit* cUnit)
330efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
331efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  cUnit->coreSpillMask |= (1 << r_RA);
332efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  cUnit->numCoreSpills++;
333efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
334efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
335efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
336efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Mark a callee-save fp register as promoted.  Note that
337efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * vpush/vpop uses contiguous register lists so we must
338efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * include any holes in the mask.  Associate holes with
339efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Dalvik register INVALID_VREG (0xFFFFU).
340efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
341efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid oatMarkPreservedSingle(CompilationUnit* cUnit, int sReg, int reg)
342efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
343efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  LOG(FATAL) << "No support yet for promoted FP regs";
344efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
345efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
346efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2)
347efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
348efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegisterInfo* info1 = oatGetRegInfo(cUnit, reg1);
349efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegisterInfo* info2 = oatGetRegInfo(cUnit, reg2);
350efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  DCHECK(info1 && info2 && info1->pair && info2->pair &&
351efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         (info1->partner == info2->reg) &&
352efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         (info2->partner == info1->reg));
353efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) {
354efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (!(info1->isTemp && info2->isTemp)) {
355efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      /* Should not happen.  If it does, there's a problem in evalLoc */
356efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      LOG(FATAL) << "Long half-temp, half-promoted";
357efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
358efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
359efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    info1->dirty = false;
360efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    info2->dirty = false;
361efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (SRegToVReg(cUnit, info2->sReg) < SRegToVReg(cUnit, info1->sReg))
362efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      info1 = info2;
363efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    int vReg = SRegToVReg(cUnit, info1->sReg);
364eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee    storeBaseDispWide(cUnit, rMIPS_SP, oatVRegOffset(cUnit, vReg), info1->reg, info1->partner);
365efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
366efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
367efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
368efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid oatFlushReg(CompilationUnit* cUnit, int reg)
369efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
370efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegisterInfo* info = oatGetRegInfo(cUnit, reg);
371efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (info->live && info->dirty) {
372efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    info->dirty = false;
373efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    int vReg = SRegToVReg(cUnit, info->sReg);
374eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee    storeBaseDisp(cUnit, rMIPS_SP, oatVRegOffset(cUnit, vReg), reg, kWord);
375efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
376efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
377efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
378efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Give access to the target-dependent FP register encoding to common code */
379efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool oatIsFpReg(int reg) {
380efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return MIPS_FPREG(reg);
381efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
382efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
383efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeuint32_t oatFpRegMask() {
384efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return MIPS_FP_REG_MASK;
385efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
386efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
387efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Clobber all regs that might be used by an external C call */
388efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeextern void oatClobberCalleeSave(CompilationUnit *cUnit)
389efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
390efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_ZERO);
391efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_AT);
392efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_V0);
393efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_V1);
394efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_A0);
395efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_A1);
396efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_A2);
397efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_A3);
398efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_T0);
399efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_T1);
400efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_T2);
401efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_T3);
402efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_T4);
403efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_T5);
404efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_T6);
405efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_T7);
406efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_T8);
407efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_T9);
408efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_K0);
409efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_K1);
410efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_GP);
411efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_FP);
412efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_RA);
413efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F0);
414efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F1);
415efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F2);
416efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F3);
417efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F4);
418efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F5);
419efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F6);
420efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F7);
421efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F8);
422efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F9);
423efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F10);
424efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F11);
425efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F12);
426efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F13);
427efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F14);
428efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatClobber(cUnit, r_F15);
429efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
430efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
431efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeextern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit)
432efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
433efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  UNIMPLEMENTED(FATAL) << "No oatGetReturnWideAlt for MIPS";
434efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = locCReturnWide();
435efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
436efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
437efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
438efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeextern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
439efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
440efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  UNIMPLEMENTED(FATAL) << "No oatGetReturnAlt for MIPS";
441efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  RegLocation res = locCReturn();
442efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
443efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
444efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
445efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeextern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg)
446efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
447efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return MIPS_FPREG(reg) ? &cUnit->regPool->FPRegs[reg & MIPS_FP_REG_MASK]
448efc6369224b036a1fb77849f7ae65b3492c832c0buzbee            : &cUnit->regPool->coreRegs[reg];
449efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
450efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
451efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */
452efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeextern void oatLockCallTemps(CompilationUnit* cUnit)
453efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
454efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatLockTemp(cUnit, rMIPS_ARG0);
455efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatLockTemp(cUnit, rMIPS_ARG1);
456efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatLockTemp(cUnit, rMIPS_ARG2);
457efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatLockTemp(cUnit, rMIPS_ARG3);
458efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
459efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
460efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* To be used when explicitly managing register use */
461efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeextern void oatFreeCallTemps(CompilationUnit* cUnit)
462efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
463efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatFreeTemp(cUnit, rMIPS_ARG0);
464efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatFreeTemp(cUnit, rMIPS_ARG1);
465efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatFreeTemp(cUnit, rMIPS_ARG2);
466efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatFreeTemp(cUnit, rMIPS_ARG3);
467efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
468efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
469efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
470efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Determine the initial instruction set to be used for this trace.
471efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Later components may decide to change this.
472efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
473efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeInstructionSet oatInstructionSet()
474efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
475efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return kMips;
476efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
477efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
478efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Architecture-specific initializations and checks go here */
479efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool oatArchVariantInit(void)
480efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
481efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return true;
482efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
483efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
484efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid oatGenMemBarrier(CompilationUnit *cUnit, int barrierKind)
485efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
486efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#if ANDROID_SMP != 0
487efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  newLIR1(cUnit, kMipsSync, barrierKind);
488efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif
489efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
490efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
491efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
492efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Alloc a pair of core registers, or a double.  Low reg in low byte,
493efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * high reg in next byte.
494efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
495efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeint oatAllocTypedTempPair(CompilationUnit *cUnit, bool fpHint,
496efc6369224b036a1fb77849f7ae65b3492c832c0buzbee                  int regClass)
497efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
498efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int highReg;
499efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int lowReg;
500efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int res = 0;
501efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
502efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#ifdef __mips_hard_float
503efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) {
504efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    lowReg = oatAllocTempDouble(cUnit);
505efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    highReg = lowReg + 1;
506efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    res = (lowReg & 0xff) | ((highReg & 0xff) << 8);
507efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    return res;
508efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
509efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif
510efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
511efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  lowReg = oatAllocTemp(cUnit);
512efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  highReg = oatAllocTemp(cUnit);
513efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  res = (lowReg & 0xff) | ((highReg & 0xff) << 8);
514efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return res;
515efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
516efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
517efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeint oatAllocTypedTemp(CompilationUnit *cUnit, bool fpHint, int regClass)
518efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
519efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#ifdef __mips_hard_float
520efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg))
521efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
522efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    return oatAllocTempFloat(cUnit);
523efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
524efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif
525efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return oatAllocTemp(cUnit);
526efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
527efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
528efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid oatInitializeRegAlloc(CompilationUnit* cUnit)
529efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
530efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int numRegs = sizeof(coreRegs)/sizeof(*coreRegs);
531efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int numReserved = sizeof(reservedRegs)/sizeof(*reservedRegs);
532efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int numTemps = sizeof(coreTemps)/sizeof(*coreTemps);
533efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#ifdef __mips_hard_float
534efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs);
535efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps);
536efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#else
537efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int numFPRegs = 0;
538efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int numFPTemps = 0;
539efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#endif
540cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee  RegisterPool *pool =
541cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      static_cast<RegisterPool*>(oatNew(cUnit, sizeof(*pool), true, kAllocRegAlloc));
542efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  cUnit->regPool = pool;
543efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  pool->numCoreRegs = numRegs;
544cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee  pool->coreRegs = static_cast<RegisterInfo*>
545cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee     (oatNew(cUnit, numRegs * sizeof(*cUnit->regPool->coreRegs), true, kAllocRegAlloc));
546efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  pool->numFPRegs = numFPRegs;
547cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee  pool->FPRegs = static_cast<RegisterInfo*>
548cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      (oatNew(cUnit, numFPRegs * sizeof(*cUnit->regPool->FPRegs), true, kAllocRegAlloc));
549efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatInitPool(pool->coreRegs, coreRegs, pool->numCoreRegs);
550efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  oatInitPool(pool->FPRegs, fpRegs, pool->numFPRegs);
551efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  // Keep special registers from being allocated
552efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  for (int i = 0; i < numReserved; i++) {
553efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (NO_SUSPEND && (reservedRegs[i] == rMIPS_SUSPEND)) {
554efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      //To measure cost of suspend check
555efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      continue;
556efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
557efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    oatMarkInUse(cUnit, reservedRegs[i]);
558efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
559efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  // Mark temp regs - all others not in use can be used for promotion
560efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  for (int i = 0; i < numTemps; i++) {
561efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    oatMarkTemp(cUnit, coreTemps[i]);
562efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
563efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  for (int i = 0; i < numFPTemps; i++) {
564efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    oatMarkTemp(cUnit, fpTemps[i]);
565efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
566efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  // Construct the alias map.
567cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee  cUnit->phiAliasMap = static_cast<int*>
568cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      (oatNew(cUnit, cUnit->numSSARegs * sizeof(cUnit->phiAliasMap[0]), false, kAllocDFInfo));
569efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  for (int i = 0; i < cUnit->numSSARegs; i++) {
570efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    cUnit->phiAliasMap[i] = i;
571efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
572efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  for (MIR* phi = cUnit->phiList; phi; phi = phi->meta.phiNext) {
573efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    int defReg = phi->ssaRep->defs[0];
574efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    for (int i = 0; i < phi->ssaRep->numUses; i++) {
575efc6369224b036a1fb77849f7ae65b3492c832c0buzbee       for (int j = 0; j < cUnit->numSSARegs; j++) {
576efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         if (cUnit->phiAliasMap[j] == phi->ssaRep->uses[i]) {
577efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           cUnit->phiAliasMap[j] = defReg;
578efc6369224b036a1fb77849f7ae65b3492c832c0buzbee         }
579efc6369224b036a1fb77849f7ae65b3492c832c0buzbee       }
580efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
581efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
582efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
583efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
584efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep,
585efc6369224b036a1fb77849f7ae65b3492c832c0buzbee           RegLocation rlFree)
586efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
587efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if ((rlFree.lowReg != rlKeep.lowReg) && (rlFree.lowReg != rlKeep.highReg) &&
588efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    (rlFree.highReg != rlKeep.lowReg) && (rlFree.highReg != rlKeep.highReg)) {
589efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    // No overlap, free both
590efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    oatFreeTemp(cUnit, rlFree.lowReg);
591efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    oatFreeTemp(cUnit, rlFree.highReg);
592efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
593efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
594efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/*
595efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * In the Arm code a it is typical to use the link register
596efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * to hold the target address.  However, for Mips we must
597efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * ensure that all branch instructions can be restarted if
598efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * there is a trap in the shadow.  Allocate a temp register.
599efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */
600efc6369224b036a1fb77849f7ae65b3492c832c0buzbeeint loadHelper(CompilationUnit* cUnit, int offset)
601efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
602efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  loadWordDisp(cUnit, rMIPS_SELF, offset, r_T9);
603efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return r_T9;
604efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
605efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
606efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid spillCoreRegs(CompilationUnit* cUnit)
607efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
608efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (cUnit->numCoreSpills == 0) {
609efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    return;
610efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
611efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  uint32_t mask = cUnit->coreSpillMask;
612efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int offset = cUnit->numCoreSpills * 4;
613efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  opRegImm(cUnit, kOpSub, rMIPS_SP, offset);
614efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  for (int reg = 0; mask; mask >>= 1, reg++) {
615efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & 0x1) {
616efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      offset -= 4;
617efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      storeWordDisp(cUnit, rMIPS_SP, offset, reg);
618efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
619efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
620efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
621efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
622efc6369224b036a1fb77849f7ae65b3492c832c0buzbeevoid unSpillCoreRegs(CompilationUnit* cUnit)
623efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
624efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  if (cUnit->numCoreSpills == 0) {
625efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    return;
626efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
627efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  uint32_t mask = cUnit->coreSpillMask;
628efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int offset = cUnit->frameSize;
629efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  for (int reg = 0; mask; mask >>= 1, reg++) {
630efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (mask & 0x1) {
631efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      offset -= 4;
632efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      loadWordDisp(cUnit, rMIPS_SP, offset, reg);
633efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
634efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
635efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  opRegImm(cUnit, kOpAdd, rMIPS_SP, cUnit->frameSize);
636efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
637efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
638cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbeebool branchUnconditional(LIR* lir)
639cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee{
640cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee  return (lir->opcode == kMipsB);
641efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
642efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
643efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* Common initialization routine for an architecture family */
644efc6369224b036a1fb77849f7ae65b3492c832c0buzbeebool oatArchInit()
645efc6369224b036a1fb77849f7ae65b3492c832c0buzbee{
646efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  int i;
647efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
648efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  for (i = 0; i < kMipsLast; i++) {
649efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    if (EncodingMap[i].opcode != i) {
650efc6369224b036a1fb77849f7ae65b3492c832c0buzbee      LOG(FATAL) << "Encoding order for " << EncodingMap[i].name <<
651cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee         " is wrong: expecting " << i << ", seeing " << static_cast<int>(EncodingMap[i].opcode);
652efc6369224b036a1fb77849f7ae65b3492c832c0buzbee    }
653efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  }
654efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
655efc6369224b036a1fb77849f7ae65b3492c832c0buzbee  return oatArchVariantInit();
656efc6369224b036a1fb77849f7ae65b3492c832c0buzbee}
657efc6369224b036a1fb77849f7ae65b3492c832c0buzbee
658efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} // namespace art
659