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

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

revision 14 by dpavlin, Mon Oct 8 16:18:51 2007 UTC revision 24 by dpavlin, Mon Oct 8 16:19:56 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_ppc_instr_loadstore.c,v 1.1 2005/08/29 14:36:41 debug Exp $   *  $Id: cpu_ppc_instr_loadstore.c,v 1.9 2006/04/02 10:21:08 debug Exp $
29   *   *
30   *  POWER/PowerPC load/store instructions.   *  POWER/PowerPC load/store instructions.
31   *   *
# Line 44  Line 44 
44  void LS_GENERIC_N(struct cpu *cpu, struct ppc_instr_call *ic)  void LS_GENERIC_N(struct cpu *cpu, struct ppc_instr_call *ic)
45  {  {
46  #ifdef MODE32  #ifdef MODE32
47          uint32_t addr = reg(ic->arg[1]) +          uint32_t addr =
48    #else
49            uint64_t addr =
50    #endif
51                reg(ic->arg[1]) +
52  #ifdef LS_INDEXED  #ifdef LS_INDEXED
53              reg(ic->arg[2]);              reg(ic->arg[2]);
54  #else  #else
# Line 52  void LS_GENERIC_N(struct cpu *cpu, struc Line 56  void LS_GENERIC_N(struct cpu *cpu, struc
56  #endif  #endif
57          unsigned char data[LS_SIZE];          unsigned char data[LS_SIZE];
58    
59            /*  Synchronize the PC:  */
60            int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
61                / sizeof(struct ppc_instr_call);
62            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT);
63            cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
64    
65  #ifndef LS_B  #ifndef LS_B
66          if (addr & (LS_SIZE-1)) {          if ((addr & 0xfff) + LS_SIZE-1 > 0xfff) {
67                  fatal("PPC LOAD/STORE misalignment: TODO\n");                  fatal("PPC LOAD/STORE misalignment across page boundary: TODO"
68                        " (addr=0x%08x, LS_SIZE=%i)\n", (int)addr, LS_SIZE);
69                  exit(1);                  exit(1);
70          }          }
71  #endif  #endif
# Line 62  void LS_GENERIC_N(struct cpu *cpu, struc Line 73  void LS_GENERIC_N(struct cpu *cpu, struc
73  #ifdef LS_LOAD  #ifdef LS_LOAD
74          if (!cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),          if (!cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),
75              MEM_READ, CACHE_DATA)) {              MEM_READ, CACHE_DATA)) {
76                  fatal("load failed: TODO\n");                  /*  Exception.  */
77                  exit(1);                  return;
78          }          }
79  #ifdef LS_B  #ifdef LS_B
80          reg(ic->arg[0]) =          reg(ic->arg[0]) =
# Line 74  void LS_GENERIC_N(struct cpu *cpu, struc Line 85  void LS_GENERIC_N(struct cpu *cpu, struc
85  #endif  #endif
86  #ifdef LS_H  #ifdef LS_H
87          reg(ic->arg[0]) =          reg(ic->arg[0]) =
88    #ifdef LS_BYTEREVERSE
89                ((data[1] << 8) + data[0]);
90    #else
91  #ifndef LS_ZERO  #ifndef LS_ZERO
92              (int16_t)              (int16_t)
93  #endif  #endif
94              ((data[0] << 8) + data[1]);              ((data[0] << 8) + data[1]);
95    #endif /*  !BYTEREVERSE  */
96  #endif  #endif
97  #ifdef LS_W  #ifdef LS_W
98          reg(ic->arg[0]) =          reg(ic->arg[0]) =
99    #ifdef LS_BYTEREVERSE
100                ((data[3] << 24) + (data[2] << 16) +
101                (data[1] << 8) + data[0]);
102    #else  /* !LS_BYTEREVERSE  */
103  #ifndef LS_ZERO  #ifndef LS_ZERO
104              (int32_t)              (int32_t)
105    #else
106                (uint32_t)
107  #endif  #endif
108              ((data[0] << 24) + (data[1] << 16) +              ((data[0] << 24) + (data[1] << 16) +
109              (data[2] << 8) + data[3]);              (data[2] << 8) + data[3]);
110    #endif /* !LS_BYTEREVERSE */
111  #endif  #endif
112  #ifdef LS_D  #ifdef LS_D
113          reg(ic->arg[0]) =          (*(uint64_t *)(ic->arg[0])) =
114              ((uint64_t)data[0] << 56) +              ((uint64_t)data[0] << 56) + ((uint64_t)data[1] << 48) +
115              ((uint64_t)data[1] << 48) +              ((uint64_t)data[2] << 40) + ((uint64_t)data[3] << 32) +
116              ((uint64_t)data[2] << 40) +              ((uint64_t)data[4] << 24) + (data[5] << 16) +
117              ((uint64_t)data[3] << 32) +              (data[6] << 8) + data[7];
             (data[4] << 24) + (data[5] << 16) + (data[6] << 8) + data[7];  
118  #endif  #endif
119    
120  #else   /*  store:  */  #else   /*  store:  */
# Line 102  void LS_GENERIC_N(struct cpu *cpu, struc Line 123  void LS_GENERIC_N(struct cpu *cpu, struc
123          data[0] = reg(ic->arg[0]);          data[0] = reg(ic->arg[0]);
124  #endif  #endif
125  #ifdef LS_H  #ifdef LS_H
126    #ifdef LS_BYTEREVERSE
127            data[0] = reg(ic->arg[0]);
128            data[1] = reg(ic->arg[0]) >> 8;
129    #else
130          data[0] = reg(ic->arg[0]) >> 8;          data[0] = reg(ic->arg[0]) >> 8;
131          data[1] = reg(ic->arg[0]);          data[1] = reg(ic->arg[0]);
132  #endif  #endif
133    #endif
134  #ifdef LS_W  #ifdef LS_W
135    #ifdef LS_BYTEREVERSE
136            data[0] = reg(ic->arg[0]);
137            data[1] = reg(ic->arg[0]) >> 8;
138            data[2] = reg(ic->arg[0]) >> 16;
139            data[3] = reg(ic->arg[0]) >> 24;
140    #else
141          data[0] = reg(ic->arg[0]) >> 24;          data[0] = reg(ic->arg[0]) >> 24;
142          data[1] = reg(ic->arg[0]) >> 16;          data[1] = reg(ic->arg[0]) >> 16;
143          data[2] = reg(ic->arg[0]) >> 8;          data[2] = reg(ic->arg[0]) >> 8;
144          data[3] = reg(ic->arg[0]);          data[3] = reg(ic->arg[0]);
145    #endif /* !LS_BYTEREVERSE */
146  #endif  #endif
147  #ifdef LS_D  #ifdef LS_D
148          data[0] = (uint64_t)reg(ic->arg[0]) >> 56;          { uint64_t x = *(uint64_t *)(ic->arg[0]);
149          data[1] = (uint64_t)reg(ic->arg[0]) >> 48;          data[0] = x >> 56;
150          data[2] = (uint64_t)reg(ic->arg[0]) >> 40;          data[1] = x >> 48;
151          data[3] = (uint64_t)reg(ic->arg[0]) >> 32;          data[2] = x >> 40;
152          data[4] = reg(ic->arg[0]) >> 24;          data[3] = x >> 32;
153          data[5] = reg(ic->arg[0]) >> 16;          data[4] = x >> 24;
154          data[6] = reg(ic->arg[0]) >> 8;          data[5] = x >> 16;
155          data[7] = reg(ic->arg[0]);          data[6] = x >> 8;
156            data[7] = x; }
157  #endif  #endif
158          if (!cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),          if (!cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),
159              MEM_WRITE, CACHE_DATA)) {              MEM_WRITE, CACHE_DATA)) {
160                  fatal("store failed: TODO\n");                  /*  Exception.  */
161                  exit(1);                  return;
162          }          }
163  #endif  #endif
164    
165  #ifdef LS_UPDATE  #ifdef LS_UPDATE
166          reg(ic->arg[1]) = addr;          reg(ic->arg[1]) = addr;
167  #endif  #endif
 #else   /*  !MODE32  */  
         fatal("TODO: mode64\n");  
 #endif  /*  !MODE32  */  
168  }  }
169  #endif  #endif
170    
# Line 141  void LS_GENERIC_N(struct cpu *cpu, struc Line 172  void LS_GENERIC_N(struct cpu *cpu, struc
172  void LS_N(struct cpu *cpu, struct ppc_instr_call *ic)  void LS_N(struct cpu *cpu, struct ppc_instr_call *ic)
173  {  {
174  #ifdef MODE32  #ifdef MODE32
175          uint32_t addr = reg(ic->arg[1])          uint32_t addr =
176    #else
177            uint64_t addr =
178    #endif
179                reg(ic->arg[1])
180  #ifdef LS_INDEXED  #ifdef LS_INDEXED
181              + reg(ic->arg[2])              + reg(ic->arg[2])
182  #else  #else
# Line 164  void LS_N(struct cpu *cpu, struct ppc_in Line 199  void LS_N(struct cpu *cpu, struct ppc_in
199    
200  #ifndef LS_B  #ifndef LS_B
201          if (addr & (LS_SIZE-1)) {          if (addr & (LS_SIZE-1)) {
                 fatal("PPC LOAD/STORE misalignment: TODO\n");  
                 exit(1);  
   
 /*  
  *  TODO:  
  *  Removing the fatal() call above causes WEIRD BUGS with compaq's cc! :(  
  */  
   
202                  LS_GENERIC_N(cpu, ic);                  LS_GENERIC_N(cpu, ic);
203                  return;                  return;
204          }          }
205  #endif  #endif
206    
207    
208    #ifndef MODE32
209    /*******************************************/
210    if (!cpu->is_32bit) {
211    LS_GENERIC_N(cpu, ic);
212    return;
213    }
214    /*******************************************/
215    #endif
216    
217    
218          if (page == NULL) {          if (page == NULL) {
219                  LS_GENERIC_N(cpu, ic);                  LS_GENERIC_N(cpu, ic);
220                  return;                  return;
# Line 193  void LS_N(struct cpu *cpu, struct ppc_in Line 231  void LS_N(struct cpu *cpu, struct ppc_in
231  #endif  /*  LS_B  */  #endif  /*  LS_B  */
232  #ifdef LS_H  #ifdef LS_H
233                  reg(ic->arg[0]) =                  reg(ic->arg[0]) =
234    #ifdef LS_BYTEREVERSE
235                        ((page[addr+1] << 8) + page[addr]);
236    #else
237  #ifndef LS_ZERO  #ifndef LS_ZERO
238                      (int16_t)                      (int16_t)
239  #endif  #endif
240                      ((page[addr] << 8) + page[addr+1]);                      ((page[addr] << 8) + page[addr+1]);
241    #endif /* !BYTEREVERSE */
242  #endif  /*  LS_H  */  #endif  /*  LS_H  */
243  #ifdef LS_W  #ifdef LS_W
244                  reg(ic->arg[0]) =                  reg(ic->arg[0]) =
245    #ifdef LS_BYTEREVERSE
246                        ((page[addr+3] << 24) + (page[addr+2] << 16) +
247                        (page[addr+1] << 8) + page[addr]);
248    #else  /*  !LS_BYTEREVERSE  */
249  #ifndef LS_ZERO  #ifndef LS_ZERO
250                      (int32_t)                      (int32_t)
251    #else
252                        (uint32_t)
253  #endif  #endif
254                      ((page[addr] << 24) + (page[addr+1] << 16) +                      ((page[addr] << 24) + (page[addr+1] << 16) +
255                      (page[addr+2] << 8) + page[addr+3]);                      (page[addr+2] << 8) + page[addr+3]);
256    #endif  /*  !LS_BYTEREVERSE  */
257  #endif  /*  LS_W  */  #endif  /*  LS_W  */
258  #ifdef LS_D  #ifdef LS_D
259                  reg(ic->arg[0]) =                  (*(uint64_t *)(ic->arg[0])) =
260                      ((uint64_t)page[addr+0] << 56) +                      ((uint64_t)page[addr+0] << 56) +
261                      ((uint64_t)page[addr+1] << 48) +                      ((uint64_t)page[addr+1] << 48) +
262                      ((uint64_t)page[addr+2] << 40) +                      ((uint64_t)page[addr+2] << 40) +
263                      ((uint64_t)page[addr+3] << 32) +                      ((uint64_t)page[addr+3] << 32) +
264                      (page[addr+4] << 24) + (page[addr+5] << 16) +                      ((uint64_t)page[addr+4] << 24) + (page[addr+5] << 16) +
265                      (page[addr+6] << 8) + page[addr+7];                      (page[addr+6] << 8) + page[addr+7];
266  #endif  /*  LS_D  */  #endif  /*  LS_D  */
267    
# Line 223  void LS_N(struct cpu *cpu, struct ppc_in Line 272  void LS_N(struct cpu *cpu, struct ppc_in
272                  page[addr] = reg(ic->arg[0]);                  page[addr] = reg(ic->arg[0]);
273  #endif  #endif
274  #ifdef LS_H  #ifdef LS_H
275    #ifdef LS_BYTEREVERSE
276                    page[addr]   = reg(ic->arg[0]);
277                    page[addr+1] = reg(ic->arg[0]) >> 8;
278    #else
279                  page[addr]   = reg(ic->arg[0]) >> 8;                  page[addr]   = reg(ic->arg[0]) >> 8;
280                  page[addr+1] = reg(ic->arg[0]);                  page[addr+1] = reg(ic->arg[0]);
281    #endif /* !BYTEREVERSE */
282  #endif  #endif
283  #ifdef LS_W  #ifdef LS_W
284    #ifdef LS_BYTEREVERSE
285                    page[addr]   = reg(ic->arg[0]);
286                    page[addr+1] = reg(ic->arg[0]) >> 8;
287                    page[addr+2] = reg(ic->arg[0]) >> 16;
288                    page[addr+3] = reg(ic->arg[0]) >> 24;
289    #else
290                  page[addr]   = reg(ic->arg[0]) >> 24;                  page[addr]   = reg(ic->arg[0]) >> 24;
291                  page[addr+1] = reg(ic->arg[0]) >> 16;                  page[addr+1] = reg(ic->arg[0]) >> 16;
292                  page[addr+2] = reg(ic->arg[0]) >> 8;                  page[addr+2] = reg(ic->arg[0]) >> 8;
293                  page[addr+3] = reg(ic->arg[0]);                  page[addr+3] = reg(ic->arg[0]);
294    #endif /* !LS_BYTEREVERSE  */
295  #endif  #endif
296  #ifdef LS_D  #ifdef LS_D
297                  page[addr]   = (uint64_t)reg(ic->arg[0]) >> 56;                  { uint64_t x = *(uint64_t *)(ic->arg[0]);
298                  page[addr+1] = (uint64_t)reg(ic->arg[0]) >> 48;                  page[addr]   = x >> 56;
299                  page[addr+2] = (uint64_t)reg(ic->arg[0]) >> 40;                  page[addr+1] = x >> 48;
300                  page[addr+3] = (uint64_t)reg(ic->arg[0]) >> 32;                  page[addr+2] = x >> 40;
301                  page[addr+4] = reg(ic->arg[0]) >> 24;                  page[addr+3] = x >> 32;
302                  page[addr+5] = reg(ic->arg[0]) >> 16;                  page[addr+4] = x >> 24;
303                  page[addr+6] = reg(ic->arg[0]) >> 8;                  page[addr+5] = x >> 16;
304                  page[addr+7] = reg(ic->arg[0]);                  page[addr+6] = x >> 8;
305                    page[addr+7] = x; }
306  #endif  #endif
307  #endif  /*  !LS_LOAD  */  #endif  /*  !LS_LOAD  */
308          }          }
# Line 248  void LS_N(struct cpu *cpu, struct ppc_in Line 310  void LS_N(struct cpu *cpu, struct ppc_in
310  #ifdef LS_UPDATE  #ifdef LS_UPDATE
311          reg(ic->arg[1]) = new_addr;          reg(ic->arg[1]) = new_addr;
312  #endif  #endif
   
 #else   /*  !MODE32  */  
         fatal("ppc load/store mode64: TODO\n");  
         exit(1);  
 #endif  
313  }  }
314    

Legend:
Removed from v.14  
changed lines
  Added in v.24

  ViewVC Help
Powered by ViewVC 1.1.26