/[gxemul]/upstream/0.3.8/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

Contents of /upstream/0.3.8/src/cpus/cpu_ppc_instr_loadstore.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Mon Oct 8 16:19:43 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 7459 byte(s)
0.3.8
1 /*
2 * Copyright (C) 2005 Anders Gavare. All rights reserved.
3 *
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 * $Id: cpu_ppc_instr_loadstore.c,v 1.6 2005/11/23 06:59:52 debug Exp $
29 *
30 * POWER/PowerPC load/store instructions.
31 *
32 *
33 * Load/store instructions have the following arguments:
34 *
35 * arg[0] = pointer to the register to load to or store from
36 * arg[1] = pointer to the base register
37 *
38 * arg[2] = offset (as an int32_t)
39 * (or, for Indexed load/stores: pointer to index register)
40 */
41
42
43 #ifndef LS_IGNOREOFS
44 void LS_GENERIC_N(struct cpu *cpu, struct ppc_instr_call *ic)
45 {
46 #ifdef MODE32
47 uint32_t addr = reg(ic->arg[1]) +
48 #ifdef LS_INDEXED
49 reg(ic->arg[2]);
50 #else
51 (int32_t)ic->arg[2];
52 #endif
53 unsigned char data[LS_SIZE];
54
55 /* Synchronize the PC: */
56 int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
57 / sizeof(struct ppc_instr_call);
58 cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT);
59 cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
60
61 #ifndef LS_B
62 if ((addr & 0xfff) + LS_SIZE-1 > 0xfff) {
63 fatal("PPC LOAD/STORE misalignment across page boundary: TODO"
64 " (addr=0x%08x, LS_SIZE=%i)\n", (int)addr, LS_SIZE);
65 exit(1);
66 }
67 #endif
68
69 #ifdef LS_LOAD
70 if (!cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),
71 MEM_READ, CACHE_DATA)) {
72 /* Exception. */
73 return;
74 }
75 #ifdef LS_B
76 reg(ic->arg[0]) =
77 #ifndef LS_ZERO
78 (int8_t)
79 #endif
80 data[0];
81 #endif
82 #ifdef LS_H
83 reg(ic->arg[0]) =
84 #ifdef LS_BYTEREVERSE
85 ((data[1] << 8) + data[0]);
86 #else
87 #ifndef LS_ZERO
88 (int16_t)
89 #endif
90 ((data[0] << 8) + data[1]);
91 #endif /* !BYTEREVERSE */
92 #endif
93 #ifdef LS_W
94 reg(ic->arg[0]) =
95 #ifdef LS_BYTEREVERSE
96 ((data[3] << 24) + (data[2] << 16) +
97 (data[1] << 8) + data[0]);
98 #else /* !LS_BYTEREVERSE */
99 #ifndef LS_ZERO
100 (int32_t)
101 #else
102 (uint32_t)
103 #endif
104 ((data[0] << 24) + (data[1] << 16) +
105 (data[2] << 8) + data[3]);
106 #endif /* !LS_BYTEREVERSE */
107 #endif
108 #ifdef LS_D
109 (*(uint64_t *)(ic->arg[0])) =
110 ((uint64_t)data[0] << 56) + ((uint64_t)data[1] << 48) +
111 ((uint64_t)data[2] << 40) + ((uint64_t)data[3] << 32) +
112 ((uint64_t)data[4] << 24) + (data[5] << 16) +
113 (data[6] << 8) + data[7];
114 #endif
115
116 #else /* store: */
117
118 #ifdef LS_B
119 data[0] = reg(ic->arg[0]);
120 #endif
121 #ifdef LS_H
122 #ifdef LS_BYTEREVERSE
123 data[0] = reg(ic->arg[0]);
124 data[1] = reg(ic->arg[0]) >> 8;
125 #else
126 data[0] = reg(ic->arg[0]) >> 8;
127 data[1] = reg(ic->arg[0]);
128 #endif
129 #endif
130 #ifdef LS_W
131 #ifdef LS_BYTEREVERSE
132 data[0] = reg(ic->arg[0]);
133 data[1] = reg(ic->arg[0]) >> 8;
134 data[2] = reg(ic->arg[0]) >> 16;
135 data[3] = reg(ic->arg[0]) >> 24;
136 #else
137 data[0] = reg(ic->arg[0]) >> 24;
138 data[1] = reg(ic->arg[0]) >> 16;
139 data[2] = reg(ic->arg[0]) >> 8;
140 data[3] = reg(ic->arg[0]);
141 #endif /* !LS_BYTEREVERSE */
142 #endif
143 #ifdef LS_D
144 { uint64_t x = *(uint64_t *)(ic->arg[0]);
145 data[0] = x >> 56;
146 data[1] = x >> 48;
147 data[2] = x >> 40;
148 data[3] = x >> 32;
149 data[4] = x >> 24;
150 data[5] = x >> 16;
151 data[6] = x >> 8;
152 data[7] = x; }
153 #endif
154 if (!cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),
155 MEM_WRITE, CACHE_DATA)) {
156 /* Exception. */
157 return;
158 }
159 #endif
160
161 #ifdef LS_UPDATE
162 reg(ic->arg[1]) = addr;
163 #endif
164 #else /* !MODE32 */
165 fatal("TODO: mode64\n");
166 #endif /* !MODE32 */
167 }
168 #endif
169
170
171 void LS_N(struct cpu *cpu, struct ppc_instr_call *ic)
172 {
173 #ifdef MODE32
174 uint32_t addr = reg(ic->arg[1])
175 #ifdef LS_INDEXED
176 + reg(ic->arg[2])
177 #else
178 #ifndef LS_IGNOREOFS
179 + (int32_t)ic->arg[2]
180 #endif
181 #endif
182 ;
183
184 unsigned char *page = cpu->cd.ppc.
185 #ifdef LS_LOAD
186 host_load
187 #else
188 host_store
189 #endif
190 [addr >> 12];
191 #ifdef LS_UPDATE
192 uint32_t new_addr = addr;
193 #endif
194
195 #ifndef LS_B
196 if (addr & (LS_SIZE-1)) {
197 LS_GENERIC_N(cpu, ic);
198 return;
199 }
200 #endif
201
202 if (page == NULL) {
203 LS_GENERIC_N(cpu, ic);
204 return;
205 } else {
206 addr &= 4095;
207 #ifdef LS_LOAD
208 /* Load: */
209 #ifdef LS_B
210 reg(ic->arg[0]) =
211 #ifndef LS_ZERO
212 (int8_t)
213 #endif
214 page[addr];
215 #endif /* LS_B */
216 #ifdef LS_H
217 reg(ic->arg[0]) =
218 #ifdef LS_BYTEREVERSE
219 ((page[addr+1] << 8) + page[addr]);
220 #else
221 #ifndef LS_ZERO
222 (int16_t)
223 #endif
224 ((page[addr] << 8) + page[addr+1]);
225 #endif /* !BYTEREVERSE */
226 #endif /* LS_H */
227 #ifdef LS_W
228 reg(ic->arg[0]) =
229 #ifdef LS_BYTEREVERSE
230 ((page[addr+3] << 24) + (page[addr+2] << 16) +
231 (page[addr+1] << 8) + page[addr]);
232 #else /* !LS_BYTEREVERSE */
233 #ifndef LS_ZERO
234 (int32_t)
235 #else
236 (uint32_t)
237 #endif
238 ((page[addr] << 24) + (page[addr+1] << 16) +
239 (page[addr+2] << 8) + page[addr+3]);
240 #endif /* !LS_BYTEREVERSE */
241 #endif /* LS_W */
242 #ifdef LS_D
243 (*(uint64_t *)(ic->arg[0])) =
244 ((uint64_t)page[addr+0] << 56) +
245 ((uint64_t)page[addr+1] << 48) +
246 ((uint64_t)page[addr+2] << 40) +
247 ((uint64_t)page[addr+3] << 32) +
248 ((uint64_t)page[addr+4] << 24) + (page[addr+5] << 16) +
249 (page[addr+6] << 8) + page[addr+7];
250 #endif /* LS_D */
251
252 #else /* !LS_LOAD */
253
254 /* Store: */
255 #ifdef LS_B
256 page[addr] = reg(ic->arg[0]);
257 #endif
258 #ifdef LS_H
259 #ifdef LS_BYTEREVERSE
260 page[addr] = reg(ic->arg[0]);
261 page[addr+1] = reg(ic->arg[0]) >> 8;
262 #else
263 page[addr] = reg(ic->arg[0]) >> 8;
264 page[addr+1] = reg(ic->arg[0]);
265 #endif /* !BYTEREVERSE */
266 #endif
267 #ifdef LS_W
268 #ifdef LS_BYTEREVERSE
269 page[addr] = reg(ic->arg[0]);
270 page[addr+1] = reg(ic->arg[0]) >> 8;
271 page[addr+2] = reg(ic->arg[0]) >> 16;
272 page[addr+3] = reg(ic->arg[0]) >> 24;
273 #else
274 page[addr] = reg(ic->arg[0]) >> 24;
275 page[addr+1] = reg(ic->arg[0]) >> 16;
276 page[addr+2] = reg(ic->arg[0]) >> 8;
277 page[addr+3] = reg(ic->arg[0]);
278 #endif /* !LS_BYTEREVERSE */
279 #endif
280 #ifdef LS_D
281 { uint64_t x = *(uint64_t *)(ic->arg[0]);
282 page[addr] = x >> 56;
283 page[addr+1] = x >> 48;
284 page[addr+2] = x >> 40;
285 page[addr+3] = x >> 32;
286 page[addr+4] = x >> 24;
287 page[addr+5] = x >> 16;
288 page[addr+6] = x >> 8;
289 page[addr+7] = x; }
290 #endif
291 #endif /* !LS_LOAD */
292 }
293
294 #ifdef LS_UPDATE
295 reg(ic->arg[1]) = new_addr;
296 #endif
297
298 #else /* !MODE32 */
299 fatal("ppc load/store mode64: TODO\n");
300 exit(1);
301 #endif
302 }
303

  ViewVC Help
Powered by ViewVC 1.1.26