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

Annotation of /trunk/src/cpus/cpu_alpha_instr_loadstore.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 28 - (hide annotations)
Mon Oct 8 16:20:26 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 6969 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1298 2006/07/22 11:27:46 debug Exp $
20060626	Continuing on SPARC emulation (beginning on the 'save'
		instruction, register windows, etc).
20060629	Planning statistics gathering (new -s command line option),
		and renaming speed_tricks to allow_instruction_combinations.
20060630	Some minor manual page updates.
		Various cleanups.
		Implementing the -s command line option.
20060701	FINALLY found the bug which prevented Linux and Ultrix from
		running without the ugly hack in the R2000/R3000 cache isol
		code; it was the phystranslation hint array which was buggy.
		Removing the phystranslation hint code completely, for now.
20060702	Minor dyntrans cleanups; invalidation of physpages now only
		invalidate those parts of a page that have actually been
		translated. (32 parts per page.)
		Some MIPS non-R3000 speed fixes.
		Experimenting with MIPS instruction combination for some
		addiu+bne+sw loops, and sw+sw+sw.
		Adding support (again) for larger-than-4KB pages in MIPS tlbw*.
		Continuing on SPARC emulation: adding load/store instructions.
20060704	Fixing a virtual vs physical page shift bug in the new tlbw*
		implementation. Problem noticed by Jakub Jermar. (Many thanks.)
		Moving rfe and eret to cpu_mips_instr.c, since that is the
		only place that uses them nowadays.
20060705	Removing the BSD license from the "testmachine" include files,
		placing them in the public domain instead; this enables the
		testmachine stuff to be used from projects which are
		incompatible with the BSD license for some reason.
20060707	Adding instruction combinations for the R2000/R3000 L1
		I-cache invalidation code used by NetBSD/pmax 3.0, lui+addiu,
		various branches followed by addiu or nop, and jr ra followed
		by addiu. The time it takes to perform a full NetBSD/pmax R3000
		install on the laptop has dropped from 573 seconds to 539. :-)
20060708	Adding a framebuffer controller device (dev_fbctrl), which so
		far can be used to change the fb resolution during runtime, but
		in the future will also be useful for accelerated block fill/
		copy, and possibly also simplified character output.
		Adding an instruction combination for NetBSD/pmax' strlen.
20060709	Minor fixes: reading raw files in src/file.c wasn't memblock
		aligned, removing buggy multi_sw MIPS instruction combination,
		etc.
20060711	Adding a machine_qemu.c, which contains a "qemu_mips" machine.
		(It mimics QEMU's MIPS machine mode, so that a test kernel
		made for QEMU_MIPS also can run in GXemul... at least to some
		extent.)  Adding a short section about how to run this mode to
		doc/guestoses.html.
20060714	Misc. minor code cleanups.
20060715	Applying a patch which adds getchar() to promemul/yamon.c
		(from Oleksandr Tymoshenko).
		Adding yamon.h from NetBSD, and rewriting yamon.c to use it
		(instead of ugly hardcoded numbers) + some cleanup.
20060716	Found and fixed the bug which broke single-stepping of 64-bit
		programs between 0.4.0 and 0.4.0.1 (caused by too quick
		refactoring and no testing). Hopefully this fix will not
		break too many other things.
20060718	Continuing on the 8253 PIT; it now works with Linux/QEMU_MIPS.
		Re-adding the sw+sw+sw instr comb (the problem was that I had
		ignored endian issues); however, it doesn't seem to give any
		big performance gain.
20060720	Adding a dummy Transputer mode (T414, T800 etc) skeleton (only
		the 'j' and 'ldc' instructions are implemented so far). :-}
20060721	Adding gtreg.h from NetBSD, updating dev_gt.c to use it, plus
		misc. other updates to get Linux 2.6 for evbmips/malta working
		(thanks to Alec Voropay for the details).
		FINALLY found and fixed the bug which made tlbw* for non-R3000
		buggy; it was a reference count problem in the dyntrans core.
20060722	Testing stuff; things seem stable enough for a new release.

==============  RELEASE 0.4.1  ==============


1 dpavlin 14 /*
2 dpavlin 22 * Copyright (C) 2005-2006 Anders Gavare. All rights reserved.
3 dpavlin 14 *
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 28 * $Id: cpu_alpha_instr_loadstore.c,v 1.5 2006/06/30 20:22:53 debug Exp $
29 dpavlin 14 *
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 dpavlin 20 data_x += ((uint64_t)data[3] << 24);
82 dpavlin 14 #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 dpavlin 24 unsigned char *page;
132     uint64_t addr = (*((uint64_t *)ic->arg[1]))
133 dpavlin 14 #ifndef LS_IGNORE_OFFSET
134     + (int32_t)ic->arg[2]
135     #endif
136     ;
137    
138 dpavlin 24 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 dpavlin 14 #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 dpavlin 24 if (page != NULL) {
202 dpavlin 14 #ifdef LS_LOAD
203     #ifdef HOST_BIG_ENDIAN
204 dpavlin 24 uint64_t data_x;
205     data_x = page[c];
206 dpavlin 14 #ifndef LS_B
207 dpavlin 24 data_x += (page[c+1] << 8);
208 dpavlin 14 #ifndef LS_W
209 dpavlin 24 data_x += (page[c+2] << 16);
210     data_x += ((uint64_t)page[c+3] << 24);
211 dpavlin 14 #ifndef LS_L
212 dpavlin 24 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 dpavlin 14 #endif
217     #endif
218     #endif
219     #ifdef LS_L
220 dpavlin 24 *((uint64_t *)ic->arg[0]) = (int64_t)(int32_t)data_x;
221 dpavlin 14 #else
222 dpavlin 24 *((uint64_t *)ic->arg[0]) = data_x;
223 dpavlin 14 #endif
224     #else
225     #ifdef LS_B
226 dpavlin 24 *((uint64_t *)ic->arg[0]) = page[c];
227 dpavlin 14 #endif
228     #ifdef LS_W
229 dpavlin 24 uint16_t d = *((uint16_t *) (page + c));
230     *((uint64_t *)ic->arg[0]) = d;
231 dpavlin 14 #endif
232     #ifdef LS_L
233 dpavlin 24 int32_t d = *((int32_t *) (page + c));
234     *((uint64_t *)ic->arg[0]) = (int64_t)d;
235 dpavlin 14 #endif
236     #ifdef LS_Q
237 dpavlin 24 uint64_t d = *((uint64_t *) (page + c));
238     *((uint64_t *)ic->arg[0]) = d;
239 dpavlin 14 #endif
240     #endif
241     #else
242 dpavlin 24 /* Store: */
243 dpavlin 14 #ifdef HOST_BIG_ENDIAN
244 dpavlin 24 uint64_t data_x = *((uint64_t *)ic->arg[0]);
245     page[c] = data_x;
246 dpavlin 14 #ifndef LS_B
247 dpavlin 24 page[c+1] = data_x >> 8;
248 dpavlin 14 #ifndef LS_W
249 dpavlin 24 page[c+2] = data_x >> 16;
250     page[c+3] = data_x >> 24;
251 dpavlin 14 #ifndef LS_L
252 dpavlin 24 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 dpavlin 14 #endif
257     #endif
258     #endif
259     #else
260 dpavlin 24 /* Native byte order: */
261 dpavlin 14 #ifdef LS_B
262 dpavlin 24 page[c] = *((uint64_t *)ic->arg[0]);
263 dpavlin 14 #endif
264     #ifdef LS_W
265 dpavlin 24 uint32_t d = *((uint64_t *)ic->arg[0]);
266     *((uint16_t *) (page + c)) = d;
267 dpavlin 14 #endif
268     #ifdef LS_L
269 dpavlin 24 uint32_t d = *((uint64_t *)ic->arg[0]);
270     *((uint32_t *) (page + c)) = d;
271 dpavlin 14 #endif
272     #ifdef LS_Q
273 dpavlin 24 uint64_t d = *((uint64_t *)ic->arg[0]);
274     *((uint64_t *) (page + c)) = d;
275 dpavlin 14 #endif
276     #endif
277    
278     #ifdef LS_LLSC
279     #ifndef LS_LOAD
280 dpavlin 24 *((uint64_t *)ic->arg[0]) = 1;
281 dpavlin 14 #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