/[gxemul]/trunk/src/cpus/cpu_arm_instr_loadstore.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_loadstore.c

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

revision 17 by dpavlin, Mon Oct 8 16:19:01 2007 UTC revision 18 by dpavlin, Mon Oct 8 16:19:11 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_arm_instr_loadstore.c,v 1.9 2005/10/09 21:32:07 debug Exp $   *  $Id: cpu_arm_instr_loadstore.c,v 1.15 2005/10/27 14:01:13 debug Exp $
29   *   *
30   *   *
31   *  TODO:  Many things...   *  TODO:  Many things...
# Line 35  Line 35 
35   *      o)  Alignment checks!   *      o)  Alignment checks!
36   *   *
37   *      o)  Native load/store if the endianness is the same as the host's   *      o)  Native load/store if the endianness is the same as the host's
38     *          (only implemented for little endian, so far, and it assumes that
39     *          alignment is correct!)
40   *   *
41   *      o)  "Base Updated Abort Model", which updates the base register   *      o)  "Base Updated Abort Model", which updates the base register
42   *          even if the memory access failed.   *          even if the memory access failed.
# Line 51  Line 53 
53   */   */
54    
55    
56    #if defined(A__SIGNED) && defined(A__H) && !defined(A__L)
57    #define A__STRD
58    #endif
59    
60    
61  /*  /*
62   *  General load/store, by using memory_rw(). If at all possible, memory_rw()   *  General load/store, by using memory_rw(). If at all possible, memory_rw()
63   *  then inserts the page into the translation array, so that the fast   *  then inserts the page into the translation array, so that the fast
# Line 63  void A__NAME__general(struct cpu *cpu, s Line 70  void A__NAME__general(struct cpu *cpu, s
70  #else  #else
71          const int memory_rw_flags = CACHE_DATA;          const int memory_rw_flags = CACHE_DATA;
72  #endif  #endif
73    
74  #ifdef A__REG  #ifdef A__REG
75          uint32_t (*reg_func)(struct cpu *, struct arm_instr_call *)          uint32_t (*reg_func)(struct cpu *, struct arm_instr_call *)
76              = (void *)(size_t)ic->arg[1];              = (void *)(size_t)ic->arg[1];
77  #endif  #endif
78    
79    #ifdef A__STRD
80            unsigned char data[8];
81            const int datalen = 8;
82    #else
83  #ifdef A__B  #ifdef A__B
84          unsigned char data[1];          unsigned char data[1];
85            const int datalen = 1;
86  #else  #else
87  #ifdef A__H  #ifdef A__H
88          unsigned char data[2];          unsigned char data[2];
89            const int datalen = 2;
90    #else
91            const int datalen = 4;
92    #ifdef HOST_LITTLE_ENDIAN
93            unsigned char *data = (unsigned char *) ic->arg[2];
94  #else  #else
95          unsigned char data[4];          unsigned char data[4];
96  #endif  #endif
97  #endif  #endif
98    #endif
99    #endif
100    
101          uint32_t addr, low_pc, offset =          uint32_t addr, low_pc, offset =
102  #ifndef A__U  #ifndef A__U
103              -              -
# Line 101  void A__NAME__general(struct cpu *cpu, s Line 123  void A__NAME__general(struct cpu *cpu, s
123    
124  #ifdef A__L  #ifdef A__L
125          /*  Load:  */          /*  Load:  */
126          if (!cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),          if (!cpu->memory_rw(cpu, cpu->mem, addr, data, datalen,
127              MEM_READ, memory_rw_flags)) {              MEM_READ, memory_rw_flags)) {
128                  /*  load failed, an exception was generated  */                  /*  load failed, an exception was generated  */
129                  return;                  return;
# Line 120  void A__NAME__general(struct cpu *cpu, s Line 142  void A__NAME__general(struct cpu *cpu, s
142  #endif  #endif
143              (data[0] + (data[1] << 8));              (data[0] + (data[1] << 8));
144  #else  #else
145    #ifdef HOST_LITTLE_ENDIAN
146            /*  Nothing.  */
147    #else
148          reg(ic->arg[2]) = data[0] + (data[1] << 8) +          reg(ic->arg[2]) = data[0] + (data[1] << 8) +
149              (data[2] << 16) + (data[3] << 24);              (data[2] << 16) + (data[3] << 24);
150  #endif  #endif
151  #endif  #endif
152    #endif
153  #else  #else
154          /*  Store:  */          /*  Store:  */
155  #ifdef A__B  #if !defined(A__B) && !defined(A__H) && defined(HOST_LITTLE_ENDIAN)
156          data[0] = reg(ic->arg[2]);  #ifdef A__STRD
157            *(uint32_t *)data = reg(ic->arg[2]);
158            *(uint32_t *)(data + 4) = reg(ic->arg[2] + 4);
159    #endif
160  #else  #else
 #ifdef A__H  
161          data[0] = reg(ic->arg[2]);          data[0] = reg(ic->arg[2]);
162    #ifndef A__B
163          data[1] = reg(ic->arg[2]) >> 8;          data[1] = reg(ic->arg[2]) >> 8;
164  #else  #if !defined(A__H) || defined(A__STRD)
         data[0] = reg(ic->arg[2]);  
165          data[1] = reg(ic->arg[2]) >> 8;          data[1] = reg(ic->arg[2]) >> 8;
166          data[2] = reg(ic->arg[2]) >> 16;          data[2] = reg(ic->arg[2]) >> 16;
167          data[3] = reg(ic->arg[2]) >> 24;          data[3] = reg(ic->arg[2]) >> 24;
168    #ifdef A__STRD
169            data[4] = reg(ic->arg[2] + 4);
170            data[5] = reg(ic->arg[2] + 4) >> 8;
171            data[6] = reg(ic->arg[2] + 4) >> 16;
172            data[7] = reg(ic->arg[2] + 4) >> 24;
173    #endif
174  #endif  #endif
175  #endif  #endif
176          if (!cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),  #endif
177            if (!cpu->memory_rw(cpu, cpu->mem, addr, data, datalen,
178              MEM_WRITE, memory_rw_flags)) {              MEM_WRITE, memory_rw_flags)) {
179                  /*  store failed, an exception was generated  */                  /*  store failed, an exception was generated  */
180                  return;                  return;
# Line 161  void A__NAME__general(struct cpu *cpu, s Line 196  void A__NAME__general(struct cpu *cpu, s
196   */   */
197  void A__NAME(struct cpu *cpu, struct arm_instr_call *ic)  void A__NAME(struct cpu *cpu, struct arm_instr_call *ic)
198  {  {
199  #if !defined(A__P) && defined(A__W)  #ifdef A__STRD
200          /*  T-bit: userland access. Use the general routine for that.  */          /*  Chicken out, let's do this unoptimized for now:  */
201          A__NAME__general(cpu, ic);          A__NAME__general(cpu, ic);
202  #else  #else
203  #ifdef A__REG  #ifdef A__REG
# Line 191  void A__NAME(struct cpu *cpu, struct arm Line 226  void A__NAME(struct cpu *cpu, struct arm
226  #endif  #endif
227              [addr >> 12];              [addr >> 12];
228    
229    
230    #if !defined(A__P) && defined(A__W)
231            /*
232             *  T-bit: userland access: check the corresponding bit in the
233             *  is_userpage array. If it is set, then we're ok. Otherwise: use the
234             *  generic function.
235             */
236            unsigned char x = cpu->cd.arm.is_userpage[addr >> 15];
237            if (!(x & (1 << ((addr >> 12) & 7))))
238                    A__NAME__general(cpu, ic);
239            else
240    #endif
241    
242    
243          if (page == NULL) {          if (page == NULL) {
244                  A__NAME__general(cpu, ic);                  A__NAME__general(cpu, ic);
245          } else {          } else {
246  #ifdef A__L  #ifdef A__L
247  #ifdef A__B  #ifdef A__B
# Line 209  void A__NAME(struct cpu *cpu, struct arm Line 258  void A__NAME(struct cpu *cpu, struct arm
258  #endif  #endif
259                      (page[addr & 0xfff] + (page[(addr & 0xfff) + 1] << 8));                      (page[addr & 0xfff] + (page[(addr & 0xfff) + 1] << 8));
260  #else  #else
261    #ifdef HOST_LITTLE_ENDIAN
262                    reg(ic->arg[2]) = *(uint32_t *)(page + (addr & 0xffc));
263    #else
264                  reg(ic->arg[2]) = page[addr & 0xfff] +                  reg(ic->arg[2]) = page[addr & 0xfff] +
265                      (page[(addr & 0xfff) + 1] << 8) +                      (page[(addr & 0xfff) + 1] << 8) +
266                      (page[(addr & 0xfff) + 2] << 16) +                      (page[(addr & 0xfff) + 2] << 16) +
267                      (page[(addr & 0xfff) + 3] << 24);                      (page[(addr & 0xfff) + 3] << 24);
268  #endif  #endif
269  #endif  #endif
270    #endif
271  #else  #else
272  #ifdef A__B  #ifdef A__B
273                  page[addr & 0xfff] = reg(ic->arg[2]);                  page[addr & 0xfff] = reg(ic->arg[2]);
# Line 223  void A__NAME(struct cpu *cpu, struct arm Line 276  void A__NAME(struct cpu *cpu, struct arm
276                  page[addr & 0xfff] = reg(ic->arg[2]);                  page[addr & 0xfff] = reg(ic->arg[2]);
277                  page[(addr & 0xfff)+1] = reg(ic->arg[2]) >> 8;                  page[(addr & 0xfff)+1] = reg(ic->arg[2]) >> 8;
278  #else  #else
279    #ifdef HOST_LITTLE_ENDIAN
280                    *(uint32_t *)(page + (addr & 0xffc)) = reg(ic->arg[2]);
281    #else
282                  page[addr & 0xfff] = reg(ic->arg[2]);                  page[addr & 0xfff] = reg(ic->arg[2]);
283                  page[(addr & 0xfff)+1] = reg(ic->arg[2]) >> 8;                  page[(addr & 0xfff)+1] = reg(ic->arg[2]) >> 8;
284                  page[(addr & 0xfff)+2] = reg(ic->arg[2]) >> 16;                  page[(addr & 0xfff)+2] = reg(ic->arg[2]) >> 16;
# Line 230  void A__NAME(struct cpu *cpu, struct arm Line 286  void A__NAME(struct cpu *cpu, struct arm
286  #endif  #endif
287  #endif  #endif
288  #endif  #endif
289    #endif
290    
291                  /*  Index Write-back:  */                  /*  Index Write-back:  */
292  #ifdef A__P  #ifdef A__P
# Line 241  void A__NAME(struct cpu *cpu, struct arm Line 298  void A__NAME(struct cpu *cpu, struct arm
298                  reg(ic->arg[0]) = addr + offset;                  reg(ic->arg[0]) = addr + offset;
299  #endif  #endif
300          }          }
301  #endif  /*  not T-bit  */  #endif  /*  not STRD  */
302  }  }
303    
304    
# Line 278  void A__NAME_PC(struct cpu *cpu, struct Line 335  void A__NAME_PC(struct cpu *cpu, struct
335          A__NAME(cpu, ic);          A__NAME(cpu, ic);
336          if (ic->arg[2] == (size_t)(&cpu->cd.arm.r[ARM_PC])) {          if (ic->arg[2] == (size_t)(&cpu->cd.arm.r[ARM_PC])) {
337                  cpu->pc = cpu->cd.arm.r[ARM_PC];                  cpu->pc = cpu->cd.arm.r[ARM_PC];
338                  arm_pc_to_pointers(cpu);                  if (cpu->machine->show_trace_tree)
339                            cpu_functioncall_trace(cpu, cpu->pc);
340                    quick_pc_to_pointers(cpu);
341          }          }
342  #else  #else
343          /*  Store:  */          /*  Store:  */
# Line 375  void A__NAME_PC__le(struct cpu *cpu, str Line 434  void A__NAME_PC__le(struct cpu *cpu, str
434  ((cpu->cd.arm.cpsr & ARM_FLAG_V)?1:0) ||  ((cpu->cd.arm.cpsr & ARM_FLAG_V)?1:0) ||
435  (cpu->cd.arm.cpsr & ARM_FLAG_Z)) A__NAME_PC(cpu, ic); }  (cpu->cd.arm.cpsr & ARM_FLAG_Z)) A__NAME_PC(cpu, ic); }
436  #endif  #endif
437    
438    
439    #ifdef A__STRD
440    #undef A__STRD
441    #endif

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

  ViewVC Help
Powered by ViewVC 1.1.26