/[gxemul]/upstream/0.4.2/src/cpus/cpu_alpha_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.4.2/src/cpus/cpu_alpha_instr_loadstore.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations)
Mon Oct 8 16:20:48 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 6969 byte(s)
0.4.2
1 /*
2 * Copyright (C) 2005-2006 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_alpha_instr_loadstore.c,v 1.5 2006/06/30 20:22:53 debug Exp $
29 *
30 * Alpha load/store instructions. (Included from cpu_alpha_instr_inc.c.)
31 *
32 *
33 * Load/store instructions have the following arguments:
34 *
35 * arg[0] = pointer to the register to load to or store from (uint64_t)
36 * arg[1] = pointer to the base register (uint64_t)
37 * arg[2] = offset (as an int32_t)
38 *
39 * NOTE:
40 * Alpha byte and word loads (8- and 16-bit) are unsigned, while
41 * 32-bit long words are sign-extended up to 64 bits during a load!
42 */
43
44
45 #ifndef LS_IGNORE_OFFSET
46 static void LS_GENERIC_N(struct cpu *cpu, struct alpha_instr_call *ic)
47 {
48 #ifdef LS_B
49 unsigned char data[1];
50 #endif
51 #ifdef LS_W
52 unsigned char data[2];
53 #endif
54 #ifdef LS_L
55 unsigned char data[4];
56 #endif
57 #ifdef LS_Q
58 unsigned char data[8];
59 #endif
60 uint64_t addr = *((uint64_t *)ic->arg[1]);
61 uint64_t data_x;
62
63 addr += (int32_t)ic->arg[2];
64 #ifdef LS_UNALIGNED
65 addr &= ~7;
66 #endif
67
68 #ifdef LS_LOAD
69 /* Load: */
70 if (!cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),
71 MEM_READ, CACHE_DATA)) {
72 fatal("store failed: TODO\n");
73 exit(1);
74 }
75
76 data_x = data[0];
77 #ifndef LS_B
78 data_x += (data[1] << 8);
79 #ifndef LS_W
80 data_x += (data[2] << 16);
81 data_x += ((uint64_t)data[3] << 24);
82 #ifdef LS_L
83 data_x = (int64_t)(int32_t)data_x;
84 #endif
85 #ifndef LS_L
86 data_x += ((uint64_t)data[4] << 32);
87 data_x += ((uint64_t)data[5] << 40);
88 data_x += ((uint64_t)data[6] << 48);
89 data_x += ((uint64_t)data[7] << 56);
90 #endif
91 #endif
92 #endif
93 *((uint64_t *)ic->arg[0]) = data_x;
94 #else
95 /* Store: */
96 data_x = *((uint64_t *)ic->arg[0]);
97 data[0] = data_x;
98 #ifndef LS_B
99 data[1] = data_x >> 8;
100 #ifndef LS_W
101 data[2] = data_x >> 16;
102 data[3] = data_x >> 24;
103 #ifndef LS_L
104 data[4] = data_x >> 32;
105 data[5] = data_x >> 40;
106 data[6] = data_x >> 48;
107 data[7] = data_x >> 56;
108 #endif
109 #endif
110 #endif
111
112 if (!cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),
113 MEM_WRITE, CACHE_DATA)) {
114 fatal("store failed: TODO\n");
115 exit(1);
116 }
117
118 #ifdef LS_LLSC
119 #ifndef LS_LOAD
120 *((uint64_t *)ic->arg[0]) = 1;
121 #endif
122 #endif
123
124 #endif
125 }
126 #endif
127
128
129 static void LS_N(struct cpu *cpu, struct alpha_instr_call *ic)
130 {
131 unsigned char *page;
132 uint64_t addr = (*((uint64_t *)ic->arg[1]))
133 #ifndef LS_IGNORE_OFFSET
134 + (int32_t)ic->arg[2]
135 #endif
136 ;
137
138 const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
139 const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
140 const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
141 uint32_t x1, x2, x3, c;
142 struct DYNTRANS_L2_64_TABLE *l2;
143 struct DYNTRANS_L3_64_TABLE *l3;
144 x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
145 x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
146 x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-DYNTRANS_L3N)) & mask3;
147 /* fatal("X3: addr=%016"PRIx64" x1=%x x2=%x x3=%x\n",
148 (uint64_t) addr, (int) x1, (int) x2, (int) x3); */
149 l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1];
150 /* fatal(" l2 = %p\n", l2); */
151 l3 = l2->l3[x2];
152 /* fatal(" l3 = %p\n", l3); */
153 #ifdef LS_LOAD
154 page = l3->host_load[x3];
155 #else
156 page = l3->host_store[x3];
157 #endif
158
159 #ifdef LS_UNALIGNED
160 addr &= ~7;
161 #endif
162
163 #ifdef LS_LLSC
164 #ifdef LS_LOAD
165 /* TODO: cache-line size! */
166 cpu->cd.alpha.load_linked_addr = addr & ~63;
167 cpu->cd.alpha.ll_flag = 1;
168 #else
169 /* TODO: only invalidate per cache line, not everything! */
170 if (cpu->cd.alpha.ll_flag == 1) {
171 int i;
172 for (i=0; i<cpu->machine->ncpus; i++)
173 cpu->machine->cpus[i]->cd.alpha.ll_flag = 0;
174 } else {
175 *((uint64_t *)ic->arg[0]) = 0;
176 return;
177 }
178 #endif
179 #endif
180
181 c = addr & 8191;
182
183 #ifndef LS_B
184 if (c &
185 #ifdef LS_W
186 1
187 #endif
188 #ifdef LS_L
189 3
190 #endif
191 #ifdef LS_Q
192 7
193 #endif
194 ) {
195 LS_GENERIC_N(cpu, ic);
196 return;
197 }
198 else
199 #endif
200
201 if (page != NULL) {
202 #ifdef LS_LOAD
203 #ifdef HOST_BIG_ENDIAN
204 uint64_t data_x;
205 data_x = page[c];
206 #ifndef LS_B
207 data_x += (page[c+1] << 8);
208 #ifndef LS_W
209 data_x += (page[c+2] << 16);
210 data_x += ((uint64_t)page[c+3] << 24);
211 #ifndef LS_L
212 data_x += ((uint64_t)page[c+4] << 32);
213 data_x += ((uint64_t)page[c+5] << 40);
214 data_x += ((uint64_t)page[c+6] << 48);
215 data_x += ((uint64_t)page[c+7] << 56);
216 #endif
217 #endif
218 #endif
219 #ifdef LS_L
220 *((uint64_t *)ic->arg[0]) = (int64_t)(int32_t)data_x;
221 #else
222 *((uint64_t *)ic->arg[0]) = data_x;
223 #endif
224 #else
225 #ifdef LS_B
226 *((uint64_t *)ic->arg[0]) = page[c];
227 #endif
228 #ifdef LS_W
229 uint16_t d = *((uint16_t *) (page + c));
230 *((uint64_t *)ic->arg[0]) = d;
231 #endif
232 #ifdef LS_L
233 int32_t d = *((int32_t *) (page + c));
234 *((uint64_t *)ic->arg[0]) = (int64_t)d;
235 #endif
236 #ifdef LS_Q
237 uint64_t d = *((uint64_t *) (page + c));
238 *((uint64_t *)ic->arg[0]) = d;
239 #endif
240 #endif
241 #else
242 /* Store: */
243 #ifdef HOST_BIG_ENDIAN
244 uint64_t data_x = *((uint64_t *)ic->arg[0]);
245 page[c] = data_x;
246 #ifndef LS_B
247 page[c+1] = data_x >> 8;
248 #ifndef LS_W
249 page[c+2] = data_x >> 16;
250 page[c+3] = data_x >> 24;
251 #ifndef LS_L
252 page[c+4] = data_x >> 32;
253 page[c+5] = data_x >> 40;
254 page[c+6] = data_x >> 48;
255 page[c+7] = data_x >> 56;
256 #endif
257 #endif
258 #endif
259 #else
260 /* Native byte order: */
261 #ifdef LS_B
262 page[c] = *((uint64_t *)ic->arg[0]);
263 #endif
264 #ifdef LS_W
265 uint32_t d = *((uint64_t *)ic->arg[0]);
266 *((uint16_t *) (page + c)) = d;
267 #endif
268 #ifdef LS_L
269 uint32_t d = *((uint64_t *)ic->arg[0]);
270 *((uint32_t *) (page + c)) = d;
271 #endif
272 #ifdef LS_Q
273 uint64_t d = *((uint64_t *)ic->arg[0]);
274 *((uint64_t *) (page + c)) = d;
275 #endif
276 #endif
277
278 #ifdef LS_LLSC
279 #ifndef LS_LOAD
280 *((uint64_t *)ic->arg[0]) = 1;
281 #endif
282 #endif
283
284 #endif /* !LS_LOAD */
285 } else
286 LS_GENERIC_N(cpu, ic);
287 }
288

  ViewVC Help
Powered by ViewVC 1.1.26