summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Lioncash2015-01-02 22:31:56 -0500
committerGravatar Lioncash2015-01-02 22:40:43 -0500
commit2f19acf0640c317c1da0b313f111515717e382d3 (patch)
treebc409a5dcbd7d189a260137e2a4640fa043088ec /src
parentMerge pull request #381 from Subv/savedatacheck (diff)
downloadyuzu-2f19acf0640c317c1da0b313f111515717e382d3.tar.gz
yuzu-2f19acf0640c317c1da0b313f111515717e382d3.tar.xz
yuzu-2f19acf0640c317c1da0b313f111515717e382d3.zip
dyncom: Implement REVSH
Also joins the REV ops into one common place.
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp90
1 files changed, 45 insertions, 45 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index a37e6c94e..85f3d3d88 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -871,6 +871,8 @@ typedef struct _mvn_inst {
871typedef struct _rev_inst { 871typedef struct _rev_inst {
872 unsigned int Rd; 872 unsigned int Rd;
873 unsigned int Rm; 873 unsigned int Rm;
874 unsigned int op1;
875 unsigned int op2;
874} rev_inst; 876} rev_inst;
875 877
876typedef struct _rsb_inst { 878typedef struct _rsb_inst {
@@ -2083,36 +2085,33 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index)
2083{ 2085{
2084 return INTERPRETER_TRANSLATE(qadd8)(inst, index); 2086 return INTERPRETER_TRANSLATE(qadd8)(inst, index);
2085} 2087}
2088
2086ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) 2089ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index)
2087{ 2090{
2088 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); 2091 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
2089 rev_inst *inst_cream = (rev_inst *)inst_base->component; 2092 rev_inst* const inst_cream = (rev_inst*)inst_base->component;
2090 2093
2091 inst_base->cond = BITS(inst, 28, 31); 2094 inst_base->cond = BITS(inst, 28, 31);
2092 inst_base->idx = index; 2095 inst_base->idx = index;
2093 inst_base->br = NON_BRANCH; 2096 inst_base->br = NON_BRANCH;
2094 inst_base->load_r15 = 0; 2097 inst_base->load_r15 = 0;
2095 2098
2096 inst_cream->Rm = BITS(inst, 0, 3); 2099 inst_cream->Rm = BITS(inst, 0, 3);
2097 inst_cream->Rd = BITS(inst, 12, 15); 2100 inst_cream->Rd = BITS(inst, 12, 15);
2101 inst_cream->op1 = BITS(inst, 20, 22);
2102 inst_cream->op2 = BITS(inst, 5, 7);
2098 2103
2099 return inst_base; 2104 return inst_base;
2100} 2105}
2101ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){ 2106ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index)
2102 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); 2107{
2103 rev_inst *inst_cream = (rev_inst *)inst_base->component; 2108 return INTERPRETER_TRANSLATE(rev)(inst, index);
2104
2105 inst_base->cond = BITS(inst, 28, 31);
2106 inst_base->idx = index;
2107 inst_base->br = NON_BRANCH;
2108 inst_base->load_r15 = 0;
2109
2110 inst_cream->Rm = BITS(inst, 0, 3);
2111 inst_cream->Rd = BITS(inst, 12, 15);
2112
2113 return inst_base;
2114} 2109}
2115ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("REVSH"); } 2110ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index)
2111{
2112 return INTERPRETER_TRANSLATE(rev)(inst, index);
2113}
2114
2116ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("RFE"); } 2115ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("RFE"); }
2117ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index) 2116ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index)
2118{ 2117{
@@ -5057,39 +5056,40 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5057 QDADD_INST: 5056 QDADD_INST:
5058 QDSUB_INST: 5057 QDSUB_INST:
5059 QSUB_INST: 5058 QSUB_INST:
5059
5060 REV_INST: 5060 REV_INST:
5061 {
5062 rev_inst *inst_cream = (rev_inst *)inst_base->component;
5063 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5064 RD = ((RM & 0xff) << 24) |
5065 (((RM >> 8) & 0xff) << 16) |
5066 (((RM >> 16) & 0xff) << 8) |
5067 ((RM >> 24) & 0xff);
5068 if (inst_cream->Rm == 15) {
5069 LOG_ERROR(Core_ARM11, "invalid operand for REV");
5070 CITRA_IGNORE_EXIT(-1);
5071 }
5072 }
5073 cpu->Reg[15] += GET_INST_SIZE(cpu);
5074 INC_PC(sizeof(rev_inst));
5075 FETCH_INST;
5076 GOTO_NEXT_INST;
5077 }
5078 REV16_INST: 5061 REV16_INST:
5062 REVSH_INST:
5079 { 5063 {
5080 rev_inst *inst_cream = (rev_inst *)inst_base->component; 5064
5081 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5065 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5082 RD = (BITS(RM, 0, 7) << 8) | 5066 rev_inst* const inst_cream = (rev_inst*)inst_base->component;
5083 BITS(RM, 8, 15) | 5067
5084 (BITS(RM, 16, 23) << 24) | 5068 const u8 op1 = inst_cream->op1;
5085 (BITS(RM, 24, 31) << 16); 5069 const u8 op2 = inst_cream->op2;
5070
5071 // REV
5072 if (op1 == 0x03 && op2 == 0x01) {
5073 RD = ((RM & 0xFF) << 24) | (((RM >> 8) & 0xFF) << 16) | (((RM >> 16) & 0xFF) << 8) | ((RM >> 24) & 0xFF);
5074 }
5075 // REV16
5076 else if (op1 == 0x03 && op2 == 0x05) {
5077 RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8) | ((RM & 0xFF0000) << 8) | ((RM & 0xFF000000) >> 8);
5078 }
5079 // REVSH
5080 else if (op1 == 0x07 && op2 == 0x05) {
5081 RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8);
5082 if (RD & 0x8000)
5083 RD |= 0xffff0000;
5084 }
5086 } 5085 }
5086
5087 cpu->Reg[15] += GET_INST_SIZE(cpu); 5087 cpu->Reg[15] += GET_INST_SIZE(cpu);
5088 INC_PC(sizeof(rev_inst)); 5088 INC_PC(sizeof(rev_inst));
5089 FETCH_INST; 5089 FETCH_INST;
5090 GOTO_NEXT_INST; 5090 GOTO_NEXT_INST;
5091 } 5091 }
5092 REVSH_INST: 5092
5093 RFE_INST: 5093 RFE_INST:
5094 RSB_INST: 5094 RSB_INST:
5095 { 5095 {