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

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

Issue 993002: Port of optimized ICs for external and pixel arrays from ia32 to ARM. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 void DecodeType3(Instr* instr); 122 void DecodeType3(Instr* instr);
123 void DecodeType4(Instr* instr); 123 void DecodeType4(Instr* instr);
124 void DecodeType5(Instr* instr); 124 void DecodeType5(Instr* instr);
125 void DecodeType6(Instr* instr); 125 void DecodeType6(Instr* instr);
126 void DecodeType7(Instr* instr); 126 void DecodeType7(Instr* instr);
127 void DecodeUnconditional(Instr* instr); 127 void DecodeUnconditional(Instr* instr);
128 // For VFP support. 128 // For VFP support.
129 void DecodeTypeVFP(Instr* instr); 129 void DecodeTypeVFP(Instr* instr);
130 void DecodeType6CoprocessorIns(Instr* instr); 130 void DecodeType6CoprocessorIns(Instr* instr);
131 131
132 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instr* instr);
133 void DecodeVCMP(Instr* instr);
134 void DecodeVCVTBetweenDoubleAndSingle(Instr* instr);
135 void DecodeVCVTBetweenFloatingPointAndInteger(Instr* instr);
132 136
133 const disasm::NameConverter& converter_; 137 const disasm::NameConverter& converter_;
134 v8::internal::Vector<char> out_buffer_; 138 v8::internal::Vector<char> out_buffer_;
135 int out_buffer_pos_; 139 int out_buffer_pos_;
136 140
137 DISALLOW_COPY_AND_ASSIGN(Decoder); 141 DISALLOW_COPY_AND_ASSIGN(Decoder);
138 }; 142 };
139 143
140 144
141 // Support for assertions in the Decoder formatting functions. 145 // Support for assertions in the Decoder formatting functions.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 } 178 }
175 179
176 180
177 // Print the register name according to the active name converter. 181 // Print the register name according to the active name converter.
178 void Decoder::PrintRegister(int reg) { 182 void Decoder::PrintRegister(int reg) {
179 Print(converter_.NameOfCPURegister(reg)); 183 Print(converter_.NameOfCPURegister(reg));
180 } 184 }
181 185
182 // Print the VFP S register name according to the active name converter. 186 // Print the VFP S register name according to the active name converter.
183 void Decoder::PrintSRegister(int reg) { 187 void Decoder::PrintSRegister(int reg) {
184 Print(assembler::arm::VFPRegisters::Name(reg)); 188 Print(assembler::arm::VFPRegisters::Name(reg, false));
185 } 189 }
186 190
187 // Print the VFP D register name according to the active name converter. 191 // Print the VFP D register name according to the active name converter.
188 void Decoder::PrintDRegister(int reg) { 192 void Decoder::PrintDRegister(int reg) {
189 Print(assembler::arm::VFPRegisters::Name(reg + 32)); 193 Print(assembler::arm::VFPRegisters::Name(reg, true));
190 } 194 }
191 195
192 196
193 // These shift names are defined in a way to match the native disassembler 197 // These shift names are defined in a way to match the native disassembler
194 // formatting. See for example the command "objdump -d <binary file>". 198 // formatting. See for example the command "objdump -d <binary file>".
195 static const char* shift_names[max_shift] = { 199 static const char* shift_names[max_shift] = {
196 "lsl", "lsr", "asr", "ror" 200 "lsl", "lsr", "asr", "ror"
197 }; 201 };
198 202
199 203
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 // vcvt: Dd = Sm 927 // vcvt: Dd = Sm
924 // vcvt: Sd = Dm 928 // vcvt: Sd = Dm
925 // Dd = vadd(Dn, Dm) 929 // Dd = vadd(Dn, Dm)
926 // Dd = vsub(Dn, Dm) 930 // Dd = vsub(Dn, Dm)
927 // Dd = vmul(Dn, Dm) 931 // Dd = vmul(Dn, Dm)
928 // Dd = vdiv(Dn, Dm) 932 // Dd = vdiv(Dn, Dm)
929 // vcmp(Dd, Dm) 933 // vcmp(Dd, Dm)
930 // VMRS 934 // VMRS
931 void Decoder::DecodeTypeVFP(Instr* instr) { 935 void Decoder::DecodeTypeVFP(Instr* instr) {
932 ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) ); 936 ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) );
937 ASSERT(instr->Bits(11, 9) == 0x5);
933 938
934 if (instr->Bit(23) == 1) { 939 if (instr->Bit(4) == 0) {
935 if ((instr->Bits(21, 19) == 0x7) && 940 if (instr->Opc1Field() == 0x7) {
936 (instr->Bits(18, 16) == 0x5) && 941 // Other data processing instructions
937 (instr->Bits(11, 9) == 0x5) && 942 if ((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3)) {
938 (instr->Bit(8) == 1) && 943 DecodeVCVTBetweenDoubleAndSingle(instr);
939 (instr->Bit(6) == 1) && 944 } else if ((instr->Opc2Field() == 0x8) && (instr->Opc3Field() & 0x1)) {
940 (instr->Bit(4) == 0)) { 945 DecodeVCVTBetweenFloatingPointAndInteger(instr);
941 Format(instr, "vcvt.s32.f64'cond 'Sd, 'Dm"); 946 } else if (((instr->Opc2Field() >> 1) == 0x6) &&
942 } else if ((instr->Bits(21, 19) == 0x7) && 947 (instr->Opc3Field() & 0x1)) {
943 (instr->Bits(18, 16) == 0x0) && 948 DecodeVCVTBetweenFloatingPointAndInteger(instr);
944 (instr->Bits(11, 9) == 0x5) && 949 } else if (((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) &&
945 (instr->Bit(8) == 1) && 950 (instr->Opc3Field() & 0x1)) {
946 (instr->Bit(7) == 1) && 951 DecodeVCMP(instr);
947 (instr->Bit(6) == 1) && 952 } else {
948 (instr->Bit(4) == 0)) { 953 Unknown(instr); // Not used by V8.
949 Format(instr, "vcvt.f64.s32'cond 'Dd, 'Sm"); 954 }
950 } else if ((instr->Bit(21) == 0x0) && 955 } else if (instr->Opc1Field() == 0x3) {
951 (instr->Bit(20) == 0x0) && 956 if (instr->SzField() == 0x1) {
952 (instr->Bits(11, 9) == 0x5) && 957 if (instr->Opc3Field() & 0x1) {
953 (instr->Bit(8) == 1) && 958 Format(instr, "vsub.f64'cond 'Dd, 'Dn, 'Dm");
954 (instr->Bit(6) == 0) && 959 } else {
955 (instr->Bit(4) == 0)) { 960 Format(instr, "vadd.f64'cond 'Dd, 'Dn, 'Dm");
961 }
962 } else {
963 Unknown(instr); // Not used by V8.
964 }
965 } else if ((instr->Opc1Field() == 0x2) && !(instr->Opc3Field() & 0x1)) {
966 if (instr->SzField() == 0x1) {
967 Format(instr, "vmul.f64'cond 'Dd, 'Dn, 'Dm");
968 } else {
969 Unknown(instr); // Not used by V8.
970 }
971 } else if ((instr->Opc1Field() == 0x4) && !(instr->Opc3Field() & 0x1)) {
972 if (instr->SzField() == 0x1) {
956 Format(instr, "vdiv.f64'cond 'Dd, 'Dn, 'Dm"); 973 Format(instr, "vdiv.f64'cond 'Dd, 'Dn, 'Dm");
957 } else if ((instr->Bits(21, 20) == 0x3) && 974 } else {
958 (instr->Bits(19, 16) == 0x4) && 975 Unknown(instr); // Not used by V8.
959 (instr->Bits(11, 9) == 0x5) && 976 }
960 (instr->Bit(8) == 0x1) &&
961 (instr->Bit(6) == 0x1) &&
962 (instr->Bit(4) == 0x0)) {
963 Format(instr, "vcmp.f64'cond 'Dd, 'Dm");
964 } else if ((instr->Bits(23, 20) == 0xF) &&
965 (instr->Bits(19, 16) == 0x1) &&
966 (instr->Bits(11, 8) == 0xA) &&
967 (instr->Bits(7, 5) == 0x0) &&
968 (instr->Bit(4) == 0x1) &&
969 (instr->Bits(3, 0) == 0x0)) {
970 if (instr->Bits(15, 12) == 0xF)
971 Format(instr, "vmrs'cond APSR, FPSCR");
972 else
973 Unknown(instr); // Not used by V8.
974 } else {
975 Unknown(instr); // Not used by V8.
976 }
977 } else if (instr->Bit(21) == 1) {
978 if ((instr->Bit(20) == 0x1) &&
979 (instr->Bits(11, 9) == 0x5) &&
980 (instr->Bit(8) == 0x1) &&
981 (instr->Bit(6) == 0) &&
982 (instr->Bit(4) == 0)) {
983 Format(instr, "vadd.f64'cond 'Dd, 'Dn, 'Dm");
984 } else if ((instr->Bit(20) == 0x1) &&
985 (instr->Bits(11, 9) == 0x5) &&
986 (instr->Bit(8) == 0x1) &&
987 (instr->Bit(6) == 1) &&
988 (instr->Bit(4) == 0)) {
989 Format(instr, "vsub.f64'cond 'Dd, 'Dn, 'Dm");
990 } else if ((instr->Bit(20) == 0x0) &&
991 (instr->Bits(11, 9) == 0x5) &&
992 (instr->Bit(8) == 0x1) &&
993 (instr->Bit(6) == 0) &&
994 (instr->Bit(4) == 0)) {
995 Format(instr, "vmul.f64'cond 'Dd, 'Dn, 'Dm");
996 } else { 977 } else {
997 Unknown(instr); // Not used by V8. 978 Unknown(instr); // Not used by V8.
998 } 979 }
999 } else { 980 } else {
1000 if ((instr->Bit(20) == 0x0) && 981 if ((instr->VCField() == 0x0) &&
1001 (instr->Bits(11, 8) == 0xA) && 982 (instr->VAField() == 0x0)) {
1002 (instr->Bits(6, 5) == 0x0) && 983 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
1003 (instr->Bit(4) == 1) && 984 } else if ((instr->VLField() == 0x1) &&
1004 (instr->Bits(3, 0) == 0x0)) { 985 (instr->VCField() == 0x0) &&
1005 Format(instr, "vmov'cond 'Sn, 'rt"); 986 (instr->VAField() == 0x7) &&
1006 } else if ((instr->Bit(20) == 0x1) && 987 (instr->Bits(19, 16) == 0x1)) {
1007 (instr->Bits(11, 8) == 0xA) && 988 if (instr->Bits(15, 12) == 0xF)
1008 (instr->Bits(6, 5) == 0x0) && 989 Format(instr, "vmrs'cond APSR, FPSCR");
1009 (instr->Bit(4) == 1) && 990 else
1010 (instr->Bits(3, 0) == 0x0)) { 991 Unknown(instr); // Not used by V8.
1011 Format(instr, "vmov'cond 'rt, 'Sn");
1012 } else { 992 } else {
1013 Unknown(instr); // Not used by V8. 993 Unknown(instr); // Not used by V8.
1014 } 994 }
1015 } 995 }
1016 } 996 }
1017 997
998
999 void Decoder::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instr* instr) {
1000 ASSERT((instr->Bit(4) == 1) && (instr->VCField() == 0x0) &&
1001 (instr->VAField() == 0x0));
1002
1003 bool to_arm_register = (instr->VLField() == 0x1);
1004
1005 if (to_arm_register) {
1006 Format(instr, "vmov'cond 'rt, 'Sn");
1007 } else {
1008 Format(instr, "vmov'cond 'Sn, 'rt");
1009 }
1010 }
1011
1012
1013 void Decoder::DecodeVCMP(Instr* instr) {
1014 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
1015 ASSERT(((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) &&
1016 (instr->Opc3Field() & 0x1));
1017
1018 // Comparison.
1019 bool dp_operation = (instr->SzField() == 1);
1020 bool raise_exception_for_qnan = (instr->Bit(7) == 0x1);
1021
1022 if (dp_operation && !raise_exception_for_qnan) {
1023 Format(instr, "vcmp.f64'cond 'Dd, 'Dm");
1024 } else {
1025 Unknown(instr); // Not used by V8.
1026 }
1027 }
1028
1029
1030 void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instr* instr) {
1031 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
1032 ASSERT((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3));
1033
1034 bool double_to_single = (instr->SzField() == 1);
1035
1036 if (double_to_single) {
1037 Format(instr, "vcvt.f32.f64'cond 'Sd, 'Dm");
1038 } else {
1039 Format(instr, "vcvt.f64.f32'cond 'Dd, 'Sm");
1040 }
1041 }
1042
1043
1044 void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instr* instr) {
1045 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
1046 ASSERT(((instr->Opc2Field() == 0x8) && (instr->Opc3Field() & 0x1)) ||
1047 (((instr->Opc2Field() >> 1) == 0x6) && (instr->Opc3Field() & 0x1)));
1048
1049 bool to_integer = (instr->Bit(18) == 1);
1050 bool dp_operation = (instr->SzField() == 1);
1051 if (to_integer) {
1052 bool unsigned_integer = (instr->Bit(16) == 0);
1053
1054 if (dp_operation) {
1055 if (unsigned_integer) {
1056 Format(instr, "vcvt.u32.f64'cond 'Sd, 'Dm");
1057 } else {
1058 Format(instr, "vcvt.s32.f64'cond 'Sd, 'Dm");
1059 }
1060 } else {
1061 if (unsigned_integer) {
1062 Format(instr, "vcvt.u32.f32'cond 'Sd, 'Sm");
1063 } else {
1064 Format(instr, "vcvt.s32.f32'cond 'Sd, 'Sm");
1065 }
1066 }
1067 } else {
1068 bool unsigned_integer = (instr->Bit(7) == 0);
1069
1070 if (dp_operation) {
1071 if (unsigned_integer) {
1072 Format(instr, "vcvt.f64.u32'cond 'Dd, 'Sm");
1073 } else {
1074 Format(instr, "vcvt.f64.s32'cond 'Dd, 'Sm");
1075 }
1076 } else {
1077 if (unsigned_integer) {
1078 Format(instr, "vcvt.f32.u32'cond 'Sd, 'Sm");
1079 } else {
1080 Format(instr, "vcvt.f32.s32'cond 'Sd, 'Sm");
1081 }
1082 }
1083 }
1084 }
1085
1018 1086
1019 // Decode Type 6 coprocessor instructions. 1087 // Decode Type 6 coprocessor instructions.
1020 // Dm = vmov(Rt, Rt2) 1088 // Dm = vmov(Rt, Rt2)
1021 // <Rt, Rt2> = vmov(Dm) 1089 // <Rt, Rt2> = vmov(Dm)
1022 // Ddst = MEM(Rbase + 4*offset). 1090 // Ddst = MEM(Rbase + 4*offset).
1023 // MEM(Rbase + 4*offset) = Dsrc. 1091 // MEM(Rbase + 4*offset) = Dsrc.
1024 void Decoder::DecodeType6CoprocessorIns(Instr* instr) { 1092 void Decoder::DecodeType6CoprocessorIns(Instr* instr) {
1025 ASSERT((instr->TypeField() == 6)); 1093 ASSERT((instr->TypeField() == 6));
1026 1094
1027 if (instr->CoprocessorField() != 0xB) { 1095 if (instr->CoprocessorField() == 0xA) {
1028 Unknown(instr); // Not used by V8. 1096 switch (instr->OpcodeField()) {
1029 } else { 1097 case 0x8:
1098 if (instr->HasL()) {
1099 Format(instr, "vldr'cond 'Sd, ['rn - 4*'off8]");
1100 } else {
1101 Format(instr, "vstr'cond 'Sd, ['rn - 4*'off8]");
1102 }
1103 break;
1104 case 0xC:
1105 if (instr->HasL()) {
1106 Format(instr, "vldr'cond 'Sd, ['rn + 4*'off8]");
1107 } else {
1108 Format(instr, "vstr'cond 'Sd, ['rn + 4*'off8]");
1109 }
1110 break;
1111 default:
1112 Unknown(instr); // Not used by V8.
1113 break;
1114 }
1115 } else if (instr->CoprocessorField() == 0xB) {
1030 switch (instr->OpcodeField()) { 1116 switch (instr->OpcodeField()) {
1031 case 0x2: 1117 case 0x2:
1032 // Load and store double to two GP registers 1118 // Load and store double to two GP registers
1033 if (instr->Bits(7, 4) != 0x1) { 1119 if (instr->Bits(7, 4) != 0x1) {
1034 Unknown(instr); // Not used by V8. 1120 Unknown(instr); // Not used by V8.
1035 } else if (instr->HasL()) { 1121 } else if (instr->HasL()) {
1036 Format(instr, "vmov'cond 'rt, 'rn, 'Dm"); 1122 Format(instr, "vmov'cond 'rt, 'rn, 'Dm");
1037 } else { 1123 } else {
1038 Format(instr, "vmov'cond 'Dm, 'rt, 'rn"); 1124 Format(instr, "vmov'cond 'Dm, 'rt, 'rn");
1039 } 1125 }
1040 break; 1126 break;
1041 case 0x8: 1127 case 0x8:
1042 if (instr->HasL()) { 1128 if (instr->HasL()) {
1043 Format(instr, "vldr'cond 'Dd, ['rn - 4*'off8]"); 1129 Format(instr, "vldr'cond 'Dd, ['rn - 4*'off8]");
1044 } else { 1130 } else {
1045 Format(instr, "vstr'cond 'Dd, ['rn - 4*'off8]"); 1131 Format(instr, "vstr'cond 'Dd, ['rn - 4*'off8]");
1046 } 1132 }
1047 break; 1133 break;
1048 case 0xC: 1134 case 0xC:
1049 if (instr->HasL()) { 1135 if (instr->HasL()) {
1050 Format(instr, "vldr'cond 'Dd, ['rn + 4*'off8]"); 1136 Format(instr, "vldr'cond 'Dd, ['rn + 4*'off8]");
1051 } else { 1137 } else {
1052 Format(instr, "vstr'cond 'Dd, ['rn + 4*'off8]"); 1138 Format(instr, "vstr'cond 'Dd, ['rn + 4*'off8]");
1053 } 1139 }
1054 break; 1140 break;
1055 default: 1141 default:
1056 Unknown(instr); // Not used by V8. 1142 Unknown(instr); // Not used by V8.
1057 break; 1143 break;
1058 } 1144 }
1145 } else {
1146 UNIMPLEMENTED(); // Not used by V8.
1059 } 1147 }
1060 } 1148 }
1061 1149
1062 1150
1063 // Disassemble the instruction at *instr_ptr into the output buffer. 1151 // Disassemble the instruction at *instr_ptr into the output buffer.
1064 int Decoder::InstructionDecode(byte* instr_ptr) { 1152 int Decoder::InstructionDecode(byte* instr_ptr) {
1065 Instr* instr = Instr::At(instr_ptr); 1153 Instr* instr = Instr::At(instr_ptr);
1066 // Print raw instruction bytes. 1154 // Print raw instruction bytes.
1067 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 1155 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1068 "%08x ", 1156 "%08x ",
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1192 buffer[0] = '\0'; 1280 buffer[0] = '\0';
1193 byte* prev_pc = pc; 1281 byte* prev_pc = pc;
1194 pc += d.InstructionDecode(buffer, pc); 1282 pc += d.InstructionDecode(buffer, pc);
1195 fprintf(f, "%p %08x %s\n", 1283 fprintf(f, "%p %08x %s\n",
1196 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); 1284 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
1197 } 1285 }
1198 } 1286 }
1199 1287
1200 1288
1201 } // namespace disasm 1289 } // namespace disasm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698