summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp111
-rw-r--r--src/core/arm/interpreter/armsupp.cpp20
-rw-r--r--src/core/arm/skyeye_common/armdefs.h5
-rw-r--r--src/core/arm/skyeye_common/armemu.h6
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}
2056ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); } 2056
2057ARM_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}
2074ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index)
2075{
2076 return INTERPRETER_TRANSLATE(qadd)(inst, index);
2077}
2078ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index)
2079{
2080 return INTERPRETER_TRANSLATE(qadd)(inst, index);
2081}
2082ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index)
2083{
2084 return INTERPRETER_TRANSLATE(qadd)(inst, index);
2085}
2086
2057ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) 2087ARM_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}
2083ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); }
2084ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); }
2085ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); }
2086ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) 2113ARM_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 422bool AddOverflow(ARMword a, ARMword b, ARMword result)
423int
424AddOverflow (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 429bool SubOverflow(ARMword a, ARMword b, ARMword result)
432int
433SubOverflow (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__
74typedef char *VoidStar; 77typedef 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
789extern bool AddOverflow(ARMword, ARMword, ARMword);
790extern bool SubOverflow(ARMword, ARMword, ARMword);
786 791
787extern void ARMul_UndefInstr(ARMul_State*, ARMword); 792extern void ARMul_UndefInstr(ARMul_State*, ARMword);
788extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword); 793extern 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. */
563extern unsigned ARMul_NthReg (ARMword, unsigned); 560extern unsigned ARMul_NthReg (ARMword, unsigned);
564extern int AddOverflow (ARMword, ARMword, ARMword); 561
565extern 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" {