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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 35 - (hide annotations)
Mon Oct 8 16:21:26 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 45218 byte(s)
0.4.4
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 34 * $Id: cpu_sparc_instr.c,v 1.26 2006/12/30 13:30:55 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 30 * rd: Read special register
1024 dpavlin 24 *
1025     * arg[2] = ptr to rd
1026     */
1027     X(rd_psr)
1028     {
1029     reg(ic->arg[2]) = cpu->cd.sparc.psr;
1030     }
1031    
1032    
1033     /*
1034 dpavlin 30 * rdpr: Read privileged register
1035     *
1036     * arg[2] = ptr to rd
1037     */
1038     X(rdpr_tba)
1039     {
1040     reg(ic->arg[2]) = cpu->cd.sparc.tba;
1041     }
1042     X(rdpr_ver)
1043     {
1044     reg(ic->arg[2]) = cpu->cd.sparc.ver;
1045     }
1046    
1047    
1048     /*
1049 dpavlin 24 * wrpr: Write to privileged register
1050     *
1051     * arg[0] = ptr to rs1
1052     * arg[1] = ptr to rs2 or an immediate value (int32_t)
1053     */
1054     X(wrpr_tick)
1055     {
1056     cpu->cd.sparc.tick = (uint32_t) (reg(ic->arg[0]) ^ reg(ic->arg[1]));
1057     }
1058     X(wrpr_tick_imm)
1059     {
1060     cpu->cd.sparc.tick = (uint32_t) (reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
1061     }
1062     X(wrpr_pil)
1063     {
1064     cpu->cd.sparc.pil = (reg(ic->arg[0]) ^ reg(ic->arg[1]))
1065     & SPARC_PIL_MASK;
1066     }
1067     X(wrpr_pil_imm)
1068     {
1069     cpu->cd.sparc.pil = (reg(ic->arg[0]) ^ (int32_t)ic->arg[1])
1070     & SPARC_PIL_MASK;
1071     }
1072     X(wrpr_pstate)
1073     {
1074     sparc_update_pstate(cpu, reg(ic->arg[0]) ^ reg(ic->arg[1]));
1075     }
1076     X(wrpr_pstate_imm)
1077     {
1078     sparc_update_pstate(cpu, reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
1079     }
1080    
1081    
1082     /*****************************************************************************/
1083    
1084    
1085 dpavlin 14 X(end_of_page)
1086     {
1087     /* Update the PC: (offset 0, but on the next page) */
1088     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1) <<
1089     SPARC_INSTR_ALIGNMENT_SHIFT);
1090     cpu->pc += (SPARC_IC_ENTRIES_PER_PAGE <<
1091     SPARC_INSTR_ALIGNMENT_SHIFT);
1092    
1093     /* Find the new physical page and update the translation pointers: */
1094 dpavlin 24 quick_pc_to_pointers(cpu);
1095 dpavlin 14
1096     /* end_of_page doesn't count as an executed instruction: */
1097     cpu->n_translated_instrs --;
1098     }
1099    
1100    
1101 dpavlin 24 X(end_of_page2)
1102     {
1103     /* Synchronize PC on the _second_ instruction on the next page: */
1104     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
1105     / sizeof(struct sparc_instr_call);
1106     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
1107     << SPARC_INSTR_ALIGNMENT_SHIFT);
1108     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
1109    
1110     /* This doesn't count as an executed instruction. */
1111     cpu->n_translated_instrs --;
1112    
1113     quick_pc_to_pointers(cpu);
1114    
1115     if (cpu->delay_slot == NOT_DELAYED)
1116     return;
1117    
1118     fatal("end_of_page2: fatal error, we're in a delay slot\n");
1119     exit(1);
1120     }
1121    
1122    
1123 dpavlin 14 /*****************************************************************************/
1124    
1125    
1126     /*
1127     * sparc_instr_to_be_translated():
1128     *
1129 dpavlin 24 * Translate an instruction word into a sparc_instr_call. ic is filled in with
1130 dpavlin 14 * valid data for the translated instruction, or a "nothing" instruction if
1131     * there was a translation failure. The newly translated instruction is then
1132     * executed.
1133     */
1134     X(to_be_translated)
1135     {
1136 dpavlin 24 MODE_uint_t addr;
1137 dpavlin 28 int low_pc, in_crosspage_delayslot = 0;
1138 dpavlin 14 uint32_t iword;
1139     unsigned char *page;
1140     unsigned char ib[4];
1141 dpavlin 24 int main_opcode, op2, rd, rs1, rs2, btype, asi, cc, p, use_imm, x64 = 0;
1142 dpavlin 28 int store, signedness, size;
1143 dpavlin 24 int32_t tmpi32, siconst;
1144 dpavlin 20 /* void (*samepage_function)(struct cpu *, struct sparc_instr_call *);*/
1145 dpavlin 14
1146     /* Figure out the (virtual) address of the instruction: */
1147     low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
1148     / sizeof(struct sparc_instr_call);
1149 dpavlin 24
1150     /* Special case for branch with delayslot on the next page: */
1151     if (cpu->delay_slot == TO_BE_DELAYED && low_pc == 0) {
1152     /* fatal("[ delay-slot translation across page "
1153     "boundary ]\n"); */
1154     in_crosspage_delayslot = 1;
1155     }
1156    
1157 dpavlin 14 addr = cpu->pc & ~((SPARC_IC_ENTRIES_PER_PAGE-1)
1158     << SPARC_INSTR_ALIGNMENT_SHIFT);
1159     addr += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
1160     cpu->pc = addr;
1161     addr &= ~((1 << SPARC_INSTR_ALIGNMENT_SHIFT) - 1);
1162    
1163     /* Read the instruction word from memory: */
1164 dpavlin 24 #ifdef MODE32
1165 dpavlin 14 page = cpu->cd.sparc.host_load[addr >> 12];
1166 dpavlin 24 #else
1167     {
1168     const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
1169     const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
1170     const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
1171     uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
1172     uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
1173     uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
1174     DYNTRANS_L3N)) & mask3;
1175     struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.sparc.l1_64[x1];
1176     struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
1177     page = l3->host_load[x3];
1178     }
1179     #endif
1180 dpavlin 14
1181     if (page != NULL) {
1182     /* fatal("TRANSLATION HIT!\n"); */
1183 dpavlin 24 memcpy(ib, page + (addr & 0xffc), sizeof(ib));
1184 dpavlin 14 } else {
1185     /* fatal("TRANSLATION MISS!\n"); */
1186     if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
1187     sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
1188     fatal("to_be_translated(): "
1189     "read failed: TODO\n");
1190     goto bad;
1191     }
1192     }
1193    
1194 dpavlin 24 /* SPARC instruction words are always big-endian. Convert
1195     to host order: */
1196     iword = BE32_TO_HOST( *((uint32_t *)&ib[0]) );
1197 dpavlin 14
1198    
1199     #define DYNTRANS_TO_BE_TRANSLATED_HEAD
1200     #include "cpu_dyntrans.c"
1201     #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
1202    
1203    
1204     /*
1205     * Translate the instruction:
1206     */
1207    
1208 dpavlin 24 main_opcode = iword >> 30;
1209     rd = (iword >> 25) & 31;
1210     btype = rd & (N_SPARC_BRANCH_TYPES - 1);
1211     rs1 = (iword >> 14) & 31;
1212     use_imm = (iword >> 13) & 1;
1213     asi = (iword >> 5) & 0xff;
1214     rs2 = iword & 31;
1215     siconst = (int16_t)((iword & 0x1fff) << 3) >> 3;
1216     op2 = (main_opcode == 0)? ((iword >> 22) & 7) : ((iword >> 19) & 0x3f);
1217     cc = (iword >> 20) & 3;
1218     p = (iword >> 19) & 1;
1219 dpavlin 14
1220     switch (main_opcode) {
1221    
1222 dpavlin 24 case 0: switch (op2) {
1223    
1224 dpavlin 30 case 1: /* branch (icc or xcc) */
1225     tmpi32 = (iword << 13);
1226     tmpi32 >>= 11;
1227     ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1228     /* rd contains the annul bit concatenated with 4 bits
1229     of condition code. cc=0 for icc, 2 for xcc: */
1230     /* TODO: samepage */
1231     switch (rd + (cc << 5)) {
1232     case 0x01: ic->f = instr(be); break;
1233 dpavlin 32 case 0x02: ic->f = instr(ble); break;
1234 dpavlin 30 case 0x03: ic->f = instr(bl); break;
1235 dpavlin 32 case 0x08: ic->f = instr(ba); break;
1236 dpavlin 30 case 0x09: ic->f = instr(bne); break;
1237 dpavlin 32 case 0x0a: ic->f = instr(bg); break;
1238 dpavlin 30 case 0x0b: ic->f = instr(bge); break;
1239 dpavlin 32 case 0x19: ic->f = instr(bne_a); break;
1240 dpavlin 30 case 0x41: ic->f = instr(be_xcc); break;
1241 dpavlin 32 case 0x42: ic->f = instr(ble_xcc);break;
1242 dpavlin 30 case 0x43: ic->f = instr(bl_xcc); break;
1243 dpavlin 32 case 0x48: ic->f = instr(ba); break;
1244 dpavlin 30 case 0x4a: ic->f = instr(bg_xcc); break;
1245 dpavlin 32 case 0x4b: ic->f = instr(bge_xcc);break;
1246 dpavlin 30 default:fatal("Unimplemented branch, 0x%x\n",
1247     rd + (cc<<5));
1248     goto bad;
1249     }
1250     break;
1251    
1252 dpavlin 24 case 2: /* branch (32-bit integer comparison) */
1253     tmpi32 = (iword << 10);
1254     tmpi32 >>= 8;
1255     ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1256     /* rd contains the annul bit concatenated with 4 bits
1257     of condition code: */
1258     /* TODO: samepage */
1259     switch (rd) {
1260 dpavlin 30 case 0x01: ic->f = instr(be); break;
1261     case 0x03: ic->f = instr(bl); break;
1262     case 0x08: ic->f = instr(ba); break;
1263 dpavlin 32 case 0x09: ic->f = instr(bne); break;
1264 dpavlin 30 case 0x0b: ic->f = instr(bge); break;
1265     default:fatal("Unimplemented branch rd=%i\n", rd);
1266     goto bad;
1267 dpavlin 24 }
1268     break;
1269    
1270 dpavlin 30 case 3: /* branch on register, 64-bit integer comparison */
1271     tmpi32 = ((iword & 0x300000) >> 6) | (iword & 0x3fff);
1272     tmpi32 <<= 16;
1273     tmpi32 >>= 14;
1274     ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1275     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs1];
1276     /* TODO: samepage */
1277     switch (btype) {
1278     case 0x05: ic->f = instr(brnz); break;
1279     default:fatal("Unimplemented branch 0x%x\n", rd);
1280     goto bad;
1281     }
1282     break;
1283    
1284 dpavlin 24 case 4: /* sethi */
1285     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rd];
1286     ic->arg[1] = (iword & 0x3fffff) << 10;
1287     ic->f = instr(set);
1288     if (rd == SPARC_ZEROREG)
1289     ic->f = instr(nop);
1290     break;
1291    
1292     default:fatal("TODO: unimplemented op2=%i for main "
1293     "opcode %i\n", op2, main_opcode);
1294     goto bad;
1295     }
1296     break;
1297    
1298     case 1: /* call and link */
1299     tmpi32 = (iword << 2);
1300     ic->arg[0] = (int32_t)tmpi32;
1301     ic->arg[1] = addr & 0xffc;
1302     if (cpu->machine->show_trace_tree)
1303     ic->f = instr(call_trace);
1304     else
1305     ic->f = instr(call);
1306     /* TODO: samepage */
1307     break;
1308    
1309     case 2: switch (op2) {
1310    
1311     case 0: /* add */
1312     case 1: /* and */
1313     case 2: /* or */
1314     case 3: /* xor */
1315     case 4: /* sub */
1316 dpavlin 32 case 5: /* andn */
1317 dpavlin 30 case 14:/* udiv */
1318     case 16:/* addcc */
1319     case 17:/* andcc */
1320 dpavlin 24 case 20:/* subcc (cmp) */
1321     case 37:/* sll */
1322     case 38:/* srl */
1323     case 39:/* sra */
1324 dpavlin 28 case 60:/* save */
1325 dpavlin 24 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1326     ic->f = NULL;
1327     if (use_imm) {
1328     ic->arg[1] = siconst;
1329     switch (op2) {
1330     case 0: ic->f = instr(add_imm); break;
1331     case 1: ic->f = instr(and_imm); break;
1332     case 2: ic->f = instr(or_imm); break;
1333     case 3: ic->f = instr(xor_imm); break;
1334     case 4: ic->f = instr(sub_imm); break;
1335 dpavlin 32 case 5: ic->f = instr(andn_imm); break;
1336 dpavlin 30 case 14:ic->f = instr(udiv_imm); break;
1337     case 16:ic->f = instr(addcc_imm); break;
1338     case 17:ic->f = instr(andcc_imm); break;
1339 dpavlin 24 case 20:ic->f = instr(subcc_imm); break;
1340     case 37:if (siconst & 0x1000) {
1341     ic->f = instr(sllx_imm);
1342     ic->arg[1] &= 63;
1343     x64 = 1;
1344     } else {
1345     ic->f = instr(sll_imm);
1346     ic->arg[1] &= 31;
1347     }
1348     break;
1349     case 38:if (siconst & 0x1000) {
1350     ic->f = instr(srlx_imm);
1351     ic->arg[1] &= 63;
1352     x64 = 1;
1353     } else {
1354     ic->f = instr(srl_imm);
1355     ic->arg[1] &= 31;
1356     }
1357     break;
1358     case 39:if (siconst & 0x1000) {
1359     ic->f = instr(srax_imm);
1360     ic->arg[1] &= 63;
1361     x64 = 1;
1362     } else {
1363     ic->f = instr(sra_imm);
1364     ic->arg[1] &= 31;
1365     }
1366     break;
1367 dpavlin 28 case 60:switch (cpu->cd.sparc.cpu_type.v) {
1368     case 9: ic->f = instr(save_v9_imm);
1369     break;
1370     default:fatal("only for v9 so far\n");
1371     goto bad;
1372     }
1373 dpavlin 24 }
1374     } else {
1375     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1376     switch (op2) {
1377     case 0: ic->f = instr(add); break;
1378     case 1: ic->f = instr(and); break;
1379     case 2: ic->f = instr(or); break;
1380     case 3: ic->f = instr(xor); break;
1381     case 4: ic->f = instr(sub); break;
1382 dpavlin 32 case 5: ic->f = instr(andn); break;
1383 dpavlin 30 case 14:ic->f = instr(udiv); break;
1384     case 16:ic->f = instr(addcc); break;
1385     case 17:ic->f = instr(andcc); break;
1386 dpavlin 24 case 20:ic->f = instr(subcc); break;
1387     case 37:if (siconst & 0x1000) {
1388     ic->f = instr(sllx);
1389     x64 = 1;
1390     } else
1391     ic->f = instr(sll);
1392     break;
1393     case 38:if (siconst & 0x1000) {
1394     ic->f = instr(srlx);
1395     x64 = 1;
1396     } else
1397     ic->f = instr(srl);
1398     break;
1399     case 39:if (siconst & 0x1000) {
1400     ic->f = instr(srax);
1401     x64 = 1;
1402     } else
1403     ic->f = instr(sra);
1404     break;
1405     }
1406     }
1407     if (ic->f == NULL) {
1408     fatal("TODO: Unimplemented instruction "
1409     "(possibly missed use_imm impl.)\n");
1410     goto bad;
1411     }
1412     ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1413     if (rd == SPARC_ZEROREG) {
1414 dpavlin 28 /*
1415     * Some opcodes should write to the scratch
1416     * register instead of becoming NOPs, when
1417     * rd is the zero register.
1418 dpavlin 30 *
1419     * Any opcode which updates the condition
1420     * codes, or anything which changes register
1421     * windows.
1422 dpavlin 28 */
1423 dpavlin 24 switch (op2) {
1424 dpavlin 30 case 16:/* addcc */
1425     case 17:/* andcc */
1426 dpavlin 24 case 20:/* subcc */
1427 dpavlin 28 case 60:/* save */
1428 dpavlin 24 ic->arg[2] = (size_t)
1429     &cpu->cd.sparc.scratch;
1430     break;
1431     default:ic->f = instr(nop);
1432     }
1433     }
1434     break;
1435    
1436     case 41:/* rd %psr,%gpr on pre-sparcv9 */
1437     if (cpu->is_32bit) {
1438     ic->f = instr(rd_psr);
1439     ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1440     if (rd == SPARC_ZEROREG)
1441     ic->f = instr(nop);
1442     } else {
1443     fatal("opcode 2,41 not yet implemented"
1444     " for 64-bit cpus\n");
1445     goto bad;
1446     }
1447     break;
1448    
1449 dpavlin 30 case 42:/* rdpr on sparcv9 */
1450     if (cpu->is_32bit) {
1451     fatal("opcode 2,42 not yet implemented"
1452     " for 32-bit cpus\n");
1453     goto bad;
1454     }
1455     ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1456     if (rd == SPARC_ZEROREG)
1457     ic->f = instr(nop);
1458     switch (rs1) {
1459     case 5: ic->f = instr(rdpr_tba); break;
1460     case 31: ic->f = instr(rdpr_ver); break;
1461     default:fatal("Unimplemented rs1=%i\n", rs1);
1462     goto bad;
1463     }
1464     break;
1465    
1466 dpavlin 24 case 48:/* wr (Note: works as xor) */
1467     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1468     if (use_imm) {
1469     ic->arg[1] = siconst;
1470     ic->f = instr(xor_imm);
1471     } else {
1472     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1473     ic->f = instr(xor);
1474     }
1475     ic->arg[2] = (size_t) NULL;
1476     switch (rd) {
1477     case 0: ic->arg[2] = (size_t)&cpu->cd.sparc.y;
1478     break;
1479     case 6: ic->arg[2] = (size_t)&cpu->cd.sparc.fprs;
1480     break;
1481     case 0x17:
1482     ic->arg[2] = (size_t)&cpu->cd.sparc.tick_cmpr;
1483     break;
1484     }
1485     if (ic->arg[2] == (size_t)NULL) {
1486     fatal("TODO: Unimplemented wr instruction, "
1487     "rd = 0x%02x\n", rd);
1488     goto bad;
1489     }
1490     break;
1491    
1492     case 50:/* wrpr (Note: works as xor) */
1493     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1494     ic->f = NULL;
1495     if (use_imm) {
1496     ic->arg[1] = siconst;
1497     switch (rd) {
1498     case 4: ic->f = instr(wrpr_tick_imm); break;
1499     case 6: ic->f = instr(wrpr_pstate_imm); break;
1500     case 8: ic->f = instr(wrpr_pil_imm); break;
1501     }
1502     } else {
1503     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1504     switch (rd) {
1505     case 4: ic->f = instr(wrpr_tick); break;
1506     case 6: ic->f = instr(wrpr_pstate); break;
1507     case 8: ic->f = instr(wrpr_pil); break;
1508     }
1509     }
1510     if (ic->f == NULL) {
1511     fatal("TODO: Unimplemented wrpr instruction,"
1512     " rd = 0x%02x\n", rd);
1513     goto bad;
1514     }
1515     break;
1516    
1517     case 56:/* jump and link */
1518     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1519     ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1520     if (rd == SPARC_ZEROREG)
1521     ic->arg[2] = (size_t)&cpu->cd.sparc.scratch;
1522    
1523     if (use_imm) {
1524     ic->arg[1] = siconst;
1525     if (rd == SPARC_ZEROREG)
1526     ic->f = instr(jmpl_imm_no_rd);
1527     else
1528     ic->f = instr(jmpl_imm);
1529     } else {
1530     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1531     if (rd == SPARC_ZEROREG)
1532     ic->f = instr(jmpl_reg_no_rd);
1533     else
1534     ic->f = instr(jmpl_reg);
1535     }
1536    
1537     /* special trace case: */
1538     if (cpu->machine->show_trace_tree) {
1539     if (iword == 0x81c3e008)
1540     ic->f = instr(retl_trace);
1541     else {
1542     if (use_imm)
1543     ic->f = instr(jmpl_imm_trace);
1544     else
1545     ic->f = instr(jmpl_reg_trace);
1546     }
1547     }
1548     break;
1549    
1550 dpavlin 32 case 57:/* return */
1551     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1552    
1553     if (use_imm) {
1554     ic->arg[1] = siconst;
1555     ic->f = instr(return_imm);
1556     } else {
1557     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1558     ic->f = instr(return_reg);
1559     }
1560    
1561     /* special trace case: */
1562     if (cpu->machine->show_trace_tree) {
1563     if (use_imm)
1564     ic->f = instr(return_imm_trace);
1565     else
1566     ic->f = instr(return_reg_trace);
1567     }
1568     break;
1569    
1570 dpavlin 24 default:fatal("TODO: unimplemented op2=%i for main "
1571     "opcode %i\n", op2, main_opcode);
1572     goto bad;
1573     }
1574     break;
1575    
1576 dpavlin 28 case 3: switch (op2) {
1577    
1578     case 0:/* lduw */
1579     case 1:/* ldub */
1580     case 2:/* lduh */
1581     case 4:/* st(w) */
1582     case 5:/* stb */
1583     case 6:/* sth */
1584     case 8:/* ldsw */
1585     case 9:/* ldsb */
1586     case 10:/* ldsh */
1587     case 11:/* ldx */
1588     case 14:/* stx */
1589     store = 1; signedness = 0; size = 3;
1590     switch (op2) {
1591     case 0: /* lduw */ store=0; size=2; break;
1592     case 1: /* ldub */ store=0; size=0; break;
1593     case 2: /* lduh */ store=0; size=1; break;
1594     case 4: /* st */ size = 2; break;
1595     case 5: /* stb */ size = 0; break;
1596     case 6: /* sth */ size = 1; break;
1597     case 8: /* ldsw */ store=0; size=2; signedness=1;
1598     break;
1599     case 9: /* ldsb */ store=0; size=0; signedness=1;
1600     break;
1601     case 10: /* ldsh */ store=0; size=1; signedness=1;
1602     break;
1603     case 11: /* ldx */ store=0; break;
1604     case 14: /* stx */ break;
1605     }
1606     ic->f =
1607     #ifdef MODE32
1608     sparc32_loadstore
1609     #else
1610     sparc_loadstore
1611     #endif
1612     [ use_imm*16 + store*8 + size*2 + signedness ];
1613    
1614     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rd];
1615     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs1];
1616     if (use_imm)
1617     ic->arg[2] = siconst;
1618     else
1619     ic->arg[2] = (size_t)&cpu->cd.sparc.r[rs2];
1620    
1621     if (!store && rd == SPARC_ZEROREG)
1622     ic->arg[0] = (size_t)&cpu->cd.sparc.scratch;
1623    
1624     break;
1625    
1626     default:fatal("TODO: unimplemented op2=%i for main "
1627     "opcode %i\n", op2, main_opcode);
1628     goto bad;
1629     }
1630     break;
1631    
1632 dpavlin 14 }
1633    
1634    
1635 dpavlin 24 if (x64 && cpu->is_32bit) {
1636     fatal("TODO: 64-bit instr on 32-bit cpu\n");
1637     goto bad;
1638     }
1639    
1640    
1641 dpavlin 14 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
1642     #include "cpu_dyntrans.c"
1643     #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
1644     }
1645    

  ViewVC Help
Powered by ViewVC 1.1.26