1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 // A Disassembler object is used to disassemble a block of code instruction by
29 // instruction. The default implementation of the NameConverter object can be
30 // overriden to modify register names or to do symbol lookup on addresses.
31 //
32 // The example below will disassemble a block of code and print it to stdout.
33 //
34 // NameConverter converter;
35 // Disassembler d(converter);
36 // for (byte* pc = begin; pc < end;) {
37 // v8::internal::EmbeddedVector<char, 256> buffer;
38 // byte* prev_pc = pc;
39 // pc += d.InstructionDecode(buffer, pc);
40 // printf("%p %08x %s\n",
41 // prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
42 // }
43 //
44 // The Disassembler class also has a convenience method to disassemble a block
45 // of code into a FILE*, meaning that the above functionality could also be
46 // achieved by just calling Disassembler::Disassemble(stdout, begin, end);
47
48
49 #include <assert.h>
50 #include <stdio.h>
51 #include <stdarg.h>
52 #include <string.h>
53
54 #include "v8.h"
55
56 #if V8_TARGET_ARCH_ARM
57
58 #include "constants-arm.h"
59 #include "disasm.h"
60 #include "macro-assembler.h"
61 #include "platform.h"
62
63
64 namespace v8 {
65 namespace internal {
66
67
68 //------------------------------------------------------------------------------
69
70 // Decoder decodes and disassembles instructions into an output buffer.
71 // It uses the converter to convert register names and call destinations into
72 // more informative description.
73 class Decoder {
74 public:
Decoder(const disasm::NameConverter & converter,Vector<char> out_buffer)75 Decoder(const disasm::NameConverter& converter,
76 Vector<char> out_buffer)
77 : converter_(converter),
78 out_buffer_(out_buffer),
79 out_buffer_pos_(0) {
80 out_buffer_[out_buffer_pos_] = '\0';
81 }
82
~Decoder()83 ~Decoder() {}
84
85 // Writes one disassembled instruction into 'buffer' (0-terminated).
86 // Returns the length of the disassembled machine instruction in bytes.
87 int InstructionDecode(byte* instruction);
88
89 static bool IsConstantPoolAt(byte* instr_ptr);
90 static int ConstantPoolSizeAt(byte* instr_ptr);
91
92 private:
93 // Bottleneck functions to print into the out_buffer.
94 void PrintChar(const char ch);
95 void Print(const char* str);
96
97 // Printing of common values.
98 void PrintRegister(int reg);
99 void PrintSRegister(int reg);
100 void PrintDRegister(int reg);
101 int FormatVFPRegister(Instruction* instr, const char* format);
102 void PrintMovwMovt(Instruction* instr);
103 int FormatVFPinstruction(Instruction* instr, const char* format);
104 void PrintCondition(Instruction* instr);
105 void PrintShiftRm(Instruction* instr);
106 void PrintShiftImm(Instruction* instr);
107 void PrintShiftSat(Instruction* instr);
108 void PrintPU(Instruction* instr);
109 void PrintSoftwareInterrupt(SoftwareInterruptCodes svc);
110
111 // Handle formatting of instructions and their options.
112 int FormatRegister(Instruction* instr, const char* option);
113 void FormatNeonList(int Vd, int type);
114 void FormatNeonMemory(int Rn, int align, int Rm);
115 int FormatOption(Instruction* instr, const char* option);
116 void Format(Instruction* instr, const char* format);
117 void Unknown(Instruction* instr);
118
119 // Each of these functions decodes one particular instruction type, a 3-bit
120 // field in the instruction encoding.
121 // Types 0 and 1 are combined as they are largely the same except for the way
122 // they interpret the shifter operand.
123 void DecodeType01(Instruction* instr);
124 void DecodeType2(Instruction* instr);
125 void DecodeType3(Instruction* instr);
126 void DecodeType4(Instruction* instr);
127 void DecodeType5(Instruction* instr);
128 void DecodeType6(Instruction* instr);
129 // Type 7 includes special Debugger instructions.
130 int DecodeType7(Instruction* instr);
131 // For VFP support.
132 void DecodeTypeVFP(Instruction* instr);
133 void DecodeType6CoprocessorIns(Instruction* instr);
134
135 void DecodeSpecialCondition(Instruction* instr);
136
137 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr);
138 void DecodeVCMP(Instruction* instr);
139 void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr);
140 void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr);
141
142 const disasm::NameConverter& converter_;
143 Vector<char> out_buffer_;
144 int out_buffer_pos_;
145
146 DISALLOW_COPY_AND_ASSIGN(Decoder);
147 };
148
149
150 // Support for assertions in the Decoder formatting functions.
151 #define STRING_STARTS_WITH(string, compare_string) \
152 (strncmp(string, compare_string, strlen(compare_string)) == 0)
153
154
155 // Append the ch to the output buffer.
PrintChar(const char ch)156 void Decoder::PrintChar(const char ch) {
157 out_buffer_[out_buffer_pos_++] = ch;
158 }
159
160
161 // Append the str to the output buffer.
Print(const char * str)162 void Decoder::Print(const char* str) {
163 char cur = *str++;
164 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
165 PrintChar(cur);
166 cur = *str++;
167 }
168 out_buffer_[out_buffer_pos_] = 0;
169 }
170
171
172 // These condition names are defined in a way to match the native disassembler
173 // formatting. See for example the command "objdump -d <binary file>".
174 static const char* cond_names[kNumberOfConditions] = {
175 "eq", "ne", "cs" , "cc" , "mi" , "pl" , "vs" , "vc" ,
176 "hi", "ls", "ge", "lt", "gt", "le", "", "invalid",
177 };
178
179
180 // Print the condition guarding the instruction.
PrintCondition(Instruction * instr)181 void Decoder::PrintCondition(Instruction* instr) {
182 Print(cond_names[instr->ConditionValue()]);
183 }
184
185
186 // Print the register name according to the active name converter.
PrintRegister(int reg)187 void Decoder::PrintRegister(int reg) {
188 Print(converter_.NameOfCPURegister(reg));
189 }
190
191
192 // Print the VFP S register name according to the active name converter.
PrintSRegister(int reg)193 void Decoder::PrintSRegister(int reg) {
194 Print(VFPRegisters::Name(reg, false));
195 }
196
197
198 // Print the VFP D register name according to the active name converter.
PrintDRegister(int reg)199 void Decoder::PrintDRegister(int reg) {
200 Print(VFPRegisters::Name(reg, true));
201 }
202
203
204 // These shift names are defined in a way to match the native disassembler
205 // formatting. See for example the command "objdump -d <binary file>".
206 static const char* const shift_names[kNumberOfShifts] = {
207 "lsl", "lsr", "asr", "ror"
208 };
209
210
211 // Print the register shift operands for the instruction. Generally used for
212 // data processing instructions.
PrintShiftRm(Instruction * instr)213 void Decoder::PrintShiftRm(Instruction* instr) {
214 ShiftOp shift = instr->ShiftField();
215 int shift_index = instr->ShiftValue();
216 int shift_amount = instr->ShiftAmountValue();
217 int rm = instr->RmValue();
218
219 PrintRegister(rm);
220
221 if ((instr->RegShiftValue() == 0) && (shift == LSL) && (shift_amount == 0)) {
222 // Special case for using rm only.
223 return;
224 }
225 if (instr->RegShiftValue() == 0) {
226 // by immediate
227 if ((shift == ROR) && (shift_amount == 0)) {
228 Print(", RRX");
229 return;
230 } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
231 shift_amount = 32;
232 }
233 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
234 ", %s #%d",
235 shift_names[shift_index],
236 shift_amount);
237 } else {
238 // by register
239 int rs = instr->RsValue();
240 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
241 ", %s ", shift_names[shift_index]);
242 PrintRegister(rs);
243 }
244 }
245
246
247 // Print the immediate operand for the instruction. Generally used for data
248 // processing instructions.
PrintShiftImm(Instruction * instr)249 void Decoder::PrintShiftImm(Instruction* instr) {
250 int rotate = instr->RotateValue() * 2;
251 int immed8 = instr->Immed8Value();
252 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
253 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
254 "#%d", imm);
255 }
256
257
258 // Print the optional shift and immediate used by saturating instructions.
PrintShiftSat(Instruction * instr)259 void Decoder::PrintShiftSat(Instruction* instr) {
260 int shift = instr->Bits(11, 7);
261 if (shift > 0) {
262 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
263 ", %s #%d",
264 shift_names[instr->Bit(6) * 2],
265 instr->Bits(11, 7));
266 }
267 }
268
269
270 // Print PU formatting to reduce complexity of FormatOption.
PrintPU(Instruction * instr)271 void Decoder::PrintPU(Instruction* instr) {
272 switch (instr->PUField()) {
273 case da_x: {
274 Print("da");
275 break;
276 }
277 case ia_x: {
278 Print("ia");
279 break;
280 }
281 case db_x: {
282 Print("db");
283 break;
284 }
285 case ib_x: {
286 Print("ib");
287 break;
288 }
289 default: {
290 UNREACHABLE();
291 break;
292 }
293 }
294 }
295
296
297 // Print SoftwareInterrupt codes. Factoring this out reduces the complexity of
298 // the FormatOption method.
PrintSoftwareInterrupt(SoftwareInterruptCodes svc)299 void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) {
300 switch (svc) {
301 case kCallRtRedirected:
302 Print("call rt redirected");
303 return;
304 case kBreakpoint:
305 Print("breakpoint");
306 return;
307 default:
308 if (svc >= kStopCode) {
309 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
310 "%d - 0x%x",
311 svc & kStopCodeMask,
312 svc & kStopCodeMask);
313 } else {
314 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
315 "%d",
316 svc);
317 }
318 return;
319 }
320 }
321
322
323 // Handle all register based formatting in this function to reduce the
324 // complexity of FormatOption.
FormatRegister(Instruction * instr,const char * format)325 int Decoder::FormatRegister(Instruction* instr, const char* format) {
326 ASSERT(format[0] == 'r');
327 if (format[1] == 'n') { // 'rn: Rn register
328 int reg = instr->RnValue();
329 PrintRegister(reg);
330 return 2;
331 } else if (format[1] == 'd') { // 'rd: Rd register
332 int reg = instr->RdValue();
333 PrintRegister(reg);
334 return 2;
335 } else if (format[1] == 's') { // 'rs: Rs register
336 int reg = instr->RsValue();
337 PrintRegister(reg);
338 return 2;
339 } else if (format[1] == 'm') { // 'rm: Rm register
340 int reg = instr->RmValue();
341 PrintRegister(reg);
342 return 2;
343 } else if (format[1] == 't') { // 'rt: Rt register
344 int reg = instr->RtValue();
345 PrintRegister(reg);
346 return 2;
347 } else if (format[1] == 'l') {
348 // 'rlist: register list for load and store multiple instructions
349 ASSERT(STRING_STARTS_WITH(format, "rlist"));
350 int rlist = instr->RlistValue();
351 int reg = 0;
352 Print("{");
353 // Print register list in ascending order, by scanning the bit mask.
354 while (rlist != 0) {
355 if ((rlist & 1) != 0) {
356 PrintRegister(reg);
357 if ((rlist >> 1) != 0) {
358 Print(", ");
359 }
360 }
361 reg++;
362 rlist >>= 1;
363 }
364 Print("}");
365 return 5;
366 }
367 UNREACHABLE();
368 return -1;
369 }
370
371
372 // Handle all VFP register based formatting in this function to reduce the
373 // complexity of FormatOption.
FormatVFPRegister(Instruction * instr,const char * format)374 int Decoder::FormatVFPRegister(Instruction* instr, const char* format) {
375 ASSERT((format[0] == 'S') || (format[0] == 'D'));
376
377 VFPRegPrecision precision =
378 format[0] == 'D' ? kDoublePrecision : kSinglePrecision;
379
380 int retval = 2;
381 int reg = -1;
382 if (format[1] == 'n') {
383 reg = instr->VFPNRegValue(precision);
384 } else if (format[1] == 'm') {
385 reg = instr->VFPMRegValue(precision);
386 } else if (format[1] == 'd') {
387 if ((instr->TypeValue() == 7) &&
388 (instr->Bit(24) == 0x0) &&
389 (instr->Bits(11, 9) == 0x5) &&
390 (instr->Bit(4) == 0x1)) {
391 // vmov.32 has Vd in a different place.
392 reg = instr->Bits(19, 16) | (instr->Bit(7) << 4);
393 } else {
394 reg = instr->VFPDRegValue(precision);
395 }
396
397 if (format[2] == '+') {
398 int immed8 = instr->Immed8Value();
399 if (format[0] == 'S') reg += immed8 - 1;
400 if (format[0] == 'D') reg += (immed8 / 2 - 1);
401 }
402 if (format[2] == '+') retval = 3;
403 } else {
404 UNREACHABLE();
405 }
406
407 if (precision == kSinglePrecision) {
408 PrintSRegister(reg);
409 } else {
410 PrintDRegister(reg);
411 }
412
413 return retval;
414 }
415
416
FormatVFPinstruction(Instruction * instr,const char * format)417 int Decoder::FormatVFPinstruction(Instruction* instr, const char* format) {
418 Print(format);
419 return 0;
420 }
421
422
FormatNeonList(int Vd,int type)423 void Decoder::FormatNeonList(int Vd, int type) {
424 if (type == nlt_1) {
425 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
426 "{d%d}", Vd);
427 } else if (type == nlt_2) {
428 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
429 "{d%d, d%d}", Vd, Vd + 1);
430 } else if (type == nlt_3) {
431 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
432 "{d%d, d%d, d%d}", Vd, Vd + 1, Vd + 2);
433 } else if (type == nlt_4) {
434 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
435 "{d%d, d%d, d%d, d%d}", Vd, Vd + 1, Vd + 2, Vd + 3);
436 }
437 }
438
439
FormatNeonMemory(int Rn,int align,int Rm)440 void Decoder::FormatNeonMemory(int Rn, int align, int Rm) {
441 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
442 "[r%d", Rn);
443 if (align != 0) {
444 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
445 ":%d", (1 << align) << 6);
446 }
447 if (Rm == 15) {
448 Print("]");
449 } else if (Rm == 13) {
450 Print("]!");
451 } else {
452 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
453 "], r%d", Rm);
454 }
455 }
456
457
458 // Print the movw or movt instruction.
PrintMovwMovt(Instruction * instr)459 void Decoder::PrintMovwMovt(Instruction* instr) {
460 int imm = instr->ImmedMovwMovtValue();
461 int rd = instr->RdValue();
462 PrintRegister(rd);
463 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
464 ", #%d", imm);
465 }
466
467
468 // FormatOption takes a formatting string and interprets it based on
469 // the current instructions. The format string points to the first
470 // character of the option string (the option escape has already been
471 // consumed by the caller.) FormatOption returns the number of
472 // characters that were consumed from the formatting string.
FormatOption(Instruction * instr,const char * format)473 int Decoder::FormatOption(Instruction* instr, const char* format) {
474 switch (format[0]) {
475 case 'a': { // 'a: accumulate multiplies
476 if (instr->Bit(21) == 0) {
477 Print("ul");
478 } else {
479 Print("la");
480 }
481 return 1;
482 }
483 case 'b': { // 'b: byte loads or stores
484 if (instr->HasB()) {
485 Print("b");
486 }
487 return 1;
488 }
489 case 'c': { // 'cond: conditional execution
490 ASSERT(STRING_STARTS_WITH(format, "cond"));
491 PrintCondition(instr);
492 return 4;
493 }
494 case 'd': { // 'd: vmov double immediate.
495 double d = instr->DoubleImmedVmov();
496 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
497 "#%g", d);
498 return 1;
499 }
500 case 'f': { // 'f: bitfield instructions - v7 and above.
501 uint32_t lsbit = instr->Bits(11, 7);
502 uint32_t width = instr->Bits(20, 16) + 1;
503 if (instr->Bit(21) == 0) {
504 // BFC/BFI:
505 // Bits 20-16 represent most-significant bit. Covert to width.
506 width -= lsbit;
507 ASSERT(width > 0);
508 }
509 ASSERT((width + lsbit) <= 32);
510 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
511 "#%d, #%d", lsbit, width);
512 return 1;
513 }
514 case 'h': { // 'h: halfword operation for extra loads and stores
515 if (instr->HasH()) {
516 Print("h");
517 } else {
518 Print("b");
519 }
520 return 1;
521 }
522 case 'i': { // 'i: immediate value from adjacent bits.
523 // Expects tokens in the form imm%02d@%02d, i.e. imm05@07, imm10@16
524 int width = (format[3] - '0') * 10 + (format[4] - '0');
525 int lsb = (format[6] - '0') * 10 + (format[7] - '0');
526
527 ASSERT((width >= 1) && (width <= 32));
528 ASSERT((lsb >= 0) && (lsb <= 31));
529 ASSERT((width + lsb) <= 32);
530
531 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
532 "%d",
533 instr->Bits(width + lsb - 1, lsb));
534 return 8;
535 }
536 case 'l': { // 'l: branch and link
537 if (instr->HasLink()) {
538 Print("l");
539 }
540 return 1;
541 }
542 case 'm': {
543 if (format[1] == 'w') {
544 // 'mw: movt/movw instructions.
545 PrintMovwMovt(instr);
546 return 2;
547 }
548 if (format[1] == 'e') { // 'memop: load/store instructions.
549 ASSERT(STRING_STARTS_WITH(format, "memop"));
550 if (instr->HasL()) {
551 Print("ldr");
552 } else {
553 if ((instr->Bits(27, 25) == 0) && (instr->Bit(20) == 0) &&
554 (instr->Bits(7, 6) == 3) && (instr->Bit(4) == 1)) {
555 if (instr->Bit(5) == 1) {
556 Print("strd");
557 } else {
558 Print("ldrd");
559 }
560 return 5;
561 }
562 Print("str");
563 }
564 return 5;
565 }
566 // 'msg: for simulator break instructions
567 ASSERT(STRING_STARTS_WITH(format, "msg"));
568 byte* str =
569 reinterpret_cast<byte*>(instr->InstructionBits() & 0x0fffffff);
570 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
571 "%s", converter_.NameInCode(str));
572 return 3;
573 }
574 case 'o': {
575 if ((format[3] == '1') && (format[4] == '2')) {
576 // 'off12: 12-bit offset for load and store instructions
577 ASSERT(STRING_STARTS_WITH(format, "off12"));
578 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
579 "%d", instr->Offset12Value());
580 return 5;
581 } else if (format[3] == '0') {
582 // 'off0to3and8to19 16-bit immediate encoded in bits 19-8 and 3-0.
583 ASSERT(STRING_STARTS_WITH(format, "off0to3and8to19"));
584 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
585 "%d",
586 (instr->Bits(19, 8) << 4) +
587 instr->Bits(3, 0));
588 return 15;
589 }
590 // 'off8: 8-bit offset for extra load and store instructions
591 ASSERT(STRING_STARTS_WITH(format, "off8"));
592 int offs8 = (instr->ImmedHValue() << 4) | instr->ImmedLValue();
593 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
594 "%d", offs8);
595 return 4;
596 }
597 case 'p': { // 'pu: P and U bits for load and store instructions
598 ASSERT(STRING_STARTS_WITH(format, "pu"));
599 PrintPU(instr);
600 return 2;
601 }
602 case 'r': {
603 return FormatRegister(instr, format);
604 }
605 case 's': {
606 if (format[1] == 'h') { // 'shift_op or 'shift_rm or 'shift_sat.
607 if (format[6] == 'o') { // 'shift_op
608 ASSERT(STRING_STARTS_WITH(format, "shift_op"));
609 if (instr->TypeValue() == 0) {
610 PrintShiftRm(instr);
611 } else {
612 ASSERT(instr->TypeValue() == 1);
613 PrintShiftImm(instr);
614 }
615 return 8;
616 } else if (format[6] == 's') { // 'shift_sat.
617 ASSERT(STRING_STARTS_WITH(format, "shift_sat"));
618 PrintShiftSat(instr);
619 return 9;
620 } else { // 'shift_rm
621 ASSERT(STRING_STARTS_WITH(format, "shift_rm"));
622 PrintShiftRm(instr);
623 return 8;
624 }
625 } else if (format[1] == 'v') { // 'svc
626 ASSERT(STRING_STARTS_WITH(format, "svc"));
627 PrintSoftwareInterrupt(instr->SvcValue());
628 return 3;
629 } else if (format[1] == 'i') { // 'sign: signed extra loads and stores
630 ASSERT(STRING_STARTS_WITH(format, "sign"));
631 if (instr->HasSign()) {
632 Print("s");
633 }
634 return 4;
635 }
636 // 's: S field of data processing instructions
637 if (instr->HasS()) {
638 Print("s");
639 }
640 return 1;
641 }
642 case 't': { // 'target: target of branch instructions
643 ASSERT(STRING_STARTS_WITH(format, "target"));
644 int off = (instr->SImmed24Value() << 2) + 8;
645 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
646 "%+d -> %s",
647 off,
648 converter_.NameOfAddress(
649 reinterpret_cast<byte*>(instr) + off));
650 return 6;
651 }
652 case 'u': { // 'u: signed or unsigned multiplies
653 // The manual gets the meaning of bit 22 backwards in the multiply
654 // instruction overview on page A3.16.2. The instructions that
655 // exist in u and s variants are the following:
656 // smull A4.1.87
657 // umull A4.1.129
658 // umlal A4.1.128
659 // smlal A4.1.76
660 // For these 0 means u and 1 means s. As can be seen on their individual
661 // pages. The other 18 mul instructions have the bit set or unset in
662 // arbitrary ways that are unrelated to the signedness of the instruction.
663 // None of these 18 instructions exist in both a 'u' and an 's' variant.
664
665 if (instr->Bit(22) == 0) {
666 Print("u");
667 } else {
668 Print("s");
669 }
670 return 1;
671 }
672 case 'v': {
673 return FormatVFPinstruction(instr, format);
674 }
675 case 'S':
676 case 'D': {
677 return FormatVFPRegister(instr, format);
678 }
679 case 'w': { // 'w: W field of load and store instructions
680 if (instr->HasW()) {
681 Print("!");
682 }
683 return 1;
684 }
685 default: {
686 UNREACHABLE();
687 break;
688 }
689 }
690 UNREACHABLE();
691 return -1;
692 }
693
694
695 // Format takes a formatting string for a whole instruction and prints it into
696 // the output buffer. All escaped options are handed to FormatOption to be
697 // parsed further.
Format(Instruction * instr,const char * format)698 void Decoder::Format(Instruction* instr, const char* format) {
699 char cur = *format++;
700 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
701 if (cur == '\'') { // Single quote is used as the formatting escape.
702 format += FormatOption(instr, format);
703 } else {
704 out_buffer_[out_buffer_pos_++] = cur;
705 }
706 cur = *format++;
707 }
708 out_buffer_[out_buffer_pos_] = '\0';
709 }
710
711
712 // The disassembler may end up decoding data inlined in the code. We do not want
713 // it to crash if the data does not ressemble any known instruction.
714 #define VERIFY(condition) \
715 if(!(condition)) { \
716 Unknown(instr); \
717 return; \
718 }
719
720
721 // For currently unimplemented decodings the disassembler calls Unknown(instr)
722 // which will just print "unknown" of the instruction bits.
Unknown(Instruction * instr)723 void Decoder::Unknown(Instruction* instr) {
724 Format(instr, "unknown");
725 }
726
727
DecodeType01(Instruction * instr)728 void Decoder::DecodeType01(Instruction* instr) {
729 int type = instr->TypeValue();
730 if ((type == 0) && instr->IsSpecialType0()) {
731 // multiply instruction or extra loads and stores
732 if (instr->Bits(7, 4) == 9) {
733 if (instr->Bit(24) == 0) {
734 // multiply instructions
735 if (instr->Bit(23) == 0) {
736 if (instr->Bit(21) == 0) {
737 // The MUL instruction description (A 4.1.33) refers to Rd as being
738 // the destination for the operation, but it confusingly uses the
739 // Rn field to encode it.
740 Format(instr, "mul'cond's 'rn, 'rm, 'rs");
741 } else {
742 if (instr->Bit(22) == 0) {
743 // The MLA instruction description (A 4.1.28) refers to the order
744 // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
745 // Rn field to encode the Rd register and the Rd field to encode
746 // the Rn register.
747 Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd");
748 } else {
749 // The MLS instruction description (A 4.1.29) refers to the order
750 // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
751 // Rn field to encode the Rd register and the Rd field to encode
752 // the Rn register.
753 Format(instr, "mls'cond's 'rn, 'rm, 'rs, 'rd");
754 }
755 }
756 } else {
757 // The signed/long multiply instructions use the terms RdHi and RdLo
758 // when referring to the target registers. They are mapped to the Rn
759 // and Rd fields as follows:
760 // RdLo == Rd field
761 // RdHi == Rn field
762 // The order of registers is: <RdLo>, <RdHi>, <Rm>, <Rs>
763 Format(instr, "'um'al'cond's 'rd, 'rn, 'rm, 'rs");
764 }
765 } else {
766 Unknown(instr); // not used by V8
767 }
768 } else if ((instr->Bit(20) == 0) && ((instr->Bits(7, 4) & 0xd) == 0xd)) {
769 // ldrd, strd
770 switch (instr->PUField()) {
771 case da_x: {
772 if (instr->Bit(22) == 0) {
773 Format(instr, "'memop'cond's 'rd, ['rn], -'rm");
774 } else {
775 Format(instr, "'memop'cond's 'rd, ['rn], #-'off8");
776 }
777 break;
778 }
779 case ia_x: {
780 if (instr->Bit(22) == 0) {
781 Format(instr, "'memop'cond's 'rd, ['rn], +'rm");
782 } else {
783 Format(instr, "'memop'cond's 'rd, ['rn], #+'off8");
784 }
785 break;
786 }
787 case db_x: {
788 if (instr->Bit(22) == 0) {
789 Format(instr, "'memop'cond's 'rd, ['rn, -'rm]'w");
790 } else {
791 Format(instr, "'memop'cond's 'rd, ['rn, #-'off8]'w");
792 }
793 break;
794 }
795 case ib_x: {
796 if (instr->Bit(22) == 0) {
797 Format(instr, "'memop'cond's 'rd, ['rn, +'rm]'w");
798 } else {
799 Format(instr, "'memop'cond's 'rd, ['rn, #+'off8]'w");
800 }
801 break;
802 }
803 default: {
804 // The PU field is a 2-bit field.
805 UNREACHABLE();
806 break;
807 }
808 }
809 } else {
810 // extra load/store instructions
811 switch (instr->PUField()) {
812 case da_x: {
813 if (instr->Bit(22) == 0) {
814 Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm");
815 } else {
816 Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8");
817 }
818 break;
819 }
820 case ia_x: {
821 if (instr->Bit(22) == 0) {
822 Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm");
823 } else {
824 Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8");
825 }
826 break;
827 }
828 case db_x: {
829 if (instr->Bit(22) == 0) {
830 Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w");
831 } else {
832 Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w");
833 }
834 break;
835 }
836 case ib_x: {
837 if (instr->Bit(22) == 0) {
838 Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w");
839 } else {
840 Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w");
841 }
842 break;
843 }
844 default: {
845 // The PU field is a 2-bit field.
846 UNREACHABLE();
847 break;
848 }
849 }
850 return;
851 }
852 } else if ((type == 0) && instr->IsMiscType0()) {
853 if (instr->Bits(22, 21) == 1) {
854 switch (instr->BitField(7, 4)) {
855 case BX:
856 Format(instr, "bx'cond 'rm");
857 break;
858 case BLX:
859 Format(instr, "blx'cond 'rm");
860 break;
861 case BKPT:
862 Format(instr, "bkpt 'off0to3and8to19");
863 break;
864 default:
865 Unknown(instr); // not used by V8
866 break;
867 }
868 } else if (instr->Bits(22, 21) == 3) {
869 switch (instr->BitField(7, 4)) {
870 case CLZ:
871 Format(instr, "clz'cond 'rd, 'rm");
872 break;
873 default:
874 Unknown(instr); // not used by V8
875 break;
876 }
877 } else {
878 Unknown(instr); // not used by V8
879 }
880 } else if ((type == 1) && instr->IsNopType1()) {
881 Format(instr, "nop'cond");
882 } else {
883 switch (instr->OpcodeField()) {
884 case AND: {
885 Format(instr, "and'cond's 'rd, 'rn, 'shift_op");
886 break;
887 }
888 case EOR: {
889 Format(instr, "eor'cond's 'rd, 'rn, 'shift_op");
890 break;
891 }
892 case SUB: {
893 Format(instr, "sub'cond's 'rd, 'rn, 'shift_op");
894 break;
895 }
896 case RSB: {
897 Format(instr, "rsb'cond's 'rd, 'rn, 'shift_op");
898 break;
899 }
900 case ADD: {
901 Format(instr, "add'cond's 'rd, 'rn, 'shift_op");
902 break;
903 }
904 case ADC: {
905 Format(instr, "adc'cond's 'rd, 'rn, 'shift_op");
906 break;
907 }
908 case SBC: {
909 Format(instr, "sbc'cond's 'rd, 'rn, 'shift_op");
910 break;
911 }
912 case RSC: {
913 Format(instr, "rsc'cond's 'rd, 'rn, 'shift_op");
914 break;
915 }
916 case TST: {
917 if (instr->HasS()) {
918 Format(instr, "tst'cond 'rn, 'shift_op");
919 } else {
920 Format(instr, "movw'cond 'mw");
921 }
922 break;
923 }
924 case TEQ: {
925 if (instr->HasS()) {
926 Format(instr, "teq'cond 'rn, 'shift_op");
927 } else {
928 // Other instructions matching this pattern are handled in the
929 // miscellaneous instructions part above.
930 UNREACHABLE();
931 }
932 break;
933 }
934 case CMP: {
935 if (instr->HasS()) {
936 Format(instr, "cmp'cond 'rn, 'shift_op");
937 } else {
938 Format(instr, "movt'cond 'mw");
939 }
940 break;
941 }
942 case CMN: {
943 if (instr->HasS()) {
944 Format(instr, "cmn'cond 'rn, 'shift_op");
945 } else {
946 // Other instructions matching this pattern are handled in the
947 // miscellaneous instructions part above.
948 UNREACHABLE();
949 }
950 break;
951 }
952 case ORR: {
953 Format(instr, "orr'cond's 'rd, 'rn, 'shift_op");
954 break;
955 }
956 case MOV: {
957 Format(instr, "mov'cond's 'rd, 'shift_op");
958 break;
959 }
960 case BIC: {
961 Format(instr, "bic'cond's 'rd, 'rn, 'shift_op");
962 break;
963 }
964 case MVN: {
965 Format(instr, "mvn'cond's 'rd, 'shift_op");
966 break;
967 }
968 default: {
969 // The Opcode field is a 4-bit field.
970 UNREACHABLE();
971 break;
972 }
973 }
974 }
975 }
976
977
DecodeType2(Instruction * instr)978 void Decoder::DecodeType2(Instruction* instr) {
979 switch (instr->PUField()) {
980 case da_x: {
981 if (instr->HasW()) {
982 Unknown(instr); // not used in V8
983 return;
984 }
985 Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
986 break;
987 }
988 case ia_x: {
989 if (instr->HasW()) {
990 Unknown(instr); // not used in V8
991 return;
992 }
993 Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
994 break;
995 }
996 case db_x: {
997 Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w");
998 break;
999 }
1000 case ib_x: {
1001 Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w");
1002 break;
1003 }
1004 default: {
1005 // The PU field is a 2-bit field.
1006 UNREACHABLE();
1007 break;
1008 }
1009 }
1010 }
1011
1012
DecodeType3(Instruction * instr)1013 void Decoder::DecodeType3(Instruction* instr) {
1014 switch (instr->PUField()) {
1015 case da_x: {
1016 VERIFY(!instr->HasW());
1017 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
1018 break;
1019 }
1020 case ia_x: {
1021 if (instr->Bit(4) == 0) {
1022 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
1023 } else {
1024 if (instr->Bit(5) == 0) {
1025 switch (instr->Bits(22, 21)) {
1026 case 0:
1027 if (instr->Bit(20) == 0) {
1028 if (instr->Bit(6) == 0) {
1029 Format(instr, "pkhbt'cond 'rd, 'rn, 'rm, lsl #'imm05@07");
1030 } else {
1031 if (instr->Bits(11, 7) == 0) {
1032 Format(instr, "pkhtb'cond 'rd, 'rn, 'rm, asr #32");
1033 } else {
1034 Format(instr, "pkhtb'cond 'rd, 'rn, 'rm, asr #'imm05@07");
1035 }
1036 }
1037 } else {
1038 UNREACHABLE();
1039 }
1040 break;
1041 case 1:
1042 UNREACHABLE();
1043 break;
1044 case 2:
1045 UNREACHABLE();
1046 break;
1047 case 3:
1048 Format(instr, "usat 'rd, #'imm05@16, 'rm'shift_sat");
1049 break;
1050 }
1051 } else {
1052 switch (instr->Bits(22, 21)) {
1053 case 0:
1054 UNREACHABLE();
1055 break;
1056 case 1:
1057 UNREACHABLE();
1058 break;
1059 case 2:
1060 if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
1061 if (instr->Bits(19, 16) == 0xF) {
1062 switch (instr->Bits(11, 10)) {
1063 case 0:
1064 Format(instr, "uxtb16'cond 'rd, 'rm, ror #0");
1065 break;
1066 case 1:
1067 Format(instr, "uxtb16'cond 'rd, 'rm, ror #8");
1068 break;
1069 case 2:
1070 Format(instr, "uxtb16'cond 'rd, 'rm, ror #16");
1071 break;
1072 case 3:
1073 Format(instr, "uxtb16'cond 'rd, 'rm, ror #24");
1074 break;
1075 }
1076 } else {
1077 UNREACHABLE();
1078 }
1079 } else {
1080 UNREACHABLE();
1081 }
1082 break;
1083 case 3:
1084 if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
1085 if (instr->Bits(19, 16) == 0xF) {
1086 switch (instr->Bits(11, 10)) {
1087 case 0:
1088 Format(instr, "uxtb'cond 'rd, 'rm, ror #0");
1089 break;
1090 case 1:
1091 Format(instr, "uxtb'cond 'rd, 'rm, ror #8");
1092 break;
1093 case 2:
1094 Format(instr, "uxtb'cond 'rd, 'rm, ror #16");
1095 break;
1096 case 3:
1097 Format(instr, "uxtb'cond 'rd, 'rm, ror #24");
1098 break;
1099 }
1100 } else {
1101 switch (instr->Bits(11, 10)) {
1102 case 0:
1103 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #0");
1104 break;
1105 case 1:
1106 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #8");
1107 break;
1108 case 2:
1109 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #16");
1110 break;
1111 case 3:
1112 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #24");
1113 break;
1114 }
1115 }
1116 } else {
1117 UNREACHABLE();
1118 }
1119 break;
1120 }
1121 }
1122 }
1123 break;
1124 }
1125 case db_x: {
1126 if (FLAG_enable_sudiv) {
1127 if (!instr->HasW()) {
1128 if (instr->Bits(5, 4) == 0x1) {
1129 if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) {
1130 // SDIV (in V8 notation matching ARM ISA format) rn = rm/rs
1131 Format(instr, "sdiv'cond'b 'rn, 'rm, 'rs");
1132 break;
1133 }
1134 }
1135 }
1136 }
1137 Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
1138 break;
1139 }
1140 case ib_x: {
1141 if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) {
1142 uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16));
1143 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
1144 uint32_t msbit = widthminus1 + lsbit;
1145 if (msbit <= 31) {
1146 if (instr->Bit(22)) {
1147 Format(instr, "ubfx'cond 'rd, 'rm, 'f");
1148 } else {
1149 Format(instr, "sbfx'cond 'rd, 'rm, 'f");
1150 }
1151 } else {
1152 UNREACHABLE();
1153 }
1154 } else if (!instr->HasW() && (instr->Bits(6, 4) == 0x1)) {
1155 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
1156 uint32_t msbit = static_cast<uint32_t>(instr->Bits(20, 16));
1157 if (msbit >= lsbit) {
1158 if (instr->RmValue() == 15) {
1159 Format(instr, "bfc'cond 'rd, 'f");
1160 } else {
1161 Format(instr, "bfi'cond 'rd, 'rm, 'f");
1162 }
1163 } else {
1164 UNREACHABLE();
1165 }
1166 } else {
1167 Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
1168 }
1169 break;
1170 }
1171 default: {
1172 // The PU field is a 2-bit field.
1173 UNREACHABLE();
1174 break;
1175 }
1176 }
1177 }
1178
1179
DecodeType4(Instruction * instr)1180 void Decoder::DecodeType4(Instruction* instr) {
1181 if (instr->Bit(22) != 0) {
1182 // Privileged mode currently not supported.
1183 Unknown(instr);
1184 } else {
1185 if (instr->HasL()) {
1186 Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
1187 } else {
1188 Format(instr, "stm'cond'pu 'rn'w, 'rlist");
1189 }
1190 }
1191 }
1192
1193
DecodeType5(Instruction * instr)1194 void Decoder::DecodeType5(Instruction* instr) {
1195 Format(instr, "b'l'cond 'target");
1196 }
1197
1198
DecodeType6(Instruction * instr)1199 void Decoder::DecodeType6(Instruction* instr) {
1200 DecodeType6CoprocessorIns(instr);
1201 }
1202
1203
DecodeType7(Instruction * instr)1204 int Decoder::DecodeType7(Instruction* instr) {
1205 if (instr->Bit(24) == 1) {
1206 if (instr->SvcValue() >= kStopCode) {
1207 Format(instr, "stop'cond 'svc");
1208 // Also print the stop message. Its address is encoded
1209 // in the following 4 bytes.
1210 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1211 "\n %p %08x stop message: %s",
1212 reinterpret_cast<int32_t*>(instr
1213 + Instruction::kInstrSize),
1214 *reinterpret_cast<char**>(instr
1215 + Instruction::kInstrSize),
1216 *reinterpret_cast<char**>(instr
1217 + Instruction::kInstrSize));
1218 // We have decoded 2 * Instruction::kInstrSize bytes.
1219 return 2 * Instruction::kInstrSize;
1220 } else {
1221 Format(instr, "svc'cond 'svc");
1222 }
1223 } else {
1224 DecodeTypeVFP(instr);
1225 }
1226 return Instruction::kInstrSize;
1227 }
1228
1229
1230 // void Decoder::DecodeTypeVFP(Instruction* instr)
1231 // vmov: Sn = Rt
1232 // vmov: Rt = Sn
1233 // vcvt: Dd = Sm
1234 // vcvt: Sd = Dm
1235 // vcvt.f64.s32 Dd, Dd, #<fbits>
1236 // Dd = vabs(Dm)
1237 // Dd = vneg(Dm)
1238 // Dd = vadd(Dn, Dm)
1239 // Dd = vsub(Dn, Dm)
1240 // Dd = vmul(Dn, Dm)
1241 // Dd = vmla(Dn, Dm)
1242 // Dd = vmls(Dn, Dm)
1243 // Dd = vdiv(Dn, Dm)
1244 // vcmp(Dd, Dm)
1245 // vmrs
1246 // vmsr
1247 // Dd = vsqrt(Dm)
DecodeTypeVFP(Instruction * instr)1248 void Decoder::DecodeTypeVFP(Instruction* instr) {
1249 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) );
1250 VERIFY(instr->Bits(11, 9) == 0x5);
1251
1252 if (instr->Bit(4) == 0) {
1253 if (instr->Opc1Value() == 0x7) {
1254 // Other data processing instructions
1255 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) {
1256 // vmov register to register.
1257 if (instr->SzValue() == 0x1) {
1258 Format(instr, "vmov'cond.f64 'Dd, 'Dm");
1259 } else {
1260 Format(instr, "vmov'cond.f32 'Sd, 'Sm");
1261 }
1262 } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) {
1263 // vabs
1264 Format(instr, "vabs'cond.f64 'Dd, 'Dm");
1265 } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) {
1266 // vneg
1267 Format(instr, "vneg'cond.f64 'Dd, 'Dm");
1268 } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) {
1269 DecodeVCVTBetweenDoubleAndSingle(instr);
1270 } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) {
1271 DecodeVCVTBetweenFloatingPointAndInteger(instr);
1272 } else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) &&
1273 (instr->Bit(8) == 1)) {
1274 // vcvt.f64.s32 Dd, Dd, #<fbits>
1275 int fraction_bits = 32 - ((instr->Bit(5) << 4) | instr->Bits(3, 0));
1276 Format(instr, "vcvt'cond.f64.s32 'Dd, 'Dd");
1277 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1278 ", #%d", fraction_bits);
1279 } else if (((instr->Opc2Value() >> 1) == 0x6) &&
1280 (instr->Opc3Value() & 0x1)) {
1281 DecodeVCVTBetweenFloatingPointAndInteger(instr);
1282 } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
1283 (instr->Opc3Value() & 0x1)) {
1284 DecodeVCMP(instr);
1285 } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) {
1286 Format(instr, "vsqrt'cond.f64 'Dd, 'Dm");
1287 } else if (instr->Opc3Value() == 0x0) {
1288 if (instr->SzValue() == 0x1) {
1289 Format(instr, "vmov'cond.f64 'Dd, 'd");
1290 } else {
1291 Unknown(instr); // Not used by V8.
1292 }
1293 } else {
1294 Unknown(instr); // Not used by V8.
1295 }
1296 } else if (instr->Opc1Value() == 0x3) {
1297 if (instr->SzValue() == 0x1) {
1298 if (instr->Opc3Value() & 0x1) {
1299 Format(instr, "vsub'cond.f64 'Dd, 'Dn, 'Dm");
1300 } else {
1301 Format(instr, "vadd'cond.f64 'Dd, 'Dn, 'Dm");
1302 }
1303 } else {
1304 Unknown(instr); // Not used by V8.
1305 }
1306 } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) {
1307 if (instr->SzValue() == 0x1) {
1308 Format(instr, "vmul'cond.f64 'Dd, 'Dn, 'Dm");
1309 } else {
1310 Unknown(instr); // Not used by V8.
1311 }
1312 } else if ((instr->Opc1Value() == 0x0) && !(instr->Opc3Value() & 0x1)) {
1313 if (instr->SzValue() == 0x1) {
1314 Format(instr, "vmla'cond.f64 'Dd, 'Dn, 'Dm");
1315 } else {
1316 Unknown(instr); // Not used by V8.
1317 }
1318 } else if ((instr->Opc1Value() == 0x0) && (instr->Opc3Value() & 0x1)) {
1319 if (instr->SzValue() == 0x1) {
1320 Format(instr, "vmls'cond.f64 'Dd, 'Dn, 'Dm");
1321 } else {
1322 Unknown(instr); // Not used by V8.
1323 }
1324 } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) {
1325 if (instr->SzValue() == 0x1) {
1326 Format(instr, "vdiv'cond.f64 'Dd, 'Dn, 'Dm");
1327 } else {
1328 Unknown(instr); // Not used by V8.
1329 }
1330 } else {
1331 Unknown(instr); // Not used by V8.
1332 }
1333 } else {
1334 if ((instr->VCValue() == 0x0) &&
1335 (instr->VAValue() == 0x0)) {
1336 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
1337 } else if ((instr->VLValue() == 0x0) &&
1338 (instr->VCValue() == 0x1) &&
1339 (instr->Bit(23) == 0x0)) {
1340 if (instr->Bit(21) == 0x0) {
1341 Format(instr, "vmov'cond.32 'Dd[0], 'rt");
1342 } else {
1343 Format(instr, "vmov'cond.32 'Dd[1], 'rt");
1344 }
1345 } else if ((instr->VLValue() == 0x1) &&
1346 (instr->VCValue() == 0x1) &&
1347 (instr->Bit(23) == 0x0)) {
1348 if (instr->Bit(21) == 0x0) {
1349 Format(instr, "vmov'cond.32 'rt, 'Dd[0]");
1350 } else {
1351 Format(instr, "vmov'cond.32 'rt, 'Dd[1]");
1352 }
1353 } else if ((instr->VCValue() == 0x0) &&
1354 (instr->VAValue() == 0x7) &&
1355 (instr->Bits(19, 16) == 0x1)) {
1356 if (instr->VLValue() == 0) {
1357 if (instr->Bits(15, 12) == 0xF) {
1358 Format(instr, "vmsr'cond FPSCR, APSR");
1359 } else {
1360 Format(instr, "vmsr'cond FPSCR, 'rt");
1361 }
1362 } else {
1363 if (instr->Bits(15, 12) == 0xF) {
1364 Format(instr, "vmrs'cond APSR, FPSCR");
1365 } else {
1366 Format(instr, "vmrs'cond 'rt, FPSCR");
1367 }
1368 }
1369 }
1370 }
1371 }
1372
1373
DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction * instr)1374 void Decoder::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(
1375 Instruction* instr) {
1376 VERIFY((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) &&
1377 (instr->VAValue() == 0x0));
1378
1379 bool to_arm_register = (instr->VLValue() == 0x1);
1380
1381 if (to_arm_register) {
1382 Format(instr, "vmov'cond 'rt, 'Sn");
1383 } else {
1384 Format(instr, "vmov'cond 'Sn, 'rt");
1385 }
1386 }
1387
1388
DecodeVCMP(Instruction * instr)1389 void Decoder::DecodeVCMP(Instruction* instr) {
1390 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
1391 VERIFY(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
1392 (instr->Opc3Value() & 0x1));
1393
1394 // Comparison.
1395 bool dp_operation = (instr->SzValue() == 1);
1396 bool raise_exception_for_qnan = (instr->Bit(7) == 0x1);
1397
1398 if (dp_operation && !raise_exception_for_qnan) {
1399 if (instr->Opc2Value() == 0x4) {
1400 Format(instr, "vcmp'cond.f64 'Dd, 'Dm");
1401 } else if (instr->Opc2Value() == 0x5) {
1402 Format(instr, "vcmp'cond.f64 'Dd, #0.0");
1403 } else {
1404 Unknown(instr); // invalid
1405 }
1406 } else {
1407 Unknown(instr); // Not used by V8.
1408 }
1409 }
1410
1411
DecodeVCVTBetweenDoubleAndSingle(Instruction * instr)1412 void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) {
1413 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
1414 VERIFY((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3));
1415
1416 bool double_to_single = (instr->SzValue() == 1);
1417
1418 if (double_to_single) {
1419 Format(instr, "vcvt'cond.f32.f64 'Sd, 'Dm");
1420 } else {
1421 Format(instr, "vcvt'cond.f64.f32 'Dd, 'Sm");
1422 }
1423 }
1424
1425
DecodeVCVTBetweenFloatingPointAndInteger(Instruction * instr)1426 void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) {
1427 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
1428 VERIFY(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) ||
1429 (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1)));
1430
1431 bool to_integer = (instr->Bit(18) == 1);
1432 bool dp_operation = (instr->SzValue() == 1);
1433 if (to_integer) {
1434 bool unsigned_integer = (instr->Bit(16) == 0);
1435
1436 if (dp_operation) {
1437 if (unsigned_integer) {
1438 Format(instr, "vcvt'cond.u32.f64 'Sd, 'Dm");
1439 } else {
1440 Format(instr, "vcvt'cond.s32.f64 'Sd, 'Dm");
1441 }
1442 } else {
1443 if (unsigned_integer) {
1444 Format(instr, "vcvt'cond.u32.f32 'Sd, 'Sm");
1445 } else {
1446 Format(instr, "vcvt'cond.s32.f32 'Sd, 'Sm");
1447 }
1448 }
1449 } else {
1450 bool unsigned_integer = (instr->Bit(7) == 0);
1451
1452 if (dp_operation) {
1453 if (unsigned_integer) {
1454 Format(instr, "vcvt'cond.f64.u32 'Dd, 'Sm");
1455 } else {
1456 Format(instr, "vcvt'cond.f64.s32 'Dd, 'Sm");
1457 }
1458 } else {
1459 if (unsigned_integer) {
1460 Format(instr, "vcvt'cond.f32.u32 'Sd, 'Sm");
1461 } else {
1462 Format(instr, "vcvt'cond.f32.s32 'Sd, 'Sm");
1463 }
1464 }
1465 }
1466 }
1467
1468
1469 // Decode Type 6 coprocessor instructions.
1470 // Dm = vmov(Rt, Rt2)
1471 // <Rt, Rt2> = vmov(Dm)
1472 // Ddst = MEM(Rbase + 4*offset).
1473 // MEM(Rbase + 4*offset) = Dsrc.
DecodeType6CoprocessorIns(Instruction * instr)1474 void Decoder::DecodeType6CoprocessorIns(Instruction* instr) {
1475 VERIFY(instr->TypeValue() == 6);
1476
1477 if (instr->CoprocessorValue() == 0xA) {
1478 switch (instr->OpcodeValue()) {
1479 case 0x8:
1480 case 0xA:
1481 if (instr->HasL()) {
1482 Format(instr, "vldr'cond 'Sd, ['rn - 4*'imm08@00]");
1483 } else {
1484 Format(instr, "vstr'cond 'Sd, ['rn - 4*'imm08@00]");
1485 }
1486 break;
1487 case 0xC:
1488 case 0xE:
1489 if (instr->HasL()) {
1490 Format(instr, "vldr'cond 'Sd, ['rn + 4*'imm08@00]");
1491 } else {
1492 Format(instr, "vstr'cond 'Sd, ['rn + 4*'imm08@00]");
1493 }
1494 break;
1495 case 0x4:
1496 case 0x5:
1497 case 0x6:
1498 case 0x7:
1499 case 0x9:
1500 case 0xB: {
1501 bool to_vfp_register = (instr->VLValue() == 0x1);
1502 if (to_vfp_register) {
1503 Format(instr, "vldm'cond'pu 'rn'w, {'Sd-'Sd+}");
1504 } else {
1505 Format(instr, "vstm'cond'pu 'rn'w, {'Sd-'Sd+}");
1506 }
1507 break;
1508 }
1509 default:
1510 Unknown(instr); // Not used by V8.
1511 }
1512 } else if (instr->CoprocessorValue() == 0xB) {
1513 switch (instr->OpcodeValue()) {
1514 case 0x2:
1515 // Load and store double to two GP registers
1516 if (instr->Bits(7, 6) != 0 || instr->Bit(4) != 1) {
1517 Unknown(instr); // Not used by V8.
1518 } else if (instr->HasL()) {
1519 Format(instr, "vmov'cond 'rt, 'rn, 'Dm");
1520 } else {
1521 Format(instr, "vmov'cond 'Dm, 'rt, 'rn");
1522 }
1523 break;
1524 case 0x8:
1525 case 0xA:
1526 if (instr->HasL()) {
1527 Format(instr, "vldr'cond 'Dd, ['rn - 4*'imm08@00]");
1528 } else {
1529 Format(instr, "vstr'cond 'Dd, ['rn - 4*'imm08@00]");
1530 }
1531 break;
1532 case 0xC:
1533 case 0xE:
1534 if (instr->HasL()) {
1535 Format(instr, "vldr'cond 'Dd, ['rn + 4*'imm08@00]");
1536 } else {
1537 Format(instr, "vstr'cond 'Dd, ['rn + 4*'imm08@00]");
1538 }
1539 break;
1540 case 0x4:
1541 case 0x5:
1542 case 0x6:
1543 case 0x7:
1544 case 0x9:
1545 case 0xB: {
1546 bool to_vfp_register = (instr->VLValue() == 0x1);
1547 if (to_vfp_register) {
1548 Format(instr, "vldm'cond'pu 'rn'w, {'Dd-'Dd+}");
1549 } else {
1550 Format(instr, "vstm'cond'pu 'rn'w, {'Dd-'Dd+}");
1551 }
1552 break;
1553 }
1554 default:
1555 Unknown(instr); // Not used by V8.
1556 }
1557 } else {
1558 Unknown(instr); // Not used by V8.
1559 }
1560 }
1561
1562
DecodeSpecialCondition(Instruction * instr)1563 void Decoder::DecodeSpecialCondition(Instruction* instr) {
1564 switch (instr->SpecialValue()) {
1565 case 5:
1566 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
1567 (instr->Bit(4) == 1)) {
1568 // vmovl signed
1569 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
1570 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
1571 int imm3 = instr->Bits(21, 19);
1572 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1573 "vmovl.s%d q%d, d%d", imm3*8, Vd, Vm);
1574 } else {
1575 Unknown(instr);
1576 }
1577 break;
1578 case 7:
1579 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
1580 (instr->Bit(4) == 1)) {
1581 // vmovl unsigned
1582 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
1583 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
1584 int imm3 = instr->Bits(21, 19);
1585 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1586 "vmovl.u%d q%d, d%d", imm3*8, Vd, Vm);
1587 } else {
1588 Unknown(instr);
1589 }
1590 break;
1591 case 8:
1592 if (instr->Bits(21, 20) == 0) {
1593 // vst1
1594 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
1595 int Rn = instr->VnValue();
1596 int type = instr->Bits(11, 8);
1597 int size = instr->Bits(7, 6);
1598 int align = instr->Bits(5, 4);
1599 int Rm = instr->VmValue();
1600 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1601 "vst1.%d ", (1 << size) << 3);
1602 FormatNeonList(Vd, type);
1603 Print(", ");
1604 FormatNeonMemory(Rn, align, Rm);
1605 } else if (instr->Bits(21, 20) == 2) {
1606 // vld1
1607 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
1608 int Rn = instr->VnValue();
1609 int type = instr->Bits(11, 8);
1610 int size = instr->Bits(7, 6);
1611 int align = instr->Bits(5, 4);
1612 int Rm = instr->VmValue();
1613 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1614 "vld1.%d ", (1 << size) << 3);
1615 FormatNeonList(Vd, type);
1616 Print(", ");
1617 FormatNeonMemory(Rn, align, Rm);
1618 } else {
1619 Unknown(instr);
1620 }
1621 break;
1622 case 0xA:
1623 case 0xB:
1624 if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) {
1625 int Rn = instr->Bits(19, 16);
1626 int offset = instr->Bits(11, 0);
1627 if (offset == 0) {
1628 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1629 "pld [r%d]", Rn);
1630 } else if (instr->Bit(23) == 0) {
1631 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1632 "pld [r%d, #-%d]", Rn, offset);
1633 } else {
1634 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1635 "pld [r%d, #+%d]", Rn, offset);
1636 }
1637 } else {
1638 Unknown(instr);
1639 }
1640 break;
1641 default:
1642 Unknown(instr);
1643 break;
1644 }
1645 }
1646
1647 #undef VERIFIY
1648
IsConstantPoolAt(byte * instr_ptr)1649 bool Decoder::IsConstantPoolAt(byte* instr_ptr) {
1650 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr));
1651 return (instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker;
1652 }
1653
1654
ConstantPoolSizeAt(byte * instr_ptr)1655 int Decoder::ConstantPoolSizeAt(byte* instr_ptr) {
1656 if (IsConstantPoolAt(instr_ptr)) {
1657 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr));
1658 return DecodeConstantPoolLength(instruction_bits);
1659 } else {
1660 return -1;
1661 }
1662 }
1663
1664
1665 // Disassemble the instruction at *instr_ptr into the output buffer.
InstructionDecode(byte * instr_ptr)1666 int Decoder::InstructionDecode(byte* instr_ptr) {
1667 Instruction* instr = Instruction::At(instr_ptr);
1668 // Print raw instruction bytes.
1669 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1670 "%08x ",
1671 instr->InstructionBits());
1672 if (instr->ConditionField() == kSpecialCondition) {
1673 DecodeSpecialCondition(instr);
1674 return Instruction::kInstrSize;
1675 }
1676 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr));
1677 if ((instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker) {
1678 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1679 "constant pool begin (length %d)",
1680 DecodeConstantPoolLength(instruction_bits));
1681 return Instruction::kInstrSize;
1682 } else if (instruction_bits == kCodeAgeJumpInstruction) {
1683 // The code age prologue has a constant immediatly following the jump
1684 // instruction.
1685 Instruction* target = Instruction::At(instr_ptr + Instruction::kInstrSize);
1686 DecodeType2(instr);
1687 OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1688 " (0x%08x)", target->InstructionBits());
1689 return 2 * Instruction::kInstrSize;
1690 }
1691 switch (instr->TypeValue()) {
1692 case 0:
1693 case 1: {
1694 DecodeType01(instr);
1695 break;
1696 }
1697 case 2: {
1698 DecodeType2(instr);
1699 break;
1700 }
1701 case 3: {
1702 DecodeType3(instr);
1703 break;
1704 }
1705 case 4: {
1706 DecodeType4(instr);
1707 break;
1708 }
1709 case 5: {
1710 DecodeType5(instr);
1711 break;
1712 }
1713 case 6: {
1714 DecodeType6(instr);
1715 break;
1716 }
1717 case 7: {
1718 return DecodeType7(instr);
1719 }
1720 default: {
1721 // The type field is 3-bits in the ARM encoding.
1722 UNREACHABLE();
1723 break;
1724 }
1725 }
1726 return Instruction::kInstrSize;
1727 }
1728
1729
1730 } } // namespace v8::internal
1731
1732
1733
1734 //------------------------------------------------------------------------------
1735
1736 namespace disasm {
1737
1738
NameOfAddress(byte * addr) const1739 const char* NameConverter::NameOfAddress(byte* addr) const {
1740 v8::internal::OS::SNPrintF(tmp_buffer_, "%p", addr);
1741 return tmp_buffer_.start();
1742 }
1743
1744
NameOfConstant(byte * addr) const1745 const char* NameConverter::NameOfConstant(byte* addr) const {
1746 return NameOfAddress(addr);
1747 }
1748
1749
NameOfCPURegister(int reg) const1750 const char* NameConverter::NameOfCPURegister(int reg) const {
1751 return v8::internal::Registers::Name(reg);
1752 }
1753
1754
NameOfByteCPURegister(int reg) const1755 const char* NameConverter::NameOfByteCPURegister(int reg) const {
1756 UNREACHABLE(); // ARM does not have the concept of a byte register
1757 return "nobytereg";
1758 }
1759
1760
NameOfXMMRegister(int reg) const1761 const char* NameConverter::NameOfXMMRegister(int reg) const {
1762 UNREACHABLE(); // ARM does not have any XMM registers
1763 return "noxmmreg";
1764 }
1765
1766
NameInCode(byte * addr) const1767 const char* NameConverter::NameInCode(byte* addr) const {
1768 // The default name converter is called for unknown code. So we will not try
1769 // to access any memory.
1770 return "";
1771 }
1772
1773
1774 //------------------------------------------------------------------------------
1775
Disassembler(const NameConverter & converter)1776 Disassembler::Disassembler(const NameConverter& converter)
1777 : converter_(converter) {}
1778
1779
~Disassembler()1780 Disassembler::~Disassembler() {}
1781
1782
InstructionDecode(v8::internal::Vector<char> buffer,byte * instruction)1783 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
1784 byte* instruction) {
1785 v8::internal::Decoder d(converter_, buffer);
1786 return d.InstructionDecode(instruction);
1787 }
1788
1789
ConstantPoolSizeAt(byte * instruction)1790 int Disassembler::ConstantPoolSizeAt(byte* instruction) {
1791 return v8::internal::Decoder::ConstantPoolSizeAt(instruction);
1792 }
1793
1794
Disassemble(FILE * f,byte * begin,byte * end)1795 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
1796 NameConverter converter;
1797 Disassembler d(converter);
1798 for (byte* pc = begin; pc < end;) {
1799 v8::internal::EmbeddedVector<char, 128> buffer;
1800 buffer[0] = '\0';
1801 byte* prev_pc = pc;
1802 pc += d.InstructionDecode(buffer, pc);
1803 v8::internal::PrintF(
1804 f, "%p %08x %s\n",
1805 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
1806 }
1807 }
1808
1809
1810 } // namespace disasm
1811
1812 #endif // V8_TARGET_ARCH_ARM
1813