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

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

Issue 8830: Get the ARM simulator to throw an exception on unaligned accesses. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 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/simulator-arm.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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__)
OLDNEW
« no previous file with comments | « src/simulator-arm.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698