blob: 9a2b923baf6eb2892f804bd0c6642e9ee0232c30 [file] [log] [blame]
buzbeee3acd072012-02-25 17:03:10 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "../../CompilerInternals.h"
18#include "MipsLIR.h"
19#include "../Ralloc.h"
20
21#include <string>
22
23namespace art {
24
buzbeeec137432012-11-13 12:13:16 -080025/*
26 * Decode the register id.
27 */
28u8 getRegMaskCommon(CompilationUnit* cUnit, int reg)
29{
30 u8 seed;
31 int shift;
32 int regId;
33
34
35 regId = reg & 0x1f;
36 /* Each double register is equal to a pair of single-precision FP registers */
37 seed = DOUBLEREG(reg) ? 3 : 1;
38 /* FP register starts at bit position 16 */
39 shift = FPREG(reg) ? kMipsFPReg0 : 0;
40 /* Expand the double register id into single offset */
41 shift += regId;
42 return (seed << shift);
43}
44
45uint64_t getPCUseDefEncoding()
46{
47 return ENCODE_MIPS_REG_PC;
48}
49
50
buzbeeb046e162012-10-30 15:48:42 -070051void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir)
52{
53 DCHECK_EQ(cUnit->instructionSet, kMips);
54
55 // Mips-specific resource map setup here.
buzbeeec137432012-11-13 12:13:16 -080056 uint64_t flags = EncodingMap[lir->opcode].flags;
57
58 if (flags & REG_DEF_SP) {
59 lir->defMask |= ENCODE_MIPS_REG_SP;
60 }
61
62 if (flags & REG_USE_SP) {
63 lir->useMask |= ENCODE_MIPS_REG_SP;
64 }
65
buzbeeb046e162012-10-30 15:48:42 -070066 if (flags & REG_DEF_LR) {
buzbeeec137432012-11-13 12:13:16 -080067 lir->defMask |= ENCODE_MIPS_REG_LR;
buzbeeb046e162012-10-30 15:48:42 -070068 }
69}
70
buzbeee3acd072012-02-25 17:03:10 -080071/* For dumping instructions */
72#define MIPS_REG_COUNT 32
73static const char *mipsRegName[MIPS_REG_COUNT] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070074 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
75 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
76 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
77 "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
buzbeee3acd072012-02-25 17:03:10 -080078};
79
80/*
81 * Interpret a format string and build a string no longer than size
82 * See format key in Assemble.c.
83 */
buzbee5de34942012-03-01 14:51:57 -080084std::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr)
buzbeee3acd072012-02-25 17:03:10 -080085{
Bill Buzbeea114add2012-05-03 15:00:40 -070086 std::string buf;
87 int i;
88 const char *fmtEnd = &fmt[strlen(fmt)];
89 char tbuf[256];
90 char nc;
91 while (fmt < fmtEnd) {
92 int operand;
93 if (*fmt == '!') {
94 fmt++;
95 DCHECK_LT(fmt, fmtEnd);
96 nc = *fmt++;
97 if (nc=='!') {
98 strcpy(tbuf, "!");
99 } else {
100 DCHECK_LT(fmt, fmtEnd);
101 DCHECK_LT((unsigned)(nc-'0'), 4u);
102 operand = lir->operands[nc-'0'];
103 switch (*fmt++) {
104 case 'b':
105 strcpy(tbuf,"0000");
106 for (i=3; i>= 0; i--) {
107 tbuf[i] += operand & 1;
108 operand >>= 1;
109 }
110 break;
111 case 's':
112 sprintf(tbuf,"$f%d",operand & FP_REG_MASK);
113 break;
114 case 'S':
115 DCHECK_EQ(((operand & FP_REG_MASK) & 1), 0);
116 sprintf(tbuf,"$f%d",operand & FP_REG_MASK);
117 break;
118 case 'h':
119 sprintf(tbuf,"%04x", operand);
120 break;
121 case 'M':
122 case 'd':
123 sprintf(tbuf,"%d", operand);
124 break;
125 case 'D':
126 sprintf(tbuf,"%d", operand+1);
127 break;
128 case 'E':
129 sprintf(tbuf,"%d", operand*4);
130 break;
131 case 'F':
132 sprintf(tbuf,"%d", operand*2);
133 break;
134 case 't':
135 sprintf(tbuf,"0x%08x (L%p)", (int) baseAddr + lir->offset + 4 +
136 (operand << 2), lir->target);
137 break;
138 case 'T':
139 sprintf(tbuf,"0x%08x", (int) (operand << 2));
140 break;
141 case 'u': {
142 int offset_1 = lir->operands[0];
143 int offset_2 = NEXT_LIR(lir)->operands[0];
144 intptr_t target =
145 ((((intptr_t) baseAddr + lir->offset + 4) & ~3) +
146 (offset_1 << 21 >> 9) + (offset_2 << 1)) & 0xfffffffc;
147 sprintf(tbuf, "%p", (void *) target);
148 break;
149 }
buzbeee3acd072012-02-25 17:03:10 -0800150
Bill Buzbeea114add2012-05-03 15:00:40 -0700151 /* Nothing to print for BLX_2 */
152 case 'v':
153 strcpy(tbuf, "see above");
154 break;
155 case 'r':
156 DCHECK(operand >= 0 && operand < MIPS_REG_COUNT);
157 strcpy(tbuf, mipsRegName[operand]);
158 break;
159 case 'N':
160 // Placeholder for delay slot handling
161 strcpy(tbuf, "; nop");
162 break;
163 default:
164 strcpy(tbuf,"DecodeError");
165 break;
166 }
167 buf += tbuf;
168 }
169 } else {
170 buf += *fmt++;
buzbeee3acd072012-02-25 17:03:10 -0800171 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700172 }
173 return buf;
buzbeee3acd072012-02-25 17:03:10 -0800174}
175
buzbee408ad162012-06-06 16:45:18 -0700176// FIXME: need to redo resource maps for MIPS - fix this at that time
buzbeee3acd072012-02-25 17:03:10 -0800177void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix)
178{
Bill Buzbeea114add2012-05-03 15:00:40 -0700179 char buf[256];
180 buf[0] = 0;
181 LIR *mipsLIR = (LIR *) lir;
buzbeee3acd072012-02-25 17:03:10 -0800182
Bill Buzbeea114add2012-05-03 15:00:40 -0700183 if (mask == ENCODE_ALL) {
184 strcpy(buf, "all");
185 } else {
186 char num[8];
187 int i;
buzbeee3acd072012-02-25 17:03:10 -0800188
buzbeeec137432012-11-13 12:13:16 -0800189 for (i = 0; i < kMipsRegEnd; i++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700190 if (mask & (1ULL << i)) {
191 sprintf(num, "%d ", i);
192 strcat(buf, num);
193 }
buzbeee3acd072012-02-25 17:03:10 -0800194 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700195
196 if (mask & ENCODE_CCODE) {
197 strcat(buf, "cc ");
buzbeee3acd072012-02-25 17:03:10 -0800198 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700199 if (mask & ENCODE_FP_STATUS) {
200 strcat(buf, "fpcc ");
201 }
202 /* Memory bits */
203 if (mipsLIR && (mask & ENCODE_DALVIK_REG)) {
204 sprintf(buf + strlen(buf), "dr%d%s", mipsLIR->aliasInfo & 0xffff,
205 (mipsLIR->aliasInfo & 0x80000000) ? "(+1)" : "");
206 }
207 if (mask & ENCODE_LITERAL) {
208 strcat(buf, "lit ");
209 }
210
211 if (mask & ENCODE_HEAP_REF) {
212 strcat(buf, "heap ");
213 }
214 if (mask & ENCODE_MUST_NOT_ALIAS) {
215 strcat(buf, "noalias ");
216 }
217 }
218 if (buf[0]) {
219 LOG(INFO) << prefix << ": " << buf;
220 }
buzbeee3acd072012-02-25 17:03:10 -0800221}
222
buzbeee3acd072012-02-25 17:03:10 -0800223} // namespace art