OLD | NEW |
---|---|
1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 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 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
421 registers_[pc] = value; | 421 registers_[pc] = value; |
422 } | 422 } |
423 | 423 |
424 | 424 |
425 // Raw access to the PC register without the special adjustment when reading. | 425 // Raw access to the PC register without the special adjustment when reading. |
426 int32_t Simulator::get_pc() const { | 426 int32_t Simulator::get_pc() const { |
427 return registers_[pc]; | 427 return registers_[pc]; |
428 } | 428 } |
429 | 429 |
430 | 430 |
431 // The ARM cannot do unaligned reads and writes. On some ARM platforms an | |
432 // interrupt is caused. On others it does a funky rotation thing. For now we | |
433 // simply disallow unaligned reads, but at some point we may want to move to | |
434 // emulating the rotate behaviour. Note that simulator runs have the runtime | |
435 // system running directly on the host system and only generated code is | |
436 // executed in the simulator. Since the host is typically IA32 we will not | |
437 // get the correct ARM-like behaviour on unaligned accesses. | |
438 | |
439 int Simulator::ReadW(int32_t addr) { | |
440 if ((addr & 3) == 0) { | |
441 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); | |
442 return *ptr; | |
443 } | |
444 PrintF("Unaligned read at %x\n", addr); | |
iposva
2008/10/28 15:34:17
It would be helpful to print the PC and the addres
| |
445 UNIMPLEMENTED(); | |
446 return 0; | |
447 } | |
448 | |
449 | |
450 void Simulator::WriteW(int32_t addr, int value) { | |
451 if ((addr & 3) == 0) { | |
452 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); | |
453 *ptr = value; | |
454 return; | |
455 } | |
456 PrintF("Unaligned write at %x\n", addr); | |
457 UNIMPLEMENTED(); | |
458 } | |
459 | |
460 | |
461 uint16_t Simulator::ReadHU(int32_t addr) { | |
462 if ((addr & 1) == 0) { | |
463 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); | |
464 return *ptr; | |
465 } | |
466 PrintF("Unaligned read at %x\n", addr); | |
467 UNIMPLEMENTED(); | |
468 return 0; | |
469 } | |
470 | |
471 | |
472 int16_t Simulator::ReadH(int32_t addr) { | |
473 if ((addr & 1) == 0) { | |
474 int16_t* ptr = reinterpret_cast<int16_t*>(addr); | |
475 return *ptr; | |
476 } | |
477 PrintF("Unaligned read at %x\n", addr); | |
478 UNIMPLEMENTED(); | |
479 return 0; | |
480 } | |
481 | |
482 | |
483 void Simulator::WriteH(int32_t addr, uint16_t value) { | |
iposva
2008/10/28 15:34:17
The two WriteH and WriteB variants are really hard
| |
484 if ((addr & 1) == 0) { | |
485 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); | |
486 *ptr = value; | |
487 return; | |
488 } | |
489 PrintF("Unaligned write at %x\n", addr); | |
490 UNIMPLEMENTED(); | |
491 } | |
492 | |
493 | |
494 void Simulator::WriteH(int32_t addr, int16_t value) { | |
495 if ((addr & 1) == 0) { | |
496 int16_t* ptr = reinterpret_cast<int16_t*>(addr); | |
497 *ptr = value; | |
498 return; | |
499 } | |
500 PrintF("Unaligned write at %x\n", addr); | |
501 UNIMPLEMENTED(); | |
502 } | |
503 | |
504 | |
505 uint8_t Simulator::ReadBU(int32_t addr) { | |
506 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); | |
iposva
2008/10/28 15:34:17
Why no alignment check here? ;-)
| |
507 return *ptr; | |
508 } | |
509 | |
510 | |
511 int8_t Simulator::ReadB(int32_t addr) { | |
512 int8_t* ptr = reinterpret_cast<int8_t*>(addr); | |
513 return *ptr; | |
514 } | |
515 | |
516 | |
517 void Simulator::WriteB(int32_t addr, uint8_t value) { | |
518 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); | |
519 *ptr = value; | |
520 } | |
521 | |
522 | |
523 void Simulator::WriteB(int32_t addr, int8_t value) { | |
524 int8_t* ptr = reinterpret_cast<int8_t*>(addr); | |
525 *ptr = value; | |
526 } | |
527 | |
528 | |
431 // Returns the limit of the stack area to enable checking for stack overflows. | 529 // Returns the limit of the stack area to enable checking for stack overflows. |
432 uintptr_t Simulator::StackLimit() const { | 530 uintptr_t Simulator::StackLimit() const { |
433 // Leave a safety margin of 256 bytes to prevent overrunning the stack when | 531 // Leave a safety margin of 256 bytes to prevent overrunning the stack when |
434 // pushing values. | 532 // pushing values. |
435 return reinterpret_cast<uintptr_t>(stack_) + 256; | 533 return reinterpret_cast<uintptr_t>(stack_) + 256; |
436 } | 534 } |
437 | 535 |
438 | 536 |
439 // Unsupported instructions use Format to print an error and stop execution. | 537 // Unsupported instructions use Format to print an error and stop execution. |
440 void Simulator::Format(Instr* instr, const char* format) { | 538 void Simulator::Format(Instr* instr, const char* format) { |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
946 } | 1044 } |
947 default: { | 1045 default: { |
948 // The PU field is a 2-bit field. | 1046 // The PU field is a 2-bit field. |
949 UNREACHABLE(); | 1047 UNREACHABLE(); |
950 break; | 1048 break; |
951 } | 1049 } |
952 } | 1050 } |
953 } | 1051 } |
954 if (instr->HasH()) { | 1052 if (instr->HasH()) { |
955 if (instr->HasSign()) { | 1053 if (instr->HasSign()) { |
956 int16_t* haddr = reinterpret_cast<int16_t*>(addr); | |
957 if (instr->HasL()) { | 1054 if (instr->HasL()) { |
958 int16_t val = *haddr; | 1055 int16_t val = ReadH(addr); |
959 set_register(rd, val); | 1056 set_register(rd, val); |
960 } else { | 1057 } else { |
961 int16_t val = get_register(rd); | 1058 int16_t val = get_register(rd); |
962 *haddr = val; | 1059 WriteH(addr, val); |
963 } | 1060 } |
964 } else { | 1061 } else { |
965 uint16_t* haddr = reinterpret_cast<uint16_t*>(addr); | |
966 if (instr->HasL()) { | 1062 if (instr->HasL()) { |
967 uint16_t val = *haddr; | 1063 uint16_t val = ReadHU(addr); |
968 set_register(rd, val); | 1064 set_register(rd, val); |
969 } else { | 1065 } else { |
970 uint16_t val = get_register(rd); | 1066 uint16_t val = get_register(rd); |
971 *haddr = val; | 1067 WriteH(addr, val); |
972 } | 1068 } |
973 } | 1069 } |
974 } else { | 1070 } else { |
975 // signed byte loads | 1071 // signed byte loads |
976 ASSERT(instr->HasSign()); | 1072 ASSERT(instr->HasSign()); |
977 ASSERT(instr->HasL()); | 1073 ASSERT(instr->HasL()); |
978 int8_t* baddr = reinterpret_cast<int8_t*>(addr); | 1074 int8_t val = ReadB(addr); |
979 int8_t val = *baddr; | |
980 set_register(rd, val); | 1075 set_register(rd, val); |
981 } | 1076 } |
982 return; | 1077 return; |
983 } | 1078 } |
984 } else { | 1079 } else { |
985 int rd = instr->RdField(); | 1080 int rd = instr->RdField(); |
986 int rn = instr->RnField(); | 1081 int rn = instr->RnField(); |
987 int32_t rn_val = get_register(rn); | 1082 int32_t rn_val = get_register(rn); |
988 int32_t shifter_operand = 0; | 1083 int32_t shifter_operand = 0; |
989 bool shifter_carry_out = 0; | 1084 bool shifter_carry_out = 0; |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1224 set_register(rn, rn_val); | 1319 set_register(rn, rn_val); |
1225 } | 1320 } |
1226 break; | 1321 break; |
1227 } | 1322 } |
1228 default: { | 1323 default: { |
1229 UNREACHABLE(); | 1324 UNREACHABLE(); |
1230 break; | 1325 break; |
1231 } | 1326 } |
1232 } | 1327 } |
1233 if (instr->HasB()) { | 1328 if (instr->HasB()) { |
1234 byte* baddr = reinterpret_cast<byte*>(addr); | |
1235 if (instr->HasL()) { | 1329 if (instr->HasL()) { |
1236 byte val = *baddr; | 1330 byte val = ReadBU(addr); |
1237 set_register(rd, val); | 1331 set_register(rd, val); |
1238 } else { | 1332 } else { |
1239 byte val = get_register(rd); | 1333 byte val = get_register(rd); |
1240 *baddr = val; | 1334 WriteB(addr, val); |
1241 } | 1335 } |
1242 } else { | 1336 } else { |
1243 intptr_t* iaddr = reinterpret_cast<intptr_t*>(addr); | |
1244 if (instr->HasL()) { | 1337 if (instr->HasL()) { |
1245 set_register(rd, *iaddr); | 1338 set_register(rd, ReadW(addr)); |
1246 } else { | 1339 } else { |
1247 *iaddr = get_register(rd); | 1340 WriteW(addr, get_register(rd)); |
1248 } | 1341 } |
1249 } | 1342 } |
1250 } | 1343 } |
1251 | 1344 |
1252 | 1345 |
1253 void Simulator::DecodeType3(Instr* instr) { | 1346 void Simulator::DecodeType3(Instr* instr) { |
1254 int rd = instr->RdField(); | 1347 int rd = instr->RdField(); |
1255 int rn = instr->RnField(); | 1348 int rn = instr->RnField(); |
1256 int32_t rn_val = get_register(rn); | 1349 int32_t rn_val = get_register(rn); |
1257 bool shifter_carry_out = 0; | 1350 bool shifter_carry_out = 0; |
(...skipping 27 matching lines...) Expand all Loading... | |
1285 break; | 1378 break; |
1286 } | 1379 } |
1287 default: { | 1380 default: { |
1288 UNREACHABLE(); | 1381 UNREACHABLE(); |
1289 break; | 1382 break; |
1290 } | 1383 } |
1291 } | 1384 } |
1292 if (instr->HasB()) { | 1385 if (instr->HasB()) { |
1293 UNIMPLEMENTED(); | 1386 UNIMPLEMENTED(); |
1294 } else { | 1387 } else { |
1295 intptr_t* iaddr = reinterpret_cast<intptr_t*>(addr); | |
1296 if (instr->HasL()) { | 1388 if (instr->HasL()) { |
1297 set_register(rd, *iaddr); | 1389 set_register(rd, ReadW(addr)); |
1298 } else { | 1390 } else { |
1299 *iaddr = get_register(rd); | 1391 WriteW(addr, get_register(rd)); |
1300 } | 1392 } |
1301 } | 1393 } |
1302 } | 1394 } |
1303 | 1395 |
1304 | 1396 |
1305 void Simulator::DecodeType4(Instr* instr) { | 1397 void Simulator::DecodeType4(Instr* instr) { |
1306 ASSERT(instr->Bit(22) == 0); // only allowed to be set in privileged mode | 1398 ASSERT(instr->Bit(22) == 0); // only allowed to be set in privileged mode |
1307 if (instr->HasL()) { | 1399 if (instr->HasL()) { |
1308 // Format(instr, "ldm'cond'pu 'rn'w, 'rlist"); | 1400 // Format(instr, "ldm'cond'pu 'rn'w, 'rlist"); |
1309 HandleRList(instr, true); | 1401 HandleRList(instr, true); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1497 set_register(r10, r10_val); | 1589 set_register(r10, r10_val); |
1498 set_register(r11, r11_val); | 1590 set_register(r11, r11_val); |
1499 | 1591 |
1500 int result = get_register(r0); | 1592 int result = get_register(r0); |
1501 return reinterpret_cast<Object*>(result); | 1593 return reinterpret_cast<Object*>(result); |
1502 } | 1594 } |
1503 | 1595 |
1504 } } // namespace assembler::arm | 1596 } } // namespace assembler::arm |
1505 | 1597 |
1506 #endif // !defined(__arm__) | 1598 #endif // !defined(__arm__) |
OLD | NEW |