/[gxemul]/trunk/src/cpus/cpu_arm_instr_dpi.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/cpus/cpu_arm_instr_dpi.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 18 by dpavlin, Mon Oct 8 16:19:11 2007 UTC revision 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_arm_instr_dpi.c,v 1.11 2005/10/22 12:22:13 debug Exp $   *  $Id: cpu_arm_instr_dpi.c,v 1.16 2005/11/19 18:53:07 debug Exp $
29   *   *
30   *   *
31   *  ARM Data Processing Instructions   *  ARM Data Processing Instructions
# Line 69  Line 69 
69   */   */
70  void A__NAME(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME(struct cpu *cpu, struct arm_instr_call *ic)
71  {  {
72    #if defined(A__RSB) || defined(A__RSC)
73    #define VAR_A  b
74    #define VAR_B  a
75    #else
76    #define VAR_A  a
77    #define VAR_B  b
78    #endif
79    
80  #ifdef A__REG  #ifdef A__REG
81          uint32_t (*reg_func)(struct cpu *, struct arm_instr_call *)          uint32_t (*reg_func)(struct cpu *, struct arm_instr_call *)
82              = (void *)(size_t)ic->arg[1];              = (void *)(size_t)ic->arg[1];
# Line 87  void A__NAME(struct cpu *cpu, struct arm Line 95  void A__NAME(struct cpu *cpu, struct arm
95  #else  #else
96          uint32_t          uint32_t
97  #endif  #endif
98              c64,              VAR_B =
 #if !defined(A__MOV) && !defined(A__MVN)  
             a = reg(ic->arg[0]),  
 #endif  
             b =  
99  #ifdef A__REG  #ifdef A__REG
100              reg_func(cpu, ic);              reg_func(cpu, ic)
101    #else
102    #ifdef A__REGSHORT
103                reg(ic->arg[1])
104  #else  #else
105              ic->arg[1];              ic->arg[1]
106  #endif  #endif
107    #endif
108                , c64
109    #if !defined(A__MOV) && !defined(A__MVN)
110                , VAR_A = reg(ic->arg[0])
111    #endif
112                ;
113    
114  #if defined(A__MOV) || defined(A__MVN) || defined(A__TST) || defined(A__TEQ) \  #if defined(A__MOV) || defined(A__MVN) || defined(A__TST) || defined(A__TEQ) \
115   || defined(A__AND) || defined(A__BIC) || defined(A__EOR) || defined(A__ORR)   || defined(A__AND) || defined(A__BIC) || defined(A__EOR) || defined(A__ORR)
# Line 111  void A__NAME(struct cpu *cpu, struct arm Line 123  void A__NAME(struct cpu *cpu, struct arm
123           *  TODO 2: Perhaps this check should be moved out from here, and into           *  TODO 2: Perhaps this check should be moved out from here, and into
124           *  cpu_arm_instr.c. (More correct, and higher performance.)           *  cpu_arm_instr.c. (More correct, and higher performance.)
125           */           */
126          if (b > 255) {          if (VAR_B > 255) {
127                  cpu->cd.arm.cpsr &= ~ARM_FLAG_C;                  if (VAR_B & 0x80000000)
128                  if (b & 0x80000000)                          cpu->cd.arm.flags |= ARM_F_C;
129                          cpu->cd.arm.cpsr |= ARM_FLAG_C;                  else
130                            cpu->cd.arm.flags &= ~ARM_F_C;
131          }          }
132  #endif  #endif
133  #endif  #endif
# Line 123  void A__NAME(struct cpu *cpu, struct arm Line 136  void A__NAME(struct cpu *cpu, struct arm
136  #if !defined(A__MOV) && !defined(A__MVN)  #if !defined(A__MOV) && !defined(A__MVN)
137  #ifdef A__PC  #ifdef A__PC
138          if (ic->arg[0] == (size_t)&cpu->cd.arm.r[ARM_PC]) {          if (ic->arg[0] == (size_t)&cpu->cd.arm.r[ARM_PC]) {
139                  uint32_t low_pc;                  uint32_t low_pc = ((size_t)ic - (size_t)
                 low_pc = ((size_t)ic - (size_t)  
140                      cpu->cd.arm.cur_ic_page) / sizeof(struct arm_instr_call);                      cpu->cd.arm.cur_ic_page) / sizeof(struct arm_instr_call);
141                  a = cpu->pc & ~((ARM_IC_ENTRIES_PER_PAGE-1)                  VAR_A = cpu->pc & ~((ARM_IC_ENTRIES_PER_PAGE-1)
142                      << ARM_INSTR_ALIGNMENT_SHIFT);                      << ARM_INSTR_ALIGNMENT_SHIFT);
143                  a += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT) + 8;                  VAR_A += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT) + 8;
144          }          }
145  #endif  #endif
146  #endif  #endif
147    
   
 #if defined(A__RSB) || defined(A__RSC)  
         { uint32_t tmp = a; a = b; b = tmp; }  
 #endif  
   
148          /*          /*
149           *  Perform the operation:           *  Perform the operation:
150           */           */
# Line 154  void A__NAME(struct cpu *cpu, struct arm Line 161  void A__NAME(struct cpu *cpu, struct arm
161          c64 = a + b;          c64 = a + b;
162  #endif  #endif
163  #if defined(A__ADC)  #if defined(A__ADC)
164          c64 = a + b + (cpu->cd.arm.cpsr & ARM_FLAG_C? 1 : 0);          c64 = a + b + (cpu->cd.arm.flags & ARM_F_C? 1 : 0);
165  #endif  #endif
166  #if defined(A__SBC) || defined(A__RSC)  #if defined(A__SBC) || defined(A__RSC)
167          c64 = a - b - (1 - (cpu->cd.arm.cpsr & ARM_FLAG_C? 1 : 0));          b += (cpu->cd.arm.flags & ARM_F_C? 0 : 1);
168            c64 = a - b;
169  #endif  #endif
170  #if defined(A__ORR)  #if defined(A__ORR)
171          c64 = a | b;          c64 = a | b;
# Line 179  void A__NAME(struct cpu *cpu, struct arm Line 187  void A__NAME(struct cpu *cpu, struct arm
187  #ifdef A__PC  #ifdef A__PC
188          if (ic->arg[2] == (size_t)&cpu->cd.arm.r[ARM_PC]) {          if (ic->arg[2] == (size_t)&cpu->cd.arm.r[ARM_PC]) {
189  #ifndef A__S  #ifndef A__S
190                  uint32_t old_pc = cpu->cd.arm.r[ARM_PC];                  uint32_t old_pc = cpu->pc;
191                  uint32_t mask_within_page = ((ARM_IC_ENTRIES_PER_PAGE-1)                  uint32_t mask_within_page = ((ARM_IC_ENTRIES_PER_PAGE-1)
192                      << ARM_INSTR_ALIGNMENT_SHIFT) |                      << ARM_INSTR_ALIGNMENT_SHIFT) |
193                      ((1 << ARM_INSTR_ALIGNMENT_SHIFT) - 1);                      ((1 << ARM_INSTR_ALIGNMENT_SHIFT) - 1);
194  #endif  #endif
195                  cpu->pc = reg(ic->arg[2]) = c64;                  cpu->pc = (uint32_t)c64;
196  #ifdef A__S  #ifdef A__S
197                  /*  Copy the right SPSR into CPSR:  */                  /*  Copy the right SPSR into CPSR:  */
198                  arm_save_register_bank(cpu);                  arm_save_register_bank(cpu);
# Line 199  void A__NAME(struct cpu *cpu, struct arm Line 207  void A__NAME(struct cpu *cpu, struct arm
207                          cpu->cd.arm.cpsr = cpu->cd.arm.spsr_abt; break;                          cpu->cd.arm.cpsr = cpu->cd.arm.spsr_abt; break;
208                  case ARM_MODE_UND32:                  case ARM_MODE_UND32:
209                          cpu->cd.arm.cpsr = cpu->cd.arm.spsr_und; break;                          cpu->cd.arm.cpsr = cpu->cd.arm.spsr_und; break;
                 default:fatal("huh? weird mode in dpi s with pc\n");  
                         exit(1);  
210                  }                  }
211                    cpu->cd.arm.flags = cpu->cd.arm.cpsr >> 28;
212                  arm_load_register_bank(cpu);                  arm_load_register_bank(cpu);
213  #else  #else
214                  if ((old_pc & ~mask_within_page) ==                  if ((old_pc & ~mask_within_page) ==
215                      (cpu->pc & ~mask_within_page)) {                      ((uint32_t)cpu->pc & ~mask_within_page)) {
216                          cpu->cd.arm.next_ic = cpu->cd.arm.cur_ic_page +                          cpu->cd.arm.next_ic = cpu->cd.arm.cur_ic_page +
217                              ((cpu->pc & mask_within_page) >>                              ((cpu->pc & mask_within_page) >>
218                              ARM_INSTR_ALIGNMENT_SHIFT);                              ARM_INSTR_ALIGNMENT_SHIFT);
# Line 226  void A__NAME(struct cpu *cpu, struct arm Line 233  void A__NAME(struct cpu *cpu, struct arm
233           */           */
234  #ifdef A__S  #ifdef A__S
235          c32 = c64;          c32 = c64;
236          cpu->cd.arm.cpsr &= ~(ARM_FLAG_Z | ARM_FLAG_N          cpu->cd.arm.flags
237  #if defined(A__CMP) || defined(A__CMN) || defined(A__ADC) || defined(A__ADD) \  #if defined(A__CMP) || defined(A__CMN) || defined(A__ADC) || defined(A__ADD) \
238   || defined(A__RSB) || defined(A__RSC) || defined(A__SBC) || defined(A__SUB)   || defined(A__RSB) || defined(A__RSC) || defined(A__SBC) || defined(A__SUB)
239              | ARM_FLAG_V | ARM_FLAG_C              = 0;
240    #else
241                &= ~(ARM_F_Z | ARM_F_N);
242  #endif  #endif
             );  
243    
244  #if defined(A__CMP) || defined(A__RSB) || defined(A__SUB)  #if defined(A__CMP) || defined(A__RSB) || defined(A__SUB) || \
245        defined(A__RSC) || defined(A__SBC)
246          if ((uint32_t)a >= (uint32_t)b)          if ((uint32_t)a >= (uint32_t)b)
247                  cpu->cd.arm.cpsr |= ARM_FLAG_C;                  cpu->cd.arm.flags |= ARM_F_C;
248  #else  #else
249  #if defined(A__ADC) || defined(A__ADD) || defined(A__CMN)  #if defined(A__ADC) || defined(A__ADD) || defined(A__CMN)
250          if (c32 != c64)          if (c32 != c64)
251                  cpu->cd.arm.cpsr |= ARM_FLAG_C;                  cpu->cd.arm.flags |= ARM_F_C;
 #else  
 #if defined(A__RSC) || defined(A__SBC)  
         {  
                 uint32_t low_pc;  
                 low_pc = ((size_t)ic - (size_t)  
                     cpu->cd.arm.cur_ic_page) / sizeof(struct arm_instr_call);  
                 a = cpu->pc & ~((ARM_IC_ENTRIES_PER_PAGE-1)  
                     << ARM_INSTR_ALIGNMENT_SHIFT);  
                 a += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT) + 8;  
                 fatal("TODO: C flag: pc = 0x%08x\n", a);  
                 exit(1);  
         }  
 #endif  
252  #endif  #endif
253  #endif  #endif
254    
255          if (c32 == 0)          if (c32 == 0)
256                  cpu->cd.arm.cpsr |= ARM_FLAG_Z;                  cpu->cd.arm.flags |= ARM_F_Z;
257    
258          if ((int32_t)c32 < 0)          if ((int32_t)c32 < 0)
259                  cpu->cd.arm.cpsr |= ARM_FLAG_N;                  cpu->cd.arm.flags |= ARM_F_N;
260    
261          /*  Calculate the Overflow bit:  */          /*  Calculate the Overflow bit:  */
262  #if defined(A__CMP) || defined(A__CMN) || defined(A__ADC) || defined(A__ADD) \  #if defined(A__CMP) || defined(A__CMN) || defined(A__ADC) || defined(A__ADD) \
# Line 274  void A__NAME(struct cpu *cpu, struct arm Line 270  void A__NAME(struct cpu *cpu, struct arm
270                      (int32_t)c32 >= 0))                      (int32_t)c32 >= 0))
271                          v = 1;                          v = 1;
272  #else  #else
273  #if defined(A__SUB) || defined(A__RSB) || defined(A__CMP)  #if defined(A__SUB) || defined(A__RSB) || defined(A__CMP) || \
274        defined(A__RSC) || defined(A__SBC)
275                  if (((int32_t)a >= 0 && (int32_t)b < 0 &&                  if (((int32_t)a >= 0 && (int32_t)b < 0 &&
276                      (int32_t)c32 < 0) ||                      (int32_t)c32 < 0) ||
277                      ((int32_t)a < 0 && (int32_t)b >= 0 &&                      ((int32_t)a < 0 && (int32_t)b >= 0 &&
278                      (int32_t)c32 >= 0))                      (int32_t)c32 >= 0))
279                          v = 1;                          v = 1;
 #else  
                 fatal("NO\n");  
                 exit(1);  
280  #endif  #endif
281  #endif  #endif
282                  if (v)                  if (v)
283                          cpu->cd.arm.cpsr |= ARM_FLAG_V;                          cpu->cd.arm.flags |= ARM_F_V;
284          }          }
285  #endif  #endif
286  #endif  /*  A__S  */  #endif  /*  A__S  */
287    
288    #undef VAR_A
289    #undef VAR_B
290  }  }
291    
292    
293  void A__NAME__eq(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__eq(struct cpu *cpu, struct arm_instr_call *ic)
294  { if (cpu->cd.arm.cpsr & ARM_FLAG_Z) A__NAME(cpu, ic); }  { if (cpu->cd.arm.flags & ARM_F_Z) A__NAME(cpu, ic); }
295  void A__NAME__ne(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__ne(struct cpu *cpu, struct arm_instr_call *ic)
296  { if (!(cpu->cd.arm.cpsr & ARM_FLAG_Z)) A__NAME(cpu, ic); }  { if (!(cpu->cd.arm.flags & ARM_F_Z)) A__NAME(cpu, ic); }
297  void A__NAME__cs(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__cs(struct cpu *cpu, struct arm_instr_call *ic)
298  { if (cpu->cd.arm.cpsr & ARM_FLAG_C) A__NAME(cpu, ic); }  { if (cpu->cd.arm.flags & ARM_F_C) A__NAME(cpu, ic); }
299  void A__NAME__cc(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__cc(struct cpu *cpu, struct arm_instr_call *ic)
300  { if (!(cpu->cd.arm.cpsr & ARM_FLAG_C)) A__NAME(cpu, ic); }  { if (!(cpu->cd.arm.flags & ARM_F_C)) A__NAME(cpu, ic); }
301  void A__NAME__mi(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__mi(struct cpu *cpu, struct arm_instr_call *ic)
302  { if (cpu->cd.arm.cpsr & ARM_FLAG_N) A__NAME(cpu, ic); }  { if (cpu->cd.arm.flags & ARM_F_N) A__NAME(cpu, ic); }
303  void A__NAME__pl(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__pl(struct cpu *cpu, struct arm_instr_call *ic)
304  { if (!(cpu->cd.arm.cpsr & ARM_FLAG_N)) A__NAME(cpu, ic); }  { if (!(cpu->cd.arm.flags & ARM_F_N)) A__NAME(cpu, ic); }
305  void A__NAME__vs(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__vs(struct cpu *cpu, struct arm_instr_call *ic)
306  { if (cpu->cd.arm.cpsr & ARM_FLAG_V) A__NAME(cpu, ic); }  { if (cpu->cd.arm.flags & ARM_F_V) A__NAME(cpu, ic); }
307  void A__NAME__vc(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__vc(struct cpu *cpu, struct arm_instr_call *ic)
308  { if (!(cpu->cd.arm.cpsr & ARM_FLAG_V)) A__NAME(cpu, ic); }  { if (!(cpu->cd.arm.flags & ARM_F_V)) A__NAME(cpu, ic); }
309    
310    #ifndef BLAHURG
311    #define BLAHURG
312    extern uint8_t condition_hi[16];
313    extern uint8_t condition_ge[16];
314    extern uint8_t condition_gt[16];
315    #endif
316    
317  void A__NAME__hi(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__hi(struct cpu *cpu, struct arm_instr_call *ic)
318  { if (cpu->cd.arm.cpsr & ARM_FLAG_C &&  { if (condition_hi[cpu->cd.arm.flags]) A__NAME(cpu, ic); }
 !(cpu->cd.arm.cpsr & ARM_FLAG_Z)) A__NAME(cpu, ic); }  
319  void A__NAME__ls(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__ls(struct cpu *cpu, struct arm_instr_call *ic)
320  { if (cpu->cd.arm.cpsr & ARM_FLAG_Z ||  { if (!condition_hi[cpu->cd.arm.flags]) A__NAME(cpu, ic); }
 !(cpu->cd.arm.cpsr & ARM_FLAG_C)) A__NAME(cpu, ic); }  
321  void A__NAME__ge(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__ge(struct cpu *cpu, struct arm_instr_call *ic)
322  { if (((cpu->cd.arm.cpsr & ARM_FLAG_N)?1:0) ==  { if (condition_ge[cpu->cd.arm.flags]) A__NAME(cpu, ic); }
 ((cpu->cd.arm.cpsr & ARM_FLAG_V)?1:0)) A__NAME(cpu, ic); }  
323  void A__NAME__lt(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__lt(struct cpu *cpu, struct arm_instr_call *ic)
324  { if (((cpu->cd.arm.cpsr & ARM_FLAG_N)?1:0) !=  { if (!condition_ge[cpu->cd.arm.flags]) A__NAME(cpu, ic); }
 ((cpu->cd.arm.cpsr & ARM_FLAG_V)?1:0)) A__NAME(cpu, ic); }  
325  void A__NAME__gt(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__gt(struct cpu *cpu, struct arm_instr_call *ic)
326  { if (((cpu->cd.arm.cpsr & ARM_FLAG_N)?1:0) ==  { if (condition_gt[cpu->cd.arm.flags]) A__NAME(cpu, ic); }
 ((cpu->cd.arm.cpsr & ARM_FLAG_V)?1:0) &&  
 !(cpu->cd.arm.cpsr & ARM_FLAG_Z)) A__NAME(cpu, ic); }  
327  void A__NAME__le(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME__le(struct cpu *cpu, struct arm_instr_call *ic)
328  { if (((cpu->cd.arm.cpsr & ARM_FLAG_N)?1:0) !=  { if (!condition_gt[cpu->cd.arm.flags]) A__NAME(cpu, ic); }
 ((cpu->cd.arm.cpsr & ARM_FLAG_V)?1:0) ||  
 (cpu->cd.arm.cpsr & ARM_FLAG_Z)) A__NAME(cpu, ic); }  
329    

Legend:
Removed from v.18  
changed lines
  Added in v.20

  ViewVC Help
Powered by ViewVC 1.1.26