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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 36 - (hide annotations)
Mon Oct 8 16:21:34 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 45975 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1497 2007/03/18 03:41:36 debug Exp $
20070224	Minor update to the initialization of the ns16550 in
		machine_walnut.c, to allow that machine type to boot with the
		new interrupt system (although it is still a dummy machine).
		Adding a wdc at 0x14000000 to machine_landisk.c, and fixing
		the SCIF serial interrupts of the SH4 cpu enough to get
		NetBSD/landisk booting from a disk image :-)  Adding a
		preliminary install instruction skeleton to guestoses.html.
20070306	Adding SH-IPL+G PROM emulation, and also passing the "end"
		symbol in r5 on bootup, for Landisk emulation. This is enough
		to get OpenBSD/landisk to install :)  Adding a preliminary
		install instruction skeleton to the documentation. SuperH
		emulation is still shaky, though :-/
20070307	Fixed a strangeness in memory_sh.c (read/write was never
		returned for any page). (Unknown whether this fixes any actual
		problems, though.)
20070308	dev_ram.c fix: invalidate code translations on writes to
		RAM, emulated as separate devices. Linux/dreamcast gets
		further in the boot process than before, but still bugs out
		in userland.
		Fixing bugs in the "stc.l gbr,@-rN" and "ldc.l @rN+,gbr" SuperH 
		instructions (they should NOT check the MD bit), allowing the
		Linux/dreamcast Live CD to reach userland correctly :-)
20070310	Changing the cpu name "Alpha" in src/useremul.c to "21364" to
		unbreak userland syscall emulation of FreeBSD/Alpha binaries.
20070314	Applying a patch from Michael Yaroslavtsev which fixes the
		previous Linux lib64 patch to the configure script.
20070315	Adding a (dummy) sun4v machine type, and SPARC T1 cpu type.
20070316	Creating a new directory, src/disk, and moving diskimage.c
		to it. Separating out bootblock loading stuff from emul.c into
		new files in src/disk.
		Adding some more SPARC registers.
20070318	Preparing/testing for a minirelease, 0.4.4.1.

==============  RELEASE 0.4.4.1  ==============


1 dpavlin 14 /*
2 dpavlin 34 * Copyright (C) 2005-2007 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 36 * $Id: cpu_sparc_instr.c,v 1.27 2007/03/16 15:43:58 debug Exp $
29 dpavlin 14 *
30     * SPARC instructions.
31     *
32     * Individual functions should keep track of cpu->n_translated_instrs.
33     * (If no instruction was executed, then it should be decreased. If, say, 4
34     * instructions were combined into one function and executed, then it should
35     * be increased by 3.)
36     */
37    
38    
39     /*
40 dpavlin 28 * invalid: For catching bugs.
41     */
42     X(invalid)
43     {
44     fatal("FATAL ERROR: An internal error occured in the SPARC"
45     " dyntrans code. Please contact the author with detailed"
46     " repro steps on how to trigger this bug.\n");
47     exit(1);
48     }
49    
50    
51     /*
52 dpavlin 14 * nop: Do nothing.
53     */
54     X(nop)
55     {
56     }
57    
58    
59     /*****************************************************************************/
60    
61    
62 dpavlin 24 /*
63     * call
64     *
65     * arg[0] = int32_t displacement compared to the current instruction
66     * arg[1] = int32_t displacement of current instruction compared to
67     * start of the page
68     */
69     X(call)
70     {
71     MODE_uint_t old_pc = cpu->pc;
72     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
73     << SPARC_INSTR_ALIGNMENT_SHIFT);
74     old_pc += (int32_t)ic->arg[1];
75     cpu->cd.sparc.r[SPARC_REG_O7] = old_pc;
76     cpu->delay_slot = TO_BE_DELAYED;
77     ic[1].f(cpu, ic+1);
78     cpu->n_translated_instrs ++;
79     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
80     /* Note: Must be non-delayed when jumping to the new pc: */
81     cpu->delay_slot = NOT_DELAYED;
82     cpu->pc = old_pc + (int32_t)ic->arg[0];
83     quick_pc_to_pointers(cpu);
84     } else
85     cpu->delay_slot = NOT_DELAYED;
86     }
87     X(call_trace)
88     {
89     MODE_uint_t old_pc = cpu->pc;
90     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
91     << SPARC_INSTR_ALIGNMENT_SHIFT);
92     old_pc += (int32_t)ic->arg[1];
93     cpu->cd.sparc.r[SPARC_REG_O7] = old_pc;
94     cpu->delay_slot = TO_BE_DELAYED;
95     ic[1].f(cpu, ic+1);
96     cpu->n_translated_instrs ++;
97     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
98     /* Note: Must be non-delayed when jumping to the new pc: */
99     cpu->delay_slot = NOT_DELAYED;
100     cpu->pc = old_pc + (int32_t)ic->arg[0];
101     cpu_functioncall_trace(cpu, cpu->pc);
102     quick_pc_to_pointers(cpu);
103     } else
104     cpu->delay_slot = NOT_DELAYED;
105     }
106    
107    
108     /*
109 dpavlin 30 * bl
110     *
111     * arg[0] = int32_t displacement compared to the start of the current page
112     */
113     X(bl)
114     {
115     MODE_uint_t old_pc = cpu->pc;
116     int n = (cpu->cd.sparc.ccr & SPARC_CCR_N) ? 1 : 0;
117     int v = (cpu->cd.sparc.ccr & SPARC_CCR_V) ? 1 : 0;
118     int cond = n ^ v;
119     cpu->delay_slot = TO_BE_DELAYED;
120     ic[1].f(cpu, ic+1);
121     cpu->n_translated_instrs ++;
122     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
123     /* Note: Must be non-delayed when jumping to the new pc: */
124     cpu->delay_slot = NOT_DELAYED;
125     if (cond) {
126     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
127     << SPARC_INSTR_ALIGNMENT_SHIFT);
128     cpu->pc = old_pc + (int32_t)ic->arg[0];
129     quick_pc_to_pointers(cpu);
130     }
131     } else
132     cpu->delay_slot = NOT_DELAYED;
133     }
134     X(bl_xcc)
135     {
136     MODE_uint_t old_pc = cpu->pc;
137     int n = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_N)? 1:0;
138     int v = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_V)? 1:0;
139     int cond = n ^ v;
140     cpu->delay_slot = TO_BE_DELAYED;
141     ic[1].f(cpu, ic+1);
142     cpu->n_translated_instrs ++;
143     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
144     /* Note: Must be non-delayed when jumping to the new pc: */
145     cpu->delay_slot = NOT_DELAYED;
146     if (cond) {
147     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
148     << SPARC_INSTR_ALIGNMENT_SHIFT);
149     cpu->pc = old_pc + (int32_t)ic->arg[0];
150     quick_pc_to_pointers(cpu);
151     }
152     } else
153     cpu->delay_slot = NOT_DELAYED;
154     }
155    
156    
157     /*
158 dpavlin 32 * ble
159     *
160     * arg[0] = int32_t displacement compared to the start of the current page
161     */
162     X(ble)
163     {
164     MODE_uint_t old_pc = cpu->pc;
165     int n = (cpu->cd.sparc.ccr & SPARC_CCR_N) ? 1 : 0;
166     int v = (cpu->cd.sparc.ccr & SPARC_CCR_V) ? 1 : 0;
167     int z = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 1 : 0;
168     int cond = (n ^ v) || z;
169     cpu->delay_slot = TO_BE_DELAYED;
170     ic[1].f(cpu, ic+1);
171     cpu->n_translated_instrs ++;
172     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
173     /* Note: Must be non-delayed when jumping to the new pc: */
174     cpu->delay_slot = NOT_DELAYED;
175     if (cond) {
176     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
177     << SPARC_INSTR_ALIGNMENT_SHIFT);
178     cpu->pc = old_pc + (int32_t)ic->arg[0];
179     quick_pc_to_pointers(cpu);
180     }
181     } else
182     cpu->delay_slot = NOT_DELAYED;
183     }
184     X(ble_xcc)
185     {
186     MODE_uint_t old_pc = cpu->pc;
187     int n = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_N)? 1:0;
188     int v = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_V)? 1:0;
189     int z = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_Z)? 1:0;
190     int cond = (n ^ v) || z;
191     cpu->delay_slot = TO_BE_DELAYED;
192     ic[1].f(cpu, ic+1);
193     cpu->n_translated_instrs ++;
194     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
195     /* Note: Must be non-delayed when jumping to the new pc: */
196     cpu->delay_slot = NOT_DELAYED;
197     if (cond) {
198     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
199     << SPARC_INSTR_ALIGNMENT_SHIFT);
200     cpu->pc = old_pc + (int32_t)ic->arg[0];
201     quick_pc_to_pointers(cpu);
202     }
203     } else
204     cpu->delay_slot = NOT_DELAYED;
205     }
206    
207    
208     /*
209 dpavlin 30 * bne
210     *
211     * arg[0] = int32_t displacement compared to the start of the current page
212     */
213     X(bne)
214     {
215     MODE_uint_t old_pc = cpu->pc;
216     int cond = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 0 : 1;
217     cpu->delay_slot = TO_BE_DELAYED;
218     ic[1].f(cpu, ic+1);
219     cpu->n_translated_instrs ++;
220     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
221     /* Note: Must be non-delayed when jumping to the new pc: */
222     cpu->delay_slot = NOT_DELAYED;
223     if (cond) {
224     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
225     << SPARC_INSTR_ALIGNMENT_SHIFT);
226     cpu->pc = old_pc + (int32_t)ic->arg[0];
227     quick_pc_to_pointers(cpu);
228     }
229     } else
230     cpu->delay_slot = NOT_DELAYED;
231     }
232     X(bne_a)
233     {
234     MODE_uint_t old_pc = cpu->pc;
235     int cond = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 0 : 1;
236     cpu->delay_slot = TO_BE_DELAYED;
237     if (!cond) {
238     /* Nullify the delay slot: */
239     cpu->cd.sparc.next_ic ++;
240     return;
241     }
242     ic[1].f(cpu, ic+1);
243     cpu->n_translated_instrs ++;
244     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
245     /* Note: Must be non-delayed when jumping to the new pc: */
246     cpu->delay_slot = NOT_DELAYED;
247     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
248     << SPARC_INSTR_ALIGNMENT_SHIFT);
249     cpu->pc = old_pc + (int32_t)ic->arg[0];
250     quick_pc_to_pointers(cpu);
251     } else
252     cpu->delay_slot = NOT_DELAYED;
253     }
254    
255    
256     /*
257     * bg
258     *
259     * arg[0] = int32_t displacement compared to the start of the current page
260     */
261     X(bg)
262     {
263     MODE_uint_t old_pc = cpu->pc;
264     int n = (cpu->cd.sparc.ccr & SPARC_CCR_N) ? 1 : 0;
265     int v = (cpu->cd.sparc.ccr & SPARC_CCR_V) ? 1 : 0;
266     int z = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 1 : 0;
267     int cond = !(z | (n ^ v));
268     cpu->delay_slot = TO_BE_DELAYED;
269     ic[1].f(cpu, ic+1);
270     cpu->n_translated_instrs ++;
271     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
272     /* Note: Must be non-delayed when jumping to the new pc: */
273     cpu->delay_slot = NOT_DELAYED;
274     if (cond) {
275     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
276     << SPARC_INSTR_ALIGNMENT_SHIFT);
277     cpu->pc = old_pc + (int32_t)ic->arg[0];
278     quick_pc_to_pointers(cpu);
279     }
280     } else
281     cpu->delay_slot = NOT_DELAYED;
282     }
283     X(bg_xcc)
284     {
285     MODE_uint_t old_pc = cpu->pc;
286     int n = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_N)? 1:0;
287     int v = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_V)? 1:0;
288     int z = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_Z)? 1:0;
289     int cond = !(z | (n ^ v));
290     cpu->delay_slot = TO_BE_DELAYED;
291     ic[1].f(cpu, ic+1);
292     cpu->n_translated_instrs ++;
293     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
294     /* Note: Must be non-delayed when jumping to the new pc: */
295     cpu->delay_slot = NOT_DELAYED;
296     if (cond) {
297     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
298     << SPARC_INSTR_ALIGNMENT_SHIFT);
299     cpu->pc = old_pc + (int32_t)ic->arg[0];
300     quick_pc_to_pointers(cpu);
301     }
302     } else
303     cpu->delay_slot = NOT_DELAYED;
304     }
305    
306    
307     /*
308     * bge
309     *
310     * arg[0] = int32_t displacement compared to the start of the current page
311     */
312     X(bge)
313     {
314     MODE_uint_t old_pc = cpu->pc;
315     int n = (cpu->cd.sparc.ccr & SPARC_CCR_N) ? 1 : 0;
316     int v = (cpu->cd.sparc.ccr & SPARC_CCR_V) ? 1 : 0;
317     int cond = !(n ^ v);
318     cpu->delay_slot = TO_BE_DELAYED;
319     ic[1].f(cpu, ic+1);
320     cpu->n_translated_instrs ++;
321     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
322     /* Note: Must be non-delayed when jumping to the new pc: */
323     cpu->delay_slot = NOT_DELAYED;
324     if (cond) {
325     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
326     << SPARC_INSTR_ALIGNMENT_SHIFT);
327     cpu->pc = old_pc + (int32_t)ic->arg[0];
328     quick_pc_to_pointers(cpu);
329     }
330     } else
331     cpu->delay_slot = NOT_DELAYED;
332     }
333     X(bge_xcc)
334     {
335     MODE_uint_t old_pc = cpu->pc;
336     int n = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_N)? 1:0;
337     int v = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_V)? 1:0;
338     int cond = !(n ^ v);
339     cpu->delay_slot = TO_BE_DELAYED;
340     ic[1].f(cpu, ic+1);
341     cpu->n_translated_instrs ++;
342     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
343     /* Note: Must be non-delayed when jumping to the new pc: */
344     cpu->delay_slot = NOT_DELAYED;
345     if (cond) {
346     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
347     << SPARC_INSTR_ALIGNMENT_SHIFT);
348     cpu->pc = old_pc + (int32_t)ic->arg[0];
349     quick_pc_to_pointers(cpu);
350     }
351     } else
352     cpu->delay_slot = NOT_DELAYED;
353     }
354    
355    
356     /*
357     * be
358     *
359     * arg[0] = int32_t displacement compared to the start of the current page
360     */
361     X(be)
362     {
363     MODE_uint_t old_pc = cpu->pc;
364     int cond = cpu->cd.sparc.ccr & SPARC_CCR_Z;
365     cpu->delay_slot = TO_BE_DELAYED;
366     ic[1].f(cpu, ic+1);
367     cpu->n_translated_instrs ++;
368     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
369     /* Note: Must be non-delayed when jumping to the new pc: */
370     cpu->delay_slot = NOT_DELAYED;
371     if (cond) {
372     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
373     << SPARC_INSTR_ALIGNMENT_SHIFT);
374     cpu->pc = old_pc + (int32_t)ic->arg[0];
375     quick_pc_to_pointers(cpu);
376     }
377     } else
378     cpu->delay_slot = NOT_DELAYED;
379     }
380     X(be_xcc)
381     {
382     MODE_uint_t old_pc = cpu->pc;
383     int cond = (cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_Z;
384     cpu->delay_slot = TO_BE_DELAYED;
385     ic[1].f(cpu, ic+1);
386     cpu->n_translated_instrs ++;
387     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
388     /* Note: Must be non-delayed when jumping to the new pc: */
389     cpu->delay_slot = NOT_DELAYED;
390     if (cond) {
391     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
392     << SPARC_INSTR_ALIGNMENT_SHIFT);
393     cpu->pc = old_pc + (int32_t)ic->arg[0];
394     quick_pc_to_pointers(cpu);
395     }
396     } else
397     cpu->delay_slot = NOT_DELAYED;
398     }
399    
400    
401     /*
402 dpavlin 24 * ba
403     *
404     * arg[0] = int32_t displacement compared to the start of the current page
405     */
406     X(ba)
407     {
408     MODE_uint_t old_pc = cpu->pc;
409     cpu->delay_slot = TO_BE_DELAYED;
410     ic[1].f(cpu, ic+1);
411     cpu->n_translated_instrs ++;
412     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
413     /* Note: Must be non-delayed when jumping to the new pc: */
414     cpu->delay_slot = NOT_DELAYED;
415     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
416     << SPARC_INSTR_ALIGNMENT_SHIFT);
417     cpu->pc = old_pc + (int32_t)ic->arg[0];
418     quick_pc_to_pointers(cpu);
419     } else
420     cpu->delay_slot = NOT_DELAYED;
421     }
422    
423    
424     /*
425 dpavlin 30 * brnz
426     *
427     * arg[0] = int32_t displacement compared to the start of the current page
428     * arg[1] = ptr to rs1
429     */
430     X(brnz)
431     {
432     MODE_uint_t old_pc = cpu->pc;
433     int cond = reg(ic->arg[1]) != 0;
434     cpu->delay_slot = TO_BE_DELAYED;
435     ic[1].f(cpu, ic+1);
436     cpu->n_translated_instrs ++;
437     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
438     /* Note: Must be non-delayed when jumping to the new pc: */
439     cpu->delay_slot = NOT_DELAYED;
440     if (cond) {
441     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
442     << SPARC_INSTR_ALIGNMENT_SHIFT);
443     cpu->pc = old_pc + (int32_t)ic->arg[0];
444     quick_pc_to_pointers(cpu);
445     }
446     } else
447     cpu->delay_slot = NOT_DELAYED;
448     }
449    
450    
451     /*
452 dpavlin 32 * Save:
453     *
454     * arg[0] = ptr to rs1
455     * arg[1] = ptr to rs2 or an immediate value (int32_t)
456     * arg[2] = ptr to rd (_after_ the register window change)
457     */
458     X(save_v9_imm)
459     {
460     MODE_uint_t rs = reg(ic->arg[0]) + (int32_t)ic->arg[1];
461     int cwp = cpu->cd.sparc.cwp;
462    
463     if (cpu->cd.sparc.cansave == 0) {
464     fatal("save_v9_imm: spill trap. TODO\n");
465     exit(1);
466     }
467    
468     if (cpu->cd.sparc.cleanwin - cpu->cd.sparc.canrestore == 0) {
469     fatal("save_v9_imm: clean_window trap. TODO\n");
470     exit(1);
471     }
472    
473     /* Save away old in registers: */
474     memcpy(&cpu->cd.sparc.r_inout[cwp][0], &cpu->cd.sparc.r[SPARC_REG_I0],
475     sizeof(cpu->cd.sparc.r[SPARC_REG_I0]) * N_SPARC_INOUT_REG);
476    
477     /* Save away old local registers: */
478     memcpy(&cpu->cd.sparc.r_local[cwp][0], &cpu->cd.sparc.r[SPARC_REG_L0],
479     sizeof(cpu->cd.sparc.r[SPARC_REG_L0]) * N_SPARC_INOUT_REG);
480    
481     cpu->cd.sparc.cwp = (cwp + 1) % cpu->cd.sparc.cpu_type.nwindows;
482     cpu->cd.sparc.cansave --;
483     cpu->cd.sparc.canrestore ++; /* TODO: modulo here too? */
484     cwp = cpu->cd.sparc.cwp;
485    
486     /* The out registers become the new in registers: */
487     memcpy(&cpu->cd.sparc.r[SPARC_REG_I0], &cpu->cd.sparc.r[SPARC_REG_O0],
488     sizeof(cpu->cd.sparc.r[SPARC_REG_O0]) * N_SPARC_INOUT_REG);
489    
490     /* Read new local registers: */
491     memcpy(&cpu->cd.sparc.r[SPARC_REG_L0], &cpu->cd.sparc.r_local[cwp][0],
492     sizeof(cpu->cd.sparc.r[SPARC_REG_L0]) * N_SPARC_INOUT_REG);
493    
494     reg(ic->arg[2]) = rs;
495     }
496    
497    
498     /*
499     * Restore:
500     */
501     X(restore)
502     {
503     int cwp = cpu->cd.sparc.cwp;
504    
505     if (cpu->cd.sparc.canrestore == 0) {
506     fatal("restore: spill trap. TODO\n");
507     exit(1);
508     }
509    
510     cpu->cd.sparc.cwp = cwp - 1;
511     if (cwp == 0)
512     cpu->cd.sparc.cwp = cpu->cd.sparc.cpu_type.nwindows - 1;
513     cpu->cd.sparc.cansave ++;
514     cpu->cd.sparc.canrestore --;
515     cwp = cpu->cd.sparc.cwp;
516    
517     /* The in registers become the new out registers: */
518     memcpy(&cpu->cd.sparc.r[SPARC_REG_O0], &cpu->cd.sparc.r[SPARC_REG_I0],
519     sizeof(cpu->cd.sparc.r[SPARC_REG_O0]) * N_SPARC_INOUT_REG);
520    
521     /* Read back the local registers: */
522     memcpy(&cpu->cd.sparc.r[SPARC_REG_L0], &cpu->cd.sparc.r_local[cwp][0],
523     sizeof(cpu->cd.sparc.r[SPARC_REG_L0]) * N_SPARC_INOUT_REG);
524    
525     /* Read back the in registers: */
526     memcpy(&cpu->cd.sparc.r[SPARC_REG_I0], &cpu->cd.sparc.r_inout[cwp][0],
527     sizeof(cpu->cd.sparc.r[SPARC_REG_I0]) * N_SPARC_INOUT_REG);
528     }
529    
530    
531     /*
532 dpavlin 24 * Jump and link
533     *
534     * arg[0] = ptr to rs1
535     * arg[1] = ptr to rs2 or an immediate value (int32_t)
536     * arg[2] = ptr to rd
537     */
538     X(jmpl_imm)
539     {
540     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
541     / sizeof(struct sparc_instr_call);
542     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
543     << SPARC_INSTR_ALIGNMENT_SHIFT);
544     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
545     reg(ic->arg[2]) = cpu->pc;
546    
547     cpu->delay_slot = TO_BE_DELAYED;
548     ic[1].f(cpu, ic+1);
549     cpu->n_translated_instrs ++;
550    
551     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
552     /* Note: Must be non-delayed when jumping to the new pc: */
553     cpu->delay_slot = NOT_DELAYED;
554     cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
555     quick_pc_to_pointers(cpu);
556     } else
557     cpu->delay_slot = NOT_DELAYED;
558     }
559     X(jmpl_imm_no_rd)
560     {
561     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
562     / sizeof(struct sparc_instr_call);
563     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
564     << SPARC_INSTR_ALIGNMENT_SHIFT);
565     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
566    
567     cpu->delay_slot = TO_BE_DELAYED;
568     ic[1].f(cpu, ic+1);
569     cpu->n_translated_instrs ++;
570    
571     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
572     /* Note: Must be non-delayed when jumping to the new pc: */
573     cpu->delay_slot = NOT_DELAYED;
574     cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
575     quick_pc_to_pointers(cpu);
576     } else
577     cpu->delay_slot = NOT_DELAYED;
578     }
579     X(jmpl_reg)
580     {
581     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
582     / sizeof(struct sparc_instr_call);
583     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
584     << SPARC_INSTR_ALIGNMENT_SHIFT);
585     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
586     reg(ic->arg[2]) = cpu->pc;
587    
588     cpu->delay_slot = TO_BE_DELAYED;
589     ic[1].f(cpu, ic+1);
590     cpu->n_translated_instrs ++;
591    
592     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
593     /* Note: Must be non-delayed when jumping to the new pc: */
594     cpu->delay_slot = NOT_DELAYED;
595     cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
596     quick_pc_to_pointers(cpu);
597     } else
598     cpu->delay_slot = NOT_DELAYED;
599     }
600     X(jmpl_reg_no_rd)
601     {
602     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
603     / sizeof(struct sparc_instr_call);
604     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
605     << SPARC_INSTR_ALIGNMENT_SHIFT);
606     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
607    
608     cpu->delay_slot = TO_BE_DELAYED;
609     ic[1].f(cpu, ic+1);
610     cpu->n_translated_instrs ++;
611    
612     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
613     /* Note: Must be non-delayed when jumping to the new pc: */
614     cpu->delay_slot = NOT_DELAYED;
615     cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
616     quick_pc_to_pointers(cpu);
617     } else
618     cpu->delay_slot = NOT_DELAYED;
619     }
620    
621    
622     X(jmpl_imm_trace)
623     {
624     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
625     / sizeof(struct sparc_instr_call);
626     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
627     << SPARC_INSTR_ALIGNMENT_SHIFT);
628     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
629     reg(ic->arg[2]) = cpu->pc;
630    
631     cpu->delay_slot = TO_BE_DELAYED;
632     ic[1].f(cpu, ic+1);
633     cpu->n_translated_instrs ++;
634    
635     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
636     /* Note: Must be non-delayed when jumping to the new pc: */
637     cpu->delay_slot = NOT_DELAYED;
638     cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
639     cpu_functioncall_trace(cpu, cpu->pc);
640     quick_pc_to_pointers(cpu);
641     } else
642     cpu->delay_slot = NOT_DELAYED;
643     }
644     X(jmpl_reg_trace)
645     {
646     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
647     / sizeof(struct sparc_instr_call);
648     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
649     << SPARC_INSTR_ALIGNMENT_SHIFT);
650     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
651     reg(ic->arg[2]) = cpu->pc;
652    
653     cpu->delay_slot = TO_BE_DELAYED;
654     ic[1].f(cpu, ic+1);
655     cpu->n_translated_instrs ++;
656    
657     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
658     /* Note: Must be non-delayed when jumping to the new pc: */
659     cpu->delay_slot = NOT_DELAYED;
660     cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
661     cpu_functioncall_trace(cpu, cpu->pc);
662     quick_pc_to_pointers(cpu);
663     } else
664     cpu->delay_slot = NOT_DELAYED;
665     }
666     X(retl_trace)
667     {
668     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
669     / sizeof(struct sparc_instr_call);
670     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
671     << SPARC_INSTR_ALIGNMENT_SHIFT);
672     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
673    
674     cpu->delay_slot = TO_BE_DELAYED;
675     ic[1].f(cpu, ic+1);
676     cpu->n_translated_instrs ++;
677    
678     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
679     /* Note: Must be non-delayed when jumping to the new pc: */
680     cpu->delay_slot = NOT_DELAYED;
681     cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
682     quick_pc_to_pointers(cpu);
683     cpu_functioncall_trace_return(cpu);
684     } else
685     cpu->delay_slot = NOT_DELAYED;
686     }
687    
688    
689     /*
690 dpavlin 32 * Return
691     *
692     * arg[0] = ptr to rs1
693     * arg[1] = ptr to rs2 or an immediate value (int32_t)
694     */
695     X(return_imm)
696     {
697     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
698     / sizeof(struct sparc_instr_call);
699     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
700     << SPARC_INSTR_ALIGNMENT_SHIFT);
701     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
702    
703     cpu->delay_slot = TO_BE_DELAYED;
704     ic[1].f(cpu, ic+1);
705     cpu->n_translated_instrs ++;
706    
707     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
708     /* Note: Must be non-delayed when jumping to the new pc: */
709     cpu->delay_slot = NOT_DELAYED;
710     cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
711     quick_pc_to_pointers(cpu);
712     instr(restore)(cpu, ic);
713     } else
714     cpu->delay_slot = NOT_DELAYED;
715     }
716     X(return_reg)
717     {
718     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
719     / sizeof(struct sparc_instr_call);
720     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
721     << SPARC_INSTR_ALIGNMENT_SHIFT);
722     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
723    
724     cpu->delay_slot = TO_BE_DELAYED;
725     ic[1].f(cpu, ic+1);
726     cpu->n_translated_instrs ++;
727    
728     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
729     /* Note: Must be non-delayed when jumping to the new pc: */
730     cpu->delay_slot = NOT_DELAYED;
731     cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
732     quick_pc_to_pointers(cpu);
733     instr(restore)(cpu, ic);
734     } else
735     cpu->delay_slot = NOT_DELAYED;
736     }
737     X(return_imm_trace)
738     {
739     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
740     / sizeof(struct sparc_instr_call);
741     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
742     << SPARC_INSTR_ALIGNMENT_SHIFT);
743     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
744    
745     cpu->delay_slot = TO_BE_DELAYED;
746     ic[1].f(cpu, ic+1);
747     cpu->n_translated_instrs ++;
748    
749     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
750     /* Note: Must be non-delayed when jumping to the new pc: */
751     cpu->delay_slot = NOT_DELAYED;
752     cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
753     cpu_functioncall_trace(cpu, cpu->pc);
754     quick_pc_to_pointers(cpu);
755     instr(restore)(cpu, ic);
756     } else
757     cpu->delay_slot = NOT_DELAYED;
758     }
759     X(return_reg_trace)
760     {
761     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
762     / sizeof(struct sparc_instr_call);
763     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
764     << SPARC_INSTR_ALIGNMENT_SHIFT);
765     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
766    
767     cpu->delay_slot = TO_BE_DELAYED;
768     ic[1].f(cpu, ic+1);
769     cpu->n_translated_instrs ++;
770    
771     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
772     /* Note: Must be non-delayed when jumping to the new pc: */
773     cpu->delay_slot = NOT_DELAYED;
774     cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
775     cpu_functioncall_trace(cpu, cpu->pc);
776     quick_pc_to_pointers(cpu);
777     instr(restore)(cpu, ic);
778     } else
779     cpu->delay_slot = NOT_DELAYED;
780     }
781    
782    
783     /*
784 dpavlin 24 * set: Set a register to a value (e.g. sethi).
785     *
786     * arg[0] = ptr to rd
787     * arg[1] = value (uint32_t)
788     */
789     X(set)
790     {
791     reg(ic->arg[0]) = (uint32_t)ic->arg[1];
792     }
793    
794    
795     /*
796     * Computational/arithmetic instructions:
797     *
798     * arg[0] = ptr to rs1
799     * arg[1] = ptr to rs2 or an immediate value (int32_t)
800     * arg[2] = ptr to rd
801     */
802     X(add) { reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]); }
803     X(add_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) + (int32_t)ic->arg[1]; }
804     X(and) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
805     X(and_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) & (int32_t)ic->arg[1]; }
806 dpavlin 32 X(andn) { reg(ic->arg[2]) = reg(ic->arg[0]) & ~reg(ic->arg[1]); }
807     X(andn_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) & ~(int32_t)ic->arg[1]; }
808 dpavlin 24 X(or) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
809     X(or_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) | (int32_t)ic->arg[1]; }
810     X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
811     X(xor_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ (int32_t)ic->arg[1]; }
812     X(sub) { reg(ic->arg[2]) = reg(ic->arg[0]) - reg(ic->arg[1]); }
813     X(sub_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) - (int32_t)ic->arg[1]; }
814    
815     X(sll) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) <<
816     (reg(ic->arg[1]) & 31); }
817     X(sllx) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) <<
818     (reg(ic->arg[1]) & 63); }
819     X(sll_imm) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) << ic->arg[1]; }
820     X(sllx_imm) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) << ic->arg[1]; }
821    
822     X(srl) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) >>
823     (reg(ic->arg[1]) & 31); }
824     X(srlx) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) >>
825     (reg(ic->arg[1]) & 63); }
826     X(srl_imm) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) >> ic->arg[1]; }
827     X(srlx_imm) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) >> ic->arg[1]; }
828    
829     X(sra) { reg(ic->arg[2]) = (int32_t)reg(ic->arg[0]) >>
830     (reg(ic->arg[1]) & 31); }
831     X(srax) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >>
832     (reg(ic->arg[1]) & 63); }
833     X(sra_imm) { reg(ic->arg[2]) = (int32_t)reg(ic->arg[0]) >> ic->arg[1]; }
834     X(srax_imm) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >> ic->arg[1]; }
835    
836 dpavlin 30 X(udiv)
837     {
838     uint64_t z = (cpu->cd.sparc.y << 32) | (uint32_t)reg(ic->arg[0]);
839     z /= (uint32_t)reg(ic->arg[1]);
840     if (z > 0xffffffff)
841     z = 0xffffffff;
842     reg(ic->arg[2]) = z;
843     }
844     X(udiv_imm)
845     {
846     uint64_t z = (cpu->cd.sparc.y << 32) | (uint32_t)reg(ic->arg[0]);
847     z /= (uint32_t)ic->arg[1];
848     if (z > 0xffffffff)
849     z = 0xffffffff;
850     reg(ic->arg[2]) = z;
851     }
852 dpavlin 24
853 dpavlin 30
854 dpavlin 24 /*
855 dpavlin 30 * Add with ccr update:
856     *
857     * arg[0] = ptr to rs1
858     * arg[1] = ptr to rs2 or an immediate value (int32_t)
859     * arg[2] = ptr to rd
860     */
861     int32_t sparc_addcc32(struct cpu *cpu, int32_t rs1, int32_t rs2);
862     #ifdef MODE32
863     int32_t sparc_addcc32(struct cpu *cpu, int32_t rs1, int32_t rs2)
864     #else
865     int64_t sparc_addcc64(struct cpu *cpu, int64_t rs1, int64_t rs2)
866     #endif
867     {
868     int cc = 0, sign1 = 0, sign2 = 0, signd = 0, mask = SPARC_CCR_ICC_MASK;
869     MODE_int_t rd = rs1 + rs2;
870     if (rd == 0)
871     cc = SPARC_CCR_Z;
872     else if (rd < 0)
873     cc = SPARC_CCR_N, signd = 1;
874     if (rs1 < 0)
875     sign1 = 1;
876     if (rs2 < 0)
877     sign2 = 1;
878     if (sign1 == sign2 && sign1 != signd)
879     cc |= SPARC_CCR_V;
880     /* TODO: SPARC_CCR_C */
881     #ifndef MODE32
882     mask <<= SPARC_CCR_XCC_SHIFT;
883     cc <<= SPARC_CCR_XCC_SHIFT;
884     #endif
885     cpu->cd.sparc.ccr &= ~mask;
886     cpu->cd.sparc.ccr |= cc;
887     return rd;
888     }
889     X(addcc)
890     {
891     /* Like add, but updates the ccr, and does both 32-bit and
892     64-bit comparison at the same time. */
893     MODE_int_t rs1 = reg(ic->arg[0]), rs2 = reg(ic->arg[1]), rd;
894     rd = sparc_addcc32(cpu, rs1, rs2);
895     #ifndef MODE32
896     rd = sparc_addcc64(cpu, rs1, rs2);
897     #endif
898     reg(ic->arg[2]) = rd;
899     }
900     X(addcc_imm)
901     {
902     MODE_int_t rs1 = reg(ic->arg[0]), rs2 = (int32_t)ic->arg[1], rd;
903     rd = sparc_addcc32(cpu, rs1, rs2);
904     #ifndef MODE32
905     rd = sparc_addcc64(cpu, rs1, rs2);
906     #endif
907     reg(ic->arg[2]) = rd;
908     }
909    
910    
911     /*
912     * And with ccr update:
913     *
914     * arg[0] = ptr to rs1
915     * arg[1] = ptr to rs2 or an immediate value (int32_t)
916     * arg[2] = ptr to rd
917     */
918     int32_t sparc_andcc32(struct cpu *cpu, int32_t rs1, int32_t rs2);
919     #ifdef MODE32
920     int32_t sparc_andcc32(struct cpu *cpu, int32_t rs1, int32_t rs2)
921     #else
922     int64_t sparc_andcc64(struct cpu *cpu, int64_t rs1, int64_t rs2)
923     #endif
924     {
925     int cc = 0, mask = SPARC_CCR_ICC_MASK;
926     MODE_int_t rd = rs1 & rs2;
927     if (rd == 0)
928     cc = SPARC_CCR_Z;
929     else if (rd < 0)
930     cc = SPARC_CCR_N;
931     /* Note: SPARC_CCR_C and SPARC_CCR_V are always zero. */
932     #ifndef MODE32
933     mask <<= SPARC_CCR_XCC_SHIFT;
934     cc <<= SPARC_CCR_XCC_SHIFT;
935     #endif
936     cpu->cd.sparc.ccr &= ~mask;
937     cpu->cd.sparc.ccr |= cc;
938     return rd;
939     }
940     X(andcc)
941     {
942     /* Like and, but updates the ccr, and does both 32-bit and
943     64-bit comparison at the same time. */
944     MODE_int_t rs1 = reg(ic->arg[0]), rs2 = reg(ic->arg[1]), rd;
945     rd = sparc_andcc32(cpu, rs1, rs2);
946     #ifndef MODE32
947     rd = sparc_andcc64(cpu, rs1, rs2);
948     #endif
949     reg(ic->arg[2]) = rd;
950     }
951     X(andcc_imm)
952     {
953     MODE_int_t rs1 = reg(ic->arg[0]), rs2 = (int32_t)ic->arg[1], rd;
954     rd = sparc_andcc32(cpu, rs1, rs2);
955     #ifndef MODE32
956     rd = sparc_andcc64(cpu, rs1, rs2);
957     #endif
958     reg(ic->arg[2]) = rd;
959     }
960    
961    
962     /*
963 dpavlin 24 * Subtract with ccr update:
964     *
965     * arg[0] = ptr to rs1
966     * arg[1] = ptr to rs2 or an immediate value (int32_t)
967     * arg[2] = ptr to rd
968     */
969     int32_t sparc_subcc32(struct cpu *cpu, int32_t rs1, int32_t rs2);
970     #ifdef MODE32
971     int32_t sparc_subcc32(struct cpu *cpu, int32_t rs1, int32_t rs2)
972     #else
973     int64_t sparc_subcc64(struct cpu *cpu, int64_t rs1, int64_t rs2)
974     #endif
975     {
976     int cc = 0, sign1 = 0, sign2 = 0, signd = 0, mask = SPARC_CCR_ICC_MASK;
977     MODE_int_t rd = rs1 - rs2;
978     if (rd == 0)
979     cc = SPARC_CCR_Z;
980     else if (rd < 0)
981     cc = SPARC_CCR_N, signd = 1;
982     if (rs1 < 0)
983     sign1 = 1;
984     if (rs2 < 0)
985     sign2 = 1;
986     if (sign1 != sign2 && sign1 != signd)
987     cc |= SPARC_CCR_V;
988     /* TODO: SPARC_CCR_C */
989     #ifndef MODE32
990     mask <<= SPARC_CCR_XCC_SHIFT;
991     cc <<= SPARC_CCR_XCC_SHIFT;
992     #endif
993     cpu->cd.sparc.ccr &= ~mask;
994     cpu->cd.sparc.ccr |= cc;
995     return rd;
996     }
997     X(subcc)
998     {
999     /* Like sub, but updates the ccr, and does both 32-bit and
1000     64-bit comparison at the same time. */
1001     MODE_int_t rs1 = reg(ic->arg[0]), rs2 = reg(ic->arg[1]), rd;
1002     rd = sparc_subcc32(cpu, rs1, rs2);
1003     #ifndef MODE32
1004     rd = sparc_subcc64(cpu, rs1, rs2);
1005     #endif
1006     reg(ic->arg[2]) = rd;
1007     }
1008     X(subcc_imm)
1009     {
1010     MODE_int_t rs1 = reg(ic->arg[0]), rs2 = (int32_t)ic->arg[1], rd;
1011     rd = sparc_subcc32(cpu, rs1, rs2);
1012     #ifndef MODE32
1013     rd = sparc_subcc64(cpu, rs1, rs2);
1014     #endif
1015     reg(ic->arg[2]) = rd;
1016     }
1017    
1018    
1019 dpavlin 28 #include "tmp_sparc_loadstore.c"
1020    
1021    
1022 dpavlin 24 /*
1023 dpavlin 36 * flushw: Flush Register Windows
1024     */
1025     X(flushw)
1026     {
1027     /* flushw acts as a nop, if cansave = nwindows - 2: */
1028     if (cpu->cd.sparc.cansave == cpu->cd.sparc.cpu_type.nwindows - 2)
1029     return;
1030    
1031     /* TODO */
1032     fatal("flushw: TODO: cansave = %i\n", cpu->cd.sparc.cansave);
1033     exit(1);
1034     }
1035    
1036    
1037     /*
1038 dpavlin 30 * rd: Read special register
1039 dpavlin 24 *
1040     * arg[2] = ptr to rd
1041     */
1042     X(rd_psr)
1043     {
1044     reg(ic->arg[2]) = cpu->cd.sparc.psr;
1045     }
1046    
1047    
1048     /*
1049 dpavlin 30 * rdpr: Read privileged register
1050     *
1051     * arg[2] = ptr to rd
1052     */
1053     X(rdpr_tba)
1054     {
1055     reg(ic->arg[2]) = cpu->cd.sparc.tba;
1056     }
1057     X(rdpr_ver)
1058     {
1059     reg(ic->arg[2]) = cpu->cd.sparc.ver;
1060     }
1061    
1062    
1063     /*
1064 dpavlin 24 * wrpr: Write to privileged register
1065     *
1066     * arg[0] = ptr to rs1
1067     * arg[1] = ptr to rs2 or an immediate value (int32_t)
1068     */
1069     X(wrpr_tick)
1070     {
1071     cpu->cd.sparc.tick = (uint32_t) (reg(ic->arg[0]) ^ reg(ic->arg[1]));
1072     }
1073     X(wrpr_tick_imm)
1074     {
1075     cpu->cd.sparc.tick = (uint32_t) (reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
1076     }
1077     X(wrpr_pil)
1078     {
1079     cpu->cd.sparc.pil = (reg(ic->arg[0]) ^ reg(ic->arg[1]))
1080     & SPARC_PIL_MASK;
1081     }
1082     X(wrpr_pil_imm)
1083     {
1084     cpu->cd.sparc.pil = (reg(ic->arg[0]) ^ (int32_t)ic->arg[1])
1085     & SPARC_PIL_MASK;
1086     }
1087     X(wrpr_pstate)
1088     {
1089     sparc_update_pstate(cpu, reg(ic->arg[0]) ^ reg(ic->arg[1]));
1090     }
1091     X(wrpr_pstate_imm)
1092     {
1093     sparc_update_pstate(cpu, reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
1094     }
1095 dpavlin 36 X(wrpr_cleanwin)
1096     {
1097     cpu->cd.sparc.cleanwin = (uint32_t) (reg(ic->arg[0]) ^ reg(ic->arg[1]));
1098     }
1099     X(wrpr_cleanwin_imm)
1100     {
1101     cpu->cd.sparc.cleanwin =
1102     (uint32_t) (reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
1103     }
1104 dpavlin 24
1105    
1106     /*****************************************************************************/
1107    
1108    
1109 dpavlin 14 X(end_of_page)
1110     {
1111     /* Update the PC: (offset 0, but on the next page) */
1112     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1) <<
1113     SPARC_INSTR_ALIGNMENT_SHIFT);
1114     cpu->pc += (SPARC_IC_ENTRIES_PER_PAGE <<
1115     SPARC_INSTR_ALIGNMENT_SHIFT);
1116    
1117     /* Find the new physical page and update the translation pointers: */
1118 dpavlin 24 quick_pc_to_pointers(cpu);
1119 dpavlin 14
1120     /* end_of_page doesn't count as an executed instruction: */
1121     cpu->n_translated_instrs --;
1122     }
1123    
1124    
1125 dpavlin 24 X(end_of_page2)
1126     {
1127     /* Synchronize PC on the _second_ instruction on the next page: */
1128     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
1129     / sizeof(struct sparc_instr_call);
1130     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
1131     << SPARC_INSTR_ALIGNMENT_SHIFT);
1132     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
1133    
1134     /* This doesn't count as an executed instruction. */
1135     cpu->n_translated_instrs --;
1136    
1137     quick_pc_to_pointers(cpu);
1138    
1139     if (cpu->delay_slot == NOT_DELAYED)
1140     return;
1141    
1142     fatal("end_of_page2: fatal error, we're in a delay slot\n");
1143     exit(1);
1144     }
1145    
1146    
1147 dpavlin 14 /*****************************************************************************/
1148    
1149    
1150     /*
1151     * sparc_instr_to_be_translated():
1152     *
1153 dpavlin 24 * Translate an instruction word into a sparc_instr_call. ic is filled in with
1154 dpavlin 14 * valid data for the translated instruction, or a "nothing" instruction if
1155     * there was a translation failure. The newly translated instruction is then
1156     * executed.
1157     */
1158     X(to_be_translated)
1159     {
1160 dpavlin 24 MODE_uint_t addr;
1161 dpavlin 28 int low_pc, in_crosspage_delayslot = 0;
1162 dpavlin 14 uint32_t iword;
1163     unsigned char *page;
1164     unsigned char ib[4];
1165 dpavlin 24 int main_opcode, op2, rd, rs1, rs2, btype, asi, cc, p, use_imm, x64 = 0;
1166 dpavlin 28 int store, signedness, size;
1167 dpavlin 24 int32_t tmpi32, siconst;
1168 dpavlin 20 /* void (*samepage_function)(struct cpu *, struct sparc_instr_call *);*/
1169 dpavlin 14
1170     /* Figure out the (virtual) address of the instruction: */
1171     low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
1172     / sizeof(struct sparc_instr_call);
1173 dpavlin 24
1174     /* Special case for branch with delayslot on the next page: */
1175     if (cpu->delay_slot == TO_BE_DELAYED && low_pc == 0) {
1176     /* fatal("[ delay-slot translation across page "
1177     "boundary ]\n"); */
1178     in_crosspage_delayslot = 1;
1179     }
1180    
1181 dpavlin 14 addr = cpu->pc & ~((SPARC_IC_ENTRIES_PER_PAGE-1)
1182     << SPARC_INSTR_ALIGNMENT_SHIFT);
1183     addr += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
1184     cpu->pc = addr;
1185     addr &= ~((1 << SPARC_INSTR_ALIGNMENT_SHIFT) - 1);
1186    
1187     /* Read the instruction word from memory: */
1188 dpavlin 24 #ifdef MODE32
1189 dpavlin 14 page = cpu->cd.sparc.host_load[addr >> 12];
1190 dpavlin 24 #else
1191     {
1192     const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
1193     const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
1194     const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
1195     uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
1196     uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
1197     uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
1198     DYNTRANS_L3N)) & mask3;
1199     struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.sparc.l1_64[x1];
1200     struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
1201     page = l3->host_load[x3];
1202     }
1203     #endif
1204 dpavlin 14
1205     if (page != NULL) {
1206     /* fatal("TRANSLATION HIT!\n"); */
1207 dpavlin 24 memcpy(ib, page + (addr & 0xffc), sizeof(ib));
1208 dpavlin 14 } else {
1209     /* fatal("TRANSLATION MISS!\n"); */
1210     if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
1211     sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
1212     fatal("to_be_translated(): "
1213     "read failed: TODO\n");
1214     goto bad;
1215     }
1216     }
1217    
1218 dpavlin 24 /* SPARC instruction words are always big-endian. Convert
1219     to host order: */
1220     iword = BE32_TO_HOST( *((uint32_t *)&ib[0]) );
1221 dpavlin 14
1222    
1223     #define DYNTRANS_TO_BE_TRANSLATED_HEAD
1224     #include "cpu_dyntrans.c"
1225     #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
1226    
1227    
1228     /*
1229     * Translate the instruction:
1230     */
1231    
1232 dpavlin 24 main_opcode = iword >> 30;
1233     rd = (iword >> 25) & 31;
1234     btype = rd & (N_SPARC_BRANCH_TYPES - 1);
1235     rs1 = (iword >> 14) & 31;
1236     use_imm = (iword >> 13) & 1;
1237     asi = (iword >> 5) & 0xff;
1238     rs2 = iword & 31;
1239     siconst = (int16_t)((iword & 0x1fff) << 3) >> 3;
1240     op2 = (main_opcode == 0)? ((iword >> 22) & 7) : ((iword >> 19) & 0x3f);
1241     cc = (iword >> 20) & 3;
1242     p = (iword >> 19) & 1;
1243 dpavlin 14
1244     switch (main_opcode) {
1245    
1246 dpavlin 24 case 0: switch (op2) {
1247    
1248 dpavlin 30 case 1: /* branch (icc or xcc) */
1249     tmpi32 = (iword << 13);
1250     tmpi32 >>= 11;
1251     ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1252     /* rd contains the annul bit concatenated with 4 bits
1253     of condition code. cc=0 for icc, 2 for xcc: */
1254     /* TODO: samepage */
1255     switch (rd + (cc << 5)) {
1256     case 0x01: ic->f = instr(be); break;
1257 dpavlin 32 case 0x02: ic->f = instr(ble); break;
1258 dpavlin 30 case 0x03: ic->f = instr(bl); break;
1259 dpavlin 32 case 0x08: ic->f = instr(ba); break;
1260 dpavlin 30 case 0x09: ic->f = instr(bne); break;
1261 dpavlin 32 case 0x0a: ic->f = instr(bg); break;
1262 dpavlin 30 case 0x0b: ic->f = instr(bge); break;
1263 dpavlin 32 case 0x19: ic->f = instr(bne_a); break;
1264 dpavlin 30 case 0x41: ic->f = instr(be_xcc); break;
1265 dpavlin 32 case 0x42: ic->f = instr(ble_xcc);break;
1266 dpavlin 30 case 0x43: ic->f = instr(bl_xcc); break;
1267 dpavlin 32 case 0x48: ic->f = instr(ba); break;
1268 dpavlin 30 case 0x4a: ic->f = instr(bg_xcc); break;
1269 dpavlin 32 case 0x4b: ic->f = instr(bge_xcc);break;
1270 dpavlin 30 default:fatal("Unimplemented branch, 0x%x\n",
1271     rd + (cc<<5));
1272     goto bad;
1273     }
1274     break;
1275    
1276 dpavlin 24 case 2: /* branch (32-bit integer comparison) */
1277     tmpi32 = (iword << 10);
1278     tmpi32 >>= 8;
1279     ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1280     /* rd contains the annul bit concatenated with 4 bits
1281     of condition code: */
1282     /* TODO: samepage */
1283     switch (rd) {
1284 dpavlin 30 case 0x01: ic->f = instr(be); break;
1285     case 0x03: ic->f = instr(bl); break;
1286     case 0x08: ic->f = instr(ba); break;
1287 dpavlin 32 case 0x09: ic->f = instr(bne); break;
1288 dpavlin 30 case 0x0b: ic->f = instr(bge); break;
1289     default:fatal("Unimplemented branch rd=%i\n", rd);
1290     goto bad;
1291 dpavlin 24 }
1292     break;
1293    
1294 dpavlin 30 case 3: /* branch on register, 64-bit integer comparison */
1295     tmpi32 = ((iword & 0x300000) >> 6) | (iword & 0x3fff);
1296     tmpi32 <<= 16;
1297     tmpi32 >>= 14;
1298     ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1299     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs1];
1300     /* TODO: samepage */
1301     switch (btype) {
1302     case 0x05: ic->f = instr(brnz); break;
1303     default:fatal("Unimplemented branch 0x%x\n", rd);
1304     goto bad;
1305     }
1306     break;
1307    
1308 dpavlin 24 case 4: /* sethi */
1309     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rd];
1310     ic->arg[1] = (iword & 0x3fffff) << 10;
1311     ic->f = instr(set);
1312     if (rd == SPARC_ZEROREG)
1313     ic->f = instr(nop);
1314     break;
1315    
1316     default:fatal("TODO: unimplemented op2=%i for main "
1317     "opcode %i\n", op2, main_opcode);
1318     goto bad;
1319     }
1320     break;
1321    
1322     case 1: /* call and link */
1323     tmpi32 = (iword << 2);
1324     ic->arg[0] = (int32_t)tmpi32;
1325     ic->arg[1] = addr & 0xffc;
1326     if (cpu->machine->show_trace_tree)
1327     ic->f = instr(call_trace);
1328     else
1329     ic->f = instr(call);
1330     /* TODO: samepage */
1331     break;
1332    
1333     case 2: switch (op2) {
1334    
1335     case 0: /* add */
1336     case 1: /* and */
1337     case 2: /* or */
1338     case 3: /* xor */
1339     case 4: /* sub */
1340 dpavlin 32 case 5: /* andn */
1341 dpavlin 30 case 14:/* udiv */
1342     case 16:/* addcc */
1343     case 17:/* andcc */
1344 dpavlin 24 case 20:/* subcc (cmp) */
1345     case 37:/* sll */
1346     case 38:/* srl */
1347     case 39:/* sra */
1348 dpavlin 28 case 60:/* save */
1349 dpavlin 24 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1350     ic->f = NULL;
1351     if (use_imm) {
1352     ic->arg[1] = siconst;
1353     switch (op2) {
1354     case 0: ic->f = instr(add_imm); break;
1355     case 1: ic->f = instr(and_imm); break;
1356     case 2: ic->f = instr(or_imm); break;
1357     case 3: ic->f = instr(xor_imm); break;
1358     case 4: ic->f = instr(sub_imm); break;
1359 dpavlin 32 case 5: ic->f = instr(andn_imm); break;
1360 dpavlin 30 case 14:ic->f = instr(udiv_imm); break;
1361     case 16:ic->f = instr(addcc_imm); break;
1362     case 17:ic->f = instr(andcc_imm); break;
1363 dpavlin 24 case 20:ic->f = instr(subcc_imm); break;
1364     case 37:if (siconst & 0x1000) {
1365     ic->f = instr(sllx_imm);
1366     ic->arg[1] &= 63;
1367     x64 = 1;
1368     } else {
1369     ic->f = instr(sll_imm);
1370     ic->arg[1] &= 31;
1371     }
1372     break;
1373     case 38:if (siconst & 0x1000) {
1374     ic->f = instr(srlx_imm);
1375     ic->arg[1] &= 63;
1376     x64 = 1;
1377     } else {
1378     ic->f = instr(srl_imm);
1379     ic->arg[1] &= 31;
1380     }
1381     break;
1382     case 39:if (siconst & 0x1000) {
1383     ic->f = instr(srax_imm);
1384     ic->arg[1] &= 63;
1385     x64 = 1;
1386     } else {
1387     ic->f = instr(sra_imm);
1388     ic->arg[1] &= 31;
1389     }
1390     break;
1391 dpavlin 28 case 60:switch (cpu->cd.sparc.cpu_type.v) {
1392     case 9: ic->f = instr(save_v9_imm);
1393     break;
1394     default:fatal("only for v9 so far\n");
1395     goto bad;
1396     }
1397 dpavlin 24 }
1398     } else {
1399     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1400     switch (op2) {
1401     case 0: ic->f = instr(add); break;
1402     case 1: ic->f = instr(and); break;
1403     case 2: ic->f = instr(or); break;
1404     case 3: ic->f = instr(xor); break;
1405     case 4: ic->f = instr(sub); break;
1406 dpavlin 32 case 5: ic->f = instr(andn); break;
1407 dpavlin 30 case 14:ic->f = instr(udiv); break;
1408     case 16:ic->f = instr(addcc); break;
1409     case 17:ic->f = instr(andcc); break;
1410 dpavlin 24 case 20:ic->f = instr(subcc); break;
1411     case 37:if (siconst & 0x1000) {
1412     ic->f = instr(sllx);
1413     x64 = 1;
1414     } else
1415     ic->f = instr(sll);
1416     break;
1417     case 38:if (siconst & 0x1000) {
1418     ic->f = instr(srlx);
1419     x64 = 1;
1420     } else
1421     ic->f = instr(srl);
1422     break;
1423     case 39:if (siconst & 0x1000) {
1424     ic->f = instr(srax);
1425     x64 = 1;
1426     } else
1427     ic->f = instr(sra);
1428     break;
1429     }
1430     }
1431     if (ic->f == NULL) {
1432     fatal("TODO: Unimplemented instruction "
1433     "(possibly missed use_imm impl.)\n");
1434     goto bad;
1435     }
1436     ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1437     if (rd == SPARC_ZEROREG) {
1438 dpavlin 28 /*
1439     * Some opcodes should write to the scratch
1440     * register instead of becoming NOPs, when
1441     * rd is the zero register.
1442 dpavlin 30 *
1443     * Any opcode which updates the condition
1444     * codes, or anything which changes register
1445     * windows.
1446 dpavlin 28 */
1447 dpavlin 24 switch (op2) {
1448 dpavlin 30 case 16:/* addcc */
1449     case 17:/* andcc */
1450 dpavlin 24 case 20:/* subcc */
1451 dpavlin 28 case 60:/* save */
1452 dpavlin 24 ic->arg[2] = (size_t)
1453     &cpu->cd.sparc.scratch;
1454     break;
1455     default:ic->f = instr(nop);
1456     }
1457     }
1458     break;
1459    
1460     case 41:/* rd %psr,%gpr on pre-sparcv9 */
1461     if (cpu->is_32bit) {
1462     ic->f = instr(rd_psr);
1463     ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1464     if (rd == SPARC_ZEROREG)
1465     ic->f = instr(nop);
1466     } else {
1467     fatal("opcode 2,41 not yet implemented"
1468     " for 64-bit cpus\n");
1469     goto bad;
1470     }
1471     break;
1472    
1473 dpavlin 30 case 42:/* rdpr on sparcv9 */
1474     if (cpu->is_32bit) {
1475     fatal("opcode 2,42 not yet implemented"
1476     " for 32-bit cpus\n");
1477     goto bad;
1478     }
1479     ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1480     if (rd == SPARC_ZEROREG)
1481     ic->f = instr(nop);
1482     switch (rs1) {
1483     case 5: ic->f = instr(rdpr_tba); break;
1484     case 31: ic->f = instr(rdpr_ver); break;
1485     default:fatal("Unimplemented rs1=%i\n", rs1);
1486     goto bad;
1487     }
1488     break;
1489    
1490 dpavlin 36 case 43:if (iword == 0x81580000) {
1491     ic->f = instr(flushw);
1492     } else {
1493     fatal("Unimplemented iword=0x%08"PRIx32"\n",
1494     iword);
1495     goto bad;
1496     }
1497     break;
1498    
1499 dpavlin 24 case 48:/* wr (Note: works as xor) */
1500     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1501     if (use_imm) {
1502     ic->arg[1] = siconst;
1503     ic->f = instr(xor_imm);
1504     } else {
1505     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1506     ic->f = instr(xor);
1507     }
1508     ic->arg[2] = (size_t) NULL;
1509     switch (rd) {
1510     case 0: ic->arg[2] = (size_t)&cpu->cd.sparc.y;
1511     break;
1512     case 6: ic->arg[2] = (size_t)&cpu->cd.sparc.fprs;
1513     break;
1514     case 0x17:
1515     ic->arg[2] = (size_t)&cpu->cd.sparc.tick_cmpr;
1516     break;
1517     }
1518     if (ic->arg[2] == (size_t)NULL) {
1519     fatal("TODO: Unimplemented wr instruction, "
1520     "rd = 0x%02x\n", rd);
1521     goto bad;
1522     }
1523     break;
1524    
1525     case 50:/* wrpr (Note: works as xor) */
1526     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1527     ic->f = NULL;
1528     if (use_imm) {
1529     ic->arg[1] = siconst;
1530     switch (rd) {
1531     case 4: ic->f = instr(wrpr_tick_imm); break;
1532     case 6: ic->f = instr(wrpr_pstate_imm); break;
1533     case 8: ic->f = instr(wrpr_pil_imm); break;
1534 dpavlin 36 case 12:ic->f = instr(wrpr_cleanwin_imm);break;
1535 dpavlin 24 }
1536     } else {
1537     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1538     switch (rd) {
1539     case 4: ic->f = instr(wrpr_tick); break;
1540     case 6: ic->f = instr(wrpr_pstate); break;
1541     case 8: ic->f = instr(wrpr_pil); break;
1542 dpavlin 36 case 12:ic->f = instr(wrpr_cleanwin); break;
1543 dpavlin 24 }
1544     }
1545     if (ic->f == NULL) {
1546     fatal("TODO: Unimplemented wrpr instruction,"
1547     " rd = 0x%02x\n", rd);
1548     goto bad;
1549     }
1550     break;
1551    
1552     case 56:/* jump and link */
1553     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1554     ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1555     if (rd == SPARC_ZEROREG)
1556     ic->arg[2] = (size_t)&cpu->cd.sparc.scratch;
1557    
1558     if (use_imm) {
1559     ic->arg[1] = siconst;
1560     if (rd == SPARC_ZEROREG)
1561     ic->f = instr(jmpl_imm_no_rd);
1562     else
1563     ic->f = instr(jmpl_imm);
1564     } else {
1565     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1566     if (rd == SPARC_ZEROREG)
1567     ic->f = instr(jmpl_reg_no_rd);
1568     else
1569     ic->f = instr(jmpl_reg);
1570     }
1571    
1572     /* special trace case: */
1573     if (cpu->machine->show_trace_tree) {
1574     if (iword == 0x81c3e008)
1575     ic->f = instr(retl_trace);
1576     else {
1577     if (use_imm)
1578     ic->f = instr(jmpl_imm_trace);
1579     else
1580     ic->f = instr(jmpl_reg_trace);
1581     }
1582     }
1583     break;
1584    
1585 dpavlin 32 case 57:/* return */
1586     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1587    
1588     if (use_imm) {
1589     ic->arg[1] = siconst;
1590     ic->f = instr(return_imm);
1591     } else {
1592     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1593     ic->f = instr(return_reg);
1594     }
1595    
1596     /* special trace case: */
1597     if (cpu->machine->show_trace_tree) {
1598     if (use_imm)
1599     ic->f = instr(return_imm_trace);
1600     else
1601     ic->f = instr(return_reg_trace);
1602     }
1603     break;
1604    
1605 dpavlin 24 default:fatal("TODO: unimplemented op2=%i for main "
1606     "opcode %i\n", op2, main_opcode);
1607     goto bad;
1608     }
1609     break;
1610    
1611 dpavlin 28 case 3: switch (op2) {
1612    
1613     case 0:/* lduw */
1614     case 1:/* ldub */
1615     case 2:/* lduh */
1616     case 4:/* st(w) */
1617     case 5:/* stb */
1618     case 6:/* sth */
1619     case 8:/* ldsw */
1620     case 9:/* ldsb */
1621     case 10:/* ldsh */
1622     case 11:/* ldx */
1623     case 14:/* stx */
1624     store = 1; signedness = 0; size = 3;
1625     switch (op2) {
1626     case 0: /* lduw */ store=0; size=2; break;
1627     case 1: /* ldub */ store=0; size=0; break;
1628     case 2: /* lduh */ store=0; size=1; break;
1629     case 4: /* st */ size = 2; break;
1630     case 5: /* stb */ size = 0; break;
1631     case 6: /* sth */ size = 1; break;
1632     case 8: /* ldsw */ store=0; size=2; signedness=1;
1633     break;
1634     case 9: /* ldsb */ store=0; size=0; signedness=1;
1635     break;
1636     case 10: /* ldsh */ store=0; size=1; signedness=1;
1637     break;
1638     case 11: /* ldx */ store=0; break;
1639     case 14: /* stx */ break;
1640     }
1641     ic->f =
1642     #ifdef MODE32
1643     sparc32_loadstore
1644     #else
1645     sparc_loadstore
1646     #endif
1647     [ use_imm*16 + store*8 + size*2 + signedness ];
1648    
1649     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rd];
1650     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs1];
1651     if (use_imm)
1652     ic->arg[2] = siconst;
1653     else
1654     ic->arg[2] = (size_t)&cpu->cd.sparc.r[rs2];
1655    
1656     if (!store && rd == SPARC_ZEROREG)
1657     ic->arg[0] = (size_t)&cpu->cd.sparc.scratch;
1658    
1659     break;
1660    
1661     default:fatal("TODO: unimplemented op2=%i for main "
1662     "opcode %i\n", op2, main_opcode);
1663     goto bad;
1664     }
1665     break;
1666    
1667 dpavlin 14 }
1668    
1669    
1670 dpavlin 24 if (x64 && cpu->is_32bit) {
1671     fatal("TODO: 64-bit instr on 32-bit cpu\n");
1672     goto bad;
1673     }
1674    
1675    
1676 dpavlin 14 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
1677     #include "cpu_dyntrans.c"
1678     #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
1679     }
1680    

  ViewVC Help
Powered by ViewVC 1.1.26