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

Legend:
Removed from v.14  
changed lines
  Added in v.36

  ViewVC Help
Powered by ViewVC 1.1.26