diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 111 | ||||
| -rw-r--r-- | src/core/arm/interpreter/armsupp.cpp | 20 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armdefs.h | 5 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armemu.h | 6 |
4 files changed, 117 insertions, 25 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index e3a8b1f6e..30f68f47a 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -2053,7 +2053,37 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) | |||
| 2053 | 2053 | ||
| 2054 | return inst_base; | 2054 | return inst_base; |
| 2055 | } | 2055 | } |
| 2056 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); } | 2056 | |
| 2057 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) | ||
| 2058 | { | ||
| 2059 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | ||
| 2060 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 2061 | |||
| 2062 | inst_base->cond = BITS(inst, 28, 31); | ||
| 2063 | inst_base->idx = index; | ||
| 2064 | inst_base->br = NON_BRANCH; | ||
| 2065 | inst_base->load_r15 = 0; | ||
| 2066 | |||
| 2067 | inst_cream->op1 = BITS(inst, 21, 22); | ||
| 2068 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 2069 | inst_cream->Rn = BITS(inst, 16, 19); | ||
| 2070 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 2071 | |||
| 2072 | return inst_base; | ||
| 2073 | } | ||
| 2074 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) | ||
| 2075 | { | ||
| 2076 | return INTERPRETER_TRANSLATE(qadd)(inst, index); | ||
| 2077 | } | ||
| 2078 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) | ||
| 2079 | { | ||
| 2080 | return INTERPRETER_TRANSLATE(qadd)(inst, index); | ||
| 2081 | } | ||
| 2082 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) | ||
| 2083 | { | ||
| 2084 | return INTERPRETER_TRANSLATE(qadd)(inst, index); | ||
| 2085 | } | ||
| 2086 | |||
| 2057 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) | 2087 | ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) |
| 2058 | { | 2088 | { |
| 2059 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | 2089 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| @@ -2080,9 +2110,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index) | |||
| 2080 | { | 2110 | { |
| 2081 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | 2111 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); |
| 2082 | } | 2112 | } |
| 2083 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); } | ||
| 2084 | ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); } | ||
| 2085 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); } | ||
| 2086 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) | 2113 | ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) |
| 2087 | { | 2114 | { |
| 2088 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); | 2115 | return INTERPRETER_TRANSLATE(qadd8)(inst, index); |
| @@ -5042,6 +5069,78 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5042 | } | 5069 | } |
| 5043 | 5070 | ||
| 5044 | QADD_INST: | 5071 | QADD_INST: |
| 5072 | QDADD_INST: | ||
| 5073 | QDSUB_INST: | ||
| 5074 | QSUB_INST: | ||
| 5075 | { | ||
| 5076 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5077 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 5078 | const u8 op1 = inst_cream->op1; | ||
| 5079 | const u32 rm_val = RM; | ||
| 5080 | const u32 rn_val = RN; | ||
| 5081 | |||
| 5082 | u32 result = 0; | ||
| 5083 | |||
| 5084 | // QADD | ||
| 5085 | if (op1 == 0x00) { | ||
| 5086 | result = rm_val + rn_val; | ||
| 5087 | |||
| 5088 | if (AddOverflow(rm_val, rn_val, result)) { | ||
| 5089 | result = POS(result) ? 0x80000000 : 0x7FFFFFFF; | ||
| 5090 | cpu->Cpsr |= (1 << 27); | ||
| 5091 | } | ||
| 5092 | } | ||
| 5093 | // QSUB | ||
| 5094 | else if (op1 == 0x01) { | ||
| 5095 | result = rm_val - rn_val; | ||
| 5096 | |||
| 5097 | if (SubOverflow(rm_val, rn_val, result)) { | ||
| 5098 | result = POS(result) ? 0x80000000 : 0x7FFFFFFF; | ||
| 5099 | cpu->Cpsr |= (1 << 27); | ||
| 5100 | } | ||
| 5101 | } | ||
| 5102 | // QDADD | ||
| 5103 | else if (op1 == 0x02) { | ||
| 5104 | u32 mul = (rn_val * 2); | ||
| 5105 | |||
| 5106 | if (AddOverflow(rn_val, rn_val, rn_val * 2)) { | ||
| 5107 | mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF; | ||
| 5108 | cpu->Cpsr |= (1 << 27); | ||
| 5109 | } | ||
| 5110 | |||
| 5111 | result = mul + rm_val; | ||
| 5112 | |||
| 5113 | if (AddOverflow(rm_val, mul, result)) { | ||
| 5114 | result = POS(result) ? 0x80000000 : 0x7FFFFFFF; | ||
| 5115 | cpu->Cpsr |= (1 << 27); | ||
| 5116 | } | ||
| 5117 | } | ||
| 5118 | // QDSUB | ||
| 5119 | else if (op1 == 0x03) { | ||
| 5120 | u32 mul = (rn_val * 2); | ||
| 5121 | |||
| 5122 | if (AddOverflow(rn_val, rn_val, mul)) { | ||
| 5123 | mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF; | ||
| 5124 | cpu->Cpsr |= (1 << 27); | ||
| 5125 | } | ||
| 5126 | |||
| 5127 | result = rm_val - mul; | ||
| 5128 | |||
| 5129 | if (SubOverflow(rm_val, mul, result)) { | ||
| 5130 | result = POS(result) ? 0x80000000 : 0x7FFFFFFF; | ||
| 5131 | cpu->Cpsr |= (1 << 27); | ||
| 5132 | } | ||
| 5133 | } | ||
| 5134 | |||
| 5135 | RD = result; | ||
| 5136 | } | ||
| 5137 | |||
| 5138 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5139 | INC_PC(sizeof(generic_arm_inst)); | ||
| 5140 | FETCH_INST; | ||
| 5141 | GOTO_NEXT_INST; | ||
| 5142 | } | ||
| 5143 | |||
| 5045 | QADD8_INST: | 5144 | QADD8_INST: |
| 5046 | QADD16_INST: | 5145 | QADD16_INST: |
| 5047 | QADDSUBX_INST: | 5146 | QADDSUBX_INST: |
| @@ -5104,10 +5203,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5104 | GOTO_NEXT_INST; | 5203 | GOTO_NEXT_INST; |
| 5105 | } | 5204 | } |
| 5106 | 5205 | ||
| 5107 | QDADD_INST: | ||
| 5108 | QDSUB_INST: | ||
| 5109 | QSUB_INST: | ||
| 5110 | |||
| 5111 | REV_INST: | 5206 | REV_INST: |
| 5112 | REV16_INST: | 5207 | REV16_INST: |
| 5113 | REVSH_INST: | 5208 | REVSH_INST: |
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp index eec34143e..68ac2a0ce 100644 --- a/src/core/arm/interpreter/armsupp.cpp +++ b/src/core/arm/interpreter/armsupp.cpp | |||
| @@ -418,22 +418,18 @@ ARMul_NegZero (ARMul_State * state, ARMword result) | |||
| 418 | } | 418 | } |
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | /* Compute whether an addition of A and B, giving RESULT, overflowed. */ | 421 | // Compute whether an addition of A and B, giving RESULT, overflowed. |
| 422 | 422 | bool AddOverflow(ARMword a, ARMword b, ARMword result) | |
| 423 | int | ||
| 424 | AddOverflow (ARMword a, ARMword b, ARMword result) | ||
| 425 | { | 423 | { |
| 426 | return ((NEG (a) && NEG (b) && POS (result)) | 424 | return ((NEG(a) && NEG(b) && POS(result)) || |
| 427 | || (POS (a) && POS (b) && NEG (result))); | 425 | (POS(a) && POS(b) && NEG(result))); |
| 428 | } | 426 | } |
| 429 | 427 | ||
| 430 | /* Compute whether a subtraction of A and B, giving RESULT, overflowed. */ | 428 | // Compute whether a subtraction of A and B, giving RESULT, overflowed. |
| 431 | 429 | bool SubOverflow(ARMword a, ARMword b, ARMword result) | |
| 432 | int | ||
| 433 | SubOverflow (ARMword a, ARMword b, ARMword result) | ||
| 434 | { | 430 | { |
| 435 | return ((NEG (a) && POS (b) && POS (result)) | 431 | return ((NEG(a) && POS(b) && POS(result)) || |
| 436 | || (POS (a) && NEG (b) && NEG (result))); | 432 | (POS(a) && NEG(b) && NEG(result))); |
| 437 | } | 433 | } |
| 438 | 434 | ||
| 439 | /* Assigns the C flag after an addition of a and b to give result. */ | 435 | /* Assigns the C flag after an addition of a and b to give result. */ |
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h index c2c78cd5a..3100d7adc 100644 --- a/src/core/arm/skyeye_common/armdefs.h +++ b/src/core/arm/skyeye_common/armdefs.h | |||
| @@ -70,6 +70,9 @@ | |||
| 70 | #define DATACACHE 1 | 70 | #define DATACACHE 1 |
| 71 | #define INSTCACHE 2 | 71 | #define INSTCACHE 2 |
| 72 | 72 | ||
| 73 | #define POS(i) ( (~(i)) >> 31 ) | ||
| 74 | #define NEG(i) ( (i) >> 31 ) | ||
| 75 | |||
| 73 | #ifndef __STDC__ | 76 | #ifndef __STDC__ |
| 74 | typedef char *VoidStar; | 77 | typedef char *VoidStar; |
| 75 | #endif | 78 | #endif |
| @@ -783,6 +786,8 @@ RUn %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",\ | |||
| 783 | //#define PXA250 0x69052903 | 786 | //#define PXA250 0x69052903 |
| 784 | // 0x69052903; //PXA250 B1 from intel 278522-001.pdf | 787 | // 0x69052903; //PXA250 B1 from intel 278522-001.pdf |
| 785 | 788 | ||
| 789 | extern bool AddOverflow(ARMword, ARMword, ARMword); | ||
| 790 | extern bool SubOverflow(ARMword, ARMword, ARMword); | ||
| 786 | 791 | ||
| 787 | extern void ARMul_UndefInstr(ARMul_State*, ARMword); | 792 | extern void ARMul_UndefInstr(ARMul_State*, ARMword); |
| 788 | extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword); | 793 | extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword); |
diff --git a/src/core/arm/skyeye_common/armemu.h b/src/core/arm/skyeye_common/armemu.h index e1b286f0f..1dfcc635a 100644 --- a/src/core/arm/skyeye_common/armemu.h +++ b/src/core/arm/skyeye_common/armemu.h | |||
| @@ -42,9 +42,6 @@ | |||
| 42 | #define R15FBIT (1L << 26) | 42 | #define R15FBIT (1L << 26) |
| 43 | #define R15IFBITS (3L << 26) | 43 | #define R15IFBITS (3L << 26) |
| 44 | 44 | ||
| 45 | #define POS(i) ( (~(i)) >> 31 ) | ||
| 46 | #define NEG(i) ( (i) >> 31 ) | ||
| 47 | |||
| 48 | #ifdef MODET /* Thumb support. */ | 45 | #ifdef MODET /* Thumb support. */ |
| 49 | /* ??? This bit is actually in the low order bit of the PC in the hardware. | 46 | /* ??? This bit is actually in the low order bit of the PC in the hardware. |
| 50 | It isn't clear if the simulator needs to model that or not. */ | 47 | It isn't clear if the simulator needs to model that or not. */ |
| @@ -561,8 +558,7 @@ tdstate; | |||
| 561 | 558 | ||
| 562 | /* Prototypes for exported functions. */ | 559 | /* Prototypes for exported functions. */ |
| 563 | extern unsigned ARMul_NthReg (ARMword, unsigned); | 560 | extern unsigned ARMul_NthReg (ARMword, unsigned); |
| 564 | extern int AddOverflow (ARMword, ARMword, ARMword); | 561 | |
| 565 | extern int SubOverflow (ARMword, ARMword, ARMword); | ||
| 566 | /* Prototypes for exported functions. */ | 562 | /* Prototypes for exported functions. */ |
| 567 | #ifdef __cplusplus | 563 | #ifdef __cplusplus |
| 568 | extern "C" { | 564 | extern "C" { |