blob: 725200a6f63146e8a099b7689383ab32c32b98fa [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{
Bill Buzbeea114add2012-05-03 15:00:40 -070027 ArmConditionCode res;
28 switch (code) {
29 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;
buzbee31a4a6f2012-02-28 15:36:15 -080050}
51
buzbee67bf8852011-08-17 17:51:35 -070052static const char* coreRegNames[16] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070053 "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",
buzbee67bf8852011-08-17 17:51:35 -070069};
70
71
72static const char* shiftNames[4] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070073 "lsl",
74 "lsr",
75 "asr",
76 "ror"};
buzbee67bf8852011-08-17 17:51:35 -070077
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{
Bill Buzbeea114add2012-05-03 15:00:40 -070081 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 }
buzbee67bf8852011-08-17 17:51:35 -070098 }
Bill Buzbeea114add2012-05-03 15:00:40 -070099 }
100 return buf;
buzbee67bf8852011-08-17 17:51:35 -0700101}
102
buzbee31a4a6f2012-02-28 15:36:15 -0800103char* decodeFPCSRegList(int count, int base, char* buf)
buzbee67bf8852011-08-17 17:51:35 -0700104{
Bill Buzbeea114add2012-05-03 15:00:40 -0700105 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;
buzbee67bf8852011-08-17 17:51:35 -0700110}
111
buzbee31a4a6f2012-02-28 15:36:15 -0800112int expandImmediate(int value)
buzbee67bf8852011-08-17 17:51:35 -0700113{
Bill Buzbeea114add2012-05-03 15:00:40 -0700114 int mode = (value & 0xf00) >> 8;
115 u4 bits = value & 0xff;
116 switch (mode) {
117 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);
buzbee67bf8852011-08-17 17:51:35 -0700130}
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 */
Bill Buzbeea114add2012-05-03 15:00:40 -0700138std::string buildInsnString(const char* fmt, LIR* lir, unsigned char* baseAddr)
buzbee67bf8852011-08-17 17:51:35 -0700139{
Bill Buzbeea114add2012-05-03 15:00:40 -0700140 std::string buf;
141 int i;
142 const char* fmtEnd = &fmt[strlen(fmt)];
143 char tbuf[256];
144 const char* name;
145 char nc;
146 while (fmt < fmtEnd) {
147 int operand;
148 if (*fmt == '!') {
149 fmt++;
150 DCHECK_LT(fmt, fmtEnd);
151 nc = *fmt++;
152 if (nc=='!') {
153 strcpy(tbuf, "!");
154 } else {
155 DCHECK_LT(fmt, fmtEnd);
156 DCHECK_LT((unsigned)(nc-'0'), 4U);
157 operand = lir->operands[nc-'0'];
158 switch (*fmt++) {
159 case 'H':
160 if (operand != 0) {
161 sprintf(tbuf, ", %s %d",shiftNames[operand & 0x3], operand >> 2);
162 } else {
163 strcpy(tbuf,"");
164 }
165 break;
166 case 'B':
167 switch (operand) {
168 case kSY:
169 name = "sy";
170 break;
171 case kST:
172 name = "st";
173 break;
174 case kISH:
175 name = "ish";
176 break;
177 case kISHST:
178 name = "ishst";
179 break;
180 case kNSH:
181 name = "nsh";
182 break;
183 case kNSHST:
184 name = "shst";
185 break;
186 default:
187 name = "DecodeError2";
188 break;
189 }
190 strcpy(tbuf, name);
191 break;
192 case 'b':
193 strcpy(tbuf,"0000");
194 for (i=3; i>= 0; i--) {
195 tbuf[i] += operand & 1;
196 operand >>= 1;
197 }
198 break;
199 case 'n':
200 operand = ~expandImmediate(operand);
201 sprintf(tbuf,"%d [%#x]", operand, operand);
202 break;
203 case 'm':
204 operand = expandImmediate(operand);
205 sprintf(tbuf,"%d [%#x]", operand, operand);
206 break;
207 case 's':
208 sprintf(tbuf,"s%d",operand & FP_REG_MASK);
209 break;
210 case 'S':
211 sprintf(tbuf,"d%d",(operand & FP_REG_MASK) >> 1);
212 break;
213 case 'h':
214 sprintf(tbuf,"%04x", operand);
215 break;
216 case 'M':
217 case 'd':
218 sprintf(tbuf,"%d", operand);
219 break;
220 case 'C':
221 sprintf(tbuf,"%s",coreRegNames[operand]);
222 break;
223 case 'E':
224 sprintf(tbuf,"%d", operand*4);
225 break;
226 case 'F':
227 sprintf(tbuf,"%d", operand*2);
228 break;
229 case 'c':
230 strcpy(tbuf, ccNames[operand]);
231 break;
232 case 't':
233 sprintf(tbuf,"0x%08x (L%p)",
234 (int) baseAddr + lir->offset + 4 +
235 (operand << 1),
236 lir->target);
237 break;
238 case 'u': {
239 int offset_1 = lir->operands[0];
240 int offset_2 = NEXT_LIR(lir)->operands[0];
241 intptr_t target =
242 ((((intptr_t) baseAddr + lir->offset + 4) &
243 ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) &
244 0xfffffffc;
245 sprintf(tbuf, "%p", (void *) target);
246 break;
247 }
buzbee67bf8852011-08-17 17:51:35 -0700248
Bill Buzbeea114add2012-05-03 15:00:40 -0700249 /* Nothing to print for BLX_2 */
250 case 'v':
251 strcpy(tbuf, "see above");
252 break;
253 case 'R':
254 decodeRegList(lir->opcode, operand, tbuf);
255 break;
256 case 'P':
257 decodeFPCSRegList(operand, 16, tbuf);
258 break;
259 case 'Q':
260 decodeFPCSRegList(operand, 0, tbuf);
261 break;
262 default:
263 strcpy(tbuf,"DecodeError1");
264 break;
buzbee67bf8852011-08-17 17:51:35 -0700265 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700266 buf += tbuf;
267 }
268 } else {
269 buf += *fmt++;
buzbee67bf8852011-08-17 17:51:35 -0700270 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700271 }
272 return buf;
buzbee67bf8852011-08-17 17:51:35 -0700273}
274
275void oatDumpResourceMask(LIR* lir, u8 mask, const char* prefix)
276{
Bill Buzbeea114add2012-05-03 15:00:40 -0700277 char buf[256];
278 buf[0] = 0;
279 LIR* armLIR = (LIR*) lir;
buzbee67bf8852011-08-17 17:51:35 -0700280
Bill Buzbeea114add2012-05-03 15:00:40 -0700281 if (mask == ENCODE_ALL) {
282 strcpy(buf, "all");
283 } else {
284 char num[8];
285 int i;
buzbee67bf8852011-08-17 17:51:35 -0700286
Bill Buzbeea114add2012-05-03 15:00:40 -0700287 for (i = 0; i < kRegEnd; i++) {
288 if (mask & (1ULL << i)) {
289 sprintf(num, "%d ", i);
290 strcat(buf, num);
291 }
buzbee67bf8852011-08-17 17:51:35 -0700292 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700293
294 if (mask & ENCODE_CCODE) {
295 strcat(buf, "cc ");
buzbee67bf8852011-08-17 17:51:35 -0700296 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700297 if (mask & ENCODE_FP_STATUS) {
298 strcat(buf, "fpcc ");
299 }
300
301 /* Memory bits */
302 if (armLIR && (mask & ENCODE_DALVIK_REG)) {
303 sprintf(buf + strlen(buf), "dr%d%s", armLIR->aliasInfo & 0xffff,
304 (armLIR->aliasInfo & 0x80000000) ? "(+1)" : "");
305 }
306 if (mask & ENCODE_LITERAL) {
307 strcat(buf, "lit ");
308 }
309
310 if (mask & ENCODE_HEAP_REF) {
311 strcat(buf, "heap ");
312 }
313 if (mask & ENCODE_MUST_NOT_ALIAS) {
314 strcat(buf, "noalias ");
315 }
316 }
317 if (buf[0]) {
318 LOG(INFO) << prefix << ": " << buf;
319 }
buzbee67bf8852011-08-17 17:51:35 -0700320}
321
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800322
323} // namespace art