blob: 4346bda05861676edb280b06a0c957ff695ea6bd [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
2 * Copyright (C) 2011 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 "ArmLIR.h"
buzbee67bc2362011-10-11 18:08:40 -070019#include "../Ralloc.h"
buzbee67bf8852011-08-17 17:51:35 -070020
Elliott Hughes3b6baaa2011-10-14 19:13:56 -070021#include <string>
22
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080023namespace art {
24
buzbee31a4a6f2012-02-28 15:36:15 -080025ArmConditionCode oatArmConditionEncoding(ConditionCode code)
26{
27 ArmConditionCode res;
Elliott Hughesb25c3f62012-03-26 16:35:06 -070028 switch (code) {
buzbee31a4a6f2012-02-28 15:36:15 -080029 case kCondEq: res = kArmCondEq; break;
30 case kCondNe: res = kArmCondNe; break;
31 case kCondCs: res = kArmCondCs; break;
32 case kCondCc: res = kArmCondCc; break;
33 case kCondMi: res = kArmCondMi; break;
34 case kCondPl: res = kArmCondPl; break;
35 case kCondVs: res = kArmCondVs; break;
36 case kCondVc: res = kArmCondVc; break;
37 case kCondHi: res = kArmCondHi; break;
38 case kCondLs: res = kArmCondLs; break;
39 case kCondGe: res = kArmCondGe; break;
40 case kCondLt: res = kArmCondLt; break;
41 case kCondGt: res = kArmCondGt; break;
42 case kCondLe: res = kArmCondLe; break;
43 case kCondAl: res = kArmCondAl; break;
44 case kCondNv: res = kArmCondNv; break;
45 default:
46 LOG(FATAL) << "Bad condition code" << (int)code;
47 res = (ArmConditionCode)0; // Quiet gcc
48 }
49 return res;
50}
51
buzbee67bf8852011-08-17 17:51:35 -070052static const char* coreRegNames[16] = {
53 "r0",
54 "r1",
55 "r2",
56 "r3",
57 "r4",
58 "r5",
59 "r6",
60 "r7",
61 "r8",
62 "rSELF",
63 "r10",
64 "r11",
65 "r12",
66 "sp",
67 "lr",
68 "pc",
69};
70
71
72static const char* shiftNames[4] = {
73 "lsl",
74 "lsr",
75 "asr",
76 "ror"};
77
78/* Decode and print a ARM register name */
buzbee31a4a6f2012-02-28 15:36:15 -080079char* decodeRegList(int opcode, int vector, char* buf)
buzbee67bf8852011-08-17 17:51:35 -070080{
81 int i;
82 bool printed = false;
83 buf[0] = 0;
84 for (i = 0; i < 16; i++, vector >>= 1) {
85 if (vector & 0x1) {
86 int regId = i;
87 if (opcode == kThumbPush && i == 8) {
88 regId = r14lr;
89 } else if (opcode == kThumbPop && i == 8) {
90 regId = r15pc;
91 }
92 if (printed) {
93 sprintf(buf + strlen(buf), ", r%d", regId);
94 } else {
95 printed = true;
96 sprintf(buf, "r%d", regId);
97 }
98 }
99 }
100 return buf;
101}
102
buzbee31a4a6f2012-02-28 15:36:15 -0800103char* decodeFPCSRegList(int count, int base, char* buf)
buzbee67bf8852011-08-17 17:51:35 -0700104{
105 sprintf(buf, "s%d", base);
106 for (int i = 1; i < count; i++) {
107 sprintf(buf + strlen(buf), ", s%d",base + i);
108 }
109 return buf;
110}
111
buzbee31a4a6f2012-02-28 15:36:15 -0800112int expandImmediate(int value)
buzbee67bf8852011-08-17 17:51:35 -0700113{
114 int mode = (value & 0xf00) >> 8;
115 u4 bits = value & 0xff;
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700116 switch (mode) {
buzbee67bf8852011-08-17 17:51:35 -0700117 case 0:
118 return bits;
119 case 1:
120 return (bits << 16) | bits;
121 case 2:
122 return (bits << 24) | (bits << 8);
123 case 3:
124 return (bits << 24) | (bits << 16) | (bits << 8) | bits;
125 default:
126 break;
127 }
128 bits = (bits | 0x80) << 24;
129 return bits >> (((value & 0xf80) >> 7) - 8);
130}
131
132const char* ccNames[] = {"eq","ne","cs","cc","mi","pl","vs","vc",
133 "hi","ls","ge","lt","gt","le","al","nv"};
134/*
135 * Interpret a format string and build a string no longer than size
136 * See format key in Assemble.c.
137 */
buzbee31a4a6f2012-02-28 15:36:15 -0800138std::string buildInsnString(const char* fmt, LIR* lir,
139 unsigned char* baseAddr)
buzbee67bf8852011-08-17 17:51:35 -0700140{
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700141 std::string buf;
buzbee67bf8852011-08-17 17:51:35 -0700142 int i;
buzbee67bf8852011-08-17 17:51:35 -0700143 const char* fmtEnd = &fmt[strlen(fmt)];
144 char tbuf[256];
145 const char* name;
146 char nc;
147 while (fmt < fmtEnd) {
148 int operand;
149 if (*fmt == '!') {
150 fmt++;
buzbeeed3e9302011-09-23 17:34:19 -0700151 DCHECK_LT(fmt, fmtEnd);
buzbee67bf8852011-08-17 17:51:35 -0700152 nc = *fmt++;
153 if (nc=='!') {
154 strcpy(tbuf, "!");
155 } else {
buzbeeed3e9302011-09-23 17:34:19 -0700156 DCHECK_LT(fmt, fmtEnd);
Elliott Hughesf5a7a472011-10-07 14:31:02 -0700157 DCHECK_LT((unsigned)(nc-'0'), 4U);
buzbee67bf8852011-08-17 17:51:35 -0700158 operand = lir->operands[nc-'0'];
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700159 switch (*fmt++) {
buzbee67bf8852011-08-17 17:51:35 -0700160 case 'H':
161 if (operand != 0) {
162 sprintf(tbuf, ", %s %d",shiftNames[operand & 0x3],
163 operand >> 2);
164 } else {
165 strcpy(tbuf,"");
166 }
167 break;
168 case 'B':
169 switch (operand) {
170 case kSY:
171 name = "sy";
172 break;
173 case kST:
174 name = "st";
175 break;
176 case kISH:
177 name = "ish";
178 break;
179 case kISHST:
180 name = "ishst";
181 break;
182 case kNSH:
183 name = "nsh";
184 break;
185 case kNSHST:
186 name = "shst";
187 break;
188 default:
189 name = "DecodeError2";
190 break;
191 }
192 strcpy(tbuf, name);
193 break;
194 case 'b':
195 strcpy(tbuf,"0000");
196 for (i=3; i>= 0; i--) {
197 tbuf[i] += operand & 1;
198 operand >>= 1;
199 }
200 break;
201 case 'n':
202 operand = ~expandImmediate(operand);
203 sprintf(tbuf,"%d [%#x]", operand, operand);
204 break;
205 case 'm':
206 operand = expandImmediate(operand);
207 sprintf(tbuf,"%d [%#x]", operand, operand);
208 break;
209 case 's':
210 sprintf(tbuf,"s%d",operand & FP_REG_MASK);
211 break;
212 case 'S':
213 sprintf(tbuf,"d%d",(operand & FP_REG_MASK) >> 1);
214 break;
215 case 'h':
216 sprintf(tbuf,"%04x", operand);
217 break;
218 case 'M':
219 case 'd':
220 sprintf(tbuf,"%d", operand);
221 break;
222 case 'C':
223 sprintf(tbuf,"%s",coreRegNames[operand]);
224 break;
225 case 'E':
226 sprintf(tbuf,"%d", operand*4);
227 break;
228 case 'F':
229 sprintf(tbuf,"%d", operand*2);
230 break;
231 case 'c':
232 strcpy(tbuf, ccNames[operand]);
233 break;
234 case 't':
235 sprintf(tbuf,"0x%08x (L%p)",
buzbee31a4a6f2012-02-28 15:36:15 -0800236 (int) baseAddr + lir->offset + 4 +
buzbee67bf8852011-08-17 17:51:35 -0700237 (operand << 1),
buzbee31a4a6f2012-02-28 15:36:15 -0800238 lir->target);
buzbee67bf8852011-08-17 17:51:35 -0700239 break;
240 case 'u': {
241 int offset_1 = lir->operands[0];
242 int offset_2 = NEXT_LIR(lir)->operands[0];
243 intptr_t target =
buzbee31a4a6f2012-02-28 15:36:15 -0800244 ((((intptr_t) baseAddr + lir->offset + 4) &
buzbee67bf8852011-08-17 17:51:35 -0700245 ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) &
246 0xfffffffc;
247 sprintf(tbuf, "%p", (void *) target);
248 break;
249 }
250
251 /* Nothing to print for BLX_2 */
252 case 'v':
253 strcpy(tbuf, "see above");
254 break;
255 case 'R':
256 decodeRegList(lir->opcode, operand, tbuf);
257 break;
258 case 'P':
259 decodeFPCSRegList(operand, 16, tbuf);
260 break;
261 case 'Q':
262 decodeFPCSRegList(operand, 0, tbuf);
263 break;
264 default:
265 strcpy(tbuf,"DecodeError1");
266 break;
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700267 }
268 buf += tbuf;
buzbee67bf8852011-08-17 17:51:35 -0700269 }
270 } else {
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700271 buf += *fmt++;
buzbee67bf8852011-08-17 17:51:35 -0700272 }
buzbee67bf8852011-08-17 17:51:35 -0700273 }
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700274 return buf;
buzbee67bf8852011-08-17 17:51:35 -0700275}
276
277void oatDumpResourceMask(LIR* lir, u8 mask, const char* prefix)
278{
279 char buf[256];
280 buf[0] = 0;
buzbee31a4a6f2012-02-28 15:36:15 -0800281 LIR* armLIR = (LIR*) lir;
buzbee67bf8852011-08-17 17:51:35 -0700282
283 if (mask == ENCODE_ALL) {
284 strcpy(buf, "all");
285 } else {
286 char num[8];
287 int i;
288
289 for (i = 0; i < kRegEnd; i++) {
290 if (mask & (1ULL << i)) {
291 sprintf(num, "%d ", i);
292 strcat(buf, num);
293 }
294 }
295
296 if (mask & ENCODE_CCODE) {
297 strcat(buf, "cc ");
298 }
299 if (mask & ENCODE_FP_STATUS) {
300 strcat(buf, "fpcc ");
301 }
302
303 /* Memory bits */
304 if (armLIR && (mask & ENCODE_DALVIK_REG)) {
305 sprintf(buf + strlen(buf), "dr%d%s", armLIR->aliasInfo & 0xffff,
306 (armLIR->aliasInfo & 0x80000000) ? "(+1)" : "");
307 }
308 if (mask & ENCODE_LITERAL) {
309 strcat(buf, "lit ");
310 }
311
312 if (mask & ENCODE_HEAP_REF) {
313 strcat(buf, "heap ");
314 }
315 if (mask & ENCODE_MUST_NOT_ALIAS) {
316 strcat(buf, "noalias ");
317 }
318 }
319 if (buf[0]) {
320 LOG(INFO) << prefix << ": " << buf;
321 }
322}
323
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800324
325} // namespace art