/[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

Diff of /trunk/src/cpus/cpu_sparc_instr.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 34 by dpavlin, Mon Oct 8 16:21:17 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_sparc_instr.c,v 1.3 2005/11/06 22:41:12 debug Exp $   *  $Id: cpu_sparc_instr.c,v 1.26 2006/12/30 13:30:55 debug Exp $
29   *   *
30   *  SPARC instructions.   *  SPARC instructions.
31   *   *
# Line 37  Line 37 
37    
38    
39  /*  /*
40     *  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   *  nop:  Do nothing.   *  nop:  Do nothing.
53   */   */
54  X(nop)  X(nop)
# Line 47  X(nop) Line 59  X(nop)
59  /*****************************************************************************/  /*****************************************************************************/
60    
61    
62    /*
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     *  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     *  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     *  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     *  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     *  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     *  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     *  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     *  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     *  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    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    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    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    
853    
854    /*
855     *  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     *  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    #include "tmp_sparc_loadstore.c"
1020    
1021    
1022    /*
1023     *  rd:  Read special register
1024     *
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     *  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     *  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  X(end_of_page)  X(end_of_page)
1086  {  {
1087          /*  Update the PC:  (offset 0, but on the next page)  */          /*  Update the PC:  (offset 0, but on the next page)  */
# Line 56  X(end_of_page) Line 1091  X(end_of_page)
1091              SPARC_INSTR_ALIGNMENT_SHIFT);              SPARC_INSTR_ALIGNMENT_SHIFT);
1092    
1093          /*  Find the new physical page and update the translation pointers:  */          /*  Find the new physical page and update the translation pointers:  */
1094          DYNTRANS_PC_TO_POINTERS(cpu);          quick_pc_to_pointers(cpu);
1095    
1096          /*  end_of_page doesn't count as an executed instruction:  */          /*  end_of_page doesn't count as an executed instruction:  */
1097          cpu->n_translated_instrs --;          cpu->n_translated_instrs --;
1098  }  }
1099    
1100    
1101    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  /*****************************************************************************/  /*****************************************************************************/
1124    
1125    
1126  /*  /*
1127   *  sparc_instr_to_be_translated():   *  sparc_instr_to_be_translated():
1128   *   *
1129   *  Translate an instruction word into an sparc_instr_call. ic is filled in with   *  Translate an instruction word into a sparc_instr_call. ic is filled in with
1130   *  valid data for the translated instruction, or a "nothing" instruction if   *  valid data for the translated instruction, or a "nothing" instruction if
1131   *  there was a translation failure. The newly translated instruction is then   *  there was a translation failure. The newly translated instruction is then
1132   *  executed.   *  executed.
1133   */   */
1134  X(to_be_translated)  X(to_be_translated)
1135  {  {
1136          uint64_t addr, low_pc;          MODE_uint_t addr;
1137            int low_pc, in_crosspage_delayslot = 0;
1138          uint32_t iword;          uint32_t iword;
1139          unsigned char *page;          unsigned char *page;
1140          unsigned char ib[4];          unsigned char ib[4];
1141          int main_opcode;          int main_opcode, op2, rd, rs1, rs2, btype, asi, cc, p, use_imm, x64 = 0;
1142            int store, signedness, size;
1143            int32_t tmpi32, siconst;
1144          /* void (*samepage_function)(struct cpu *, struct sparc_instr_call *);*/          /* void (*samepage_function)(struct cpu *, struct sparc_instr_call *);*/
1145    
1146          /*  Figure out the (virtual) address of the instruction:  */          /*  Figure out the (virtual) address of the instruction:  */
1147          low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)          low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
1148              / sizeof(struct sparc_instr_call);              / sizeof(struct sparc_instr_call);
1149    
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          addr = cpu->pc & ~((SPARC_IC_ENTRIES_PER_PAGE-1)          addr = cpu->pc & ~((SPARC_IC_ENTRIES_PER_PAGE-1)
1158              << SPARC_INSTR_ALIGNMENT_SHIFT);              << SPARC_INSTR_ALIGNMENT_SHIFT);
1159          addr += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);          addr += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
# Line 93  X(to_be_translated) Line 1161  X(to_be_translated)
1161          addr &= ~((1 << SPARC_INSTR_ALIGNMENT_SHIFT) - 1);          addr &= ~((1 << SPARC_INSTR_ALIGNMENT_SHIFT) - 1);
1162    
1163          /*  Read the instruction word from memory:  */          /*  Read the instruction word from memory:  */
1164    #ifdef MODE32
1165          page = cpu->cd.sparc.host_load[addr >> 12];          page = cpu->cd.sparc.host_load[addr >> 12];
1166    #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    
1181          if (page != NULL) {          if (page != NULL) {
1182                  /*  fatal("TRANSLATION HIT!\n");  */                  /*  fatal("TRANSLATION HIT!\n");  */
1183                  memcpy(ib, page + (addr & 0xfff), sizeof(ib));                  memcpy(ib, page + (addr & 0xffc), sizeof(ib));
1184          } else {          } else {
1185                  /*  fatal("TRANSLATION MISS!\n");  */                  /*  fatal("TRANSLATION MISS!\n");  */
1186                  if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,                  if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
# Line 108  X(to_be_translated) Line 1191  X(to_be_translated)
1191                  }                  }
1192          }          }
1193    
1194          iword = *((uint32_t *)&ib[0]);          /*  SPARC instruction words are always big-endian. Convert
1195                to host order:  */
1196  #ifdef HOST_LITTLE_ENDIAN          iword = BE32_TO_HOST( *((uint32_t *)&ib[0]) );
         iword = ((iword & 0xff) << 24) |  
                 ((iword & 0xff00) << 8) |  
                 ((iword & 0xff0000) >> 8) |  
                 ((iword & 0xff000000) >> 24);  
 #endif  
1197    
1198    
1199  #define DYNTRANS_TO_BE_TRANSLATED_HEAD  #define DYNTRANS_TO_BE_TRANSLATED_HEAD
# Line 127  X(to_be_translated) Line 1205  X(to_be_translated)
1205           *  Translate the instruction:           *  Translate the instruction:
1206           */           */
1207    
1208          main_opcode = iword >> 26;          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    
1220          switch (main_opcode) {          switch (main_opcode) {
1221    
1222          default:goto bad;          case 0: switch (op2) {
1223    
1224                    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                            case 0x02:      ic->f = instr(ble); break;
1234                            case 0x03:      ic->f = instr(bl);  break;
1235                            case 0x08:      ic->f = instr(ba);  break;
1236                            case 0x09:      ic->f = instr(bne); break;
1237                            case 0x0a:      ic->f = instr(bg);  break;
1238                            case 0x0b:      ic->f = instr(bge); break;
1239                            case 0x19:      ic->f = instr(bne_a);  break;
1240                            case 0x41:      ic->f = instr(be_xcc); break;
1241                            case 0x42:      ic->f = instr(ble_xcc);break;
1242                            case 0x43:      ic->f = instr(bl_xcc); break;
1243                            case 0x48:      ic->f = instr(ba);     break;
1244                            case 0x4a:      ic->f = instr(bg_xcc); break;
1245                            case 0x4b:      ic->f = instr(bge_xcc);break;
1246                            default:fatal("Unimplemented branch, 0x%x\n",
1247                                        rd + (cc<<5));
1248                                    goto bad;
1249                            }
1250                            break;
1251    
1252                    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                            case 0x01:      ic->f = instr(be);  break;
1261                            case 0x03:      ic->f = instr(bl);  break;
1262                            case 0x08:      ic->f = instr(ba);  break;
1263                            case 0x09:      ic->f = instr(bne); break;
1264                            case 0x0b:      ic->f = instr(bge); break;
1265                            default:fatal("Unimplemented branch rd=%i\n", rd);
1266                                    goto bad;
1267                            }
1268                            break;
1269    
1270                    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                    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                    case 5: /*  andn  */
1317                    case 14:/*  udiv  */
1318                    case 16:/*  addcc  */
1319                    case 17:/*  andcc  */
1320                    case 20:/*  subcc (cmp)  */
1321                    case 37:/*  sll  */
1322                    case 38:/*  srl  */
1323                    case 39:/*  sra  */
1324                    case 60:/*  save  */
1325                            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                                    case 5: ic->f = instr(andn_imm); break;
1336                                    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                                    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                                    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                                    }
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                                    case 5: ic->f = instr(andn); break;
1383                                    case 14:ic->f = instr(udiv); break;
1384                                    case 16:ic->f = instr(addcc); break;
1385                                    case 17:ic->f = instr(andcc); break;
1386                                    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                                    /*
1415                                     *  Some opcodes should write to the scratch
1416                                     *  register instead of becoming NOPs, when
1417                                     *  rd is the zero register.
1418                                     *
1419                                     *  Any opcode which updates the condition
1420                                     *  codes, or anything which changes register
1421                                     *  windows.
1422                                     */
1423                                    switch (op2) {
1424                                    case 16:/*  addcc  */
1425                                    case 17:/*  andcc  */
1426                                    case 20:/*  subcc  */
1427                                    case 60:/*  save  */
1428                                            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                    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                    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                    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                    default:fatal("TODO: unimplemented op2=%i for main "
1571                                "opcode %i\n", op2, main_opcode);
1572                            goto bad;
1573                    }
1574                    break;
1575    
1576            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            }
1633    
1634    
1635            if (x64 && cpu->is_32bit) {
1636                    fatal("TODO: 64-bit instr on 32-bit cpu\n");
1637                    goto bad;
1638          }          }
1639    
1640    

Legend:
Removed from v.20  
changed lines
  Added in v.34

  ViewVC Help
Powered by ViewVC 1.1.26