diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 7 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpinstr.cpp | 54 |
2 files changed, 40 insertions, 21 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 0c20c2bc3..759ef7285 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -5997,7 +5997,12 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5997 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; | 5997 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; |
| 5998 | inst_cream->get_addr(cpu, inst_cream->inst, addr); | 5998 | inst_cream->get_addr(cpu, inst_cream->inst, addr); |
| 5999 | 5999 | ||
| 6000 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 6000 | unsigned int reg = BITS(inst_cream->inst, 12, 15); |
| 6001 | unsigned int value = cpu->Reg[reg]; | ||
| 6002 | |||
| 6003 | if (reg == 15) | ||
| 6004 | value += 2 * cpu->GetInstructionSize(); | ||
| 6005 | |||
| 6001 | cpu->WriteMemory32(addr, value); | 6006 | cpu->WriteMemory32(addr, value); |
| 6002 | } | 6007 | } |
| 6003 | cpu->Reg[15] += cpu->GetInstructionSize(); | 6008 | cpu->Reg[15] += cpu->GetInstructionSize(); |
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp index 9b99fc5bc..49298d7ba 100644 --- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp | |||
| @@ -1511,19 +1511,26 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index) | |||
| 1511 | #ifdef VFP_INTERPRETER_IMPL | 1511 | #ifdef VFP_INTERPRETER_IMPL |
| 1512 | VSTM_INST: /* encoding 1 */ | 1512 | VSTM_INST: /* encoding 1 */ |
| 1513 | { | 1513 | { |
| 1514 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 1514 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 1515 | CHECK_VFP_ENABLED; | 1515 | CHECK_VFP_ENABLED; |
| 1516 | 1516 | ||
| 1517 | vstm_inst *inst_cream = (vstm_inst *)inst_base->component; | 1517 | vstm_inst* inst_cream = (vstm_inst*)inst_base->component; |
| 1518 | |||
| 1519 | u32 address = cpu->Reg[inst_cream->n]; | ||
| 1518 | 1520 | ||
| 1519 | addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); | 1521 | // Only possible in ARM mode, where PC accesses have an 8 byte offset. |
| 1522 | if (inst_cream->n == 15) | ||
| 1523 | address += 8; | ||
| 1524 | |||
| 1525 | if (inst_cream->add == 0) | ||
| 1526 | address -= inst_cream->imm32; | ||
| 1520 | 1527 | ||
| 1521 | for (unsigned int i = 0; i < inst_cream->regs; i++) | 1528 | for (unsigned int i = 0; i < inst_cream->regs; i++) |
| 1522 | { | 1529 | { |
| 1523 | if (inst_cream->single) | 1530 | if (inst_cream->single) |
| 1524 | { | 1531 | { |
| 1525 | cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]); | 1532 | cpu->WriteMemory32(address, cpu->ExtReg[inst_cream->d+i]); |
| 1526 | addr += 4; | 1533 | address += 4; |
| 1527 | } | 1534 | } |
| 1528 | else | 1535 | else |
| 1529 | { | 1536 | { |
| @@ -1531,17 +1538,17 @@ VSTM_INST: /* encoding 1 */ | |||
| 1531 | const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1]; | 1538 | const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1]; |
| 1532 | 1539 | ||
| 1533 | if (cpu->InBigEndianMode()) { | 1540 | if (cpu->InBigEndianMode()) { |
| 1534 | cpu->WriteMemory32(addr + 0, word2); | 1541 | cpu->WriteMemory32(address + 0, word2); |
| 1535 | cpu->WriteMemory32(addr + 4, word1); | 1542 | cpu->WriteMemory32(address + 4, word1); |
| 1536 | } else { | 1543 | } else { |
| 1537 | cpu->WriteMemory32(addr + 0, word1); | 1544 | cpu->WriteMemory32(address + 0, word1); |
| 1538 | cpu->WriteMemory32(addr + 4, word2); | 1545 | cpu->WriteMemory32(address + 4, word2); |
| 1539 | } | 1546 | } |
| 1540 | 1547 | ||
| 1541 | addr += 8; | 1548 | address += 8; |
| 1542 | } | 1549 | } |
| 1543 | } | 1550 | } |
| 1544 | if (inst_cream->wback){ | 1551 | if (inst_cream->wback) { |
| 1545 | cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : | 1552 | cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : |
| 1546 | cpu->Reg[inst_cream->n] - inst_cream->imm32); | 1553 | cpu->Reg[inst_cream->n] - inst_cream->imm32); |
| 1547 | } | 1554 | } |
| @@ -1731,24 +1738,31 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index) | |||
| 1731 | #ifdef VFP_INTERPRETER_IMPL | 1738 | #ifdef VFP_INTERPRETER_IMPL |
| 1732 | VLDM_INST: | 1739 | VLDM_INST: |
| 1733 | { | 1740 | { |
| 1734 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 1741 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 1735 | CHECK_VFP_ENABLED; | 1742 | CHECK_VFP_ENABLED; |
| 1736 | 1743 | ||
| 1737 | vldm_inst *inst_cream = (vldm_inst *)inst_base->component; | 1744 | vldm_inst* inst_cream = (vldm_inst*)inst_base->component; |
| 1745 | |||
| 1746 | u32 address = cpu->Reg[inst_cream->n]; | ||
| 1747 | |||
| 1748 | // Only possible in ARM mode, where PC accesses have an 8 byte offset. | ||
| 1749 | if (inst_cream->n == 15) | ||
| 1750 | address += 8; | ||
| 1738 | 1751 | ||
| 1739 | addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); | 1752 | if (inst_cream->add == 0) |
| 1753 | address -= inst_cream->imm32; | ||
| 1740 | 1754 | ||
| 1741 | for (unsigned int i = 0; i < inst_cream->regs; i++) | 1755 | for (unsigned int i = 0; i < inst_cream->regs; i++) |
| 1742 | { | 1756 | { |
| 1743 | if (inst_cream->single) | 1757 | if (inst_cream->single) |
| 1744 | { | 1758 | { |
| 1745 | cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr); | 1759 | cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(address); |
| 1746 | addr += 4; | 1760 | address += 4; |
| 1747 | } | 1761 | } |
| 1748 | else | 1762 | else |
| 1749 | { | 1763 | { |
| 1750 | const u32 word1 = cpu->ReadMemory32(addr + 0); | 1764 | const u32 word1 = cpu->ReadMemory32(address + 0); |
| 1751 | const u32 word2 = cpu->ReadMemory32(addr + 4); | 1765 | const u32 word2 = cpu->ReadMemory32(address + 4); |
| 1752 | 1766 | ||
| 1753 | if (cpu->InBigEndianMode()) { | 1767 | if (cpu->InBigEndianMode()) { |
| 1754 | cpu->ExtReg[(inst_cream->d+i)*2+0] = word2; | 1768 | cpu->ExtReg[(inst_cream->d+i)*2+0] = word2; |
| @@ -1758,10 +1772,10 @@ VLDM_INST: | |||
| 1758 | cpu->ExtReg[(inst_cream->d+i)*2+1] = word2; | 1772 | cpu->ExtReg[(inst_cream->d+i)*2+1] = word2; |
| 1759 | } | 1773 | } |
| 1760 | 1774 | ||
| 1761 | addr += 8; | 1775 | address += 8; |
| 1762 | } | 1776 | } |
| 1763 | } | 1777 | } |
| 1764 | if (inst_cream->wback){ | 1778 | if (inst_cream->wback) { |
| 1765 | cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : | 1779 | cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : |
| 1766 | cpu->Reg[inst_cream->n] - inst_cream->imm32); | 1780 | cpu->Reg[inst_cream->n] - inst_cream->imm32); |
| 1767 | } | 1781 | } |