Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(287)

Side by Side Diff: src/disasm-arm.cc

Issue 1941: Fixed arm disassembler build problems. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/platform-macos.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2007-2008 the V8 project authors. All rights reserved. 1 // Copyright 2007-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 45
46 46
47 //------------------------------------------------------------------------------ 47 //------------------------------------------------------------------------------
48 48
49 // Decoder decodes and disassembles instructions into an output buffer. 49 // Decoder decodes and disassembles instructions into an output buffer.
50 // It uses the converter to convert register names and call destinations into 50 // It uses the converter to convert register names and call destinations into
51 // more informative description. 51 // more informative description.
52 class Decoder { 52 class Decoder {
53 public: 53 public:
54 Decoder(const disasm::NameConverter& converter, 54 Decoder(const disasm::NameConverter& converter,
55 char* out_buffer, const int out_buffer_size) 55 v8::internal::Vector<char> out_buffer)
56 : converter_(converter), 56 : converter_(converter),
57 out_buffer_(out_buffer), 57 out_buffer_(out_buffer),
58 out_buffer_size_(out_buffer_size),
59 out_buffer_pos_(0) { 58 out_buffer_pos_(0) {
60 ASSERT(out_buffer_size_ > 0); 59 ASSERT(out_buffer_size_ > 0);
61 out_buffer_[out_buffer_pos_] = '\0'; 60 out_buffer_[out_buffer_pos_] = '\0';
62 } 61 }
63 62
64 ~Decoder() {} 63 ~Decoder() {}
65 64
66 // Writes one disassembled instruction into 'buffer' (0-terminated). 65 // Writes one disassembled instruction into 'buffer' (0-terminated).
67 // Returns the length of the disassembled machine instruction in bytes. 66 // Returns the length of the disassembled machine instruction in bytes.
68 int InstructionDecode(byte* instruction); 67 int InstructionDecode(byte* instruction);
69 68
70 private: 69 private:
71 const disasm::NameConverter& converter_; 70 const disasm::NameConverter& converter_;
72 char* out_buffer_; 71 v8::internal::Vector<char> out_buffer_;
73 const int out_buffer_size_;
74 int out_buffer_pos_; 72 int out_buffer_pos_;
75 73
76 void PrintChar(const char ch); 74 void PrintChar(const char ch);
77 void Print(const char* str); 75 void Print(const char* str);
78 76
79 void PrintRegister(int reg); 77 void PrintRegister(int reg);
80 void PrintCondition(Instr* instr); 78 void PrintCondition(Instr* instr);
81 void PrintShiftRm(Instr* instr); 79 void PrintShiftRm(Instr* instr);
82 void PrintShiftImm(Instr* instr); 80 void PrintShiftImm(Instr* instr);
83 81
(...skipping 15 matching lines...) Expand all
99 // Append the ch to the output buffer. 97 // Append the ch to the output buffer.
100 void Decoder::PrintChar(const char ch) { 98 void Decoder::PrintChar(const char ch) {
101 ASSERT(out_buffer_pos_ < out_buffer_size_); 99 ASSERT(out_buffer_pos_ < out_buffer_size_);
102 out_buffer_[out_buffer_pos_++] = ch; 100 out_buffer_[out_buffer_pos_++] = ch;
103 } 101 }
104 102
105 103
106 // Append the str to the output buffer. 104 // Append the str to the output buffer.
107 void Decoder::Print(const char* str) { 105 void Decoder::Print(const char* str) {
108 char cur = *str++; 106 char cur = *str++;
109 while (cur != 0 && (out_buffer_pos_ < (out_buffer_size_-1))) { 107 while (cur != 0 && (out_buffer_pos_ < (out_buffer_.length()-1))) {
110 PrintChar(cur); 108 PrintChar(cur);
111 cur = *str++; 109 cur = *str++;
112 } 110 }
113 out_buffer_[out_buffer_pos_] = 0; 111 out_buffer_[out_buffer_pos_] = 0;
114 } 112 }
115 113
116 114
117 static const char* cond_names[16] = { 115 static const char* cond_names[16] = {
118 "eq", "ne", "cs" , "cc" , "mi" , "pl" , "vs" , "vc" , 116 "eq", "ne", "cs" , "cc" , "mi" , "pl" , "vs" , "vc" ,
119 "hi", "ls", "ge", "lt", "gt", "le", "", "invalid", 117 "hi", "ls", "ge", "lt", "gt", "le", "", "invalid",
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 } 150 }
153 if (instr->RegShiftField() == 0) { 151 if (instr->RegShiftField() == 0) {
154 // by immediate 152 // by immediate
155 if ((shift == ROR) && (shift_amount == 0)) { 153 if ((shift == ROR) && (shift_amount == 0)) {
156 Print(", RRX"); 154 Print(", RRX");
157 return; 155 return;
158 } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) { 156 } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
159 shift_amount = 32; 157 shift_amount = 32;
160 } 158 }
161 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 159 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
162 out_buffer_size_ - out_buffer_pos_,
163 ", %s #%d", 160 ", %s #%d",
164 shift_names[shift], shift_amount); 161 shift_names[shift], shift_amount);
165 } else { 162 } else {
166 // by register 163 // by register
167 int rs = instr->RsField(); 164 int rs = instr->RsField();
168 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 165 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
169 out_buffer_size_ - out_buffer_pos_,
170 ", %s ", shift_names[shift]); 166 ", %s ", shift_names[shift]);
171 PrintRegister(rs); 167 PrintRegister(rs);
172 } 168 }
173 } 169 }
174 170
175 171
176 // Print the immediate operand for the instruction. Generally used for data 172 // Print the immediate operand for the instruction. Generally used for data
177 // processing instructions. 173 // processing instructions.
178 void Decoder::PrintShiftImm(Instr* instr) { 174 void Decoder::PrintShiftImm(Instr* instr) {
179 int rotate = instr->RotateField() * 2; 175 int rotate = instr->RotateField() * 2;
180 int immed8 = instr->Immed8Field(); 176 int immed8 = instr->Immed8Field();
181 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate)); 177 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
182 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 178 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
183 out_buffer_size_ - out_buffer_pos_,
184 "#%d", imm); 179 "#%d", imm);
185 } 180 }
186 181
187 182
188 // FormatOption takes a formatting string and interprets it based on 183 // FormatOption takes a formatting string and interprets it based on
189 // the current instructions. The format string points to the first 184 // the current instructions. The format string points to the first
190 // character of the option string (the option escape has already been 185 // character of the option string (the option escape has already been
191 // consumed by the caller.) FormatOption returns the number of 186 // consumed by the caller.) FormatOption returns the number of
192 // characters that were consumed from the formatting string. 187 // characters that were consumed from the formatting string.
193 int Decoder::FormatOption(Instr* instr, const char* format) { 188 int Decoder::FormatOption(Instr* instr, const char* format) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 Print("ldr"); 238 Print("ldr");
244 } else { 239 } else {
245 Print("str"); 240 Print("str");
246 } 241 }
247 return 5; 242 return 5;
248 } else { 243 } else {
249 ASSERT(format[1] == 's' && format[2] == 'g'); 244 ASSERT(format[1] == 's' && format[2] == 'g');
250 byte* str = 245 byte* str =
251 reinterpret_cast<byte*>(instr->InstructionBits() & 0x0fffffff); 246 reinterpret_cast<byte*>(instr->InstructionBits() & 0x0fffffff);
252 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 247 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
253 out_buffer_size_ - out_buffer_pos_,
254 "%s", converter_.NameInCode(str)); 248 "%s", converter_.NameInCode(str));
255 return 3; 249 return 3;
256 } 250 }
257 break; 251 break;
258 } 252 }
259 case 'o': { 253 case 'o': {
260 ASSERT(format[1] == 'f' && format[2] == 'f'); 254 ASSERT(format[1] == 'f' && format[2] == 'f');
261 if (format[3] == '1') { 255 if (format[3] == '1') {
262 // 'off12: 12-bit offset for load and store instructions 256 // 'off12: 12-bit offset for load and store instructions
263 ASSERT(format[4] == '2'); 257 ASSERT(format[4] == '2');
264 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 258 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
265 out_buffer_size_ - out_buffer_pos_,
266 "%d", instr->Offset12Field()); 259 "%d", instr->Offset12Field());
267 return 5; 260 return 5;
268 } else { 261 } else {
269 // 'off8: 8-bit offset for extra load and store instructions 262 // 'off8: 8-bit offset for extra load and store instructions
270 ASSERT(format[3] == '8'); 263 ASSERT(format[3] == '8');
271 int offs8 = (instr->ImmedHField() << 4) | instr->ImmedLField(); 264 int offs8 = (instr->ImmedHField() << 4) | instr->ImmedLField();
272 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 265 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
273 out_buffer_size_ - out_buffer_pos_,
274 "%d", offs8); 266 "%d", offs8);
275 return 4; 267 return 4;
276 } 268 }
277 break; 269 break;
278 } 270 }
279 case 'p': { // 'pu: P and U bits for load and store instructions 271 case 'p': { // 'pu: P and U bits for load and store instructions
280 ASSERT(format[1] == 'u'); 272 ASSERT(format[1] == 'u');
281 switch (instr->PUField()) { 273 switch (instr->PUField()) {
282 case 0: { 274 case 0: {
283 Print("da"); 275 Print("da");
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 break; 352 break;
361 case call_rt_r2: 353 case call_rt_r2:
362 Print("call_rt_r2"); 354 Print("call_rt_r2");
363 break; 355 break;
364 case break_point: 356 case break_point:
365 Print("break_point"); 357 Print("break_point");
366 break; 358 break;
367 default: 359 default:
368 out_buffer_pos_ += v8i::OS::SNPrintF( 360 out_buffer_pos_ += v8i::OS::SNPrintF(
369 out_buffer_ + out_buffer_pos_, 361 out_buffer_ + out_buffer_pos_,
370 out_buffer_size_ - out_buffer_pos_,
371 "%d", 362 "%d",
372 swi); 363 swi);
373 break; 364 break;
374 } 365 }
375 return 3; 366 return 3;
376 } else if (format[1] == 'i') { // 'sign: signed extra loads and stores 367 } else if (format[1] == 'i') { // 'sign: signed extra loads and stores
377 ASSERT(format[2] == 'g' && format[3] == 'n'); 368 ASSERT(format[2] == 'g' && format[3] == 'n');
378 if (instr->HasSign()) { 369 if (instr->HasSign()) {
379 Print("s"); 370 Print("s");
380 } 371 }
381 return 4; 372 return 4;
382 break; 373 break;
383 } else { // 's: S field of data processing instructions 374 } else { // 's: S field of data processing instructions
384 if (instr->HasS()) { 375 if (instr->HasS()) {
385 Print("s"); 376 Print("s");
386 } 377 }
387 return 1; 378 return 1;
388 } 379 }
389 break; 380 break;
390 } 381 }
391 case 't': { // 'target: target of branch instructions 382 case 't': { // 'target: target of branch instructions
392 ASSERT(format[1] == 'a' && format[2] == 'r' && format[3] == 'g' 383 ASSERT(format[1] == 'a' && format[2] == 'r' && format[3] == 'g'
393 && format[4] == 'e' && format[5] == 't'); 384 && format[4] == 'e' && format[5] == 't');
394 int off = (instr->SImmed24Field() << 2) + 8; 385 int off = (instr->SImmed24Field() << 2) + 8;
395 out_buffer_pos_ += v8i::OS::SNPrintF( 386 out_buffer_pos_ += v8i::OS::SNPrintF(
396 out_buffer_ + out_buffer_pos_, 387 out_buffer_ + out_buffer_pos_,
397 out_buffer_size_ - out_buffer_pos_,
398 "%+d -> %s", 388 "%+d -> %s",
399 off, 389 off,
400 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off)); 390 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off));
401 return 6; 391 return 6;
402 break; 392 break;
403 } 393 }
404 case 'u': { // 'u: signed or unsigned multiplies 394 case 'u': { // 'u: signed or unsigned multiplies
405 if (instr->Bit(22) == 0) { 395 if (instr->Bit(22) == 0) {
406 Print("u"); 396 Print("u");
407 } else { 397 } else {
(...skipping 17 matching lines...) Expand all
425 UNREACHABLE(); 415 UNREACHABLE();
426 return -1; 416 return -1;
427 } 417 }
428 418
429 419
430 // Format takes a formatting string for a whole instruction and prints it into 420 // Format takes a formatting string for a whole instruction and prints it into
431 // the output buffer. All escaped options are handed to FormatOption to be 421 // the output buffer. All escaped options are handed to FormatOption to be
432 // parsed further. 422 // parsed further.
433 void Decoder::Format(Instr* instr, const char* format) { 423 void Decoder::Format(Instr* instr, const char* format) {
434 char cur = *format++; 424 char cur = *format++;
435 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_size_ - 1))) { 425 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
436 if (cur == '\'') { // Single quote is used as the formatting escape. 426 if (cur == '\'') { // Single quote is used as the formatting escape.
437 format += FormatOption(instr, format); 427 format += FormatOption(instr, format);
438 } else { 428 } else {
439 out_buffer_[out_buffer_pos_++] = cur; 429 out_buffer_[out_buffer_pos_++] = cur;
440 } 430 }
441 cur = *format++; 431 cur = *format++;
442 } 432 }
443 ASSERT(out_buffer_pos_ < out_buffer_size_); 433 ASSERT(out_buffer_pos_ < out_buffer_size_);
444 out_buffer_[out_buffer_pos_] = '\0'; 434 out_buffer_[out_buffer_pos_] = '\0';
445 } 435 }
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 Unknown(instr); 787 Unknown(instr);
798 } 788 }
799 } 789 }
800 790
801 791
802 // Disassemble the instruction at *instr_ptr into the output buffer. 792 // Disassemble the instruction at *instr_ptr into the output buffer.
803 int Decoder::InstructionDecode(byte* instr_ptr) { 793 int Decoder::InstructionDecode(byte* instr_ptr) {
804 Instr* instr = Instr::At(instr_ptr); 794 Instr* instr = Instr::At(instr_ptr);
805 // Print raw instruction bytes. 795 // Print raw instruction bytes.
806 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 796 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
807 out_buffer_size_ - out_buffer_pos_,
808 "%08x ", 797 "%08x ",
809 instr->InstructionBits()); 798 instr->InstructionBits());
810 if (instr->ConditionField() == special_condition) { 799 if (instr->ConditionField() == special_condition) {
811 Format(instr, "break 'msg"); 800 Format(instr, "break 'msg");
812 return Instr::kInstrSize; 801 return Instr::kInstrSize;
813 } 802 }
814 switch (instr->TypeField()) { 803 switch (instr->TypeField()) {
815 case 0: { 804 case 0: {
816 DecodeType0(instr); 805 DecodeType0(instr);
817 break; 806 break;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 Disassembler::Disassembler() : converter_(defaultConverter) {} 904 Disassembler::Disassembler() : converter_(defaultConverter) {}
916 905
917 906
918 Disassembler::Disassembler(const NameConverter& converter) 907 Disassembler::Disassembler(const NameConverter& converter)
919 : converter_(converter) {} 908 : converter_(converter) {}
920 909
921 910
922 Disassembler::~Disassembler() {} 911 Disassembler::~Disassembler() {}
923 912
924 913
925 int Disassembler::InstructionDecode(char* buffer, const int buffer_size, 914 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
926 byte* instruction) { 915 byte* instruction) {
927 assembler::arm::Decoder d(converter_, buffer, buffer_size); 916 assembler::arm::Decoder d(converter_, buffer);
928 return d.InstructionDecode(instruction); 917 return d.InstructionDecode(instruction);
929 } 918 }
930 919
931 920
932 int Disassembler::ConstantPoolSizeAt(byte* instruction) { 921 int Disassembler::ConstantPoolSizeAt(byte* instruction) {
933 int instruction_bits = *(reinterpret_cast<int*>(instruction)); 922 int instruction_bits = *(reinterpret_cast<int*>(instruction));
934 if ((instruction_bits & 0xfff00000) == 0x03000000) { 923 if ((instruction_bits & 0xfff00000) == 0x03000000) {
935 return instruction_bits & 0x0000ffff; 924 return instruction_bits & 0x0000ffff;
936 } else { 925 } else {
937 return -1; 926 return -1;
938 } 927 }
939 } 928 }
940 929
941 930
942 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { 931 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
943 Disassembler d; 932 Disassembler d;
944 for (byte* pc = begin; pc < end;) { 933 for (byte* pc = begin; pc < end;) {
945 char buffer[128]; 934 v8::internal::EmbeddedVector<char, 128> buffer;
946 buffer[0] = '\0'; 935 buffer[0] = '\0';
947 byte* prev_pc = pc; 936 byte* prev_pc = pc;
948 pc += d.InstructionDecode(buffer, sizeof buffer, pc); 937 pc += d.InstructionDecode(buffer, pc);
949 fprintf(f, "%p %08x %s\n", 938 fprintf(f, "%p %08x %s\n",
950 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer); 939 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
951 } 940 }
952 } 941 }
953 942
954 943
955 } // namespace disasm 944 } // namespace disasm
OLDNEW
« no previous file with comments | « no previous file | src/platform-macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698