diff options
| author | 2014-12-31 00:06:34 -0500 | |
|---|---|---|
| committer | 2014-12-31 00:06:34 -0500 | |
| commit | c072095a6b0791ea17830bffe4118686b1f04bd2 (patch) | |
| tree | da601e8a202deaad9aec76ebcfd8d38fee534afd /src | |
| parent | Merge pull request #369 from darkf/mingw_ (diff) | |
| parent | dyncom: Massive refactor (diff) | |
| download | yuzu-c072095a6b0791ea17830bffe4118686b1f04bd2.tar.gz yuzu-c072095a6b0791ea17830bffe4118686b1f04bd2.tar.xz yuzu-c072095a6b0791ea17830bffe4118686b1f04bd2.zip | |
Merge pull request #374 from bunnei/dyncom-cleanup-2
dyncom: Massive refactor
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 705 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpinstr.cpp | 170 |
2 files changed, 221 insertions, 654 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index ce316ead6..926761cff 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -13,19 +13,12 @@ | |||
| 13 | 13 | ||
| 14 | using namespace std; | 14 | using namespace std; |
| 15 | 15 | ||
| 16 | // __WIN32__ was never defined on MSVC, but it is on MinGW, | ||
| 17 | // so we need to remove it. | ||
| 18 | // #ifdefs to __WIN32__ are dead code and will not even compile | ||
| 19 | // anymore, due to bank_defs.h missing. | ||
| 20 | #ifdef _WIN32 | ||
| 21 | #undef __WIN32__ | ||
| 22 | #endif | ||
| 23 | |||
| 24 | #include "core/arm/skyeye_common/armdefs.h" | 16 | #include "core/arm/skyeye_common/armdefs.h" |
| 25 | #include "core/arm/skyeye_common/armmmu.h" | 17 | #include "core/arm/skyeye_common/armmmu.h" |
| 26 | #include "arm_dyncom_thumb.h" | 18 | #include "arm_dyncom_thumb.h" |
| 27 | #include "arm_dyncom_run.h" | 19 | #include "arm_dyncom_run.h" |
| 28 | #include "core/arm/skyeye_common/vfp/vfp.h" | 20 | #include "core/arm/skyeye_common/vfp/vfp.h" |
| 21 | #include "core/arm/disassembler/arm_disasm.h" | ||
| 29 | 22 | ||
| 30 | #include "core/mem_map.h" | 23 | #include "core/mem_map.h" |
| 31 | #include "core/hle/hle.h" | 24 | #include "core/hle/hle.h" |
| @@ -283,50 +276,7 @@ typedef struct _MiscRegPstIdx { | |||
| 283 | typedef struct _LSWordorUnsignedByte { | 276 | typedef struct _LSWordorUnsignedByte { |
| 284 | } LDnST; | 277 | } LDnST; |
| 285 | 278 | ||
| 286 | #if USER_MODE_OPT | 279 | typedef void (*get_addr_fp_t)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw); |
| 287 | static inline fault_t interpreter_read_memory(addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size){ | ||
| 288 | switch(size) { | ||
| 289 | case 8: | ||
| 290 | value = Memory::Read8(virt_addr); | ||
| 291 | break; | ||
| 292 | case 16: | ||
| 293 | value = Memory::Read16(virt_addr); | ||
| 294 | break; | ||
| 295 | case 32: | ||
| 296 | value = Memory::Read32(virt_addr); | ||
| 297 | break; | ||
| 298 | } | ||
| 299 | return NO_FAULT; | ||
| 300 | } | ||
| 301 | |||
| 302 | static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size) { | ||
| 303 | switch(size) { | ||
| 304 | case 8: | ||
| 305 | Memory::Write8(virt_addr, value & 0xff); | ||
| 306 | break; | ||
| 307 | case 16: | ||
| 308 | Memory::Write16(virt_addr, value & 0xffff); | ||
| 309 | break; | ||
| 310 | case 32: | ||
| 311 | Memory::Write32(virt_addr, value); | ||
| 312 | break; | ||
| 313 | } | ||
| 314 | return NO_FAULT; | ||
| 315 | } | ||
| 316 | |||
| 317 | static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw) { | ||
| 318 | *phys_addr = virt_addr; | ||
| 319 | return NO_FAULT; | ||
| 320 | } | ||
| 321 | |||
| 322 | #else | ||
| 323 | fault_t interpreter_read_memory(cpu_t *cpu, addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size); | ||
| 324 | fault_t interpreter_write_memory(cpu_t *cpu, addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size); | ||
| 325 | fault_t interpreter_fetch(cpu_t *cpu, addr_t virt_addr, uint32_t &value, uint32_t size); | ||
| 326 | fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw, tlb_type_t access_type = DATA_TLB); | ||
| 327 | #endif | ||
| 328 | |||
| 329 | typedef fault_t (*get_addr_fp_t)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw); | ||
| 330 | 280 | ||
| 331 | typedef struct _ldst_inst { | 281 | typedef struct _ldst_inst { |
| 332 | unsigned int inst; | 282 | unsigned int inst; |
| @@ -344,133 +294,105 @@ int CondPassed(arm_processor *cpu, unsigned int cond); | |||
| 344 | #define I_BIT BIT(inst, 25) | 294 | #define I_BIT BIT(inst, 25) |
| 345 | #define P_BIT BIT(inst, 24) | 295 | #define P_BIT BIT(inst, 24) |
| 346 | #define OFFSET_12 BITS(inst, 0, 11) | 296 | #define OFFSET_12 BITS(inst, 0, 11) |
| 347 | fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 297 | |
| 298 | void LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { | ||
| 348 | unsigned int Rn = BITS(inst, 16, 19); | 299 | unsigned int Rn = BITS(inst, 16, 19); |
| 349 | unsigned int addr; | 300 | unsigned int addr; |
| 350 | fault_t fault; | 301 | |
| 351 | if (U_BIT) { | 302 | if (U_BIT) |
| 352 | addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; | 303 | addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; |
| 353 | } else { | 304 | else |
| 354 | addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; | 305 | addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; |
| 355 | } | 306 | |
| 356 | virt_addr = addr; | 307 | virt_addr = addr; |
| 357 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 358 | return fault; | ||
| 359 | } | 308 | } |
| 360 | 309 | ||
| 361 | fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 310 | void LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 362 | fault_t fault; | ||
| 363 | unsigned int Rn = BITS(inst, 16, 19); | 311 | unsigned int Rn = BITS(inst, 16, 19); |
| 364 | unsigned int Rm = BITS(inst, 0, 3); | 312 | unsigned int Rm = BITS(inst, 0, 3); |
| 365 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 313 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 366 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 314 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 367 | unsigned int addr; | 315 | unsigned int addr; |
| 368 | if (U_BIT) { | 316 | |
| 317 | if (U_BIT) | ||
| 369 | addr = rn + rm; | 318 | addr = rn + rm; |
| 370 | } else { | 319 | else |
| 371 | addr = rn - rm; | 320 | addr = rn - rm; |
| 372 | } | 321 | |
| 373 | virt_addr = addr; | 322 | virt_addr = addr; |
| 374 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 375 | return fault; | ||
| 376 | } | 323 | } |
| 377 | 324 | ||
| 378 | fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 325 | void LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 379 | fault_t fault; | ||
| 380 | unsigned int Rn = BITS(inst, 16, 19); | 326 | unsigned int Rn = BITS(inst, 16, 19); |
| 381 | unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn); | 327 | unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn); |
| 382 | |||
| 383 | virt_addr = addr; | ||
| 384 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 385 | if (fault) return fault; | ||
| 386 | 328 | ||
| 387 | if (U_BIT) { | 329 | if (U_BIT) |
| 388 | cpu->Reg[Rn] += OFFSET_12; | 330 | cpu->Reg[Rn] += OFFSET_12; |
| 389 | } else { | 331 | else |
| 390 | cpu->Reg[Rn] -= OFFSET_12; | 332 | cpu->Reg[Rn] -= OFFSET_12; |
| 391 | } | 333 | |
| 392 | return fault; | 334 | virt_addr = addr; |
| 393 | } | 335 | } |
| 394 | 336 | ||
| 395 | fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 337 | void LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 396 | fault_t fault; | ||
| 397 | unsigned int Rn = BITS(inst, 16, 19); | 338 | unsigned int Rn = BITS(inst, 16, 19); |
| 398 | unsigned int addr; | 339 | unsigned int addr; |
| 399 | if (U_BIT) { | 340 | |
| 341 | if (U_BIT) | ||
| 400 | addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; | 342 | addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12; |
| 401 | } else { | 343 | else |
| 402 | addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; | 344 | addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12; |
| 403 | } | ||
| 404 | 345 | ||
| 405 | virt_addr = addr; | 346 | virt_addr = addr; |
| 406 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 407 | if (fault) return fault; | ||
| 408 | 347 | ||
| 409 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 348 | if (CondPassed(cpu, BITS(inst, 28, 31))) |
| 410 | cpu->Reg[Rn] = addr; | 349 | cpu->Reg[Rn] = addr; |
| 411 | } | ||
| 412 | return fault; | ||
| 413 | } | 350 | } |
| 414 | 351 | ||
| 415 | fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 352 | void MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 416 | fault_t fault; | ||
| 417 | unsigned int addr; | 353 | unsigned int addr; |
| 418 | unsigned int Rn = BITS(inst, 16, 19); | 354 | unsigned int Rn = BITS(inst, 16, 19); |
| 419 | unsigned int Rm = BITS(inst, 0, 3); | 355 | unsigned int Rm = BITS(inst, 0, 3); |
| 420 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 356 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 421 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 357 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 422 | 358 | ||
| 423 | if (U_BIT) { | 359 | if (U_BIT) |
| 424 | addr = rn + rm; | 360 | addr = rn + rm; |
| 425 | } else | 361 | else |
| 426 | addr = rn - rm; | 362 | addr = rn - rm; |
| 427 | if(BIT(inst, 20)){ // L BIT | ||
| 428 | } | ||
| 429 | if(BIT(inst, 6)){ // Sign Bit | ||
| 430 | } | ||
| 431 | if(BIT(inst, 5)){ // Half Bit | ||
| 432 | } | ||
| 433 | 363 | ||
| 434 | virt_addr = addr; | 364 | virt_addr = addr; |
| 435 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 436 | if (fault) return fault; | ||
| 437 | 365 | ||
| 438 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 366 | if (CondPassed(cpu, BITS(inst, 28, 31))) |
| 439 | cpu->Reg[Rn] = addr; | 367 | cpu->Reg[Rn] = addr; |
| 440 | } | ||
| 441 | return fault; | ||
| 442 | } | 368 | } |
| 443 | 369 | ||
| 444 | fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 370 | void LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 445 | fault_t fault; | ||
| 446 | unsigned int Rn = BITS(inst, 16, 19); | 371 | unsigned int Rn = BITS(inst, 16, 19); |
| 447 | unsigned int Rm = BITS(inst, 0, 3); | 372 | unsigned int Rm = BITS(inst, 0, 3); |
| 448 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 373 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 449 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 374 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 450 | unsigned int addr; | 375 | unsigned int addr; |
| 451 | if (U_BIT) { | 376 | |
| 377 | if (U_BIT) | ||
| 452 | addr = rn + rm; | 378 | addr = rn + rm; |
| 453 | } else { | 379 | else |
| 454 | addr = rn - rm; | 380 | addr = rn - rm; |
| 455 | } | 381 | |
| 456 | virt_addr = addr; | 382 | virt_addr = addr; |
| 457 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 383 | |
| 458 | if(fault) | ||
| 459 | return fault; | ||
| 460 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 384 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 461 | cpu->Reg[Rn] = addr; | 385 | cpu->Reg[Rn] = addr; |
| 462 | } | 386 | } |
| 463 | return fault; | ||
| 464 | } | 387 | } |
| 465 | fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 388 | |
| 466 | fault_t fault; | 389 | void LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 467 | unsigned int shift = BITS(inst, 5, 6); | 390 | unsigned int shift = BITS(inst, 5, 6); |
| 468 | unsigned int shift_imm = BITS(inst, 7, 11); | 391 | unsigned int shift_imm = BITS(inst, 7, 11); |
| 469 | unsigned int Rn = BITS(inst, 16, 19); | 392 | unsigned int Rn = BITS(inst, 16, 19); |
| 470 | unsigned int Rm = BITS(inst, 0, 3); | 393 | unsigned int Rm = BITS(inst, 0, 3); |
| 471 | unsigned int index; | 394 | unsigned int index; |
| 472 | unsigned int addr; | 395 | unsigned int addr; |
| 473 | |||
| 474 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 396 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 475 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 397 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 476 | 398 | ||
| @@ -492,33 +414,27 @@ fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, | |||
| 492 | DEBUG_MSG; | 414 | DEBUG_MSG; |
| 493 | break; | 415 | break; |
| 494 | } | 416 | } |
| 495 | if (U_BIT) { | 417 | |
| 418 | if (U_BIT) | ||
| 496 | addr = rn + index; | 419 | addr = rn + index; |
| 497 | } else | 420 | else |
| 498 | addr = rn - index; | 421 | addr = rn - index; |
| 422 | |||
| 499 | virt_addr = addr; | 423 | virt_addr = addr; |
| 500 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 501 | if(fault) | ||
| 502 | return fault; | ||
| 503 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | ||
| 504 | cpu->Reg[Rn] = addr; | ||
| 505 | } | ||
| 506 | 424 | ||
| 507 | return fault; | 425 | if (CondPassed(cpu, BITS(inst, 28, 31))) |
| 426 | cpu->Reg[Rn] = addr; | ||
| 508 | } | 427 | } |
| 509 | 428 | ||
| 510 | fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 429 | void LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 511 | fault_t fault; | ||
| 512 | unsigned int shift = BITS(inst, 5, 6); | 430 | unsigned int shift = BITS(inst, 5, 6); |
| 513 | unsigned int shift_imm = BITS(inst, 7, 11); | 431 | unsigned int shift_imm = BITS(inst, 7, 11); |
| 514 | unsigned int Rn = BITS(inst, 16, 19); | 432 | unsigned int Rn = BITS(inst, 16, 19); |
| 515 | unsigned int Rm = BITS(inst, 0, 3); | 433 | unsigned int Rm = BITS(inst, 0, 3); |
| 516 | unsigned int index; | 434 | unsigned int index; |
| 517 | unsigned int addr; | 435 | unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn); |
| 518 | |||
| 519 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 436 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 520 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 437 | |
| 521 | addr = rn; | ||
| 522 | switch (shift) { | 438 | switch (shift) { |
| 523 | case 0: | 439 | case 0: |
| 524 | index = rm << shift_imm; | 440 | index = rm << shift_imm; |
| @@ -537,31 +453,23 @@ fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst | |||
| 537 | DEBUG_MSG; | 453 | DEBUG_MSG; |
| 538 | break; | 454 | break; |
| 539 | } | 455 | } |
| 456 | |||
| 540 | virt_addr = addr; | 457 | virt_addr = addr; |
| 541 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | 458 | |
| 542 | if(fault) | ||
| 543 | return fault; | ||
| 544 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 459 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 545 | if (U_BIT) | 460 | if (U_BIT) |
| 546 | cpu->Reg[Rn] += index; | 461 | cpu->Reg[Rn] += index; |
| 547 | else | 462 | else |
| 548 | cpu->Reg[Rn] -= index; | 463 | cpu->Reg[Rn] -= index; |
| 549 | } | 464 | } |
| 550 | |||
| 551 | return fault; | ||
| 552 | } | 465 | } |
| 553 | 466 | ||
| 554 | fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 467 | void LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 555 | fault_t fault; | ||
| 556 | unsigned int Rn = BITS(inst, 16, 19); | 468 | unsigned int Rn = BITS(inst, 16, 19); |
| 557 | unsigned int Rm = BITS(inst, 0, 3); | 469 | unsigned int Rm = BITS(inst, 0, 3); |
| 558 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 470 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 559 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 560 | 471 | ||
| 561 | unsigned int addr = rn; | 472 | virt_addr = CHECK_READ_REG15_WA(cpu, Rn); |
| 562 | virt_addr = addr; | ||
| 563 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 564 | if (fault) return fault; | ||
| 565 | 473 | ||
| 566 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 474 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 567 | if (U_BIT) { | 475 | if (U_BIT) { |
| @@ -570,52 +478,40 @@ fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsi | |||
| 570 | cpu->Reg[Rn] -= rm; | 478 | cpu->Reg[Rn] -= rm; |
| 571 | } | 479 | } |
| 572 | } | 480 | } |
| 573 | return fault; | ||
| 574 | } | 481 | } |
| 575 | 482 | ||
| 576 | fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 483 | void MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 577 | fault_t fault; | ||
| 578 | unsigned int immedL = BITS(inst, 0, 3); | 484 | unsigned int immedL = BITS(inst, 0, 3); |
| 579 | unsigned int immedH = BITS(inst, 8, 11); | 485 | unsigned int immedH = BITS(inst, 8, 11); |
| 580 | |||
| 581 | unsigned int Rn = BITS(inst, 16, 19); | 486 | unsigned int Rn = BITS(inst, 16, 19); |
| 582 | unsigned int addr; | 487 | unsigned int addr; |
| 583 | 488 | ||
| 584 | unsigned int offset_8 = (immedH << 4) | immedL; | 489 | unsigned int offset_8 = (immedH << 4) | immedL; |
| 585 | if (U_BIT) { | 490 | |
| 491 | if (U_BIT) | ||
| 586 | addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8; | 492 | addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8; |
| 587 | } else | 493 | else |
| 588 | addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8; | 494 | addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8; |
| 589 | 495 | ||
| 590 | virt_addr = addr; | 496 | virt_addr = addr; |
| 591 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 592 | return fault; | ||
| 593 | } | 497 | } |
| 594 | 498 | ||
| 595 | fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 499 | void MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 596 | fault_t fault; | ||
| 597 | unsigned int addr; | 500 | unsigned int addr; |
| 598 | unsigned int Rn = BITS(inst, 16, 19); | 501 | unsigned int Rn = BITS(inst, 16, 19); |
| 599 | unsigned int Rm = BITS(inst, 0, 3); | 502 | unsigned int Rm = BITS(inst, 0, 3); |
| 600 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 503 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 601 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 504 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 602 | if (U_BIT) { | 505 | |
| 506 | if (U_BIT) | ||
| 603 | addr = rn + rm; | 507 | addr = rn + rm; |
| 604 | } else | 508 | else |
| 605 | addr = rn - rm; | 509 | addr = rn - rm; |
| 606 | if(BIT(inst, 20)){ // L BIT | 510 | |
| 607 | } | ||
| 608 | if(BIT(inst, 6)){ // Sign Bit | ||
| 609 | } | ||
| 610 | if(BIT(inst, 5)){ // Half Bit | ||
| 611 | } | ||
| 612 | virt_addr = addr; | 511 | virt_addr = addr; |
| 613 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 614 | return fault; | ||
| 615 | } | 512 | } |
| 616 | 513 | ||
| 617 | fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 514 | void MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 618 | fault_t fault; | ||
| 619 | unsigned int Rn = BITS(inst, 16, 19); | 515 | unsigned int Rn = BITS(inst, 16, 19); |
| 620 | unsigned int immedH = BITS(inst, 8, 11); | 516 | unsigned int immedH = BITS(inst, 8, 11); |
| 621 | unsigned int immedL = BITS(inst, 0, 3); | 517 | unsigned int immedL = BITS(inst, 0, 3); |
| @@ -623,189 +519,129 @@ fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigne | |||
| 623 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 519 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 624 | unsigned int offset_8 = (immedH << 4) | immedL; | 520 | unsigned int offset_8 = (immedH << 4) | immedL; |
| 625 | 521 | ||
| 626 | if (U_BIT) { | 522 | if (U_BIT) |
| 627 | addr = rn + offset_8; | 523 | addr = rn + offset_8; |
| 628 | } else | 524 | else |
| 629 | addr = rn - offset_8; | 525 | addr = rn - offset_8; |
| 630 | 526 | ||
| 631 | virt_addr = addr; | 527 | virt_addr = addr; |
| 632 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 633 | if (fault) return fault; | ||
| 634 | 528 | ||
| 635 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 529 | if (CondPassed(cpu, BITS(inst, 28, 31))) |
| 636 | cpu->Reg[Rn] = addr; | 530 | cpu->Reg[Rn] = addr; |
| 637 | } | ||
| 638 | return fault; | ||
| 639 | } | 531 | } |
| 640 | 532 | ||
| 641 | fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 533 | void MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 642 | fault_t fault; | ||
| 643 | unsigned int Rn = BITS(inst, 16, 19); | 534 | unsigned int Rn = BITS(inst, 16, 19); |
| 644 | unsigned int immedH = BITS(inst, 8, 11); | 535 | unsigned int immedH = BITS(inst, 8, 11); |
| 645 | unsigned int immedL = BITS(inst, 0, 3); | 536 | unsigned int immedL = BITS(inst, 0, 3); |
| 646 | unsigned int addr; | ||
| 647 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 537 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 648 | addr = rn; | ||
| 649 | 538 | ||
| 650 | virt_addr = addr; | 539 | virt_addr = rn; |
| 651 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 652 | if (fault) return fault; | ||
| 653 | 540 | ||
| 654 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 541 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 655 | unsigned int offset_8 = (immedH << 4) | immedL; | 542 | unsigned int offset_8 = (immedH << 4) | immedL; |
| 656 | if (U_BIT) { | 543 | if (U_BIT) |
| 657 | rn += offset_8; | 544 | rn += offset_8; |
| 658 | } else { | 545 | else |
| 659 | rn -= offset_8; | 546 | rn -= offset_8; |
| 660 | } | 547 | |
| 661 | cpu->Reg[Rn] = rn; | 548 | cpu->Reg[Rn] = rn; |
| 662 | } | 549 | } |
| 663 | |||
| 664 | return fault; | ||
| 665 | } | 550 | } |
| 666 | fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 551 | |
| 667 | fault_t fault; | 552 | void MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 668 | unsigned int Rn = BITS(inst, 16, 19); | 553 | unsigned int Rn = BITS(inst, 16, 19); |
| 669 | unsigned int Rm = BITS(inst, 0, 3); | 554 | unsigned int Rm = BITS(inst, 0, 3); |
| 670 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 555 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 671 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 672 | unsigned int addr = rn; | ||
| 673 | 556 | ||
| 674 | virt_addr = addr; | 557 | virt_addr = CHECK_READ_REG15_WA(cpu, Rn); |
| 675 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 676 | if (fault) return fault; | ||
| 677 | 558 | ||
| 678 | if (CondPassed(cpu, BITS(inst, 28, 31))) { | 559 | if (CondPassed(cpu, BITS(inst, 28, 31))) { |
| 679 | if (U_BIT) { | 560 | if (U_BIT) |
| 680 | cpu->Reg[Rn] += rm; | 561 | cpu->Reg[Rn] += rm; |
| 681 | } else { | 562 | else |
| 682 | cpu->Reg[Rn] -= rm; | 563 | cpu->Reg[Rn] -= rm; |
| 683 | } | ||
| 684 | } | 564 | } |
| 685 | return fault; | ||
| 686 | } | 565 | } |
| 687 | 566 | ||
| 688 | fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 567 | void LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 689 | fault_t fault; | ||
| 690 | unsigned int Rn = BITS(inst, 16, 19); | 568 | unsigned int Rn = BITS(inst, 16, 19); |
| 691 | unsigned int i = BITS(inst, 0, 15); | 569 | unsigned int i = BITS(inst, 0, 15); |
| 692 | int count = 0; | 570 | int count = 0; |
| 693 | while(i) { | 571 | |
| 694 | if(i & 1) count ++; | 572 | while (i) { |
| 573 | if (i & 1) count++; | ||
| 695 | i = i >> 1; | 574 | i = i >> 1; |
| 696 | } | 575 | } |
| 697 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 698 | unsigned int start_addr = rn - count * 4; | ||
| 699 | unsigned int end_addr = rn - 4; | ||
| 700 | |||
| 701 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); | ||
| 702 | virt_addr = end_addr; | ||
| 703 | if (fault) return fault; | ||
| 704 | 576 | ||
| 705 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | 577 | virt_addr = CHECK_READ_REG15_WA(cpu, Rn) - count * 4; |
| 706 | virt_addr = start_addr; | ||
| 707 | if (fault) return fault; | ||
| 708 | 578 | ||
| 709 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { | 579 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) |
| 710 | cpu->Reg[Rn] -= count * 4; | 580 | cpu->Reg[Rn] -= count * 4; |
| 711 | } | ||
| 712 | |||
| 713 | return fault; | ||
| 714 | } | 581 | } |
| 715 | 582 | ||
| 716 | fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 583 | void LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 717 | fault_t fault; | ||
| 718 | unsigned int Rn = BITS(inst, 16, 19); | 584 | unsigned int Rn = BITS(inst, 16, 19); |
| 719 | unsigned int i = BITS(inst, 0, 15); | 585 | unsigned int i = BITS(inst, 0, 15); |
| 720 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 721 | int count = 0; | 586 | int count = 0; |
| 722 | while(i) { | 587 | |
| 723 | if(i & 1) count ++; | 588 | while (i) { |
| 589 | if (i & 1) count++; | ||
| 724 | i = i >> 1; | 590 | i = i >> 1; |
| 725 | } | 591 | } |
| 726 | 592 | ||
| 727 | unsigned int start_addr = rn + 4; | 593 | virt_addr = CHECK_READ_REG15_WA(cpu, Rn) + 4; |
| 728 | unsigned int end_addr = rn + count * 4; | ||
| 729 | |||
| 730 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); | ||
| 731 | virt_addr = end_addr; | ||
| 732 | if (fault) return fault; | ||
| 733 | |||
| 734 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | ||
| 735 | virt_addr = start_addr; | ||
| 736 | if (fault) return fault; | ||
| 737 | 594 | ||
| 738 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { | 595 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) |
| 739 | cpu->Reg[Rn] += count * 4; | 596 | cpu->Reg[Rn] += count * 4; |
| 740 | } | ||
| 741 | return fault; | ||
| 742 | } | 597 | } |
| 743 | 598 | ||
| 744 | fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 599 | void LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 745 | fault_t fault; | ||
| 746 | unsigned int Rn = BITS(inst, 16, 19); | 600 | unsigned int Rn = BITS(inst, 16, 19); |
| 747 | unsigned int i = BITS(inst, 0, 15); | 601 | unsigned int i = BITS(inst, 0, 15); |
| 748 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | ||
| 749 | int count = 0; | 602 | int count = 0; |
| 603 | |||
| 750 | while(i) { | 604 | while(i) { |
| 751 | if(i & 1) count ++; | 605 | if (i & 1) count++; |
| 752 | i = i >> 1; | 606 | i = i >> 1; |
| 753 | } | 607 | } |
| 754 | unsigned int start_addr = rn; | ||
| 755 | unsigned int end_addr = rn + count * 4 - 4; | ||
| 756 | 608 | ||
| 757 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); | 609 | virt_addr = CHECK_READ_REG15_WA(cpu, Rn); |
| 758 | virt_addr = end_addr; | ||
| 759 | if (fault) return fault; | ||
| 760 | 610 | ||
| 761 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | 611 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) |
| 762 | virt_addr = start_addr; | ||
| 763 | if (fault) return fault; | ||
| 764 | |||
| 765 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { | ||
| 766 | cpu->Reg[Rn] += count * 4; | 612 | cpu->Reg[Rn] += count * 4; |
| 767 | } | ||
| 768 | return fault; | ||
| 769 | } | 613 | } |
| 770 | 614 | ||
| 771 | fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 615 | void LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 772 | fault_t fault; | ||
| 773 | unsigned int Rn = BITS(inst, 16, 19); | 616 | unsigned int Rn = BITS(inst, 16, 19); |
| 774 | unsigned int i = BITS(inst, 0, 15); | 617 | unsigned int i = BITS(inst, 0, 15); |
| 775 | int count = 0; | 618 | int count = 0; |
| 776 | while(i) { | 619 | while(i) { |
| 777 | if(i & 1) count ++; | 620 | if(i & 1) count++; |
| 778 | i = i >> 1; | 621 | i = i >> 1; |
| 779 | } | 622 | } |
| 780 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 623 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 781 | unsigned int start_addr = rn - count * 4 + 4; | 624 | unsigned int start_addr = rn - count * 4 + 4; |
| 782 | unsigned int end_addr = rn; | 625 | unsigned int end_addr = rn; |
| 783 | 626 | ||
| 784 | fault = check_address_validity(cpu, end_addr, &phys_addr, rw); | ||
| 785 | virt_addr = end_addr; | 627 | virt_addr = end_addr; |
| 786 | if (fault) return fault; | ||
| 787 | |||
| 788 | fault = check_address_validity(cpu, start_addr, &phys_addr, rw); | ||
| 789 | if (fault) return fault; | ||
| 790 | virt_addr = start_addr; | 628 | virt_addr = start_addr; |
| 791 | 629 | ||
| 792 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { | 630 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { |
| 793 | cpu->Reg[Rn] -= count * 4; | 631 | cpu->Reg[Rn] -= count * 4; |
| 794 | } | 632 | } |
| 795 | return fault; | ||
| 796 | } | 633 | } |
| 797 | 634 | ||
| 798 | fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw) { | 635 | void LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw) { |
| 799 | fault_t fault; | ||
| 800 | unsigned int shift = BITS(inst, 5, 6); | 636 | unsigned int shift = BITS(inst, 5, 6); |
| 801 | unsigned int shift_imm = BITS(inst, 7, 11); | 637 | unsigned int shift_imm = BITS(inst, 7, 11); |
| 802 | unsigned int Rn = BITS(inst, 16, 19); | 638 | unsigned int Rn = BITS(inst, 16, 19); |
| 803 | unsigned int Rm = BITS(inst, 0, 3); | 639 | unsigned int Rm = BITS(inst, 0, 3); |
| 804 | unsigned int index; | 640 | unsigned int index; |
| 805 | unsigned int addr; | 641 | unsigned int addr; |
| 806 | |||
| 807 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); | 642 | unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); |
| 808 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 643 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 644 | |||
| 809 | switch (shift) { | 645 | switch (shift) { |
| 810 | case 0: | 646 | case 0: |
| 811 | index = rm << shift_imm; | 647 | index = rm << shift_imm; |
| @@ -823,8 +659,7 @@ fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, uns | |||
| 823 | index = 0xFFFFFFFF; | 659 | index = 0xFFFFFFFF; |
| 824 | else | 660 | else |
| 825 | index = 0; | 661 | index = 0; |
| 826 | } | 662 | } else { |
| 827 | else { | ||
| 828 | index = static_cast<int>(rm) >> shift_imm; | 663 | index = static_cast<int>(rm) >> shift_imm; |
| 829 | } | 664 | } |
| 830 | break; | 665 | break; |
| @@ -832,15 +667,13 @@ fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, uns | |||
| 832 | DEBUG_MSG; | 667 | DEBUG_MSG; |
| 833 | break; | 668 | break; |
| 834 | } | 669 | } |
| 670 | |||
| 835 | if (U_BIT) { | 671 | if (U_BIT) { |
| 836 | addr = rn + index; | 672 | addr = rn + index; |
| 837 | } else | 673 | } else |
| 838 | addr = rn - index; | 674 | addr = rn - index; |
| 839 | 675 | ||
| 840 | virt_addr = addr; | 676 | virt_addr = addr; |
| 841 | fault = check_address_validity(cpu, addr, &phys_addr, rw); | ||
| 842 | |||
| 843 | return fault; | ||
| 844 | } | 677 | } |
| 845 | 678 | ||
| 846 | #define ISNEG(n) (n < 0) | 679 | #define ISNEG(n) (n < 0) |
| @@ -3541,30 +3374,19 @@ int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr) { | |||
| 3541 | if (cpu->TFlag) | 3374 | if (cpu->TFlag) |
| 3542 | thumb = THUMB; | 3375 | thumb = THUMB; |
| 3543 | 3376 | ||
| 3544 | addr_t phys_addr; | 3377 | addr_t phys_addr = addr; |
| 3545 | addr_t pc_start; | 3378 | addr_t pc_start = cpu->Reg[15]; |
| 3546 | fault_t fault = NO_FAULT; | ||
| 3547 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 3548 | if(fault != NO_FAULT){ | ||
| 3549 | cpu->abortSig = true; | ||
| 3550 | cpu->Aborted = ARMul_PrefetchAbortV; | ||
| 3551 | cpu->AbortAddr = addr; | ||
| 3552 | cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff; | ||
| 3553 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; | ||
| 3554 | return FETCH_EXCEPTION; | ||
| 3555 | } | ||
| 3556 | |||
| 3557 | pc_start = phys_addr; | ||
| 3558 | 3379 | ||
| 3559 | while(ret == NON_BRANCH) { | 3380 | while(ret == NON_BRANCH) { |
| 3560 | inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC); | 3381 | inst = Memory::Read32(phys_addr & 0xFFFFFFFC); |
| 3561 | 3382 | ||
| 3562 | size ++; | 3383 | size++; |
| 3563 | // If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction | 3384 | // If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction |
| 3564 | if (cpu->TFlag) { | 3385 | if (cpu->TFlag) { |
| 3565 | uint32_t arm_inst; | 3386 | uint32_t arm_inst; |
| 3566 | tdstate state; | 3387 | tdstate state; |
| 3567 | state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base); | 3388 | state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base); |
| 3389 | |||
| 3568 | // We have translated the branch instruction of thumb in thumb decoder | 3390 | // We have translated the branch instruction of thumb in thumb decoder |
| 3569 | if(state == t_branch){ | 3391 | if(state == t_branch){ |
| 3570 | goto translated; | 3392 | goto translated; |
| @@ -3574,7 +3396,8 @@ int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr) { | |||
| 3574 | 3396 | ||
| 3575 | ret = decode_arm_instr(inst, &idx); | 3397 | ret = decode_arm_instr(inst, &idx); |
| 3576 | if (ret == DECODE_FAILURE) { | 3398 | if (ret == DECODE_FAILURE) { |
| 3577 | LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : [%x]", phys_addr, inst); | 3399 | std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst); |
| 3400 | LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst); | ||
| 3578 | LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); | 3401 | LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); |
| 3579 | CITRA_IGNORE_EXIT(-1); | 3402 | CITRA_IGNORE_EXIT(-1); |
| 3580 | } | 3403 | } |
| @@ -3603,15 +3426,15 @@ void InterpreterInitInstLength(unsigned long long int *ptr, size_t size) { | |||
| 3603 | memcpy(InstLabel, ptr, size); | 3426 | memcpy(InstLabel, ptr, size); |
| 3604 | qsort(InstLabel, array_size, sizeof(void *), cmp); | 3427 | qsort(InstLabel, array_size, sizeof(void *), cmp); |
| 3605 | InstLength = new unsigned int[array_size - 4]; | 3428 | InstLength = new unsigned int[array_size - 4]; |
| 3606 | for (int i = 0; i < array_size - 4; i ++) { | 3429 | for (int i = 0; i < array_size - 4; i++) { |
| 3607 | for (int j = 0; j < array_size; j ++) { | 3430 | for (int j = 0; j < array_size; j++) { |
| 3608 | if (ptr[i] == InstLabel[j]) { | 3431 | if (ptr[i] == InstLabel[j]) { |
| 3609 | InstLength[i] = InstLabel[j + 1] - InstLabel[j]; | 3432 | InstLength[i] = InstLabel[j + 1] - InstLabel[j]; |
| 3610 | break; | 3433 | break; |
| 3611 | } | 3434 | } |
| 3612 | } | 3435 | } |
| 3613 | } | 3436 | } |
| 3614 | for (int i = 0; i < array_size - 4; i ++) | 3437 | for (int i = 0; i < array_size - 4; i++) |
| 3615 | LOG_DEBUG(Core_ARM11, "[%d]:%d", i, InstLength[i]); | 3438 | LOG_DEBUG(Core_ARM11, "[%d]:%d", i, InstLength[i]); |
| 3616 | } | 3439 | } |
| 3617 | 3440 | ||
| @@ -3928,7 +3751,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 3928 | unsigned int phys_addr; | 3751 | unsigned int phys_addr; |
| 3929 | unsigned int last_pc = 0; | 3752 | unsigned int last_pc = 0; |
| 3930 | unsigned int num_instrs = 0; | 3753 | unsigned int num_instrs = 0; |
| 3931 | fault_t fault; | 3754 | |
| 3932 | static unsigned int last_physical_base = 0, last_logical_base = 0; | 3755 | static unsigned int last_physical_base = 0, last_logical_base = 0; |
| 3933 | int ptr; | 3756 | int ptr; |
| 3934 | bool single_step = (cpu->NumInstrsToExecute == 1); | 3757 | bool single_step = (cpu->NumInstrsToExecute == 1); |
| @@ -3949,7 +3772,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 3949 | 3772 | ||
| 3950 | phys_addr = cpu->Reg[15]; | 3773 | phys_addr = cpu->Reg[15]; |
| 3951 | 3774 | ||
| 3952 | if (find_bb(phys_addr, ptr) == -1) | 3775 | if (find_bb(cpu->Reg[15], ptr) == -1) |
| 3953 | if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) | 3776 | if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) |
| 3954 | goto END; | 3777 | goto END; |
| 3955 | 3778 | ||
| @@ -4299,53 +4122,34 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4299 | { | 4122 | { |
| 4300 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4123 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4301 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4124 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4302 | int i; | 4125 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4303 | unsigned int ret; | 4126 | |
| 4304 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | ||
| 4305 | if (fault) { | ||
| 4306 | goto MMU_EXCEPTION; | ||
| 4307 | } | ||
| 4308 | unsigned int inst = inst_cream->inst; | 4127 | unsigned int inst = inst_cream->inst; |
| 4309 | if (BIT(inst, 22) && !BIT(inst, 15)) { | 4128 | if (BIT(inst, 22) && !BIT(inst, 15)) { |
| 4310 | for (i = 0; i < 13; i++) { | 4129 | for (int i = 0; i < 13; i++) { |
| 4311 | if(BIT(inst, i)){ | 4130 | if(BIT(inst, i)) { |
| 4312 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | 4131 | cpu->Reg[i] = Memory::Read32(addr); |
| 4313 | cpu->Reg[i] = ret; | ||
| 4314 | addr += 4; | 4132 | addr += 4; |
| 4315 | if ((addr & 0xfff) == 0) { | ||
| 4316 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4317 | } else { | ||
| 4318 | phys_addr += 4; | ||
| 4319 | } | ||
| 4320 | } | 4133 | } |
| 4321 | } | 4134 | } |
| 4322 | if (BIT(inst, 13)) { | 4135 | if (BIT(inst, 13)) { |
| 4323 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | ||
| 4324 | |||
| 4325 | if (cpu->Mode == USER32MODE) | 4136 | if (cpu->Mode == USER32MODE) |
| 4326 | cpu->Reg[13] = ret; | 4137 | cpu->Reg[13] = Memory::Read32(addr); |
| 4327 | else | 4138 | else |
| 4328 | cpu->Reg_usr[0] = ret; | 4139 | cpu->Reg_usr[0] = Memory::Read32(addr); |
| 4140 | |||
| 4329 | addr += 4; | 4141 | addr += 4; |
| 4330 | if ((addr & 0xfff) == 0) { | ||
| 4331 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4332 | } else { | ||
| 4333 | phys_addr += 4; | ||
| 4334 | } | ||
| 4335 | } | 4142 | } |
| 4336 | if (BIT(inst, 14)) { | 4143 | if (BIT(inst, 14)) { |
| 4337 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | ||
| 4338 | |||
| 4339 | if (cpu->Mode == USER32MODE) | 4144 | if (cpu->Mode == USER32MODE) |
| 4340 | cpu->Reg[14] = ret; | 4145 | cpu->Reg[14] = Memory::Read32(addr); |
| 4341 | else | 4146 | else |
| 4342 | cpu->Reg_usr[1] = ret; | 4147 | cpu->Reg_usr[1] = Memory::Read32(addr); |
| 4343 | } | 4148 | } |
| 4344 | } else if (!BIT(inst, 22)) { | 4149 | } else if (!BIT(inst, 22)) { |
| 4345 | for( i = 0; i < 16; i ++ ){ | 4150 | for(int i = 0; i < 16; i++ ){ |
| 4346 | if(BIT(inst, i)){ | 4151 | if(BIT(inst, i)){ |
| 4347 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | 4152 | unsigned int ret = Memory::Read32(addr); |
| 4348 | if (fault) goto MMU_EXCEPTION; | ||
| 4349 | 4153 | ||
| 4350 | // For armv5t, should enter thumb when bits[0] is non-zero. | 4154 | // For armv5t, should enter thumb when bits[0] is non-zero. |
| 4351 | if(i == 15){ | 4155 | if(i == 15){ |
| @@ -4355,39 +4159,25 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4355 | 4159 | ||
| 4356 | cpu->Reg[i] = ret; | 4160 | cpu->Reg[i] = ret; |
| 4357 | addr += 4; | 4161 | addr += 4; |
| 4358 | if ((addr & 0xfff) == 0) { | ||
| 4359 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4360 | } else { | ||
| 4361 | phys_addr += 4; | ||
| 4362 | } | ||
| 4363 | } | 4162 | } |
| 4364 | } | 4163 | } |
| 4365 | } else if (BIT(inst, 22) && BIT(inst, 15)) { | 4164 | } else if (BIT(inst, 22) && BIT(inst, 15)) { |
| 4366 | for( i = 0; i < 15; i ++ ){ | 4165 | for(int i = 0; i < 15; i++ ){ |
| 4367 | if(BIT(inst, i)){ | 4166 | if(BIT(inst, i)){ |
| 4368 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | 4167 | cpu->Reg[i] = Memory::Read32(addr); |
| 4369 | cpu->Reg[i] = ret; | ||
| 4370 | addr += 4; | 4168 | addr += 4; |
| 4371 | if ((addr & 0xfff) == 0) { | ||
| 4372 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4373 | } else { | ||
| 4374 | phys_addr += 4; | ||
| 4375 | } | ||
| 4376 | } | 4169 | } |
| 4377 | } | 4170 | } |
| 4378 | 4171 | ||
| 4379 | if (CurrentModeHasSPSR) { | 4172 | if (CurrentModeHasSPSR) { |
| 4380 | cpu->Cpsr = cpu->Spsr_copy; | 4173 | cpu->Cpsr = cpu->Spsr_copy; |
| 4381 | switch_mode(cpu, cpu->Cpsr & 0x1f); | 4174 | switch_mode(cpu, cpu->Cpsr & 0x1f); |
| 4382 | LOAD_NZCVT; | 4175 | LOAD_NZCVT; |
| 4383 | } | 4176 | } |
| 4384 | 4177 | ||
| 4385 | fault = interpreter_read_memory(addr, phys_addr, ret, 32); | 4178 | cpu->Reg[15] = Memory::Read32(addr); |
| 4386 | if (fault) { | 4179 | } |
| 4387 | goto MMU_EXCEPTION; | 4180 | |
| 4388 | } | ||
| 4389 | cpu->Reg[15] = ret; | ||
| 4390 | } | ||
| 4391 | if (BIT(inst, 15)) { | 4181 | if (BIT(inst, 15)) { |
| 4392 | INC_PC(sizeof(ldst_inst)); | 4182 | INC_PC(sizeof(ldst_inst)); |
| 4393 | goto DISPATCH; | 4183 | goto DISPATCH; |
| @@ -4419,16 +4209,16 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4419 | { | 4209 | { |
| 4420 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4210 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4421 | //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4211 | //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4422 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4212 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4423 | if (fault) goto MMU_EXCEPTION; | 4213 | |
| 4424 | unsigned int value; | 4214 | unsigned int value = Memory::Read32(addr); |
| 4425 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | ||
| 4426 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) | 4215 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) |
| 4427 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4216 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4428 | else { | 4217 | else { |
| 4429 | value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); | 4218 | value = ROTATE_RIGHT_32(value,(8*(addr&0x3))); |
| 4430 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4219 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4431 | } | 4220 | } |
| 4221 | |||
| 4432 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4222 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4433 | // For armv5t, should enter thumb when bits[0] is non-zero. | 4223 | // For armv5t, should enter thumb when bits[0] is non-zero. |
| 4434 | cpu->TFlag = value & 0x1; | 4224 | cpu->TFlag = value & 0x1; |
| @@ -4437,6 +4227,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4437 | goto DISPATCH; | 4227 | goto DISPATCH; |
| 4438 | } | 4228 | } |
| 4439 | //} | 4229 | //} |
| 4230 | |||
| 4440 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4231 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4441 | INC_PC(sizeof(ldst_inst)); | 4232 | INC_PC(sizeof(ldst_inst)); |
| 4442 | FETCH_INST; | 4233 | FETCH_INST; |
| @@ -4446,10 +4237,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4446 | { | 4237 | { |
| 4447 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4238 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4448 | if (CondPassed(cpu, inst_base->cond)) { | 4239 | if (CondPassed(cpu, inst_base->cond)) { |
| 4449 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4240 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4450 | if (fault) goto MMU_EXCEPTION; | 4241 | unsigned int value = Memory::Read32(addr); |
| 4451 | unsigned int value; | ||
| 4452 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | ||
| 4453 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) | 4242 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) |
| 4454 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4243 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4455 | else { | 4244 | else { |
| @@ -4504,12 +4293,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4504 | { | 4293 | { |
| 4505 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4294 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4506 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4295 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4507 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4296 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4508 | if (fault) goto MMU_EXCEPTION; | 4297 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read8(addr); |
| 4509 | unsigned int value; | 4298 | |
| 4510 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | ||
| 4511 | if (fault) goto MMU_EXCEPTION; | ||
| 4512 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4513 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4299 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4514 | INC_PC(sizeof(ldst_inst)); | 4300 | INC_PC(sizeof(ldst_inst)); |
| 4515 | goto DISPATCH; | 4301 | goto DISPATCH; |
| @@ -4524,12 +4310,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4524 | { | 4310 | { |
| 4525 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4311 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4526 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4312 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4527 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4313 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4528 | if (fault) goto MMU_EXCEPTION; | 4314 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read8(addr); |
| 4529 | unsigned int value; | 4315 | |
| 4530 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | ||
| 4531 | if (fault) goto MMU_EXCEPTION; | ||
| 4532 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4533 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4316 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4534 | INC_PC(sizeof(ldst_inst)); | 4317 | INC_PC(sizeof(ldst_inst)); |
| 4535 | goto DISPATCH; | 4318 | goto DISPATCH; |
| @@ -4545,22 +4328,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4545 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4328 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4546 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4329 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4547 | // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) | 4330 | // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) |
| 4548 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4331 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4549 | if (fault) goto MMU_EXCEPTION; | 4332 | |
| 4550 | uint32_t rear_phys_addr; | 4333 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read32(addr); |
| 4551 | fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1); | 4334 | cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = Memory::Read32(addr + 4); |
| 4552 | if(fault){ | ||
| 4553 | LOG_ERROR(Core_ARM11, "MMU fault , should rollback the above get_addr\n"); | ||
| 4554 | CITRA_IGNORE_EXIT(-1); | ||
| 4555 | goto MMU_EXCEPTION; | ||
| 4556 | } | ||
| 4557 | unsigned int value; | ||
| 4558 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | ||
| 4559 | if (fault) goto MMU_EXCEPTION; | ||
| 4560 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4561 | fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32); | ||
| 4562 | if (fault) goto MMU_EXCEPTION; | ||
| 4563 | cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value; | ||
| 4564 | 4335 | ||
| 4565 | // No dispatch since this operation should not modify R15 | 4336 | // No dispatch since this operation should not modify R15 |
| 4566 | } | 4337 | } |
| @@ -4575,13 +4346,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4575 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4346 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4576 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4347 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4577 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 4348 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; |
| 4578 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4579 | if (fault) goto MMU_EXCEPTION; | ||
| 4580 | unsigned int value; | ||
| 4581 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | ||
| 4582 | if (fault) goto MMU_EXCEPTION; | ||
| 4583 | 4349 | ||
| 4584 | add_exclusive_addr(cpu, phys_addr); | 4350 | unsigned int value = Memory::Read32(addr); |
| 4351 | |||
| 4352 | add_exclusive_addr(cpu, addr); | ||
| 4585 | cpu->exclusive_state = 1; | 4353 | cpu->exclusive_state = 1; |
| 4586 | 4354 | ||
| 4587 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4355 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| @@ -4600,13 +4368,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4600 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4368 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4601 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4369 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4602 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 4370 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; |
| 4603 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 4604 | if (fault) goto MMU_EXCEPTION; | ||
| 4605 | unsigned int value; | ||
| 4606 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | ||
| 4607 | if (fault) goto MMU_EXCEPTION; | ||
| 4608 | 4371 | ||
| 4609 | add_exclusive_addr(cpu, phys_addr); | 4372 | unsigned int value = Memory::Read8(addr); |
| 4373 | |||
| 4374 | add_exclusive_addr(cpu, addr); | ||
| 4610 | cpu->exclusive_state = 1; | 4375 | cpu->exclusive_state = 1; |
| 4611 | 4376 | ||
| 4612 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4377 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| @@ -4624,12 +4389,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4624 | { | 4389 | { |
| 4625 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4390 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4626 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4391 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4627 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4392 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4628 | if (fault) goto MMU_EXCEPTION; | 4393 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read16(addr); |
| 4629 | unsigned int value = 0; | ||
| 4630 | fault = interpreter_read_memory(addr, phys_addr, value, 16); | ||
| 4631 | if (fault) goto MMU_EXCEPTION; | ||
| 4632 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||
| 4633 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4394 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4634 | INC_PC(sizeof(ldst_inst)); | 4395 | INC_PC(sizeof(ldst_inst)); |
| 4635 | goto DISPATCH; | 4396 | goto DISPATCH; |
| @@ -4644,11 +4405,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4644 | { | 4405 | { |
| 4645 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4406 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4646 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4407 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4647 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4408 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4648 | if (fault) goto MMU_EXCEPTION; | 4409 | unsigned int value = Memory::Read8(addr); |
| 4649 | unsigned int value; | ||
| 4650 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | ||
| 4651 | if (fault) goto MMU_EXCEPTION; | ||
| 4652 | if (BIT(value, 7)) { | 4410 | if (BIT(value, 7)) { |
| 4653 | value |= 0xffffff00; | 4411 | value |= 0xffffff00; |
| 4654 | } | 4412 | } |
| @@ -4667,11 +4425,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4667 | { | 4425 | { |
| 4668 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4426 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4669 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4427 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4670 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4428 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4671 | if (fault) goto MMU_EXCEPTION; | 4429 | unsigned int value = Memory::Read16(addr); |
| 4672 | unsigned int value; | ||
| 4673 | fault = interpreter_read_memory(addr, phys_addr, value, 16); | ||
| 4674 | if (fault) goto MMU_EXCEPTION; | ||
| 4675 | if (BIT(value, 15)) { | 4430 | if (BIT(value, 15)) { |
| 4676 | value |= 0xffff0000; | 4431 | value |= 0xffff0000; |
| 4677 | } | 4432 | } |
| @@ -4690,11 +4445,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4690 | { | 4445 | { |
| 4691 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4446 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4692 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4447 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4693 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1); | 4448 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4694 | if (fault) goto MMU_EXCEPTION; | 4449 | unsigned int value = Memory::Read32(addr); |
| 4695 | unsigned int value; | ||
| 4696 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | ||
| 4697 | if (fault) goto MMU_EXCEPTION; | ||
| 4698 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4450 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4699 | 4451 | ||
| 4700 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) | 4452 | if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) |
| @@ -5640,78 +5392,49 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5640 | unsigned int Rn = BITS(inst, 16, 19); | 5392 | unsigned int Rn = BITS(inst, 16, 19); |
| 5641 | unsigned int old_RN = cpu->Reg[Rn]; | 5393 | unsigned int old_RN = cpu->Reg[Rn]; |
| 5642 | 5394 | ||
| 5643 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5395 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
| 5644 | if (fault) goto MMU_EXCEPTION; | ||
| 5645 | if (BIT(inst_cream->inst, 22) == 1) { | 5396 | if (BIT(inst_cream->inst, 22) == 1) { |
| 5646 | for (i = 0; i < 13; i++) { | 5397 | for (i = 0; i < 13; i++) { |
| 5647 | if(BIT(inst_cream->inst, i)){ | 5398 | if(BIT(inst_cream->inst, i)) { |
| 5648 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5399 | Memory::Write32(addr, cpu->Reg[i]); |
| 5649 | if (fault) goto MMU_EXCEPTION; | ||
| 5650 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | ||
| 5651 | if (fault) goto MMU_EXCEPTION; | ||
| 5652 | addr += 4; | 5400 | addr += 4; |
| 5653 | phys_addr += 4; | ||
| 5654 | } | 5401 | } |
| 5655 | } | 5402 | } |
| 5656 | if (BIT(inst_cream->inst, 13)) { | 5403 | if (BIT(inst_cream->inst, 13)) { |
| 5657 | if (cpu->Mode == USER32MODE) { | 5404 | if (cpu->Mode == USER32MODE) { |
| 5658 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5405 | Memory::Write32(addr, cpu->Reg[i]); |
| 5659 | if (fault) goto MMU_EXCEPTION; | ||
| 5660 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | ||
| 5661 | if (fault) goto MMU_EXCEPTION; | ||
| 5662 | addr += 4; | 5406 | addr += 4; |
| 5663 | phys_addr += 4; | ||
| 5664 | } else { | 5407 | } else { |
| 5665 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32); | 5408 | Memory::Write32(addr, cpu->Reg_usr[0]); |
| 5666 | if (fault) goto MMU_EXCEPTION; | ||
| 5667 | addr += 4; | 5409 | addr += 4; |
| 5668 | phys_addr += 4; | ||
| 5669 | } | 5410 | } |
| 5670 | } | 5411 | } |
| 5671 | if (BIT(inst_cream->inst, 14)) { | 5412 | if (BIT(inst_cream->inst, 14)) { |
| 5672 | if (cpu->Mode == USER32MODE) { | 5413 | if (cpu->Mode == USER32MODE) { |
| 5673 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5414 | Memory::Write32(addr, cpu->Reg[i]); |
| 5674 | if (fault) goto MMU_EXCEPTION; | ||
| 5675 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | ||
| 5676 | if (fault) goto MMU_EXCEPTION; | ||
| 5677 | addr += 4; | 5415 | addr += 4; |
| 5678 | phys_addr += 4; | ||
| 5679 | } else { | 5416 | } else { |
| 5680 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5417 | Memory::Write32(addr, cpu->Reg_usr[1]); |
| 5681 | if (fault) goto MMU_EXCEPTION; | ||
| 5682 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32); | ||
| 5683 | if (fault) goto MMU_EXCEPTION; | ||
| 5684 | addr += 4; | 5418 | addr += 4; |
| 5685 | phys_addr += 4; | ||
| 5686 | } | 5419 | } |
| 5687 | } | 5420 | } |
| 5688 | if (BIT(inst_cream->inst, 15)) { | 5421 | if (BIT(inst_cream->inst, 15)) { |
| 5689 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5422 | Memory::Write32(addr, cpu->Reg_usr[1] + 8); |
| 5690 | if (fault) goto MMU_EXCEPTION; | ||
| 5691 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); | ||
| 5692 | if (fault) goto MMU_EXCEPTION; | ||
| 5693 | } | 5423 | } |
| 5694 | } else { | 5424 | } else { |
| 5695 | for( i = 0; i < 15; i ++ ) { | 5425 | for( i = 0; i < 15; i++ ) { |
| 5696 | if(BIT(inst_cream->inst, i)) { | 5426 | if(BIT(inst_cream->inst, i)) { |
| 5697 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 5698 | if (fault) goto MMU_EXCEPTION; | ||
| 5699 | if(i == Rn) | 5427 | if(i == Rn) |
| 5700 | fault = interpreter_write_memory(addr, phys_addr, old_RN, 32); | 5428 | Memory::Write32(addr, old_RN); |
| 5701 | else | 5429 | else |
| 5702 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32); | 5430 | Memory::Write32(addr, cpu->Reg[i]); |
| 5703 | if (fault) goto MMU_EXCEPTION; | ||
| 5704 | addr += 4; | 5431 | addr += 4; |
| 5705 | phys_addr += 4; | ||
| 5706 | } | 5432 | } |
| 5707 | } | 5433 | } |
| 5708 | 5434 | ||
| 5709 | // Check PC reg | 5435 | // Check PC reg |
| 5710 | if(BIT(inst_cream->inst, i)) { | 5436 | if(BIT(inst_cream->inst, i)) { |
| 5711 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 5437 | Memory::Write32(addr, cpu->Reg_usr[1] + 8); |
| 5712 | if (fault) goto MMU_EXCEPTION; | ||
| 5713 | fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32); | ||
| 5714 | if (fault) goto MMU_EXCEPTION; | ||
| 5715 | } | 5438 | } |
| 5716 | } | 5439 | } |
| 5717 | } | 5440 | } |
| @@ -5744,11 +5467,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5744 | { | 5467 | { |
| 5745 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5468 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5746 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5469 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5747 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5470 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
| 5748 | if (fault) goto MMU_EXCEPTION; | ||
| 5749 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 5471 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
| 5750 | fault = interpreter_write_memory(addr, phys_addr, value, 32); | 5472 | Memory::Write32(addr, value); |
| 5751 | if (fault) goto MMU_EXCEPTION; | ||
| 5752 | } | 5473 | } |
| 5753 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5474 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5754 | INC_PC(sizeof(ldst_inst)); | 5475 | INC_PC(sizeof(ldst_inst)); |
| @@ -5785,11 +5506,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5785 | { | 5506 | { |
| 5786 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5507 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5787 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5508 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5788 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5509 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
| 5789 | if (fault) goto MMU_EXCEPTION; | ||
| 5790 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; | 5510 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; |
| 5791 | fault = interpreter_write_memory(addr, phys_addr, value, 8); | 5511 | Memory::Write8(addr, value); |
| 5792 | if (fault) goto MMU_EXCEPTION; | ||
| 5793 | } | 5512 | } |
| 5794 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5513 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5795 | INC_PC(sizeof(ldst_inst)); | 5514 | INC_PC(sizeof(ldst_inst)); |
| @@ -5800,11 +5519,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5800 | { | 5519 | { |
| 5801 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5520 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5802 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5521 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5803 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5522 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
| 5804 | if (fault) goto MMU_EXCEPTION; | ||
| 5805 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; | 5523 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; |
| 5806 | fault = interpreter_write_memory(addr, phys_addr, value, 8); | 5524 | Memory::Write8(addr, value); |
| 5807 | if (fault) goto MMU_EXCEPTION; | ||
| 5808 | } | 5525 | } |
| 5809 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5526 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5810 | INC_PC(sizeof(ldst_inst)); | 5527 | INC_PC(sizeof(ldst_inst)); |
| @@ -5815,22 +5532,12 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5815 | { | 5532 | { |
| 5816 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5533 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5817 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5534 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5818 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5535 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
| 5819 | if (fault) goto MMU_EXCEPTION; | ||
| 5820 | uint32_t rear_phys_addr; | ||
| 5821 | fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0); | ||
| 5822 | if (fault){ | ||
| 5823 | LOG_ERROR(Core_ARM11, "MMU fault , should rollback the above get_addr"); | ||
| 5824 | CITRA_IGNORE_EXIT(-1); | ||
| 5825 | goto MMU_EXCEPTION; | ||
| 5826 | } | ||
| 5827 | 5536 | ||
| 5828 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 5537 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
| 5829 | fault = interpreter_write_memory(addr, phys_addr, value, 32); | 5538 | Memory::Write32(addr, value); |
| 5830 | if (fault) goto MMU_EXCEPTION; | ||
| 5831 | value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]; | 5539 | value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]; |
| 5832 | fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32); | 5540 | Memory::Write32(addr + 4, value); |
| 5833 | if (fault) goto MMU_EXCEPTION; | ||
| 5834 | } | 5541 | } |
| 5835 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5542 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5836 | INC_PC(sizeof(ldst_inst)); | 5543 | INC_PC(sizeof(ldst_inst)); |
| @@ -5843,17 +5550,14 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5843 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5550 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5844 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 5551 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; |
| 5845 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)]; | 5552 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)]; |
| 5846 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 5847 | if (fault) goto MMU_EXCEPTION; | ||
| 5848 | 5553 | ||
| 5849 | int dest_reg = BITS(inst_cream->inst, 12, 15); | 5554 | int dest_reg = BITS(inst_cream->inst, 12, 15); |
| 5850 | if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ | 5555 | if((exclusive_detect(cpu, addr) == 0) && (cpu->exclusive_state == 1)){ |
| 5851 | remove_exclusive(cpu, phys_addr); | 5556 | remove_exclusive(cpu, addr); |
| 5852 | cpu->Reg[dest_reg] = 0; | 5557 | cpu->Reg[dest_reg] = 0; |
| 5853 | cpu->exclusive_state = 0; | 5558 | cpu->exclusive_state = 0; |
| 5854 | 5559 | ||
| 5855 | fault = interpreter_write_memory(addr, phys_addr, value, 32); | 5560 | Memory::Write32(addr, value); |
| 5856 | if (fault) goto MMU_EXCEPTION; | ||
| 5857 | } else { | 5561 | } else { |
| 5858 | // Failed to write due to mutex access | 5562 | // Failed to write due to mutex access |
| 5859 | cpu->Reg[dest_reg] = 1; | 5563 | cpu->Reg[dest_reg] = 1; |
| @@ -5870,15 +5574,12 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5870 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5574 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5871 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 5575 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; |
| 5872 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff; | 5576 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff; |
| 5873 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | ||
| 5874 | if (fault) goto MMU_EXCEPTION; | ||
| 5875 | int dest_reg = BITS(inst_cream->inst, 12, 15); | 5577 | int dest_reg = BITS(inst_cream->inst, 12, 15); |
| 5876 | if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){ | 5578 | if((exclusive_detect(cpu, addr) == 0) && (cpu->exclusive_state == 1)){ |
| 5877 | remove_exclusive(cpu, phys_addr); | 5579 | remove_exclusive(cpu, addr); |
| 5878 | cpu->Reg[dest_reg] = 0; | 5580 | cpu->Reg[dest_reg] = 0; |
| 5879 | cpu->exclusive_state = 0; | 5581 | cpu->exclusive_state = 0; |
| 5880 | fault = interpreter_write_memory(addr, phys_addr, value, 8); | 5582 | Memory::Write8(addr, value); |
| 5881 | if (fault) goto MMU_EXCEPTION; | ||
| 5882 | } else { | 5583 | } else { |
| 5883 | cpu->Reg[dest_reg] = 1; | 5584 | cpu->Reg[dest_reg] = 1; |
| 5884 | } | 5585 | } |
| @@ -5892,11 +5593,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5892 | { | 5593 | { |
| 5893 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5594 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5894 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5595 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5895 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5596 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
| 5896 | if (fault) goto MMU_EXCEPTION; | ||
| 5897 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; | 5597 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; |
| 5898 | fault = interpreter_write_memory(addr, phys_addr, value, 16); | 5598 | Memory::Write16(addr, value); |
| 5899 | if (fault) goto MMU_EXCEPTION; | ||
| 5900 | } | 5599 | } |
| 5901 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5600 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5902 | INC_PC(sizeof(ldst_inst)); | 5601 | INC_PC(sizeof(ldst_inst)); |
| @@ -5907,11 +5606,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5907 | { | 5606 | { |
| 5908 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5607 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 5909 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5608 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5910 | fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0); | 5609 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
| 5911 | if (fault) goto MMU_EXCEPTION; | ||
| 5912 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 5610 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
| 5913 | fault = interpreter_write_memory(addr, phys_addr, value, 32); | 5611 | Memory::Write32(addr, value); |
| 5914 | if (fault) goto MMU_EXCEPTION; | ||
| 5915 | } | 5612 | } |
| 5916 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5613 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5917 | INC_PC(sizeof(ldst_inst)); | 5614 | INC_PC(sizeof(ldst_inst)); |
| @@ -5967,15 +5664,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5967 | swp_inst *inst_cream = (swp_inst *)inst_base->component; | 5664 | swp_inst *inst_cream = (swp_inst *)inst_base->component; |
| 5968 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5665 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5969 | addr = RN; | 5666 | addr = RN; |
| 5970 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | ||
| 5971 | if (fault) goto MMU_EXCEPTION; | ||
| 5972 | unsigned int value; | 5667 | unsigned int value; |
| 5973 | fault = interpreter_read_memory(addr, phys_addr, value, 32); | 5668 | value = Memory::Read32(addr); |
| 5974 | if (fault) goto MMU_EXCEPTION; | 5669 | Memory::Write32(addr, RM); |
| 5975 | fault = interpreter_write_memory(addr, phys_addr, RM, 32); | ||
| 5976 | if (fault) goto MMU_EXCEPTION; | ||
| 5977 | 5670 | ||
| 5978 | assert((phys_addr & 0x3) == 0); | ||
| 5979 | RD = value; | 5671 | RD = value; |
| 5980 | } | 5672 | } |
| 5981 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5673 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| @@ -5988,13 +5680,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5988 | swp_inst *inst_cream = (swp_inst *)inst_base->component; | 5680 | swp_inst *inst_cream = (swp_inst *)inst_base->component; |
| 5989 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5681 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5990 | addr = RN; | 5682 | addr = RN; |
| 5991 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 5683 | unsigned int value = Memory::Read8(addr); |
| 5992 | if (fault) goto MMU_EXCEPTION; | 5684 | Memory::Write8(addr, (RM & 0xFF)); |
| 5993 | unsigned int value; | ||
| 5994 | fault = interpreter_read_memory(addr, phys_addr, value, 8); | ||
| 5995 | if (fault) goto MMU_EXCEPTION; | ||
| 5996 | fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8); | ||
| 5997 | if (fault) goto MMU_EXCEPTION; | ||
| 5998 | } | 5685 | } |
| 5999 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5686 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6000 | INC_PC(sizeof(swp_inst)); | 5687 | INC_PC(sizeof(swp_inst)); |
| @@ -6459,17 +6146,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6459 | #define VFP_INTERPRETER_IMPL | 6146 | #define VFP_INTERPRETER_IMPL |
| 6460 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | 6147 | #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" |
| 6461 | #undef VFP_INTERPRETER_IMPL | 6148 | #undef VFP_INTERPRETER_IMPL |
| 6462 | MMU_EXCEPTION: | 6149 | |
| 6463 | { | ||
| 6464 | SAVE_NZCVT; | ||
| 6465 | cpu->abortSig = true; | ||
| 6466 | cpu->Aborted = ARMul_DataAbortV; | ||
| 6467 | cpu->AbortAddr = addr; | ||
| 6468 | cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff; | ||
| 6469 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; | ||
| 6470 | cpu->NumInstrsToExecute = 0; | ||
| 6471 | return num_instrs; | ||
| 6472 | } | ||
| 6473 | END: | 6150 | END: |
| 6474 | { | 6151 | { |
| 6475 | SAVE_NZCVT; | 6152 | SAVE_NZCVT; |
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp index cc70fc33c..b5fcbac86 100644 --- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp | |||
| @@ -2891,32 +2891,15 @@ VSTR_INST: | |||
| 2891 | 2891 | ||
| 2892 | unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); | 2892 | unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); |
| 2893 | addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); | 2893 | addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); |
| 2894 | DBG("VSTR :\n"); | 2894 | |
| 2895 | |||
| 2896 | |||
| 2897 | if (inst_cream->single) | 2895 | if (inst_cream->single) |
| 2898 | { | 2896 | { |
| 2899 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 2897 | Memory::Write32(addr, cpu->ExtReg[inst_cream->d]); |
| 2900 | if (fault) goto MMU_EXCEPTION; | ||
| 2901 | fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d], 32); | ||
| 2902 | if (fault) goto MMU_EXCEPTION; | ||
| 2903 | DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d, cpu->ExtReg[inst_cream->d]); | ||
| 2904 | } | 2898 | } |
| 2905 | else | 2899 | else |
| 2906 | { | 2900 | { |
| 2907 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 2901 | Memory::Write32(addr, cpu->ExtReg[inst_cream->d*2]); |
| 2908 | if (fault) goto MMU_EXCEPTION; | 2902 | Memory::Write32(addr + 4, cpu->ExtReg[inst_cream->d*2+1]); |
| 2909 | |||
| 2910 | /* Check endianness */ | ||
| 2911 | fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d*2], 32); | ||
| 2912 | if (fault) goto MMU_EXCEPTION; | ||
| 2913 | |||
| 2914 | fault = check_address_validity(cpu, addr + 4, &phys_addr, 0); | ||
| 2915 | if (fault) goto MMU_EXCEPTION; | ||
| 2916 | |||
| 2917 | fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[inst_cream->d*2+1], 32); | ||
| 2918 | if (fault) goto MMU_EXCEPTION; | ||
| 2919 | DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, inst_cream->d*2+1, inst_cream->d*2, cpu->ExtReg[inst_cream->d*2+1], cpu->ExtReg[inst_cream->d*2]); | ||
| 2920 | } | 2903 | } |
| 2921 | } | 2904 | } |
| 2922 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 2905 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| @@ -3027,47 +3010,27 @@ VPUSH_INST: | |||
| 3027 | { | 3010 | { |
| 3028 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 3011 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 3029 | CHECK_VFP_ENABLED; | 3012 | CHECK_VFP_ENABLED; |
| 3030 | |||
| 3031 | int i; | 3013 | int i; |
| 3032 | 3014 | ||
| 3033 | vpush_inst *inst_cream = (vpush_inst *)inst_base->component; | 3015 | vpush_inst *inst_cream = (vpush_inst *)inst_base->component; |
| 3034 | 3016 | ||
| 3035 | DBG("VPUSH :\n"); | ||
| 3036 | |||
| 3037 | addr = cpu->Reg[R13] - inst_cream->imm32; | 3017 | addr = cpu->Reg[R13] - inst_cream->imm32; |
| 3038 | 3018 | ||
| 3039 | |||
| 3040 | for (i = 0; i < inst_cream->regs; i++) | 3019 | for (i = 0; i < inst_cream->regs; i++) |
| 3041 | { | 3020 | { |
| 3042 | if (inst_cream->single) | 3021 | if (inst_cream->single) |
| 3043 | { | 3022 | { |
| 3044 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 3023 | Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); |
| 3045 | if (fault) goto MMU_EXCEPTION; | ||
| 3046 | fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); | ||
| 3047 | if (fault) goto MMU_EXCEPTION; | ||
| 3048 | DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); | ||
| 3049 | addr += 4; | 3024 | addr += 4; |
| 3050 | } | 3025 | } |
| 3051 | else | 3026 | else |
| 3052 | { | 3027 | { |
| 3053 | /* Careful of endianness, little by default */ | 3028 | Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); |
| 3054 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 3029 | Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); |
| 3055 | if (fault) goto MMU_EXCEPTION; | ||
| 3056 | fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32); | ||
| 3057 | if (fault) goto MMU_EXCEPTION; | ||
| 3058 | |||
| 3059 | fault = check_address_validity(cpu, addr + 4, &phys_addr, 0); | ||
| 3060 | if (fault) goto MMU_EXCEPTION; | ||
| 3061 | fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); | ||
| 3062 | if (fault) goto MMU_EXCEPTION; | ||
| 3063 | DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); | ||
| 3064 | addr += 8; | 3030 | addr += 8; |
| 3065 | } | 3031 | } |
| 3066 | } | 3032 | } |
| 3067 | DBG("\tsp[%x]", cpu->Reg[R13]); | ||
| 3068 | cpu->Reg[R13] = cpu->Reg[R13] - inst_cream->imm32; | 3033 | cpu->Reg[R13] = cpu->Reg[R13] - inst_cream->imm32; |
| 3069 | DBG("=>[%x]\n", cpu->Reg[R13]); | ||
| 3070 | |||
| 3071 | } | 3034 | } |
| 3072 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 3035 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 3073 | INC_PC(sizeof(vpush_inst)); | 3036 | INC_PC(sizeof(vpush_inst)); |
| @@ -3110,7 +3073,7 @@ int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ | |||
| 3110 | { | 3073 | { |
| 3111 | if (single) | 3074 | if (single) |
| 3112 | { | 3075 | { |
| 3113 | //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); | 3076 | //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); |
| 3114 | #if 0 | 3077 | #if 0 |
| 3115 | phys_addr = get_phys_addr(cpu, bb, Addr, 0); | 3078 | phys_addr = get_phys_addr(cpu, bb, Addr, 0); |
| 3116 | bb = cpu->dyncom_engine->bb; | 3079 | bb = cpu->dyncom_engine->bb; |
| @@ -3199,43 +3162,24 @@ VSTM_INST: /* encoding 1 */ | |||
| 3199 | vstm_inst *inst_cream = (vstm_inst *)inst_base->component; | 3162 | vstm_inst *inst_cream = (vstm_inst *)inst_base->component; |
| 3200 | 3163 | ||
| 3201 | addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); | 3164 | addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); |
| 3202 | DBG("VSTM : addr[%x]\n", addr); | 3165 | |
| 3203 | |||
| 3204 | |||
| 3205 | for (i = 0; i < inst_cream->regs; i++) | 3166 | for (i = 0; i < inst_cream->regs; i++) |
| 3206 | { | 3167 | { |
| 3207 | if (inst_cream->single) | 3168 | if (inst_cream->single) |
| 3208 | { | 3169 | { |
| 3209 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 3170 | Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); |
| 3210 | if (fault) goto MMU_EXCEPTION; | ||
| 3211 | |||
| 3212 | fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); | ||
| 3213 | if (fault) goto MMU_EXCEPTION; | ||
| 3214 | DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); | ||
| 3215 | addr += 4; | 3171 | addr += 4; |
| 3216 | } | 3172 | } |
| 3217 | else | 3173 | else |
| 3218 | { | 3174 | { |
| 3219 | /* Careful of endianness, little by default */ | 3175 | Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); |
| 3220 | fault = check_address_validity(cpu, addr, &phys_addr, 0); | 3176 | Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); |
| 3221 | if (fault) goto MMU_EXCEPTION; | ||
| 3222 | |||
| 3223 | fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32); | ||
| 3224 | if (fault) goto MMU_EXCEPTION; | ||
| 3225 | |||
| 3226 | fault = check_address_validity(cpu, addr + 4, &phys_addr, 0); | ||
| 3227 | if (fault) goto MMU_EXCEPTION; | ||
| 3228 | |||
| 3229 | fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); | ||
| 3230 | if (fault) goto MMU_EXCEPTION; | ||
| 3231 | DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); | ||
| 3232 | addr += 8; | 3177 | addr += 8; |
| 3233 | } | 3178 | } |
| 3234 | } | 3179 | } |
| 3235 | if (inst_cream->wback){ | 3180 | if (inst_cream->wback){ |
| 3236 | cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : | 3181 | cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : |
| 3237 | cpu->Reg[inst_cream->n] - inst_cream->imm32); | 3182 | cpu->Reg[inst_cream->n] - inst_cream->imm32); |
| 3238 | DBG("\twback r%d[%x]\n", inst_cream->n, cpu->Reg[inst_cream->n]); | ||
| 3239 | } | 3183 | } |
| 3240 | 3184 | ||
| 3241 | } | 3185 | } |
| @@ -3290,7 +3234,7 @@ int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ | |||
| 3290 | if (single) | 3234 | if (single) |
| 3291 | { | 3235 | { |
| 3292 | 3236 | ||
| 3293 | //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); | 3237 | //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); |
| 3294 | /* if R(i) is R15? */ | 3238 | /* if R(i) is R15? */ |
| 3295 | #if 0 | 3239 | #if 0 |
| 3296 | phys_addr = get_phys_addr(cpu, bb, Addr, 0); | 3240 | phys_addr = get_phys_addr(cpu, bb, Addr, 0); |
| @@ -3300,14 +3244,13 @@ int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ | |||
| 3300 | //memory_write(cpu, bb, Addr, RSPR(d + i), 32); | 3244 | //memory_write(cpu, bb, Addr, RSPR(d + i), 32); |
| 3301 | memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)),32); | 3245 | memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)),32); |
| 3302 | bb = cpu->dyncom_engine->bb; | 3246 | bb = cpu->dyncom_engine->bb; |
| 3303 | //if (fault) goto MMU_EXCEPTION; | ||
| 3304 | //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); | 3247 | //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); |
| 3305 | Addr = ADD(Addr, CONST(4)); | 3248 | Addr = ADD(Addr, CONST(4)); |
| 3306 | } | 3249 | } |
| 3307 | else | 3250 | else |
| 3308 | { | 3251 | { |
| 3309 | 3252 | ||
| 3310 | //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32); | 3253 | //Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); |
| 3311 | #if 0 | 3254 | #if 0 |
| 3312 | phys_addr = get_phys_addr(cpu, bb, Addr, 0); | 3255 | phys_addr = get_phys_addr(cpu, bb, Addr, 0); |
| 3313 | bb = cpu->dyncom_engine->bb; | 3256 | bb = cpu->dyncom_engine->bb; |
| @@ -3316,9 +3259,8 @@ int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ | |||
| 3316 | //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32); | 3259 | //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32); |
| 3317 | memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)),32); | 3260 | memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)),32); |
| 3318 | bb = cpu->dyncom_engine->bb; | 3261 | bb = cpu->dyncom_engine->bb; |
| 3319 | //if (fault) goto MMU_EXCEPTION; | ||
| 3320 | 3262 | ||
| 3321 | //fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); | 3263 | //Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); |
| 3322 | #if 0 | 3264 | #if 0 |
| 3323 | phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0); | 3265 | phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0); |
| 3324 | bb = cpu->dyncom_engine->bb; | 3266 | bb = cpu->dyncom_engine->bb; |
| @@ -3327,7 +3269,6 @@ int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ | |||
| 3327 | //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32); | 3269 | //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32); |
| 3328 | memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32); | 3270 | memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32); |
| 3329 | bb = cpu->dyncom_engine->bb; | 3271 | bb = cpu->dyncom_engine->bb; |
| 3330 | //if (fault) goto MMU_EXCEPTION; | ||
| 3331 | //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); | 3272 | //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); |
| 3332 | //addr += 8; | 3273 | //addr += 8; |
| 3333 | Addr = ADD(Addr, CONST(8)); | 3274 | Addr = ADD(Addr, CONST(8)); |
| @@ -3385,49 +3326,27 @@ VPOP_INST: | |||
| 3385 | unsigned int value1, value2; | 3326 | unsigned int value1, value2; |
| 3386 | 3327 | ||
| 3387 | vpop_inst *inst_cream = (vpop_inst *)inst_base->component; | 3328 | vpop_inst *inst_cream = (vpop_inst *)inst_base->component; |
| 3388 | 3329 | ||
| 3389 | DBG("VPOP :\n"); | ||
| 3390 | |||
| 3391 | addr = cpu->Reg[R13]; | 3330 | addr = cpu->Reg[R13]; |
| 3392 | |||
| 3393 | 3331 | ||
| 3394 | for (i = 0; i < inst_cream->regs; i++) | 3332 | for (i = 0; i < inst_cream->regs; i++) |
| 3395 | { | 3333 | { |
| 3396 | if (inst_cream->single) | 3334 | if (inst_cream->single) |
| 3397 | { | 3335 | { |
| 3398 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 3336 | value1 = Memory::Read32(addr); |
| 3399 | if (fault) goto MMU_EXCEPTION; | ||
| 3400 | |||
| 3401 | fault = interpreter_read_memory(addr, phys_addr, value1, 32); | ||
| 3402 | if (fault) goto MMU_EXCEPTION; | ||
| 3403 | DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, value1, addr); | ||
| 3404 | cpu->ExtReg[inst_cream->d+i] = value1; | 3337 | cpu->ExtReg[inst_cream->d+i] = value1; |
| 3405 | addr += 4; | 3338 | addr += 4; |
| 3406 | } | 3339 | } |
| 3407 | else | 3340 | else |
| 3408 | { | 3341 | { |
| 3409 | /* Careful of endianness, little by default */ | 3342 | value1 = Memory::Read32(addr); |
| 3410 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 3343 | value2 = Memory::Read32(addr + 4); |
| 3411 | if (fault) goto MMU_EXCEPTION; | ||
| 3412 | |||
| 3413 | fault = interpreter_read_memory(addr, phys_addr, value1, 32); | ||
| 3414 | if (fault) goto MMU_EXCEPTION; | ||
| 3415 | |||
| 3416 | fault = check_address_validity(cpu, addr + 4, &phys_addr, 1); | ||
| 3417 | if (fault) goto MMU_EXCEPTION; | ||
| 3418 | |||
| 3419 | fault = interpreter_read_memory(addr + 4, phys_addr, value2, 32); | ||
| 3420 | if (fault) goto MMU_EXCEPTION; | ||
| 3421 | DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, value2, value1, addr+4, addr); | ||
| 3422 | cpu->ExtReg[(inst_cream->d+i)*2] = value1; | 3344 | cpu->ExtReg[(inst_cream->d+i)*2] = value1; |
| 3423 | cpu->ExtReg[(inst_cream->d+i)*2 + 1] = value2; | 3345 | cpu->ExtReg[(inst_cream->d+i)*2 + 1] = value2; |
| 3424 | addr += 8; | 3346 | addr += 8; |
| 3425 | } | 3347 | } |
| 3426 | } | 3348 | } |
| 3427 | DBG("\tsp[%x]", cpu->Reg[R13]); | ||
| 3428 | cpu->Reg[R13] = cpu->Reg[R13] + inst_cream->imm32; | 3349 | cpu->Reg[R13] = cpu->Reg[R13] + inst_cream->imm32; |
| 3429 | DBG("=>[%x]\n", cpu->Reg[R13]); | ||
| 3430 | |||
| 3431 | } | 3350 | } |
| 3432 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 3351 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 3433 | INC_PC(sizeof(vpop_inst)); | 3352 | INC_PC(sizeof(vpop_inst)); |
| @@ -3565,33 +3484,19 @@ VLDR_INST: | |||
| 3565 | 3484 | ||
| 3566 | unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); | 3485 | unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); |
| 3567 | addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); | 3486 | addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); |
| 3568 | DBG("VLDR :\n", addr); | 3487 | |
| 3569 | |||
| 3570 | |||
| 3571 | if (inst_cream->single) | 3488 | if (inst_cream->single) |
| 3572 | { | 3489 | { |
| 3573 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 3490 | cpu->ExtReg[inst_cream->d] = Memory::Read32(addr); |
| 3574 | if (fault) goto MMU_EXCEPTION; | ||
| 3575 | fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d], 32); | ||
| 3576 | if (fault) goto MMU_EXCEPTION; | ||
| 3577 | DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d, cpu->ExtReg[inst_cream->d], addr); | ||
| 3578 | } | 3491 | } |
| 3579 | else | 3492 | else |
| 3580 | { | 3493 | { |
| 3581 | unsigned int word1, word2; | 3494 | unsigned int word1, word2; |
| 3582 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 3495 | word1 = Memory::Read32(addr); |
| 3583 | if (fault) goto MMU_EXCEPTION; | 3496 | word2 = Memory::Read32(addr + 4); |
| 3584 | fault = interpreter_read_memory(addr, phys_addr, word1, 32); | 3497 | |
| 3585 | if (fault) goto MMU_EXCEPTION; | ||
| 3586 | |||
| 3587 | fault = check_address_validity(cpu, addr + 4, &phys_addr, 1); | ||
| 3588 | if (fault) goto MMU_EXCEPTION; | ||
| 3589 | fault = interpreter_read_memory(addr + 4, phys_addr, word2, 32); | ||
| 3590 | if (fault) goto MMU_EXCEPTION; | ||
| 3591 | /* Check endianness */ | ||
| 3592 | cpu->ExtReg[inst_cream->d*2] = word1; | 3498 | cpu->ExtReg[inst_cream->d*2] = word1; |
| 3593 | cpu->ExtReg[inst_cream->d*2+1] = word2; | 3499 | cpu->ExtReg[inst_cream->d*2+1] = word2; |
| 3594 | DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", inst_cream->d*2+1, inst_cream->d*2, word2, word1, addr+4, addr); | ||
| 3595 | } | 3500 | } |
| 3596 | } | 3501 | } |
| 3597 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 3502 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| @@ -3729,32 +3634,18 @@ VLDM_INST: | |||
| 3729 | vldm_inst *inst_cream = (vldm_inst *)inst_base->component; | 3634 | vldm_inst *inst_cream = (vldm_inst *)inst_base->component; |
| 3730 | 3635 | ||
| 3731 | addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); | 3636 | addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); |
| 3732 | DBG("VLDM : addr[%x]\n", addr); | 3637 | |
| 3733 | |||
| 3734 | for (i = 0; i < inst_cream->regs; i++) | 3638 | for (i = 0; i < inst_cream->regs; i++) |
| 3735 | { | 3639 | { |
| 3736 | if (inst_cream->single) | 3640 | if (inst_cream->single) |
| 3737 | { | 3641 | { |
| 3738 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 3642 | cpu->ExtReg[inst_cream->d+i] = Memory::Read32(addr); |
| 3739 | if (fault) goto MMU_EXCEPTION; | ||
| 3740 | fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); | ||
| 3741 | if (fault) goto MMU_EXCEPTION; | ||
| 3742 | DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, cpu->ExtReg[inst_cream->d+i], addr); | ||
| 3743 | addr += 4; | 3643 | addr += 4; |
| 3744 | } | 3644 | } |
| 3745 | else | 3645 | else |
| 3746 | { | 3646 | { |
| 3747 | /* Careful of endianness, little by default */ | 3647 | cpu->ExtReg[(inst_cream->d+i)*2] = Memory::Read32(addr); |
| 3748 | fault = check_address_validity(cpu, addr, &phys_addr, 1); | 3648 | cpu->ExtReg[(inst_cream->d+i)*2 + 1] = Memory::Read32(addr + 4); |
| 3749 | if (fault) goto MMU_EXCEPTION; | ||
| 3750 | fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32); | ||
| 3751 | if (fault) goto MMU_EXCEPTION; | ||
| 3752 | |||
| 3753 | fault = check_address_validity(cpu, addr + 4, &phys_addr, 1); | ||
| 3754 | if (fault) goto MMU_EXCEPTION; | ||
| 3755 | fault = interpreter_read_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); | ||
| 3756 | if (fault) goto MMU_EXCEPTION; | ||
| 3757 | DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2], addr+4, addr); | ||
| 3758 | addr += 8; | 3649 | addr += 8; |
| 3759 | } | 3650 | } |
| 3760 | } | 3651 | } |
| @@ -3815,7 +3706,7 @@ int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ | |||
| 3815 | if (single) | 3706 | if (single) |
| 3816 | { | 3707 | { |
| 3817 | 3708 | ||
| 3818 | //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); | 3709 | //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); |
| 3819 | /* if R(i) is R15? */ | 3710 | /* if R(i) is R15? */ |
| 3820 | #if 0 | 3711 | #if 0 |
| 3821 | phys_addr = get_phys_addr(cpu, bb, Addr, 1); | 3712 | phys_addr = get_phys_addr(cpu, bb, Addr, 1); |
| @@ -3827,7 +3718,6 @@ int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ | |||
| 3827 | val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); | 3718 | val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); |
| 3828 | //LETS(d + i, val); | 3719 | //LETS(d + i, val); |
| 3829 | LETFPS(d + i, FPBITCAST32(val)); | 3720 | LETFPS(d + i, FPBITCAST32(val)); |
| 3830 | //if (fault) goto MMU_EXCEPTION; | ||
| 3831 | //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); | 3721 | //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); |
| 3832 | Addr = ADD(Addr, CONST(4)); | 3722 | Addr = ADD(Addr, CONST(4)); |
| 3833 | } | 3723 | } |
| @@ -3852,7 +3742,7 @@ int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ | |||
| 3852 | val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); | 3742 | val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); |
| 3853 | LETFPS((d + i) * 2 + 1, FPBITCAST32(val)); | 3743 | LETFPS((d + i) * 2 + 1, FPBITCAST32(val)); |
| 3854 | 3744 | ||
| 3855 | //fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); | 3745 | //Memory::Write(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); |
| 3856 | //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); | 3746 | //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); |
| 3857 | //addr += 8; | 3747 | //addr += 8; |
| 3858 | Addr = ADD(Addr, CONST(8)); | 3748 | Addr = ADD(Addr, CONST(8)); |