OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 void Decoder::DecodeTypeVFP(Instruction* instr) { | 1117 void Decoder::DecodeTypeVFP(Instruction* instr) { |
1118 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) ); | 1118 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) ); |
1119 VERIFY(instr->Bits(11, 9) == 0x5); | 1119 VERIFY(instr->Bits(11, 9) == 0x5); |
1120 | 1120 |
1121 if (instr->Bit(4) == 0) { | 1121 if (instr->Bit(4) == 0) { |
1122 if (instr->Opc1Value() == 0x7) { | 1122 if (instr->Opc1Value() == 0x7) { |
1123 // Other data processing instructions | 1123 // Other data processing instructions |
1124 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) { | 1124 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) { |
1125 // vmov register to register. | 1125 // vmov register to register. |
1126 if (instr->SzValue() == 0x1) { | 1126 if (instr->SzValue() == 0x1) { |
1127 Format(instr, "vmov.f64'cond 'Dd, 'Dm"); | 1127 Format(instr, "vmov'cond.f64 'Dd, 'Dm"); |
1128 } else { | 1128 } else { |
1129 Format(instr, "vmov.f32'cond 'Sd, 'Sm"); | 1129 Format(instr, "vmov'cond.f32 'Sd, 'Sm"); |
1130 } | 1130 } |
1131 } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) { | 1131 } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) { |
1132 // vabs | 1132 // vabs |
1133 Format(instr, "vabs.f64'cond 'Dd, 'Dm"); | 1133 Format(instr, "vabs'cond.f64 'Dd, 'Dm"); |
1134 } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) { | 1134 } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) { |
1135 // vneg | 1135 // vneg |
1136 Format(instr, "vneg.f64'cond 'Dd, 'Dm"); | 1136 Format(instr, "vneg'cond.f64 'Dd, 'Dm"); |
1137 } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) { | 1137 } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) { |
1138 DecodeVCVTBetweenDoubleAndSingle(instr); | 1138 DecodeVCVTBetweenDoubleAndSingle(instr); |
1139 } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) { | 1139 } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) { |
1140 DecodeVCVTBetweenFloatingPointAndInteger(instr); | 1140 DecodeVCVTBetweenFloatingPointAndInteger(instr); |
1141 } else if (((instr->Opc2Value() >> 1) == 0x6) && | 1141 } else if (((instr->Opc2Value() >> 1) == 0x6) && |
1142 (instr->Opc3Value() & 0x1)) { | 1142 (instr->Opc3Value() & 0x1)) { |
1143 DecodeVCVTBetweenFloatingPointAndInteger(instr); | 1143 DecodeVCVTBetweenFloatingPointAndInteger(instr); |
1144 } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && | 1144 } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && |
1145 (instr->Opc3Value() & 0x1)) { | 1145 (instr->Opc3Value() & 0x1)) { |
1146 DecodeVCMP(instr); | 1146 DecodeVCMP(instr); |
1147 } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) { | 1147 } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) { |
1148 Format(instr, "vsqrt.f64'cond 'Dd, 'Dm"); | 1148 Format(instr, "vsqrt'cond.f64 'Dd, 'Dm"); |
1149 } else if (instr->Opc3Value() == 0x0) { | 1149 } else if (instr->Opc3Value() == 0x0) { |
1150 if (instr->SzValue() == 0x1) { | 1150 if (instr->SzValue() == 0x1) { |
1151 Format(instr, "vmov.f64'cond 'Dd, 'd"); | 1151 Format(instr, "vmov'cond.f64 'Dd, 'd"); |
1152 } else { | 1152 } else { |
1153 Unknown(instr); // Not used by V8. | 1153 Unknown(instr); // Not used by V8. |
1154 } | 1154 } |
1155 } else { | 1155 } else { |
1156 Unknown(instr); // Not used by V8. | 1156 Unknown(instr); // Not used by V8. |
1157 } | 1157 } |
1158 } else if (instr->Opc1Value() == 0x3) { | 1158 } else if (instr->Opc1Value() == 0x3) { |
1159 if (instr->SzValue() == 0x1) { | 1159 if (instr->SzValue() == 0x1) { |
1160 if (instr->Opc3Value() & 0x1) { | 1160 if (instr->Opc3Value() & 0x1) { |
1161 Format(instr, "vsub.f64'cond 'Dd, 'Dn, 'Dm"); | 1161 Format(instr, "vsub'cond.f64 'Dd, 'Dn, 'Dm"); |
1162 } else { | 1162 } else { |
1163 Format(instr, "vadd.f64'cond 'Dd, 'Dn, 'Dm"); | 1163 Format(instr, "vadd'cond.f64 'Dd, 'Dn, 'Dm"); |
1164 } | 1164 } |
1165 } else { | 1165 } else { |
1166 Unknown(instr); // Not used by V8. | 1166 Unknown(instr); // Not used by V8. |
1167 } | 1167 } |
1168 } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) { | 1168 } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) { |
1169 if (instr->SzValue() == 0x1) { | 1169 if (instr->SzValue() == 0x1) { |
1170 Format(instr, "vmul.f64'cond 'Dd, 'Dn, 'Dm"); | 1170 Format(instr, "vmul'cond.f64 'Dd, 'Dn, 'Dm"); |
1171 } else { | 1171 } else { |
1172 Unknown(instr); // Not used by V8. | 1172 Unknown(instr); // Not used by V8. |
1173 } | 1173 } |
1174 } else if ((instr->Opc1Value() == 0x0) && !(instr->Opc3Value() & 0x1)) { | 1174 } else if ((instr->Opc1Value() == 0x0) && !(instr->Opc3Value() & 0x1)) { |
1175 if (instr->SzValue() == 0x1) { | 1175 if (instr->SzValue() == 0x1) { |
1176 Format(instr, "vmla.f64'cond 'Dd, 'Dn, 'Dm"); | 1176 Format(instr, "vmla'cond.f64 'Dd, 'Dn, 'Dm"); |
1177 } else { | 1177 } else { |
1178 Unknown(instr); // Not used by V8. | 1178 Unknown(instr); // Not used by V8. |
1179 } | 1179 } |
1180 } else if ((instr->Opc1Value() == 0x0) && (instr->Opc3Value() & 0x1)) { | 1180 } else if ((instr->Opc1Value() == 0x0) && (instr->Opc3Value() & 0x1)) { |
1181 if (instr->SzValue() == 0x1) { | 1181 if (instr->SzValue() == 0x1) { |
1182 Format(instr, "vmls.f64'cond 'Dd, 'Dn, 'Dm"); | 1182 Format(instr, "vmls'cond.f64 'Dd, 'Dn, 'Dm"); |
1183 } else { | 1183 } else { |
1184 Unknown(instr); // Not used by V8. | 1184 Unknown(instr); // Not used by V8. |
1185 } | 1185 } |
1186 } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) { | 1186 } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) { |
1187 if (instr->SzValue() == 0x1) { | 1187 if (instr->SzValue() == 0x1) { |
1188 Format(instr, "vdiv.f64'cond 'Dd, 'Dn, 'Dm"); | 1188 Format(instr, "vdiv'cond.f64 'Dd, 'Dn, 'Dm"); |
1189 } else { | 1189 } else { |
1190 Unknown(instr); // Not used by V8. | 1190 Unknown(instr); // Not used by V8. |
1191 } | 1191 } |
1192 } else { | 1192 } else { |
1193 Unknown(instr); // Not used by V8. | 1193 Unknown(instr); // Not used by V8. |
1194 } | 1194 } |
1195 } else { | 1195 } else { |
1196 if ((instr->VCValue() == 0x0) && | 1196 if ((instr->VCValue() == 0x0) && |
1197 (instr->VAValue() == 0x0)) { | 1197 (instr->VAValue() == 0x0)) { |
1198 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); | 1198 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); |
1199 } else if ((instr->VLValue() == 0x0) && | 1199 } else if ((instr->VLValue() == 0x0) && |
1200 (instr->VCValue() == 0x1) && | 1200 (instr->VCValue() == 0x1) && |
1201 (instr->Bit(23) == 0x0)) { | 1201 (instr->Bit(23) == 0x0)) { |
1202 if (instr->Bit(21) == 0x0) { | 1202 if (instr->Bit(21) == 0x0) { |
1203 Format(instr, "vmov.32'cond 'Dd[0], 'rt"); | 1203 Format(instr, "vmov'cond.32 'Dd[0], 'rt"); |
1204 } else { | 1204 } else { |
1205 Format(instr, "vmov.32'cond 'Dd[1], 'rt"); | 1205 Format(instr, "vmov'cond.32 'Dd[1], 'rt"); |
1206 } | 1206 } |
1207 } else if ((instr->VCValue() == 0x0) && | 1207 } else if ((instr->VCValue() == 0x0) && |
1208 (instr->VAValue() == 0x7) && | 1208 (instr->VAValue() == 0x7) && |
1209 (instr->Bits(19, 16) == 0x1)) { | 1209 (instr->Bits(19, 16) == 0x1)) { |
1210 if (instr->VLValue() == 0) { | 1210 if (instr->VLValue() == 0) { |
1211 if (instr->Bits(15, 12) == 0xF) { | 1211 if (instr->Bits(15, 12) == 0xF) { |
1212 Format(instr, "vmsr'cond FPSCR, APSR"); | 1212 Format(instr, "vmsr'cond FPSCR, APSR"); |
1213 } else { | 1213 } else { |
1214 Format(instr, "vmsr'cond FPSCR, 'rt"); | 1214 Format(instr, "vmsr'cond FPSCR, 'rt"); |
1215 } | 1215 } |
(...skipping 28 matching lines...) Expand all Loading... |
1244 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); | 1244 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); |
1245 VERIFY(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && | 1245 VERIFY(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && |
1246 (instr->Opc3Value() & 0x1)); | 1246 (instr->Opc3Value() & 0x1)); |
1247 | 1247 |
1248 // Comparison. | 1248 // Comparison. |
1249 bool dp_operation = (instr->SzValue() == 1); | 1249 bool dp_operation = (instr->SzValue() == 1); |
1250 bool raise_exception_for_qnan = (instr->Bit(7) == 0x1); | 1250 bool raise_exception_for_qnan = (instr->Bit(7) == 0x1); |
1251 | 1251 |
1252 if (dp_operation && !raise_exception_for_qnan) { | 1252 if (dp_operation && !raise_exception_for_qnan) { |
1253 if (instr->Opc2Value() == 0x4) { | 1253 if (instr->Opc2Value() == 0x4) { |
1254 Format(instr, "vcmp.f64'cond 'Dd, 'Dm"); | 1254 Format(instr, "vcmp'cond.f64 'Dd, 'Dm"); |
1255 } else if (instr->Opc2Value() == 0x5) { | 1255 } else if (instr->Opc2Value() == 0x5) { |
1256 Format(instr, "vcmp.f64'cond 'Dd, #0.0"); | 1256 Format(instr, "vcmp'cond.f64 'Dd, #0.0"); |
1257 } else { | 1257 } else { |
1258 Unknown(instr); // invalid | 1258 Unknown(instr); // invalid |
1259 } | 1259 } |
1260 } else { | 1260 } else { |
1261 Unknown(instr); // Not used by V8. | 1261 Unknown(instr); // Not used by V8. |
1262 } | 1262 } |
1263 } | 1263 } |
1264 | 1264 |
1265 | 1265 |
1266 void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) { | 1266 void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) { |
1267 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); | 1267 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); |
1268 VERIFY((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)); | 1268 VERIFY((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)); |
1269 | 1269 |
1270 bool double_to_single = (instr->SzValue() == 1); | 1270 bool double_to_single = (instr->SzValue() == 1); |
1271 | 1271 |
1272 if (double_to_single) { | 1272 if (double_to_single) { |
1273 Format(instr, "vcvt.f32.f64'cond 'Sd, 'Dm"); | 1273 Format(instr, "vcvt'cond.f32.f64 'Sd, 'Dm"); |
1274 } else { | 1274 } else { |
1275 Format(instr, "vcvt.f64.f32'cond 'Dd, 'Sm"); | 1275 Format(instr, "vcvt'cond.f64.f32 'Dd, 'Sm"); |
1276 } | 1276 } |
1277 } | 1277 } |
1278 | 1278 |
1279 | 1279 |
1280 void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) { | 1280 void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) { |
1281 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); | 1281 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); |
1282 VERIFY(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) || | 1282 VERIFY(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) || |
1283 (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1))); | 1283 (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1))); |
1284 | 1284 |
1285 bool to_integer = (instr->Bit(18) == 1); | 1285 bool to_integer = (instr->Bit(18) == 1); |
1286 bool dp_operation = (instr->SzValue() == 1); | 1286 bool dp_operation = (instr->SzValue() == 1); |
1287 if (to_integer) { | 1287 if (to_integer) { |
1288 bool unsigned_integer = (instr->Bit(16) == 0); | 1288 bool unsigned_integer = (instr->Bit(16) == 0); |
1289 | 1289 |
1290 if (dp_operation) { | 1290 if (dp_operation) { |
1291 if (unsigned_integer) { | 1291 if (unsigned_integer) { |
1292 Format(instr, "vcvt.u32.f64'cond 'Sd, 'Dm"); | 1292 Format(instr, "vcvt'cond.u32.f64 'Sd, 'Dm"); |
1293 } else { | 1293 } else { |
1294 Format(instr, "vcvt.s32.f64'cond 'Sd, 'Dm"); | 1294 Format(instr, "vcvt'cond.s32.f64 'Sd, 'Dm"); |
1295 } | 1295 } |
1296 } else { | 1296 } else { |
1297 if (unsigned_integer) { | 1297 if (unsigned_integer) { |
1298 Format(instr, "vcvt.u32.f32'cond 'Sd, 'Sm"); | 1298 Format(instr, "vcvt'cond.u32.f32 'Sd, 'Sm"); |
1299 } else { | 1299 } else { |
1300 Format(instr, "vcvt.s32.f32'cond 'Sd, 'Sm"); | 1300 Format(instr, "vcvt'cond.s32.f32 'Sd, 'Sm"); |
1301 } | 1301 } |
1302 } | 1302 } |
1303 } else { | 1303 } else { |
1304 bool unsigned_integer = (instr->Bit(7) == 0); | 1304 bool unsigned_integer = (instr->Bit(7) == 0); |
1305 | 1305 |
1306 if (dp_operation) { | 1306 if (dp_operation) { |
1307 if (unsigned_integer) { | 1307 if (unsigned_integer) { |
1308 Format(instr, "vcvt.f64.u32'cond 'Dd, 'Sm"); | 1308 Format(instr, "vcvt'cond.f64.u32 'Dd, 'Sm"); |
1309 } else { | 1309 } else { |
1310 Format(instr, "vcvt.f64.s32'cond 'Dd, 'Sm"); | 1310 Format(instr, "vcvt'cond.f64.s32 'Dd, 'Sm"); |
1311 } | 1311 } |
1312 } else { | 1312 } else { |
1313 if (unsigned_integer) { | 1313 if (unsigned_integer) { |
1314 Format(instr, "vcvt.f32.u32'cond 'Sd, 'Sm"); | 1314 Format(instr, "vcvt'cond.f32.u32 'Sd, 'Sm"); |
1315 } else { | 1315 } else { |
1316 Format(instr, "vcvt.f32.s32'cond 'Sd, 'Sm"); | 1316 Format(instr, "vcvt'cond.f32.s32 'Sd, 'Sm"); |
1317 } | 1317 } |
1318 } | 1318 } |
1319 } | 1319 } |
1320 } | 1320 } |
1321 | 1321 |
1322 | 1322 |
1323 // Decode Type 6 coprocessor instructions. | 1323 // Decode Type 6 coprocessor instructions. |
1324 // Dm = vmov(Rt, Rt2) | 1324 // Dm = vmov(Rt, Rt2) |
1325 // <Rt, Rt2> = vmov(Dm) | 1325 // <Rt, Rt2> = vmov(Dm) |
1326 // Ddst = MEM(Rbase + 4*offset). | 1326 // Ddst = MEM(Rbase + 4*offset). |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1563 pc += d.InstructionDecode(buffer, pc); | 1563 pc += d.InstructionDecode(buffer, pc); |
1564 fprintf(f, "%p %08x %s\n", | 1564 fprintf(f, "%p %08x %s\n", |
1565 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1565 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1566 } | 1566 } |
1567 } | 1567 } |
1568 | 1568 |
1569 | 1569 |
1570 } // namespace disasm | 1570 } // namespace disasm |
1571 | 1571 |
1572 #endif // V8_TARGET_ARCH_ARM | 1572 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |