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

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

Issue 348019: Add vfp support on ARM. Patch from John Jozwiak. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 1 month 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 | « src/arm/cpu-arm.cc ('k') | src/arm/simulator-arm.h » ('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-2009 the V8 project authors. All rights reserved. 1 // Copyright 2007-2009 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 // Returns the length of the disassembled machine instruction in bytes. 90 // Returns the length of the disassembled machine instruction in bytes.
91 int InstructionDecode(byte* instruction); 91 int InstructionDecode(byte* instruction);
92 92
93 private: 93 private:
94 // Bottleneck functions to print into the out_buffer. 94 // Bottleneck functions to print into the out_buffer.
95 void PrintChar(const char ch); 95 void PrintChar(const char ch);
96 void Print(const char* str); 96 void Print(const char* str);
97 97
98 // Printing of common values. 98 // Printing of common values.
99 void PrintRegister(int reg); 99 void PrintRegister(int reg);
100 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);
100 void PrintCondition(Instr* instr); 104 void PrintCondition(Instr* instr);
101 void PrintShiftRm(Instr* instr); 105 void PrintShiftRm(Instr* instr);
102 void PrintShiftImm(Instr* instr); 106 void PrintShiftImm(Instr* instr);
103 void PrintPU(Instr* instr); 107 void PrintPU(Instr* instr);
104 void PrintSoftwareInterrupt(SoftwareInterruptCodes swi); 108 void PrintSoftwareInterrupt(SoftwareInterruptCodes swi);
105 109
106 // Handle formatting of instructions and their options. 110 // Handle formatting of instructions and their options.
107 int FormatRegister(Instr* instr, const char* option); 111 int FormatRegister(Instr* instr, const char* option);
108 int FormatOption(Instr* instr, const char* option); 112 int FormatOption(Instr* instr, const char* option);
109 void Format(Instr* instr, const char* format); 113 void Format(Instr* instr, const char* format);
110 void Unknown(Instr* instr); 114 void Unknown(Instr* instr);
111 115
112 // Each of these functions decodes one particular instruction type, a 3-bit 116 // Each of these functions decodes one particular instruction type, a 3-bit
113 // field in the instruction encoding. 117 // field in the instruction encoding.
114 // Types 0 and 1 are combined as they are largely the same except for the way 118 // Types 0 and 1 are combined as they are largely the same except for the way
115 // they interpret the shifter operand. 119 // they interpret the shifter operand.
116 void DecodeType01(Instr* instr); 120 void DecodeType01(Instr* instr);
117 void DecodeType2(Instr* instr); 121 void DecodeType2(Instr* instr);
118 void DecodeType3(Instr* instr); 122 void DecodeType3(Instr* instr);
119 void DecodeType4(Instr* instr); 123 void DecodeType4(Instr* instr);
120 void DecodeType5(Instr* instr); 124 void DecodeType5(Instr* instr);
121 void DecodeType6(Instr* instr); 125 void DecodeType6(Instr* instr);
122 void DecodeType7(Instr* instr); 126 void DecodeType7(Instr* instr);
123 void DecodeUnconditional(Instr* instr); 127 void DecodeUnconditional(Instr* instr);
128 // For VFP support.
129 void DecodeTypeVFP(Instr* instr);
130 void DecodeType6CoprocessorIns(Instr* instr);
131
124 132
125 const disasm::NameConverter& converter_; 133 const disasm::NameConverter& converter_;
126 v8::internal::Vector<char> out_buffer_; 134 v8::internal::Vector<char> out_buffer_;
127 int out_buffer_pos_; 135 int out_buffer_pos_;
128 136
129 DISALLOW_COPY_AND_ASSIGN(Decoder); 137 DISALLOW_COPY_AND_ASSIGN(Decoder);
130 }; 138 };
131 139
132 140
133 // Support for assertions in the Decoder formatting functions. 141 // Support for assertions in the Decoder formatting functions.
(...skipping 30 matching lines...) Expand all
164 void Decoder::PrintCondition(Instr* instr) { 172 void Decoder::PrintCondition(Instr* instr) {
165 Print(cond_names[instr->ConditionField()]); 173 Print(cond_names[instr->ConditionField()]);
166 } 174 }
167 175
168 176
169 // Print the register name according to the active name converter. 177 // Print the register name according to the active name converter.
170 void Decoder::PrintRegister(int reg) { 178 void Decoder::PrintRegister(int reg) {
171 Print(converter_.NameOfCPURegister(reg)); 179 Print(converter_.NameOfCPURegister(reg));
172 } 180 }
173 181
182 // Print the VFP S register name according to the active name converter.
183 void 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.
188 void Decoder::PrintDRegister(int reg) {
189 Print(assembler::arm::VFPRegisters::Name(reg + 32));
190 }
191
174 192
175 // These shift names are defined in a way to match the native disassembler 193 // These shift names are defined in a way to match the native disassembler
176 // formatting. See for example the command "objdump -d <binary file>". 194 // formatting. See for example the command "objdump -d <binary file>".
177 static const char* shift_names[max_shift] = { 195 static const char* shift_names[max_shift] = {
178 "lsl", "lsr", "asr", "ror" 196 "lsl", "lsr", "asr", "ror"
179 }; 197 };
180 198
181 199
182 // Print the register shift operands for the instruction. Generally used for 200 // Print the register shift operands for the instruction. Generally used for
183 // data processing instructions. 201 // data processing instructions.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 PrintRegister(reg); 301 PrintRegister(reg);
284 return 2; 302 return 2;
285 } else if (format[1] == 's') { // 'rs: Rs register 303 } else if (format[1] == 's') { // 'rs: Rs register
286 int reg = instr->RsField(); 304 int reg = instr->RsField();
287 PrintRegister(reg); 305 PrintRegister(reg);
288 return 2; 306 return 2;
289 } else if (format[1] == 'm') { // 'rm: Rm register 307 } else if (format[1] == 'm') { // 'rm: Rm register
290 int reg = instr->RmField(); 308 int reg = instr->RmField();
291 PrintRegister(reg); 309 PrintRegister(reg);
292 return 2; 310 return 2;
311 } else if (format[1] == 't') { // 'rt: Rt register
312 int reg = instr->RtField();
313 PrintRegister(reg);
314 return 2;
293 } else if (format[1] == 'l') { 315 } else if (format[1] == 'l') {
294 // 'rlist: register list for load and store multiple instructions 316 // 'rlist: register list for load and store multiple instructions
295 ASSERT(STRING_STARTS_WITH(format, "rlist")); 317 ASSERT(STRING_STARTS_WITH(format, "rlist"));
296 int rlist = instr->RlistField(); 318 int rlist = instr->RlistField();
297 int reg = 0; 319 int reg = 0;
298 Print("{"); 320 Print("{");
299 // Print register list in ascending order, by scanning the bit mask. 321 // Print register list in ascending order, by scanning the bit mask.
300 while (rlist != 0) { 322 while (rlist != 0) {
301 if ((rlist & 1) != 0) { 323 if ((rlist & 1) != 0) {
302 PrintRegister(reg); 324 PrintRegister(reg);
303 if ((rlist >> 1) != 0) { 325 if ((rlist >> 1) != 0) {
304 Print(", "); 326 Print(", ");
305 } 327 }
306 } 328 }
307 reg++; 329 reg++;
308 rlist >>= 1; 330 rlist >>= 1;
309 } 331 }
310 Print("}"); 332 Print("}");
311 return 5; 333 return 5;
312 } 334 }
313 UNREACHABLE(); 335 UNREACHABLE();
314 return -1; 336 return -1;
315 } 337 }
316 338
339 // Handle all VFP register based formatting in this function to reduce the
340 // complexity of FormatOption.
341 int Decoder::FormatVFPRegister(Instr* instr, const char* format) {
342 ASSERT((format[0] == 'S') || (format[0] == 'D'));
343
344 if (format[1] == 'n') {
345 int reg = instr->VnField();
346 if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->NField()));
347 if (format[0] == 'D') PrintDRegister(reg);
348 return 2;
349 } else if (format[1] == 'm') {
350 int reg = instr->VmField();
351 if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->MField()));
352 if (format[0] == 'D') PrintDRegister(reg);
353 return 2;
354 } else if (format[1] == 'd') {
355 int reg = instr->VdField();
356 if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->DField()));
357 if (format[0] == 'D') PrintDRegister(reg);
358 return 2;
359 }
360
361 UNREACHABLE();
362 return -1;
363 }
364
365 int Decoder::FormatVFPinstruction(Instr* instr, const char* format) {
366 Print(format);
367 return 0;
368 }
369
370
371
317 372
318 // FormatOption takes a formatting string and interprets it based on 373 // FormatOption takes a formatting string and interprets it based on
319 // the current instructions. The format string points to the first 374 // the current instructions. The format string points to the first
320 // character of the option string (the option escape has already been 375 // character of the option string (the option escape has already been
321 // consumed by the caller.) FormatOption returns the number of 376 // consumed by the caller.) FormatOption returns the number of
322 // characters that were consumed from the formatting string. 377 // characters that were consumed from the formatting string.
323 int Decoder::FormatOption(Instr* instr, const char* format) { 378 int Decoder::FormatOption(Instr* instr, const char* format) {
324 switch (format[0]) { 379 switch (format[0]) {
325 case 'a': { // 'a: accumulate multiplies 380 case 'a': { // 'a: accumulate multiplies
326 if (instr->Bit(21) == 0) { 381 if (instr->Bit(21) == 0) {
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 // arbitrary ways that are unrelated to the signedness of the instruction. 507 // arbitrary ways that are unrelated to the signedness of the instruction.
453 // None of these 18 instructions exist in both a 'u' and an 's' variant. 508 // None of these 18 instructions exist in both a 'u' and an 's' variant.
454 509
455 if (instr->Bit(22) == 0) { 510 if (instr->Bit(22) == 0) {
456 Print("u"); 511 Print("u");
457 } else { 512 } else {
458 Print("s"); 513 Print("s");
459 } 514 }
460 return 1; 515 return 1;
461 } 516 }
517 case 'v': {
518 return FormatVFPinstruction(instr, format);
519 }
520 case 'S':
521 case 'D': {
522 return FormatVFPRegister(instr, format);
523 }
462 case 'w': { // 'w: W field of load and store instructions 524 case 'w': { // 'w: W field of load and store instructions
463 if (instr->HasW()) { 525 if (instr->HasW()) {
464 Print("!"); 526 Print("!");
465 } 527 }
466 return 1; 528 return 1;
467 } 529 }
468 default: { 530 default: {
469 UNREACHABLE(); 531 UNREACHABLE();
470 break; 532 break;
471 } 533 }
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 } 816 }
755 } 817 }
756 818
757 819
758 void Decoder::DecodeType5(Instr* instr) { 820 void Decoder::DecodeType5(Instr* instr) {
759 Format(instr, "b'l'cond 'target"); 821 Format(instr, "b'l'cond 'target");
760 } 822 }
761 823
762 824
763 void Decoder::DecodeType6(Instr* instr) { 825 void Decoder::DecodeType6(Instr* instr) {
764 // Coprocessor instructions currently not supported. 826 DecodeType6CoprocessorIns(instr);
765 Unknown(instr);
766 } 827 }
767 828
768 829
769 void Decoder::DecodeType7(Instr* instr) { 830 void Decoder::DecodeType7(Instr* instr) {
770 if (instr->Bit(24) == 1) { 831 if (instr->Bit(24) == 1) {
771 Format(instr, "swi'cond 'swi"); 832 Format(instr, "swi'cond 'swi");
772 } else { 833 } else {
773 // Coprocessor instructions currently not supported. 834 DecodeTypeVFP(instr);
774 Unknown(instr);
775 } 835 }
776 } 836 }
777 837
778
779 void Decoder::DecodeUnconditional(Instr* instr) { 838 void Decoder::DecodeUnconditional(Instr* instr) {
780 if (instr->Bits(7, 4) == 0xB && instr->Bits(27, 25) == 0 && instr->HasL()) { 839 if (instr->Bits(7, 4) == 0xB && instr->Bits(27, 25) == 0 && instr->HasL()) {
781 Format(instr, "'memop'h'pu 'rd, "); 840 Format(instr, "'memop'h'pu 'rd, ");
782 bool immediate = instr->HasB(); 841 bool immediate = instr->HasB();
783 switch (instr->PUField()) { 842 switch (instr->PUField()) {
784 case 0: { 843 case 0: {
785 // Post index, negative. 844 // Post index, negative.
786 if (instr->HasW()) { 845 if (instr->HasW()) {
787 Unknown(instr); 846 Unknown(instr);
788 break; 847 break;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 UNREACHABLE(); 889 UNREACHABLE();
831 break; 890 break;
832 } 891 }
833 } 892 }
834 return; 893 return;
835 } 894 }
836 Format(instr, "break 'msg"); 895 Format(instr, "break 'msg");
837 } 896 }
838 897
839 898
899 // void Decoder::DecodeTypeVFP(Instr* instr)
900 // Implements the following
901 // VFP instructions
902 // fmsr :Sn = Rt
903 // fmrs :Rt = Sn
904 // fsitod: Dd = Sm
905 // ftosid: Sd = Dm
906 // Dd = faddd(Dn, Dm)
907 // Dd = fsubd(Dn, Dm)
908 // Dd = fmuld(Dn, Dm)
909 // Dd = fdivd(Dn, Dm)
910 // vcmp(Dd, Dm)
911 // VMRS
912 void Decoder::DecodeTypeVFP(Instr* instr) {
913 ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) );
914
915 if (instr->Bit(23) == 1) {
916 if ((instr->Bits(21, 19) == 0x7) &&
917 (instr->Bits(18, 16) == 0x5) &&
918 (instr->Bits(11, 9) == 0x5) &&
919 (instr->Bit(8) == 1) &&
920 (instr->Bit(6) == 1) &&
921 (instr->Bit(4) == 0)) {
922 Format(instr, "vcvt.s32.f64'cond 'Sd, 'Dm");
923 } else if ((instr->Bits(21, 19) == 0x7) &&
924 (instr->Bits(18, 16) == 0x0) &&
925 (instr->Bits(11, 9) == 0x5) &&
926 (instr->Bit(8) == 1) &&
927 (instr->Bit(7) == 1) &&
928 (instr->Bit(6) == 1) &&
929 (instr->Bit(4) == 0)) {
930 Format(instr, "vcvt.f64.s32'cond 'Dd, 'Sm");
931 } else if ((instr->Bit(21) == 0x0) &&
932 (instr->Bit(20) == 0x0) &&
933 (instr->Bits(11, 9) == 0x5) &&
934 (instr->Bit(8) == 1) &&
935 (instr->Bit(6) == 0) &&
936 (instr->Bit(4) == 0)) {
937 Format(instr, "vdiv.f64'cond 'Dd, 'Dn, 'Dm");
938 } else if ((instr->Bits(21, 20) == 0x3) &&
939 (instr->Bits(19, 16) == 0x4) &&
940 (instr->Bits(11, 9) == 0x5) &&
941 (instr->Bit(8) == 0x1) &&
942 (instr->Bit(6) == 0x1) &&
943 (instr->Bit(4) == 0x0)) {
944 Format(instr, "vcmp.f64'cond 'Dd, 'Dm");
945 } else if ((instr->Bits(23, 20) == 0xF) &&
946 (instr->Bits(19, 16) == 0x1) &&
947 (instr->Bits(11, 8) == 0xA) &&
948 (instr->Bits(7, 5) == 0x0) &&
949 (instr->Bit(4) == 0x1) &&
950 (instr->Bits(3, 0) == 0x0)) {
951 if (instr->Bits(15, 12) == 0xF)
952 Format(instr, "vmrs'cond APSR, FPSCR");
953 else
954 Unknown(instr); // not used by V8
955 } else {
956 Unknown(instr); // not used by V8
957 }
958 } else if (instr->Bit(21) == 1) {
959 if ((instr->Bit(20) == 0x1) &&
960 (instr->Bits(11, 9) == 0x5) &&
961 (instr->Bit(8) == 0x1) &&
962 (instr->Bit(6) == 0) &&
963 (instr->Bit(4) == 0)) {
964 Format(instr, "vadd.f64'cond 'Dd, 'Dn, 'Dm");
965 } else if ((instr->Bit(20) == 0x1) &&
966 (instr->Bits(11, 9) == 0x5) &&
967 (instr->Bit(8) == 0x1) &&
968 (instr->Bit(6) == 1) &&
969 (instr->Bit(4) == 0)) {
970 Format(instr, "vsub.f64'cond 'Dd, 'Dn, 'Dm");
971 } else if ((instr->Bit(20) == 0x0) &&
972 (instr->Bits(11, 9) == 0x5) &&
973 (instr->Bit(8) == 0x1) &&
974 (instr->Bit(6) == 0) &&
975 (instr->Bit(4) == 0)) {
976 Format(instr, "vmul.f64'cond 'Dd, 'Dn, 'Dm");
977 } else {
978 Unknown(instr); // not used by V8
979 }
980 } else {
981 if ((instr->Bit(20) == 0x0) &&
982 (instr->Bits(11, 8) == 0xA) &&
983 (instr->Bits(6, 5) == 0x0) &&
984 (instr->Bit(4) == 1) &&
985 (instr->Bits(3, 0) == 0x0)) {
986 Format(instr, "vmov'cond 'Sn, 'rt");
987 } else if ((instr->Bit(20) == 0x1) &&
988 (instr->Bits(11, 8) == 0xA) &&
989 (instr->Bits(6, 5) == 0x0) &&
990 (instr->Bit(4) == 1) &&
991 (instr->Bits(3, 0) == 0x0)) {
992 Format(instr, "vmov'cond 'rt, 'Sn");
993 } else {
994 Unknown(instr); // not used by V8
995 }
996 }
997 }
998
999
1000
1001 // Decode Type 6 coprocessor instructions
1002 // Dm = fmdrr(Rt, Rt2)
1003 // <Rt, Rt2> = fmrrd(Dm)
1004 void Decoder::DecodeType6CoprocessorIns(Instr* instr) {
1005 ASSERT((instr->TypeField() == 6));
1006
1007 if (instr->Bit(23) == 1) {
1008 Unknown(instr); // not used by V8
1009 } else if (instr->Bit(22) == 1) {
1010 if ((instr->Bits(27, 24) == 0xC) &&
1011 (instr->Bit(22) == 1) &&
1012 (instr->Bits(11, 8) == 0xB) &&
1013 (instr->Bits(7, 6) == 0x0) &&
1014 (instr->Bit(4) == 1)) {
1015 if (instr->Bit(20) == 0) {
1016 Format(instr, "vmov'cond 'Dm, 'rt, 'rn");
1017 } else if (instr->Bit(20) == 1) {
1018 Format(instr, "vmov'cond 'rt, 'rn, 'Dm");
1019 }
1020 } else {
1021 Unknown(instr); // not used by V8
1022 }
1023 } else if (instr->Bit(21) == 1) {
1024 Unknown(instr); // not used by V8
1025 } else {
1026 Unknown(instr); // not used by V8
1027 }
1028 }
1029
1030
840 // Disassemble the instruction at *instr_ptr into the output buffer. 1031 // Disassemble the instruction at *instr_ptr into the output buffer.
841 int Decoder::InstructionDecode(byte* instr_ptr) { 1032 int Decoder::InstructionDecode(byte* instr_ptr) {
842 Instr* instr = Instr::At(instr_ptr); 1033 Instr* instr = Instr::At(instr_ptr);
843 // Print raw instruction bytes. 1034 // Print raw instruction bytes.
844 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 1035 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
845 "%08x ", 1036 "%08x ",
846 instr->InstructionBits()); 1037 instr->InstructionBits());
847 if (instr->ConditionField() == special_condition) { 1038 if (instr->ConditionField() == special_condition) {
848 DecodeUnconditional(instr); 1039 DecodeUnconditional(instr);
849 return Instr::kInstrSize; 1040 return Instr::kInstrSize;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 buffer[0] = '\0'; 1160 buffer[0] = '\0';
970 byte* prev_pc = pc; 1161 byte* prev_pc = pc;
971 pc += d.InstructionDecode(buffer, pc); 1162 pc += d.InstructionDecode(buffer, pc);
972 fprintf(f, "%p %08x %s\n", 1163 fprintf(f, "%p %08x %s\n",
973 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); 1164 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
974 } 1165 }
975 } 1166 }
976 1167
977 1168
978 } // namespace disasm 1169 } // namespace disasm
OLDNEW
« no previous file with comments | « src/arm/cpu-arm.cc ('k') | src/arm/simulator-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698