blob: 2f9e78f534295c0aa2693f061ede0e98fd3c4937 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2007-2009 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// char buffer[128];
38// buffer[0] = '\0';
39// byte* prev_pc = pc;
40// pc += d.InstructionDecode(buffer, sizeof buffer, pc);
41// printf("%p %08x %s\n",
42// prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
43// }
44//
45// The Disassembler class also has a convenience method to disassemble a block
46// of code into a FILE*, meaning that the above functionality could also be
47// achieved by just calling Disassembler::Disassemble(stdout, begin, end);
48
49
50#include <assert.h>
51#include <stdio.h>
52#include <stdarg.h>
53#include <string.h>
54#ifndef WIN32
55#include <stdint.h>
56#endif
57
58#include "v8.h"
59
60#include "constants-arm.h"
61#include "disasm.h"
62#include "macro-assembler.h"
63#include "platform.h"
64
65
66namespace assembler {
67namespace arm {
68
69namespace v8i = v8::internal;
70
71
72//------------------------------------------------------------------------------
73
74// Decoder decodes and disassembles instructions into an output buffer.
75// It uses the converter to convert register names and call destinations into
76// more informative description.
77class Decoder {
78 public:
79 Decoder(const disasm::NameConverter& converter,
80 v8::internal::Vector<char> out_buffer)
81 : converter_(converter),
82 out_buffer_(out_buffer),
83 out_buffer_pos_(0) {
84 out_buffer_[out_buffer_pos_] = '\0';
85 }
86
87 ~Decoder() {}
88
89 // Writes one disassembled instruction into 'buffer' (0-terminated).
90 // Returns the length of the disassembled machine instruction in bytes.
91 int InstructionDecode(byte* instruction);
92
93 private:
94 // Bottleneck functions to print into the out_buffer.
95 void PrintChar(const char ch);
96 void Print(const char* str);
97
98 // Printing of common values.
99 void PrintRegister(int reg);
Steve Blockd0582a62009-12-15 09:54:21 +0000100 void PrintSRegister(int reg);
101 void PrintDRegister(int reg);
102 int FormatVFPRegister(Instr* instr, const char* format);
103 int FormatVFPinstruction(Instr* instr, const char* format);
Steve Blocka7e24c12009-10-30 11:49:00 +0000104 void PrintCondition(Instr* instr);
105 void PrintShiftRm(Instr* instr);
106 void PrintShiftImm(Instr* instr);
107 void PrintPU(Instr* instr);
108 void PrintSoftwareInterrupt(SoftwareInterruptCodes swi);
109
110 // Handle formatting of instructions and their options.
111 int FormatRegister(Instr* instr, const char* option);
112 int FormatOption(Instr* instr, const char* option);
113 void Format(Instr* instr, const char* format);
114 void Unknown(Instr* instr);
115
116 // Each of these functions decodes one particular instruction type, a 3-bit
117 // field in the instruction encoding.
118 // Types 0 and 1 are combined as they are largely the same except for the way
119 // they interpret the shifter operand.
120 void DecodeType01(Instr* instr);
121 void DecodeType2(Instr* instr);
122 void DecodeType3(Instr* instr);
123 void DecodeType4(Instr* instr);
124 void DecodeType5(Instr* instr);
125 void DecodeType6(Instr* instr);
126 void DecodeType7(Instr* instr);
127 void DecodeUnconditional(Instr* instr);
Steve Blockd0582a62009-12-15 09:54:21 +0000128 // For VFP support.
129 void DecodeTypeVFP(Instr* instr);
130 void DecodeType6CoprocessorIns(Instr* instr);
131
Steve Blocka7e24c12009-10-30 11:49:00 +0000132
133 const disasm::NameConverter& converter_;
134 v8::internal::Vector<char> out_buffer_;
135 int out_buffer_pos_;
136
137 DISALLOW_COPY_AND_ASSIGN(Decoder);
138};
139
140
141// Support for assertions in the Decoder formatting functions.
142#define STRING_STARTS_WITH(string, compare_string) \
143 (strncmp(string, compare_string, strlen(compare_string)) == 0)
144
145
146// Append the ch to the output buffer.
147void Decoder::PrintChar(const char ch) {
148 out_buffer_[out_buffer_pos_++] = ch;
149}
150
151
152// Append the str to the output buffer.
153void Decoder::Print(const char* str) {
154 char cur = *str++;
155 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
156 PrintChar(cur);
157 cur = *str++;
158 }
159 out_buffer_[out_buffer_pos_] = 0;
160}
161
162
163// These condition names are defined in a way to match the native disassembler
164// formatting. See for example the command "objdump -d <binary file>".
165static const char* cond_names[max_condition] = {
166 "eq", "ne", "cs" , "cc" , "mi" , "pl" , "vs" , "vc" ,
167 "hi", "ls", "ge", "lt", "gt", "le", "", "invalid",
168};
169
170
171// Print the condition guarding the instruction.
172void Decoder::PrintCondition(Instr* instr) {
173 Print(cond_names[instr->ConditionField()]);
174}
175
176
177// Print the register name according to the active name converter.
178void Decoder::PrintRegister(int reg) {
179 Print(converter_.NameOfCPURegister(reg));
180}
181
Steve Blockd0582a62009-12-15 09:54:21 +0000182// Print the VFP S register name according to the active name converter.
183void Decoder::PrintSRegister(int reg) {
184 Print(assembler::arm::VFPRegisters::Name(reg));
185}
186
187// Print the VFP D register name according to the active name converter.
188void Decoder::PrintDRegister(int reg) {
189 Print(assembler::arm::VFPRegisters::Name(reg + 32));
190}
191
Steve Blocka7e24c12009-10-30 11:49:00 +0000192
193// These shift names are defined in a way to match the native disassembler
194// formatting. See for example the command "objdump -d <binary file>".
195static const char* shift_names[max_shift] = {
196 "lsl", "lsr", "asr", "ror"
197};
198
199
200// Print the register shift operands for the instruction. Generally used for
201// data processing instructions.
202void Decoder::PrintShiftRm(Instr* instr) {
203 Shift shift = instr->ShiftField();
204 int shift_amount = instr->ShiftAmountField();
205 int rm = instr->RmField();
206
207 PrintRegister(rm);
208
209 if ((instr->RegShiftField() == 0) && (shift == LSL) && (shift_amount == 0)) {
210 // Special case for using rm only.
211 return;
212 }
213 if (instr->RegShiftField() == 0) {
214 // by immediate
215 if ((shift == ROR) && (shift_amount == 0)) {
216 Print(", RRX");
217 return;
218 } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
219 shift_amount = 32;
220 }
221 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
222 ", %s #%d",
223 shift_names[shift], shift_amount);
224 } else {
225 // by register
226 int rs = instr->RsField();
227 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
228 ", %s ", shift_names[shift]);
229 PrintRegister(rs);
230 }
231}
232
233
234// Print the immediate operand for the instruction. Generally used for data
235// processing instructions.
236void Decoder::PrintShiftImm(Instr* instr) {
237 int rotate = instr->RotateField() * 2;
238 int immed8 = instr->Immed8Field();
239 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
240 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
241 "#%d", imm);
242}
243
244
245// Print PU formatting to reduce complexity of FormatOption.
246void Decoder::PrintPU(Instr* instr) {
247 switch (instr->PUField()) {
248 case 0: {
249 Print("da");
250 break;
251 }
252 case 1: {
253 Print("ia");
254 break;
255 }
256 case 2: {
257 Print("db");
258 break;
259 }
260 case 3: {
261 Print("ib");
262 break;
263 }
264 default: {
265 UNREACHABLE();
266 break;
267 }
268 }
269}
270
271
272// Print SoftwareInterrupt codes. Factoring this out reduces the complexity of
273// the FormatOption method.
274void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes swi) {
275 switch (swi) {
276 case call_rt_redirected:
277 Print("call_rt_redirected");
278 return;
279 case break_point:
280 Print("break_point");
281 return;
282 default:
283 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
284 "%d",
285 swi);
286 return;
287 }
288}
289
290
291// Handle all register based formatting in this function to reduce the
292// complexity of FormatOption.
293int Decoder::FormatRegister(Instr* instr, const char* format) {
294 ASSERT(format[0] == 'r');
295 if (format[1] == 'n') { // 'rn: Rn register
296 int reg = instr->RnField();
297 PrintRegister(reg);
298 return 2;
299 } else if (format[1] == 'd') { // 'rd: Rd register
300 int reg = instr->RdField();
301 PrintRegister(reg);
302 return 2;
303 } else if (format[1] == 's') { // 'rs: Rs register
304 int reg = instr->RsField();
305 PrintRegister(reg);
306 return 2;
307 } else if (format[1] == 'm') { // 'rm: Rm register
308 int reg = instr->RmField();
309 PrintRegister(reg);
310 return 2;
Steve Blockd0582a62009-12-15 09:54:21 +0000311 } else if (format[1] == 't') { // 'rt: Rt register
312 int reg = instr->RtField();
313 PrintRegister(reg);
314 return 2;
Steve Blocka7e24c12009-10-30 11:49:00 +0000315 } else if (format[1] == 'l') {
316 // 'rlist: register list for load and store multiple instructions
317 ASSERT(STRING_STARTS_WITH(format, "rlist"));
318 int rlist = instr->RlistField();
319 int reg = 0;
320 Print("{");
321 // Print register list in ascending order, by scanning the bit mask.
322 while (rlist != 0) {
323 if ((rlist & 1) != 0) {
324 PrintRegister(reg);
325 if ((rlist >> 1) != 0) {
326 Print(", ");
327 }
328 }
329 reg++;
330 rlist >>= 1;
331 }
332 Print("}");
333 return 5;
334 }
335 UNREACHABLE();
336 return -1;
337}
338
339
Steve Blockd0582a62009-12-15 09:54:21 +0000340// Handle all VFP register based formatting in this function to reduce the
341// complexity of FormatOption.
342int Decoder::FormatVFPRegister(Instr* instr, const char* format) {
343 ASSERT((format[0] == 'S') || (format[0] == 'D'));
344
345 if (format[1] == 'n') {
346 int reg = instr->VnField();
347 if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->NField()));
348 if (format[0] == 'D') PrintDRegister(reg);
349 return 2;
350 } else if (format[1] == 'm') {
351 int reg = instr->VmField();
352 if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->MField()));
353 if (format[0] == 'D') PrintDRegister(reg);
354 return 2;
355 } else if (format[1] == 'd') {
356 int reg = instr->VdField();
357 if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->DField()));
358 if (format[0] == 'D') PrintDRegister(reg);
359 return 2;
360 }
361
362 UNREACHABLE();
363 return -1;
364}
365
366
367int Decoder::FormatVFPinstruction(Instr* instr, const char* format) {
368 Print(format);
369 return 0;
370}
371
372
Steve Blocka7e24c12009-10-30 11:49:00 +0000373// FormatOption takes a formatting string and interprets it based on
374// the current instructions. The format string points to the first
375// character of the option string (the option escape has already been
376// consumed by the caller.) FormatOption returns the number of
377// characters that were consumed from the formatting string.
378int Decoder::FormatOption(Instr* instr, const char* format) {
379 switch (format[0]) {
380 case 'a': { // 'a: accumulate multiplies
381 if (instr->Bit(21) == 0) {
382 Print("ul");
383 } else {
384 Print("la");
385 }
386 return 1;
387 }
388 case 'b': { // 'b: byte loads or stores
389 if (instr->HasB()) {
390 Print("b");
391 }
392 return 1;
393 }
394 case 'c': { // 'cond: conditional execution
395 ASSERT(STRING_STARTS_WITH(format, "cond"));
396 PrintCondition(instr);
397 return 4;
398 }
399 case 'h': { // 'h: halfword operation for extra loads and stores
400 if (instr->HasH()) {
401 Print("h");
402 } else {
403 Print("b");
404 }
405 return 1;
406 }
407 case 'l': { // 'l: branch and link
408 if (instr->HasLink()) {
409 Print("l");
410 }
411 return 1;
412 }
413 case 'm': {
414 if (format[1] == 'e') { // 'memop: load/store instructions
415 ASSERT(STRING_STARTS_WITH(format, "memop"));
416 if (instr->HasL()) {
417 Print("ldr");
418 } else {
419 Print("str");
420 }
421 return 5;
422 }
423 // 'msg: for simulator break instructions
424 ASSERT(STRING_STARTS_WITH(format, "msg"));
425 byte* str =
426 reinterpret_cast<byte*>(instr->InstructionBits() & 0x0fffffff);
427 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
428 "%s", converter_.NameInCode(str));
429 return 3;
430 }
431 case 'o': {
432 if (format[3] == '1') {
433 // 'off12: 12-bit offset for load and store instructions
434 ASSERT(STRING_STARTS_WITH(format, "off12"));
435 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
436 "%d", instr->Offset12Field());
437 return 5;
438 }
439 // 'off8: 8-bit offset for extra load and store instructions
440 ASSERT(STRING_STARTS_WITH(format, "off8"));
441 int offs8 = (instr->ImmedHField() << 4) | instr->ImmedLField();
442 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
443 "%d", offs8);
444 return 4;
445 }
446 case 'p': { // 'pu: P and U bits for load and store instructions
447 ASSERT(STRING_STARTS_WITH(format, "pu"));
448 PrintPU(instr);
449 return 2;
450 }
451 case 'r': {
452 return FormatRegister(instr, format);
453 }
454 case 's': {
455 if (format[1] == 'h') { // 'shift_op or 'shift_rm
456 if (format[6] == 'o') { // 'shift_op
457 ASSERT(STRING_STARTS_WITH(format, "shift_op"));
458 if (instr->TypeField() == 0) {
459 PrintShiftRm(instr);
460 } else {
461 ASSERT(instr->TypeField() == 1);
462 PrintShiftImm(instr);
463 }
464 return 8;
465 } else { // 'shift_rm
466 ASSERT(STRING_STARTS_WITH(format, "shift_rm"));
467 PrintShiftRm(instr);
468 return 8;
469 }
470 } else if (format[1] == 'w') { // 'swi
471 ASSERT(STRING_STARTS_WITH(format, "swi"));
472 PrintSoftwareInterrupt(instr->SwiField());
473 return 3;
474 } else if (format[1] == 'i') { // 'sign: signed extra loads and stores
475 ASSERT(STRING_STARTS_WITH(format, "sign"));
476 if (instr->HasSign()) {
477 Print("s");
478 }
479 return 4;
480 }
481 // 's: S field of data processing instructions
482 if (instr->HasS()) {
483 Print("s");
484 }
485 return 1;
486 }
487 case 't': { // 'target: target of branch instructions
488 ASSERT(STRING_STARTS_WITH(format, "target"));
489 int off = (instr->SImmed24Field() << 2) + 8;
490 out_buffer_pos_ += v8i::OS::SNPrintF(
491 out_buffer_ + out_buffer_pos_,
492 "%+d -> %s",
493 off,
494 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off));
495 return 6;
496 }
497 case 'u': { // 'u: signed or unsigned multiplies
498 // The manual gets the meaning of bit 22 backwards in the multiply
499 // instruction overview on page A3.16.2. The instructions that
500 // exist in u and s variants are the following:
501 // smull A4.1.87
502 // umull A4.1.129
503 // umlal A4.1.128
504 // smlal A4.1.76
505 // For these 0 means u and 1 means s. As can be seen on their individual
506 // pages. The other 18 mul instructions have the bit set or unset in
507 // arbitrary ways that are unrelated to the signedness of the instruction.
508 // None of these 18 instructions exist in both a 'u' and an 's' variant.
509
510 if (instr->Bit(22) == 0) {
511 Print("u");
512 } else {
513 Print("s");
514 }
515 return 1;
516 }
Steve Blockd0582a62009-12-15 09:54:21 +0000517 case 'v': {
518 return FormatVFPinstruction(instr, format);
519 }
520 case 'S':
521 case 'D': {
522 return FormatVFPRegister(instr, format);
523 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000524 case 'w': { // 'w: W field of load and store instructions
525 if (instr->HasW()) {
526 Print("!");
527 }
528 return 1;
529 }
530 default: {
531 UNREACHABLE();
532 break;
533 }
534 }
535 UNREACHABLE();
536 return -1;
537}
538
539
540// Format takes a formatting string for a whole instruction and prints it into
541// the output buffer. All escaped options are handed to FormatOption to be
542// parsed further.
543void Decoder::Format(Instr* instr, const char* format) {
544 char cur = *format++;
545 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
546 if (cur == '\'') { // Single quote is used as the formatting escape.
547 format += FormatOption(instr, format);
548 } else {
549 out_buffer_[out_buffer_pos_++] = cur;
550 }
551 cur = *format++;
552 }
553 out_buffer_[out_buffer_pos_] = '\0';
554}
555
556
557// For currently unimplemented decodings the disassembler calls Unknown(instr)
558// which will just print "unknown" of the instruction bits.
559void Decoder::Unknown(Instr* instr) {
560 Format(instr, "unknown");
561}
562
563
564void Decoder::DecodeType01(Instr* instr) {
565 int type = instr->TypeField();
566 if ((type == 0) && instr->IsSpecialType0()) {
567 // multiply instruction or extra loads and stores
568 if (instr->Bits(7, 4) == 9) {
569 if (instr->Bit(24) == 0) {
570 // multiply instructions
571 if (instr->Bit(23) == 0) {
572 if (instr->Bit(21) == 0) {
573 // The MUL instruction description (A 4.1.33) refers to Rd as being
574 // the destination for the operation, but it confusingly uses the
575 // Rn field to encode it.
576 Format(instr, "mul'cond's 'rn, 'rm, 'rs");
577 } else {
578 // The MLA instruction description (A 4.1.28) refers to the order
579 // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
580 // Rn field to encode the Rd register and the Rd field to encode
581 // the Rn register.
582 Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd");
583 }
584 } else {
585 // The signed/long multiply instructions use the terms RdHi and RdLo
586 // when referring to the target registers. They are mapped to the Rn
587 // and Rd fields as follows:
588 // RdLo == Rd field
589 // RdHi == Rn field
590 // The order of registers is: <RdLo>, <RdHi>, <Rm>, <Rs>
591 Format(instr, "'um'al'cond's 'rd, 'rn, 'rm, 'rs");
592 }
593 } else {
594 Unknown(instr); // not used by V8
595 }
596 } else {
597 // extra load/store instructions
598 switch (instr->PUField()) {
599 case 0: {
600 if (instr->Bit(22) == 0) {
601 Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm");
602 } else {
603 Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8");
604 }
605 break;
606 }
607 case 1: {
608 if (instr->Bit(22) == 0) {
609 Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm");
610 } else {
611 Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8");
612 }
613 break;
614 }
615 case 2: {
616 if (instr->Bit(22) == 0) {
617 Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w");
618 } else {
619 Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w");
620 }
621 break;
622 }
623 case 3: {
624 if (instr->Bit(22) == 0) {
625 Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w");
626 } else {
627 Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w");
628 }
629 break;
630 }
631 default: {
632 // The PU field is a 2-bit field.
633 UNREACHABLE();
634 break;
635 }
636 }
637 return;
638 }
639 } else {
640 switch (instr->OpcodeField()) {
641 case AND: {
642 Format(instr, "and'cond's 'rd, 'rn, 'shift_op");
643 break;
644 }
645 case EOR: {
646 Format(instr, "eor'cond's 'rd, 'rn, 'shift_op");
647 break;
648 }
649 case SUB: {
650 Format(instr, "sub'cond's 'rd, 'rn, 'shift_op");
651 break;
652 }
653 case RSB: {
654 Format(instr, "rsb'cond's 'rd, 'rn, 'shift_op");
655 break;
656 }
657 case ADD: {
658 Format(instr, "add'cond's 'rd, 'rn, 'shift_op");
659 break;
660 }
661 case ADC: {
662 Format(instr, "adc'cond's 'rd, 'rn, 'shift_op");
663 break;
664 }
665 case SBC: {
666 Format(instr, "sbc'cond's 'rd, 'rn, 'shift_op");
667 break;
668 }
669 case RSC: {
670 Format(instr, "rsc'cond's 'rd, 'rn, 'shift_op");
671 break;
672 }
673 case TST: {
674 if (instr->HasS()) {
675 Format(instr, "tst'cond 'rn, 'shift_op");
676 } else {
677 Unknown(instr); // not used by V8
678 }
679 break;
680 }
681 case TEQ: {
682 if (instr->HasS()) {
683 Format(instr, "teq'cond 'rn, 'shift_op");
684 } else {
685 switch (instr->Bits(7, 4)) {
686 case BX:
687 Format(instr, "bx'cond 'rm");
688 break;
689 case BLX:
690 Format(instr, "blx'cond 'rm");
691 break;
692 default:
693 Unknown(instr); // not used by V8
694 break;
695 }
696 }
697 break;
698 }
699 case CMP: {
700 if (instr->HasS()) {
701 Format(instr, "cmp'cond 'rn, 'shift_op");
702 } else {
703 Unknown(instr); // not used by V8
704 }
705 break;
706 }
707 case CMN: {
708 if (instr->HasS()) {
709 Format(instr, "cmn'cond 'rn, 'shift_op");
710 } else {
711 switch (instr->Bits(7, 4)) {
712 case CLZ:
713 Format(instr, "clz'cond 'rd, 'rm");
714 break;
715 default:
716 Unknown(instr); // not used by V8
717 break;
718 }
719 }
720 break;
721 }
722 case ORR: {
723 Format(instr, "orr'cond's 'rd, 'rn, 'shift_op");
724 break;
725 }
726 case MOV: {
727 Format(instr, "mov'cond's 'rd, 'shift_op");
728 break;
729 }
730 case BIC: {
731 Format(instr, "bic'cond's 'rd, 'rn, 'shift_op");
732 break;
733 }
734 case MVN: {
735 Format(instr, "mvn'cond's 'rd, 'shift_op");
736 break;
737 }
738 default: {
739 // The Opcode field is a 4-bit field.
740 UNREACHABLE();
741 break;
742 }
743 }
744 }
745}
746
747
748void Decoder::DecodeType2(Instr* instr) {
749 switch (instr->PUField()) {
750 case 0: {
751 if (instr->HasW()) {
752 Unknown(instr); // not used in V8
753 }
754 Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
755 break;
756 }
757 case 1: {
758 if (instr->HasW()) {
759 Unknown(instr); // not used in V8
760 }
761 Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
762 break;
763 }
764 case 2: {
765 Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w");
766 break;
767 }
768 case 3: {
769 Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w");
770 break;
771 }
772 default: {
773 // The PU field is a 2-bit field.
774 UNREACHABLE();
775 break;
776 }
777 }
778}
779
780
781void Decoder::DecodeType3(Instr* instr) {
782 switch (instr->PUField()) {
783 case 0: {
784 ASSERT(!instr->HasW());
785 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
786 break;
787 }
788 case 1: {
789 ASSERT(!instr->HasW());
790 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
791 break;
792 }
793 case 2: {
794 Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
795 break;
796 }
797 case 3: {
798 Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
799 break;
800 }
801 default: {
802 // The PU field is a 2-bit field.
803 UNREACHABLE();
804 break;
805 }
806 }
807}
808
809
810void Decoder::DecodeType4(Instr* instr) {
811 ASSERT(instr->Bit(22) == 0); // Privileged mode currently not supported.
812 if (instr->HasL()) {
813 Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
814 } else {
815 Format(instr, "stm'cond'pu 'rn'w, 'rlist");
816 }
817}
818
819
820void Decoder::DecodeType5(Instr* instr) {
821 Format(instr, "b'l'cond 'target");
822}
823
824
825void Decoder::DecodeType6(Instr* instr) {
Steve Blockd0582a62009-12-15 09:54:21 +0000826 DecodeType6CoprocessorIns(instr);
Steve Blocka7e24c12009-10-30 11:49:00 +0000827}
828
829
830void Decoder::DecodeType7(Instr* instr) {
831 if (instr->Bit(24) == 1) {
832 Format(instr, "swi'cond 'swi");
833 } else {
Steve Blockd0582a62009-12-15 09:54:21 +0000834 DecodeTypeVFP(instr);
Steve Blocka7e24c12009-10-30 11:49:00 +0000835 }
836}
837
Steve Blocka7e24c12009-10-30 11:49:00 +0000838void Decoder::DecodeUnconditional(Instr* instr) {
839 if (instr->Bits(7, 4) == 0xB && instr->Bits(27, 25) == 0 && instr->HasL()) {
840 Format(instr, "'memop'h'pu 'rd, ");
841 bool immediate = instr->HasB();
842 switch (instr->PUField()) {
843 case 0: {
844 // Post index, negative.
845 if (instr->HasW()) {
846 Unknown(instr);
847 break;
848 }
849 if (immediate) {
850 Format(instr, "['rn], #-'imm12");
851 } else {
852 Format(instr, "['rn], -'rm");
853 }
854 break;
855 }
856 case 1: {
857 // Post index, positive.
858 if (instr->HasW()) {
859 Unknown(instr);
860 break;
861 }
862 if (immediate) {
863 Format(instr, "['rn], #+'imm12");
864 } else {
865 Format(instr, "['rn], +'rm");
866 }
867 break;
868 }
869 case 2: {
870 // Pre index or offset, negative.
871 if (immediate) {
872 Format(instr, "['rn, #-'imm12]'w");
873 } else {
874 Format(instr, "['rn, -'rm]'w");
875 }
876 break;
877 }
878 case 3: {
879 // Pre index or offset, positive.
880 if (immediate) {
881 Format(instr, "['rn, #+'imm12]'w");
882 } else {
883 Format(instr, "['rn, +'rm]'w");
884 }
885 break;
886 }
887 default: {
888 // The PU field is a 2-bit field.
889 UNREACHABLE();
890 break;
891 }
892 }
893 return;
894 }
895 Format(instr, "break 'msg");
896}
897
898
Steve Blockd0582a62009-12-15 09:54:21 +0000899// void Decoder::DecodeTypeVFP(Instr* instr)
900// Implements the following VFP instructions:
901// fmsr: Sn = Rt
902// fmrs: Rt = Sn
903// fsitod: Dd = Sm
904// ftosid: Sd = Dm
905// Dd = faddd(Dn, Dm)
906// Dd = fsubd(Dn, Dm)
907// Dd = fmuld(Dn, Dm)
908// Dd = fdivd(Dn, Dm)
909// vcmp(Dd, Dm)
910// VMRS
911void Decoder::DecodeTypeVFP(Instr* instr) {
912 ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) );
913
914 if (instr->Bit(23) == 1) {
915 if ((instr->Bits(21, 19) == 0x7) &&
916 (instr->Bits(18, 16) == 0x5) &&
917 (instr->Bits(11, 9) == 0x5) &&
918 (instr->Bit(8) == 1) &&
919 (instr->Bit(6) == 1) &&
920 (instr->Bit(4) == 0)) {
921 Format(instr, "vcvt.s32.f64'cond 'Sd, 'Dm");
922 } else if ((instr->Bits(21, 19) == 0x7) &&
923 (instr->Bits(18, 16) == 0x0) &&
924 (instr->Bits(11, 9) == 0x5) &&
925 (instr->Bit(8) == 1) &&
926 (instr->Bit(7) == 1) &&
927 (instr->Bit(6) == 1) &&
928 (instr->Bit(4) == 0)) {
929 Format(instr, "vcvt.f64.s32'cond 'Dd, 'Sm");
930 } else if ((instr->Bit(21) == 0x0) &&
931 (instr->Bit(20) == 0x0) &&
932 (instr->Bits(11, 9) == 0x5) &&
933 (instr->Bit(8) == 1) &&
934 (instr->Bit(6) == 0) &&
935 (instr->Bit(4) == 0)) {
936 Format(instr, "vdiv.f64'cond 'Dd, 'Dn, 'Dm");
937 } else if ((instr->Bits(21, 20) == 0x3) &&
938 (instr->Bits(19, 16) == 0x4) &&
939 (instr->Bits(11, 9) == 0x5) &&
940 (instr->Bit(8) == 0x1) &&
941 (instr->Bit(6) == 0x1) &&
942 (instr->Bit(4) == 0x0)) {
943 Format(instr, "vcmp.f64'cond 'Dd, 'Dm");
944 } else if ((instr->Bits(23, 20) == 0xF) &&
945 (instr->Bits(19, 16) == 0x1) &&
946 (instr->Bits(11, 8) == 0xA) &&
947 (instr->Bits(7, 5) == 0x0) &&
948 (instr->Bit(4) == 0x1) &&
949 (instr->Bits(3, 0) == 0x0)) {
950 if (instr->Bits(15, 12) == 0xF)
951 Format(instr, "vmrs'cond APSR, FPSCR");
952 else
953 Unknown(instr); // Not used by V8.
954 } else {
955 Unknown(instr); // Not used by V8.
956 }
957 } else if (instr->Bit(21) == 1) {
958 if ((instr->Bit(20) == 0x1) &&
959 (instr->Bits(11, 9) == 0x5) &&
960 (instr->Bit(8) == 0x1) &&
961 (instr->Bit(6) == 0) &&
962 (instr->Bit(4) == 0)) {
963 Format(instr, "vadd.f64'cond 'Dd, 'Dn, 'Dm");
964 } else if ((instr->Bit(20) == 0x1) &&
965 (instr->Bits(11, 9) == 0x5) &&
966 (instr->Bit(8) == 0x1) &&
967 (instr->Bit(6) == 1) &&
968 (instr->Bit(4) == 0)) {
969 Format(instr, "vsub.f64'cond 'Dd, 'Dn, 'Dm");
970 } else if ((instr->Bit(20) == 0x0) &&
971 (instr->Bits(11, 9) == 0x5) &&
972 (instr->Bit(8) == 0x1) &&
973 (instr->Bit(6) == 0) &&
974 (instr->Bit(4) == 0)) {
975 Format(instr, "vmul.f64'cond 'Dd, 'Dn, 'Dm");
976 } else {
977 Unknown(instr); // Not used by V8.
978 }
979 } else {
980 if ((instr->Bit(20) == 0x0) &&
981 (instr->Bits(11, 8) == 0xA) &&
982 (instr->Bits(6, 5) == 0x0) &&
983 (instr->Bit(4) == 1) &&
984 (instr->Bits(3, 0) == 0x0)) {
985 Format(instr, "vmov'cond 'Sn, 'rt");
986 } else if ((instr->Bit(20) == 0x1) &&
987 (instr->Bits(11, 8) == 0xA) &&
988 (instr->Bits(6, 5) == 0x0) &&
989 (instr->Bit(4) == 1) &&
990 (instr->Bits(3, 0) == 0x0)) {
991 Format(instr, "vmov'cond 'rt, 'Sn");
992 } else {
993 Unknown(instr); // Not used by V8.
994 }
995 }
996}
997
998
999// Decode Type 6 coprocessor instructions.
1000// Dm = fmdrr(Rt, Rt2)
1001// <Rt, Rt2> = fmrrd(Dm)
1002void Decoder::DecodeType6CoprocessorIns(Instr* instr) {
1003 ASSERT((instr->TypeField() == 6));
1004
1005 if (instr->Bit(23) == 1) {
1006 Unknown(instr); // Not used by V8.
1007 } else if (instr->Bit(22) == 1) {
1008 if ((instr->Bits(27, 24) == 0xC) &&
1009 (instr->Bit(22) == 1) &&
1010 (instr->Bits(11, 8) == 0xB) &&
1011 (instr->Bits(7, 6) == 0x0) &&
1012 (instr->Bit(4) == 1)) {
1013 if (instr->Bit(20) == 0) {
1014 Format(instr, "vmov'cond 'Dm, 'rt, 'rn");
1015 } else if (instr->Bit(20) == 1) {
1016 Format(instr, "vmov'cond 'rt, 'rn, 'Dm");
1017 }
1018 } else {
1019 Unknown(instr); // Not used by V8.
1020 }
1021 } else if (instr->Bit(21) == 1) {
1022 Unknown(instr); // Not used by V8.
1023 } else {
1024 Unknown(instr); // Not used by V8.
1025 }
1026}
1027
1028
Steve Blocka7e24c12009-10-30 11:49:00 +00001029// Disassemble the instruction at *instr_ptr into the output buffer.
1030int Decoder::InstructionDecode(byte* instr_ptr) {
1031 Instr* instr = Instr::At(instr_ptr);
1032 // Print raw instruction bytes.
1033 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1034 "%08x ",
1035 instr->InstructionBits());
1036 if (instr->ConditionField() == special_condition) {
1037 DecodeUnconditional(instr);
1038 return Instr::kInstrSize;
1039 }
1040 switch (instr->TypeField()) {
1041 case 0:
1042 case 1: {
1043 DecodeType01(instr);
1044 break;
1045 }
1046 case 2: {
1047 DecodeType2(instr);
1048 break;
1049 }
1050 case 3: {
1051 DecodeType3(instr);
1052 break;
1053 }
1054 case 4: {
1055 DecodeType4(instr);
1056 break;
1057 }
1058 case 5: {
1059 DecodeType5(instr);
1060 break;
1061 }
1062 case 6: {
1063 DecodeType6(instr);
1064 break;
1065 }
1066 case 7: {
1067 DecodeType7(instr);
1068 break;
1069 }
1070 default: {
1071 // The type field is 3-bits in the ARM encoding.
1072 UNREACHABLE();
1073 break;
1074 }
1075 }
1076 return Instr::kInstrSize;
1077}
1078
1079
1080} } // namespace assembler::arm
1081
1082
1083
1084//------------------------------------------------------------------------------
1085
1086namespace disasm {
1087
1088namespace v8i = v8::internal;
1089
1090
1091const char* NameConverter::NameOfAddress(byte* addr) const {
1092 static v8::internal::EmbeddedVector<char, 32> tmp_buffer;
1093 v8::internal::OS::SNPrintF(tmp_buffer, "%p", addr);
1094 return tmp_buffer.start();
1095}
1096
1097
1098const char* NameConverter::NameOfConstant(byte* addr) const {
1099 return NameOfAddress(addr);
1100}
1101
1102
1103const char* NameConverter::NameOfCPURegister(int reg) const {
1104 return assembler::arm::Registers::Name(reg);
1105}
1106
1107
1108const char* NameConverter::NameOfByteCPURegister(int reg) const {
1109 UNREACHABLE(); // ARM does not have the concept of a byte register
1110 return "nobytereg";
1111}
1112
1113
1114const char* NameConverter::NameOfXMMRegister(int reg) const {
1115 UNREACHABLE(); // ARM does not have any XMM registers
1116 return "noxmmreg";
1117}
1118
1119
1120const char* NameConverter::NameInCode(byte* addr) const {
1121 // The default name converter is called for unknown code. So we will not try
1122 // to access any memory.
1123 return "";
1124}
1125
1126
1127//------------------------------------------------------------------------------
1128
1129Disassembler::Disassembler(const NameConverter& converter)
1130 : converter_(converter) {}
1131
1132
1133Disassembler::~Disassembler() {}
1134
1135
1136int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
1137 byte* instruction) {
1138 assembler::arm::Decoder d(converter_, buffer);
1139 return d.InstructionDecode(instruction);
1140}
1141
1142
1143int Disassembler::ConstantPoolSizeAt(byte* instruction) {
1144 int instruction_bits = *(reinterpret_cast<int*>(instruction));
1145 if ((instruction_bits & 0xfff00000) == 0x03000000) {
1146 return instruction_bits & 0x0000ffff;
1147 } else {
1148 return -1;
1149 }
1150}
1151
1152
1153void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
1154 NameConverter converter;
1155 Disassembler d(converter);
1156 for (byte* pc = begin; pc < end;) {
1157 v8::internal::EmbeddedVector<char, 128> buffer;
1158 buffer[0] = '\0';
1159 byte* prev_pc = pc;
1160 pc += d.InstructionDecode(buffer, pc);
1161 fprintf(f, "%p %08x %s\n",
1162 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
1163 }
1164}
1165
1166
1167} // namespace disasm