/[gxemul]/upstream/0.4.5.1/src/cpus/cpu_mips_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

Annotation of /upstream/0.4.5.1/src/cpus/cpu_mips_instr_loadstore.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 41 - (hide annotations)
Mon Oct 8 16:22:20 2007 UTC (16 years, 9 months ago) by dpavlin
File MIME type: text/plain
File size: 7598 byte(s)
0.4.5.1
1 dpavlin 24 /*
2 dpavlin 34 * Copyright (C) 2006-2007 Anders Gavare. All rights reserved.
3 dpavlin 24 *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are met:
6     *
7     * 1. Redistributions of source code must retain the above copyright
8     * notice, this list of conditions and the following disclaimer.
9     * 2. Redistributions in binary form must reproduce the above copyright
10     * notice, this list of conditions and the following disclaimer in the
11     * documentation and/or other materials provided with the distribution.
12     * 3. The name of the author may not be used to endorse or promote products
13     * derived from this software without specific prior written permission.
14     *
15     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25     * SUCH DAMAGE.
26     *
27     *
28 dpavlin 34 * $Id: cpu_mips_instr_loadstore.c,v 1.13 2006/12/30 13:30:54 debug Exp $
29 dpavlin 24 *
30     * MIPS load/store instructions; the following args are used:
31     *
32     * arg[0] = pointer to the register to load to or store from
33     * arg[1] = pointer to the base register
34     * arg[2] = offset (as an int32_t)
35     *
36     * The GENERIC function always checks for alignment, and supports both big
37     * and little endian byte order.
38     *
39     * The quick function is included twice (big/little endian) for each
40     * GENERIC function.
41     */
42    
43    
44     #ifdef LS_INCLUDE_GENERIC
45     void LS_GENERIC_N(struct cpu *cpu, struct mips_instr_call *ic)
46     {
47     MODE_int_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
48     uint8_t data[LS_SIZE];
49     #ifdef LS_LOAD
50     uint64_t x;
51     #endif
52    
53     /* Synchronize the PC: */
54     int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
55     / sizeof(struct mips_instr_call);
56     cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<<MIPS_INSTR_ALIGNMENT_SHIFT);
57     cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
58    
59     #ifndef LS_1
60     /* Check alignment: */
61     if (addr & (LS_SIZE - 1)) {
62     fatal("TODO: mips dyntrans alignment exception, size = %i,"
63     " addr = %016"PRIx64", pc = %016"PRIx64"\n", LS_SIZE,
64     (uint64_t) addr, cpu->pc);
65    
66     /* TODO: Generalize this into a abort_call, or similar: */
67     cpu->running = 0;
68     debugger_n_steps_left_before_interaction = 0;
69     cpu->cd.mips.next_ic = &nothing_call;
70     return;
71     }
72     #endif
73    
74     #ifdef LS_LOAD
75     if (!cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),
76     MEM_READ, CACHE_DATA)) {
77     /* Exception. */
78     return;
79     }
80     x = memory_readmax64(cpu, data, LS_SIZE);
81     #ifdef LS_SIGNED
82     #ifdef LS_1
83     x = (int8_t)x;
84     #endif
85     #ifdef LS_2
86     x = (int16_t)x;
87     #endif
88     #ifdef LS_4
89     x = (int32_t)x;
90     #endif
91     #endif
92     reg(ic->arg[0]) = x;
93     #else /* LS_STORE: */
94     memory_writemax64(cpu, data, LS_SIZE, reg(ic->arg[0]));
95     if (!cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),
96     MEM_WRITE, CACHE_DATA)) {
97     /* Exception. */
98     return;
99     }
100     #endif
101     }
102     #endif /* LS_INCLUDE_GENERIC */
103    
104    
105     void LS_N(struct cpu *cpu, struct mips_instr_call *ic)
106     {
107     MODE_uint_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
108     unsigned char *p;
109     #ifdef MODE32
110     #ifdef LS_LOAD
111     p = cpu->cd.mips.host_load[addr >> 12];
112     #else
113     p = cpu->cd.mips.host_store[addr >> 12];
114     #endif
115     #else /* !MODE32 */
116     const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
117     const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
118     const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
119     uint32_t x1, x2, x3;
120     struct DYNTRANS_L2_64_TABLE *l2;
121     struct DYNTRANS_L3_64_TABLE *l3;
122    
123     x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
124     x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
125     x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-DYNTRANS_L3N)) & mask3;
126     /* fatal("X3: addr=%016"PRIx64" x1=%x x2=%x x3=%x\n",
127     (uint64_t) addr, (int) x1, (int) x2, (int) x3); */
128     l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1];
129     /* fatal(" l2 = %p\n", l2); */
130     l3 = l2->l3[x2];
131     /* fatal(" l3 = %p\n", l3); */
132     #ifdef LS_LOAD
133     p = l3->host_load[x3];
134     #else
135     p = l3->host_store[x3];
136     #endif
137     /* fatal(" p = %p\n", p); */
138     #endif
139    
140     if (p == NULL
141     #ifndef LS_1
142     || addr & (LS_SIZE - 1)
143     #endif
144     ) {
145     LS_GENERIC_N(cpu, ic);
146     return;
147     }
148    
149     addr &= 0xfff;
150    
151     #ifdef LS_LOAD
152     /* Load: */
153    
154     #ifdef LS_1
155     reg(ic->arg[0]) =
156     #ifdef LS_SIGNED
157     (int8_t)
158     #endif
159     p[addr];
160     #endif /* LS_1 */
161    
162     #ifdef LS_2
163     reg(ic->arg[0]) =
164     #ifdef LS_SIGNED
165     (int16_t)
166     #endif
167     #ifdef LS_BE
168     #ifdef HOST_BIG_ENDIAN
169     ( *(uint16_t *)(p + addr) );
170     #else
171     ((p[addr]<<8) + p[addr+1]);
172     #endif
173     #else
174     #ifdef HOST_LITTLE_ENDIAN
175     ( *(uint16_t *)(p + addr) );
176     #else
177     (p[addr] + (p[addr+1]<<8));
178     #endif
179     #endif
180     #endif /* LS_2 */
181    
182     #ifdef LS_4
183     reg(ic->arg[0]) =
184     #ifdef LS_SIGNED
185     (int32_t)
186     #else
187     (uint32_t)
188     #endif
189     #ifdef LS_BE
190     #ifdef HOST_BIG_ENDIAN
191     ( *(uint32_t *)(p + addr) );
192     #else
193     ((p[addr]<<24) + (p[addr+1]<<16) + (p[addr+2]<<8) + p[addr+3]);
194     #endif
195     #else
196     #ifdef HOST_LITTLE_ENDIAN
197     ( *(uint32_t *)(p + addr) );
198     #else
199     (p[addr] + (p[addr+1]<<8) + (p[addr+2]<<16) + (p[addr+3]<<24));
200     #endif
201     #endif
202     #endif /* LS_4 */
203    
204     #ifdef LS_8
205     *((uint64_t *)ic->arg[0]) =
206     #ifdef LS_BE
207     #ifdef HOST_BIG_ENDIAN
208     ( *(uint64_t *)(p + addr) );
209     #else
210     ((uint64_t)p[addr] << 56) + ((uint64_t)p[addr+1] << 48) +
211     ((uint64_t)p[addr+2] << 40) + ((uint64_t)p[addr+3] << 32) +
212     ((uint64_t)p[addr+4] << 24) +
213     (p[addr+5] << 16) + (p[addr+6] << 8) + p[addr+7];
214     #endif
215     #else
216     #ifdef HOST_LITTLE_ENDIAN
217     ( *(uint64_t *)(p + addr) );
218     #else
219     p[addr+0] + (p[addr+1] << 8) + (p[addr+2] << 16) +
220     ((uint64_t)p[addr+3] << 24) + ((uint64_t)p[addr+4] << 32) +
221     ((uint64_t)p[addr+5] << 40) + ((uint64_t)p[addr+6] << 48) +
222     ((uint64_t)p[addr+7] << 56);
223     #endif
224     #endif
225     #endif /* LS_8 */
226    
227     #else
228     /* Store: */
229    
230     #ifdef LS_1
231     p[addr] = reg(ic->arg[0]);
232     #endif
233     #ifdef LS_2
234     { uint32_t x = reg(ic->arg[0]);
235     #ifdef LS_BE
236     #ifdef HOST_BIG_ENDIAN
237     *((uint16_t *)(p+addr)) = x; }
238     #else
239     p[addr] = x >> 8; p[addr+1] = x; }
240     #endif
241     #else
242     #ifdef HOST_LITTLE_ENDIAN
243     *((uint16_t *)(p+addr)) = x; }
244     #else
245     p[addr] = x; p[addr+1] = x >> 8; }
246     #endif
247     #endif
248     #endif /* LS_2 */
249     #ifdef LS_4
250     { uint32_t x = reg(ic->arg[0]);
251     #ifdef LS_BE
252     #ifdef HOST_BIG_ENDIAN
253     *((uint32_t *)(p+addr)) = x; }
254     #else
255     p[addr] = x >> 24; p[addr+1] = x >> 16;
256     p[addr+2] = x >> 8; p[addr+3] = x; }
257     #endif
258     #else
259     #ifdef HOST_LITTLE_ENDIAN
260     *((uint32_t *)(p+addr)) = x; }
261     #else
262     p[addr] = x; p[addr+1] = x >> 8;
263     p[addr+2] = x >> 16; p[addr+3] = x >> 24; }
264     #endif
265     #endif
266     #endif /* LS_4 */
267     #ifdef LS_8
268     { uint64_t x = *(uint64_t *)(ic->arg[0]);
269     #ifdef LS_BE
270     #ifdef HOST_BIG_ENDIAN
271     *((uint64_t *)(p+addr)) = x; }
272     #else
273     p[addr] = x >> 56; p[addr+1] = x >> 48; p[addr+2] = x >> 40;
274     p[addr+3] = x >> 32; p[addr+4] = x >> 24; p[addr+5] = x >> 16;
275     p[addr+6] = x >> 8; p[addr+7] = x; }
276     #endif
277     #else
278     #ifdef HOST_LITTLE_ENDIAN
279     *((uint64_t *)(p+addr)) = x; }
280     #else
281     p[addr] = x; p[addr+1] = x >> 8; p[addr+2] = x >> 16;
282     p[addr+3] = x >> 24; p[addr+4] = x >> 32; p[addr+5] = x >> 40;
283     p[addr+6] = x >> 48; p[addr+7] = x >> 56; }
284     #endif
285     #endif
286     #endif /* LS_8 */
287    
288     #endif /* store */
289     }
290    

  ViewVC Help
Powered by ViewVC 1.1.26