blob: cdb8486f50779b6cb57e07fe95a6ee9cb6221759 [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':
buzbeef1f86362012-07-10 15:18:31 -0700221 DCHECK_LT(operand, static_cast<int>(
222 sizeof(coreRegNames)/sizeof(coreRegNames[0])));
Bill Buzbeea114add2012-05-03 15:00:40 -0700223 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)",
236 (int) baseAddr + lir->offset + 4 +
237 (operand << 1),
238 lir->target);
239 break;
240 case 'u': {
241 int offset_1 = lir->operands[0];
242 int offset_2 = NEXT_LIR(lir)->operands[0];
243 intptr_t target =
244 ((((intptr_t) baseAddr + lir->offset + 4) &
245 ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) &
246 0xfffffffc;
247 sprintf(tbuf, "%p", (void *) target);
248 break;
249 }
buzbee67bf8852011-08-17 17:51:35 -0700250
Bill Buzbeea114add2012-05-03 15:00:40 -0700251 /* 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;
buzbee67bf8852011-08-17 17:51:35 -0700267 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700268 buf += tbuf;
269 }
270 } else {
271 buf += *fmt++;
buzbee67bf8852011-08-17 17:51:35 -0700272 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700273 }
274 return buf;
buzbee67bf8852011-08-17 17:51:35 -0700275}
276
277void oatDumpResourceMask(LIR* lir, u8 mask, const char* prefix)
278{
Bill Buzbeea114add2012-05-03 15:00:40 -0700279 char buf[256];
280 buf[0] = 0;
281 LIR* armLIR = (LIR*) lir;
buzbee67bf8852011-08-17 17:51:35 -0700282
Bill Buzbeea114add2012-05-03 15:00:40 -0700283 if (mask == ENCODE_ALL) {
284 strcpy(buf, "all");
285 } else {
286 char num[8];
287 int i;
buzbee67bf8852011-08-17 17:51:35 -0700288
Bill Buzbeea114add2012-05-03 15:00:40 -0700289 for (i = 0; i < kRegEnd; i++) {
290 if (mask & (1ULL << i)) {
291 sprintf(num, "%d ", i);
292 strcat(buf, num);
293 }
buzbee67bf8852011-08-17 17:51:35 -0700294 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700295
296 if (mask & ENCODE_CCODE) {
297 strcat(buf, "cc ");
buzbee67bf8852011-08-17 17:51:35 -0700298 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700299 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 }
buzbee67bf8852011-08-17 17:51:35 -0700322}
323
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800324
325} // namespace art