/[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 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC revision 30 by dpavlin, Mon Oct 8 16:20:40 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_sparc_instr.c,v 1.5 2006/02/09 22:40:27 debug Exp $   *  $Id: cpu_sparc_instr.c,v 1.23 2006/07/24 22:32:44 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     *  bne
159     *
160     *  arg[0] = int32_t displacement compared to the start of the current page
161     */
162    X(bne)
163    {
164            MODE_uint_t old_pc = cpu->pc;
165            int cond = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 0 : 1;
166            cpu->delay_slot = TO_BE_DELAYED;
167            ic[1].f(cpu, ic+1);
168            cpu->n_translated_instrs ++;
169            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
170                    /*  Note: Must be non-delayed when jumping to the new pc:  */
171                    cpu->delay_slot = NOT_DELAYED;
172                    if (cond) {
173                            old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
174                                << SPARC_INSTR_ALIGNMENT_SHIFT);
175                            cpu->pc = old_pc + (int32_t)ic->arg[0];
176                            quick_pc_to_pointers(cpu);
177                    }
178            } else
179                    cpu->delay_slot = NOT_DELAYED;
180    }
181    X(bne_a)
182    {
183            MODE_uint_t old_pc = cpu->pc;
184            int cond = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 0 : 1;
185            cpu->delay_slot = TO_BE_DELAYED;
186            if (!cond) {
187                    /*  Nullify the delay slot:  */
188                    cpu->cd.sparc.next_ic ++;
189                    return;
190            }
191            ic[1].f(cpu, ic+1);
192            cpu->n_translated_instrs ++;
193            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
194                    /*  Note: Must be non-delayed when jumping to the new pc:  */
195                    cpu->delay_slot = NOT_DELAYED;
196                    old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
197                        << SPARC_INSTR_ALIGNMENT_SHIFT);
198                    cpu->pc = old_pc + (int32_t)ic->arg[0];
199                    quick_pc_to_pointers(cpu);
200            } else
201                    cpu->delay_slot = NOT_DELAYED;
202    }
203    
204    
205    /*
206     *  bg
207     *
208     *  arg[0] = int32_t displacement compared to the start of the current page
209     */
210    X(bg)
211    {
212            MODE_uint_t old_pc = cpu->pc;
213            int n = (cpu->cd.sparc.ccr & SPARC_CCR_N) ? 1 : 0;
214            int v = (cpu->cd.sparc.ccr & SPARC_CCR_V) ? 1 : 0;
215            int z = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 1 : 0;
216            int cond = !(z | (n ^ v));
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(bg_xcc)
233    {
234            MODE_uint_t old_pc = cpu->pc;
235            int n = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_N)? 1:0;
236            int v = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_V)? 1:0;
237            int z = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_Z)? 1:0;
238            int cond = !(z | (n ^ v));
239            cpu->delay_slot = TO_BE_DELAYED;
240            ic[1].f(cpu, ic+1);
241            cpu->n_translated_instrs ++;
242            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
243                    /*  Note: Must be non-delayed when jumping to the new pc:  */
244                    cpu->delay_slot = NOT_DELAYED;
245                    if (cond) {
246                            old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
247                                << SPARC_INSTR_ALIGNMENT_SHIFT);
248                            cpu->pc = old_pc + (int32_t)ic->arg[0];
249                            quick_pc_to_pointers(cpu);
250                    }
251            } else
252                    cpu->delay_slot = NOT_DELAYED;
253    }
254    
255    
256    /*
257     *  bge
258     *
259     *  arg[0] = int32_t displacement compared to the start of the current page
260     */
261    X(bge)
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 cond = !(n ^ v);
267            cpu->delay_slot = TO_BE_DELAYED;
268            ic[1].f(cpu, ic+1);
269            cpu->n_translated_instrs ++;
270            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
271                    /*  Note: Must be non-delayed when jumping to the new pc:  */
272                    cpu->delay_slot = NOT_DELAYED;
273                    if (cond) {
274                            old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
275                                << SPARC_INSTR_ALIGNMENT_SHIFT);
276                            cpu->pc = old_pc + (int32_t)ic->arg[0];
277                            quick_pc_to_pointers(cpu);
278                    }
279            } else
280                    cpu->delay_slot = NOT_DELAYED;
281    }
282    X(bge_xcc)
283    {
284            MODE_uint_t old_pc = cpu->pc;
285            int n = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_N)? 1:0;
286            int v = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_V)? 1:0;
287            int cond = !(n ^ v);
288            cpu->delay_slot = TO_BE_DELAYED;
289            ic[1].f(cpu, ic+1);
290            cpu->n_translated_instrs ++;
291            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
292                    /*  Note: Must be non-delayed when jumping to the new pc:  */
293                    cpu->delay_slot = NOT_DELAYED;
294                    if (cond) {
295                            old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
296                                << SPARC_INSTR_ALIGNMENT_SHIFT);
297                            cpu->pc = old_pc + (int32_t)ic->arg[0];
298                            quick_pc_to_pointers(cpu);
299                    }
300            } else
301                    cpu->delay_slot = NOT_DELAYED;
302    }
303    
304    
305    /*
306     *  be
307     *
308     *  arg[0] = int32_t displacement compared to the start of the current page
309     */
310    X(be)
311    {
312            MODE_uint_t old_pc = cpu->pc;
313            int cond = cpu->cd.sparc.ccr & SPARC_CCR_Z;
314            cpu->delay_slot = TO_BE_DELAYED;
315            ic[1].f(cpu, ic+1);
316            cpu->n_translated_instrs ++;
317            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
318                    /*  Note: Must be non-delayed when jumping to the new pc:  */
319                    cpu->delay_slot = NOT_DELAYED;
320                    if (cond) {
321                            old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
322                                << SPARC_INSTR_ALIGNMENT_SHIFT);
323                            cpu->pc = old_pc + (int32_t)ic->arg[0];
324                            quick_pc_to_pointers(cpu);
325                    }
326            } else
327                    cpu->delay_slot = NOT_DELAYED;
328    }
329    X(be_xcc)
330    {
331            MODE_uint_t old_pc = cpu->pc;
332            int cond = (cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_Z;
333            cpu->delay_slot = TO_BE_DELAYED;
334            ic[1].f(cpu, ic+1);
335            cpu->n_translated_instrs ++;
336            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
337                    /*  Note: Must be non-delayed when jumping to the new pc:  */
338                    cpu->delay_slot = NOT_DELAYED;
339                    if (cond) {
340                            old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
341                                << SPARC_INSTR_ALIGNMENT_SHIFT);
342                            cpu->pc = old_pc + (int32_t)ic->arg[0];
343                            quick_pc_to_pointers(cpu);
344                    }
345            } else
346                    cpu->delay_slot = NOT_DELAYED;
347    }
348    
349    
350    /*
351     *  ba
352     *
353     *  arg[0] = int32_t displacement compared to the start of the current page
354     */
355    X(ba)
356    {
357            MODE_uint_t old_pc = cpu->pc;
358            cpu->delay_slot = TO_BE_DELAYED;
359            ic[1].f(cpu, ic+1);
360            cpu->n_translated_instrs ++;
361            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
362                    /*  Note: Must be non-delayed when jumping to the new pc:  */
363                    cpu->delay_slot = NOT_DELAYED;
364                    old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
365                        << SPARC_INSTR_ALIGNMENT_SHIFT);
366                    cpu->pc = old_pc + (int32_t)ic->arg[0];
367                    quick_pc_to_pointers(cpu);
368            } else
369                    cpu->delay_slot = NOT_DELAYED;
370    }
371    
372    
373    /*
374     *  brnz
375     *
376     *  arg[0] = int32_t displacement compared to the start of the current page
377     *  arg[1] = ptr to rs1
378     */
379    X(brnz)
380    {
381            MODE_uint_t old_pc = cpu->pc;
382            int cond = reg(ic->arg[1]) != 0;
383            cpu->delay_slot = TO_BE_DELAYED;
384            ic[1].f(cpu, ic+1);
385            cpu->n_translated_instrs ++;
386            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
387                    /*  Note: Must be non-delayed when jumping to the new pc:  */
388                    cpu->delay_slot = NOT_DELAYED;
389                    if (cond) {
390                            old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
391                                << SPARC_INSTR_ALIGNMENT_SHIFT);
392                            cpu->pc = old_pc + (int32_t)ic->arg[0];
393                            quick_pc_to_pointers(cpu);
394                    }
395            } else
396                    cpu->delay_slot = NOT_DELAYED;
397    }
398    
399    
400    /*
401     *  Jump and link
402     *
403     *  arg[0] = ptr to rs1
404     *  arg[1] = ptr to rs2 or an immediate value (int32_t)
405     *  arg[2] = ptr to rd
406     */
407    X(jmpl_imm)
408    {
409            int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
410                / sizeof(struct sparc_instr_call);
411            cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
412                << SPARC_INSTR_ALIGNMENT_SHIFT);
413            cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
414            reg(ic->arg[2]) = cpu->pc;
415    
416            cpu->delay_slot = TO_BE_DELAYED;
417            ic[1].f(cpu, ic+1);
418            cpu->n_translated_instrs ++;
419    
420            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
421                    /*  Note: Must be non-delayed when jumping to the new pc:  */
422                    cpu->delay_slot = NOT_DELAYED;
423                    cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
424                    quick_pc_to_pointers(cpu);
425            } else
426                    cpu->delay_slot = NOT_DELAYED;
427    }
428    X(jmpl_imm_no_rd)
429    {
430            int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
431                / sizeof(struct sparc_instr_call);
432            cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
433                << SPARC_INSTR_ALIGNMENT_SHIFT);
434            cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
435    
436            cpu->delay_slot = TO_BE_DELAYED;
437            ic[1].f(cpu, ic+1);
438            cpu->n_translated_instrs ++;
439    
440            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
441                    /*  Note: Must be non-delayed when jumping to the new pc:  */
442                    cpu->delay_slot = NOT_DELAYED;
443                    cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
444                    quick_pc_to_pointers(cpu);
445            } else
446                    cpu->delay_slot = NOT_DELAYED;
447    }
448    X(jmpl_reg)
449    {
450            int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
451                / sizeof(struct sparc_instr_call);
452            cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
453                << SPARC_INSTR_ALIGNMENT_SHIFT);
454            cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
455            reg(ic->arg[2]) = cpu->pc;
456    
457            cpu->delay_slot = TO_BE_DELAYED;
458            ic[1].f(cpu, ic+1);
459            cpu->n_translated_instrs ++;
460    
461            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
462                    /*  Note: Must be non-delayed when jumping to the new pc:  */
463                    cpu->delay_slot = NOT_DELAYED;
464                    cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
465                    quick_pc_to_pointers(cpu);
466            } else
467                    cpu->delay_slot = NOT_DELAYED;
468    }
469    X(jmpl_reg_no_rd)
470    {
471            int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
472                / sizeof(struct sparc_instr_call);
473            cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
474                << SPARC_INSTR_ALIGNMENT_SHIFT);
475            cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
476    
477            cpu->delay_slot = TO_BE_DELAYED;
478            ic[1].f(cpu, ic+1);
479            cpu->n_translated_instrs ++;
480    
481            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
482                    /*  Note: Must be non-delayed when jumping to the new pc:  */
483                    cpu->delay_slot = NOT_DELAYED;
484                    cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
485                    quick_pc_to_pointers(cpu);
486            } else
487                    cpu->delay_slot = NOT_DELAYED;
488    }
489    
490    
491    X(jmpl_imm_trace)
492    {
493            int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
494                / sizeof(struct sparc_instr_call);
495            cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
496                << SPARC_INSTR_ALIGNMENT_SHIFT);
497            cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
498            reg(ic->arg[2]) = cpu->pc;
499    
500            cpu->delay_slot = TO_BE_DELAYED;
501            ic[1].f(cpu, ic+1);
502            cpu->n_translated_instrs ++;
503    
504            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
505                    /*  Note: Must be non-delayed when jumping to the new pc:  */
506                    cpu->delay_slot = NOT_DELAYED;
507                    cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
508                    cpu_functioncall_trace(cpu, cpu->pc);
509                    quick_pc_to_pointers(cpu);
510            } else
511                    cpu->delay_slot = NOT_DELAYED;
512    }
513    X(jmpl_reg_trace)
514    {
515            int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
516                / sizeof(struct sparc_instr_call);
517            cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
518                << SPARC_INSTR_ALIGNMENT_SHIFT);
519            cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
520            reg(ic->arg[2]) = cpu->pc;
521    
522            cpu->delay_slot = TO_BE_DELAYED;
523            ic[1].f(cpu, ic+1);
524            cpu->n_translated_instrs ++;
525    
526            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
527                    /*  Note: Must be non-delayed when jumping to the new pc:  */
528                    cpu->delay_slot = NOT_DELAYED;
529                    cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
530                    cpu_functioncall_trace(cpu, cpu->pc);
531                    quick_pc_to_pointers(cpu);
532            } else
533                    cpu->delay_slot = NOT_DELAYED;
534    }
535    X(retl_trace)
536    {
537            int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
538                / sizeof(struct sparc_instr_call);
539            cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
540                << SPARC_INSTR_ALIGNMENT_SHIFT);
541            cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
542    
543            cpu->delay_slot = TO_BE_DELAYED;
544            ic[1].f(cpu, ic+1);
545            cpu->n_translated_instrs ++;
546    
547            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
548                    /*  Note: Must be non-delayed when jumping to the new pc:  */
549                    cpu->delay_slot = NOT_DELAYED;
550                    cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
551                    quick_pc_to_pointers(cpu);
552                    cpu_functioncall_trace_return(cpu);
553            } else
554                    cpu->delay_slot = NOT_DELAYED;
555    }
556    
557    
558    /*
559     *  set:  Set a register to a value (e.g. sethi).
560     *
561     *  arg[0] = ptr to rd
562     *  arg[1] = value (uint32_t)
563     */
564    X(set)
565    {
566            reg(ic->arg[0]) = (uint32_t)ic->arg[1];
567    }
568    
569    
570    /*
571     *  Computational/arithmetic instructions:
572     *
573     *  arg[0] = ptr to rs1
574     *  arg[1] = ptr to rs2 or an immediate value (int32_t)
575     *  arg[2] = ptr to rd
576     */
577    X(add)      { reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]); }
578    X(add_imm)  { reg(ic->arg[2]) = reg(ic->arg[0]) + (int32_t)ic->arg[1]; }
579    X(and)      { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
580    X(and_imm)  { reg(ic->arg[2]) = reg(ic->arg[0]) & (int32_t)ic->arg[1]; }
581    X(or)       { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
582    X(or_imm)   { reg(ic->arg[2]) = reg(ic->arg[0]) | (int32_t)ic->arg[1]; }
583    X(xor)      { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
584    X(xor_imm)  { reg(ic->arg[2]) = reg(ic->arg[0]) ^ (int32_t)ic->arg[1]; }
585    X(sub)      { reg(ic->arg[2]) = reg(ic->arg[0]) - reg(ic->arg[1]); }
586    X(sub_imm)  { reg(ic->arg[2]) = reg(ic->arg[0]) - (int32_t)ic->arg[1]; }
587    
588    X(sll)      { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) <<
589                    (reg(ic->arg[1]) & 31); }
590    X(sllx)     { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) <<
591                    (reg(ic->arg[1]) & 63); }
592    X(sll_imm)  { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) << ic->arg[1]; }
593    X(sllx_imm) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) << ic->arg[1]; }
594    
595    X(srl)      { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) >>
596                    (reg(ic->arg[1]) & 31); }
597    X(srlx)     { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) >>
598                    (reg(ic->arg[1]) & 63); }
599    X(srl_imm)  { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) >> ic->arg[1]; }
600    X(srlx_imm) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) >> ic->arg[1]; }
601    
602    X(sra)      { reg(ic->arg[2]) = (int32_t)reg(ic->arg[0]) >>
603                    (reg(ic->arg[1]) & 31); }
604    X(srax)     { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >>
605                    (reg(ic->arg[1]) & 63); }
606    X(sra_imm)  { reg(ic->arg[2]) = (int32_t)reg(ic->arg[0]) >> ic->arg[1]; }
607    X(srax_imm) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >> ic->arg[1]; }
608    
609    X(udiv)
610    {
611            uint64_t z = (cpu->cd.sparc.y << 32) | (uint32_t)reg(ic->arg[0]);
612            z /= (uint32_t)reg(ic->arg[1]);
613            if (z > 0xffffffff)
614                    z = 0xffffffff;
615            reg(ic->arg[2]) = z;
616    }
617    X(udiv_imm)
618    {
619            uint64_t z = (cpu->cd.sparc.y << 32) | (uint32_t)reg(ic->arg[0]);
620            z /= (uint32_t)ic->arg[1];
621            if (z > 0xffffffff)
622                    z = 0xffffffff;
623            reg(ic->arg[2]) = z;
624    }
625    
626    
627    /*
628     *  Save:
629     *
630     *  arg[0] = ptr to rs1
631     *  arg[1] = ptr to rs2 or an immediate value (int32_t)
632     *  arg[2] = ptr to rd (_after_ the register window change)
633     */
634    X(save_v9_imm)
635    {
636            MODE_uint_t rs = reg(ic->arg[0]) + (int32_t)ic->arg[1];
637            int cwp = cpu->cd.sparc.cwp;
638    
639            if (cpu->cd.sparc.cansave == 0) {
640                    fatal("save_v9_imm: spill trap. TODO\n");
641                    exit(1);
642            }
643    
644            if (cpu->cd.sparc.cleanwin - cpu->cd.sparc.canrestore == 0) {
645                    fatal("save_v9_imm: clean_window trap. TODO\n");
646                    exit(1);
647            }
648    
649            /*  Save away old in registers:  */
650            memcpy(&cpu->cd.sparc.r_inout[cwp][0], &cpu->cd.sparc.r[SPARC_REG_I0],
651                sizeof(cpu->cd.sparc.r[SPARC_REG_I0]) * N_SPARC_INOUT_REG);
652    
653            /*  Save away old local registers:  */
654            memcpy(&cpu->cd.sparc.r_local[cwp][0], &cpu->cd.sparc.r[SPARC_REG_L0],
655                sizeof(cpu->cd.sparc.r[SPARC_REG_L0]) * N_SPARC_INOUT_REG);
656    
657            cwp = cpu->cd.sparc.cwp = (cwp + 1) % cpu->cd.sparc.cpu_type.nwindows;
658            cpu->cd.sparc.cansave --;
659            cpu->cd.sparc.canrestore ++;    /*  TODO: modulo here too?  */
660    
661            /*  The out registers become the new in registers:  */
662            memcpy(&cpu->cd.sparc.r[SPARC_REG_I0], &cpu->cd.sparc.r[SPARC_REG_O0],
663                sizeof(cpu->cd.sparc.r[SPARC_REG_O0]) * N_SPARC_INOUT_REG);
664    
665            /*  Read new local registers:  */
666            memcpy(&cpu->cd.sparc.r[SPARC_REG_L0], &cpu->cd.sparc.r_local[cwp][0],
667                sizeof(cpu->cd.sparc.r[SPARC_REG_L0]) * N_SPARC_INOUT_REG);
668    
669            reg(ic->arg[2]) = rs;
670    }
671    
672    
673    /*
674     *  Add with ccr update:
675     *
676     *  arg[0] = ptr to rs1
677     *  arg[1] = ptr to rs2 or an immediate value (int32_t)
678     *  arg[2] = ptr to rd
679     */
680    int32_t sparc_addcc32(struct cpu *cpu, int32_t rs1, int32_t rs2);
681    #ifdef MODE32
682    int32_t sparc_addcc32(struct cpu *cpu, int32_t rs1, int32_t rs2)
683    #else
684    int64_t sparc_addcc64(struct cpu *cpu, int64_t rs1, int64_t rs2)
685    #endif
686    {
687            int cc = 0, sign1 = 0, sign2 = 0, signd = 0, mask = SPARC_CCR_ICC_MASK;
688            MODE_int_t rd = rs1 + rs2;
689            if (rd == 0)
690                    cc = SPARC_CCR_Z;
691            else if (rd < 0)
692                    cc = SPARC_CCR_N, signd = 1;
693            if (rs1 < 0)
694                    sign1 = 1;
695            if (rs2 < 0)
696                    sign2 = 1;
697            if (sign1 == sign2 && sign1 != signd)
698                    cc |= SPARC_CCR_V;
699            /*  TODO: SPARC_CCR_C  */
700    #ifndef MODE32
701            mask <<= SPARC_CCR_XCC_SHIFT;
702            cc <<= SPARC_CCR_XCC_SHIFT;
703    #endif
704            cpu->cd.sparc.ccr &= ~mask;
705            cpu->cd.sparc.ccr |= cc;
706            return rd;
707    }
708    X(addcc)
709    {
710            /*  Like add, but updates the ccr, and does both 32-bit and
711                64-bit comparison at the same time.  */
712            MODE_int_t rs1 = reg(ic->arg[0]), rs2 = reg(ic->arg[1]), rd;
713            rd = sparc_addcc32(cpu, rs1, rs2);
714    #ifndef MODE32
715            rd = sparc_addcc64(cpu, rs1, rs2);
716    #endif
717            reg(ic->arg[2]) = rd;
718    }
719    X(addcc_imm)
720    {
721            MODE_int_t rs1 = reg(ic->arg[0]), rs2 = (int32_t)ic->arg[1], rd;
722            rd = sparc_addcc32(cpu, rs1, rs2);
723    #ifndef MODE32
724            rd = sparc_addcc64(cpu, rs1, rs2);
725    #endif
726            reg(ic->arg[2]) = rd;
727    }
728    
729    
730    /*
731     *  And with ccr update:
732     *
733     *  arg[0] = ptr to rs1
734     *  arg[1] = ptr to rs2 or an immediate value (int32_t)
735     *  arg[2] = ptr to rd
736     */
737    int32_t sparc_andcc32(struct cpu *cpu, int32_t rs1, int32_t rs2);
738    #ifdef MODE32
739    int32_t sparc_andcc32(struct cpu *cpu, int32_t rs1, int32_t rs2)
740    #else
741    int64_t sparc_andcc64(struct cpu *cpu, int64_t rs1, int64_t rs2)
742    #endif
743    {
744            int cc = 0, mask = SPARC_CCR_ICC_MASK;
745            MODE_int_t rd = rs1 & rs2;
746            if (rd == 0)
747                    cc = SPARC_CCR_Z;
748            else if (rd < 0)
749                    cc = SPARC_CCR_N;
750            /*  Note: SPARC_CCR_C and SPARC_CCR_V are always zero.  */
751    #ifndef MODE32
752            mask <<= SPARC_CCR_XCC_SHIFT;
753            cc <<= SPARC_CCR_XCC_SHIFT;
754    #endif
755            cpu->cd.sparc.ccr &= ~mask;
756            cpu->cd.sparc.ccr |= cc;
757            return rd;
758    }
759    X(andcc)
760    {
761            /*  Like and, but updates the ccr, and does both 32-bit and
762                64-bit comparison at the same time.  */
763            MODE_int_t rs1 = reg(ic->arg[0]), rs2 = reg(ic->arg[1]), rd;
764            rd = sparc_andcc32(cpu, rs1, rs2);
765    #ifndef MODE32
766            rd = sparc_andcc64(cpu, rs1, rs2);
767    #endif
768            reg(ic->arg[2]) = rd;
769    }
770    X(andcc_imm)
771    {
772            MODE_int_t rs1 = reg(ic->arg[0]), rs2 = (int32_t)ic->arg[1], rd;
773            rd = sparc_andcc32(cpu, rs1, rs2);
774    #ifndef MODE32
775            rd = sparc_andcc64(cpu, rs1, rs2);
776    #endif
777            reg(ic->arg[2]) = rd;
778    }
779    
780    
781    /*
782     *  Subtract with ccr update:
783     *
784     *  arg[0] = ptr to rs1
785     *  arg[1] = ptr to rs2 or an immediate value (int32_t)
786     *  arg[2] = ptr to rd
787     */
788    int32_t sparc_subcc32(struct cpu *cpu, int32_t rs1, int32_t rs2);
789    #ifdef MODE32
790    int32_t sparc_subcc32(struct cpu *cpu, int32_t rs1, int32_t rs2)
791    #else
792    int64_t sparc_subcc64(struct cpu *cpu, int64_t rs1, int64_t rs2)
793    #endif
794    {
795            int cc = 0, sign1 = 0, sign2 = 0, signd = 0, mask = SPARC_CCR_ICC_MASK;
796            MODE_int_t rd = rs1 - rs2;
797            if (rd == 0)
798                    cc = SPARC_CCR_Z;
799            else if (rd < 0)
800                    cc = SPARC_CCR_N, signd = 1;
801            if (rs1 < 0)
802                    sign1 = 1;
803            if (rs2 < 0)
804                    sign2 = 1;
805            if (sign1 != sign2 && sign1 != signd)
806                    cc |= SPARC_CCR_V;
807            /*  TODO: SPARC_CCR_C  */
808    #ifndef MODE32
809            mask <<= SPARC_CCR_XCC_SHIFT;
810            cc <<= SPARC_CCR_XCC_SHIFT;
811    #endif
812            cpu->cd.sparc.ccr &= ~mask;
813            cpu->cd.sparc.ccr |= cc;
814            return rd;
815    }
816    X(subcc)
817    {
818            /*  Like sub, but updates the ccr, and does both 32-bit and
819                64-bit comparison at the same time.  */
820            MODE_int_t rs1 = reg(ic->arg[0]), rs2 = reg(ic->arg[1]), rd;
821            rd = sparc_subcc32(cpu, rs1, rs2);
822    #ifndef MODE32
823            rd = sparc_subcc64(cpu, rs1, rs2);
824    #endif
825            reg(ic->arg[2]) = rd;
826    }
827    X(subcc_imm)
828    {
829            MODE_int_t rs1 = reg(ic->arg[0]), rs2 = (int32_t)ic->arg[1], rd;
830            rd = sparc_subcc32(cpu, rs1, rs2);
831    #ifndef MODE32
832            rd = sparc_subcc64(cpu, rs1, rs2);
833    #endif
834            reg(ic->arg[2]) = rd;
835    }
836    
837    
838    #include "tmp_sparc_loadstore.c"
839    
840    
841    /*
842     *  rd:  Read special register
843     *
844     *  arg[2] = ptr to rd
845     */
846    X(rd_psr)
847    {
848            reg(ic->arg[2]) = cpu->cd.sparc.psr;
849    }
850    
851    
852    /*
853     *  rdpr:  Read privileged register
854     *
855     *  arg[2] = ptr to rd
856     */
857    X(rdpr_tba)
858    {
859            reg(ic->arg[2]) = cpu->cd.sparc.tba;
860    }
861    X(rdpr_ver)
862    {
863            reg(ic->arg[2]) = cpu->cd.sparc.ver;
864    }
865    
866    
867    /*
868     *  wrpr:  Write to privileged register
869     *
870     *  arg[0] = ptr to rs1
871     *  arg[1] = ptr to rs2 or an immediate value (int32_t)
872     */
873    X(wrpr_tick)
874    {
875            cpu->cd.sparc.tick = (uint32_t) (reg(ic->arg[0]) ^ reg(ic->arg[1]));
876    }
877    X(wrpr_tick_imm)
878    {
879            cpu->cd.sparc.tick = (uint32_t) (reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
880    }
881    X(wrpr_pil)
882    {
883            cpu->cd.sparc.pil = (reg(ic->arg[0]) ^ reg(ic->arg[1]))
884                & SPARC_PIL_MASK;
885    }
886    X(wrpr_pil_imm)
887    {
888            cpu->cd.sparc.pil = (reg(ic->arg[0]) ^ (int32_t)ic->arg[1])
889                & SPARC_PIL_MASK;
890    }
891    X(wrpr_pstate)
892    {
893            sparc_update_pstate(cpu, reg(ic->arg[0]) ^ reg(ic->arg[1]));
894    }
895    X(wrpr_pstate_imm)
896    {
897            sparc_update_pstate(cpu, reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
898    }
899    
900    
901    /*****************************************************************************/
902    
903    
904  X(end_of_page)  X(end_of_page)
905  {  {
906          /*  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 910  X(end_of_page)
910              SPARC_INSTR_ALIGNMENT_SHIFT);              SPARC_INSTR_ALIGNMENT_SHIFT);
911    
912          /*  Find the new physical page and update the translation pointers:  */          /*  Find the new physical page and update the translation pointers:  */
913          DYNTRANS_PC_TO_POINTERS(cpu);          quick_pc_to_pointers(cpu);
914    
915          /*  end_of_page doesn't count as an executed instruction:  */          /*  end_of_page doesn't count as an executed instruction:  */
916          cpu->n_translated_instrs --;          cpu->n_translated_instrs --;
917  }  }
918    
919    
920    X(end_of_page2)
921    {
922            /*  Synchronize PC on the _second_ instruction on the next page:  */
923            int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
924                / sizeof(struct sparc_instr_call);
925            cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
926                << SPARC_INSTR_ALIGNMENT_SHIFT);
927            cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
928    
929            /*  This doesn't count as an executed instruction.  */
930            cpu->n_translated_instrs --;
931    
932            quick_pc_to_pointers(cpu);
933    
934            if (cpu->delay_slot == NOT_DELAYED)
935                    return;
936    
937            fatal("end_of_page2: fatal error, we're in a delay slot\n");
938            exit(1);
939    }
940    
941    
942  /*****************************************************************************/  /*****************************************************************************/
943    
944    
945  /*  /*
946   *  sparc_instr_to_be_translated():   *  sparc_instr_to_be_translated():
947   *   *
948   *  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
949   *  valid data for the translated instruction, or a "nothing" instruction if   *  valid data for the translated instruction, or a "nothing" instruction if
950   *  there was a translation failure. The newly translated instruction is then   *  there was a translation failure. The newly translated instruction is then
951   *  executed.   *  executed.
952   */   */
953  X(to_be_translated)  X(to_be_translated)
954  {  {
955          uint64_t addr, low_pc;          MODE_uint_t addr;
956  #ifdef DYNTRANS_BACKEND          int low_pc, in_crosspage_delayslot = 0;
         int simple = 0;  
 #endif  
957          uint32_t iword;          uint32_t iword;
958          unsigned char *page;          unsigned char *page;
959          unsigned char ib[4];          unsigned char ib[4];
960          int main_opcode;          int main_opcode, op2, rd, rs1, rs2, btype, asi, cc, p, use_imm, x64 = 0;
961            int store, signedness, size;
962            int32_t tmpi32, siconst;
963          /* void (*samepage_function)(struct cpu *, struct sparc_instr_call *);*/          /* void (*samepage_function)(struct cpu *, struct sparc_instr_call *);*/
964    
965          /*  Figure out the (virtual) address of the instruction:  */          /*  Figure out the (virtual) address of the instruction:  */
966          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)
967              / sizeof(struct sparc_instr_call);              / sizeof(struct sparc_instr_call);
968    
969            /*  Special case for branch with delayslot on the next page:  */
970            if (cpu->delay_slot == TO_BE_DELAYED && low_pc == 0) {
971                    /*  fatal("[ delay-slot translation across page "
972                        "boundary ]\n");  */
973                    in_crosspage_delayslot = 1;
974            }
975    
976          addr = cpu->pc & ~((SPARC_IC_ENTRIES_PER_PAGE-1)          addr = cpu->pc & ~((SPARC_IC_ENTRIES_PER_PAGE-1)
977              << SPARC_INSTR_ALIGNMENT_SHIFT);              << SPARC_INSTR_ALIGNMENT_SHIFT);
978          addr += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);          addr += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
# Line 96  X(to_be_translated) Line 980  X(to_be_translated)
980          addr &= ~((1 << SPARC_INSTR_ALIGNMENT_SHIFT) - 1);          addr &= ~((1 << SPARC_INSTR_ALIGNMENT_SHIFT) - 1);
981    
982          /*  Read the instruction word from memory:  */          /*  Read the instruction word from memory:  */
983    #ifdef MODE32
984          page = cpu->cd.sparc.host_load[addr >> 12];          page = cpu->cd.sparc.host_load[addr >> 12];
985    #else
986            {
987                    const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
988                    const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
989                    const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
990                    uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
991                    uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
992                    uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
993                        DYNTRANS_L3N)) & mask3;
994                    struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.sparc.l1_64[x1];
995                    struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
996                    page = l3->host_load[x3];
997            }
998    #endif
999    
1000          if (page != NULL) {          if (page != NULL) {
1001                  /*  fatal("TRANSLATION HIT!\n");  */                  /*  fatal("TRANSLATION HIT!\n");  */
1002                  memcpy(ib, page + (addr & 0xfff), sizeof(ib));                  memcpy(ib, page + (addr & 0xffc), sizeof(ib));
1003          } else {          } else {
1004                  /*  fatal("TRANSLATION MISS!\n");  */                  /*  fatal("TRANSLATION MISS!\n");  */
1005                  if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,                  if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
# Line 111  X(to_be_translated) Line 1010  X(to_be_translated)
1010                  }                  }
1011          }          }
1012    
1013          iword = *((uint32_t *)&ib[0]);          /*  SPARC instruction words are always big-endian. Convert
1014                to host order:  */
1015  #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  
1016    
1017    
1018  #define DYNTRANS_TO_BE_TRANSLATED_HEAD  #define DYNTRANS_TO_BE_TRANSLATED_HEAD
# Line 130  X(to_be_translated) Line 1024  X(to_be_translated)
1024           *  Translate the instruction:           *  Translate the instruction:
1025           */           */
1026    
1027          main_opcode = iword >> 26;          main_opcode = iword >> 30;
1028            rd = (iword >> 25) & 31;
1029            btype = rd & (N_SPARC_BRANCH_TYPES - 1);
1030            rs1 = (iword >> 14) & 31;
1031            use_imm = (iword >> 13) & 1;
1032            asi = (iword >> 5) & 0xff;
1033            rs2 = iword & 31;
1034            siconst = (int16_t)((iword & 0x1fff) << 3) >> 3;
1035            op2 = (main_opcode == 0)? ((iword >> 22) & 7) : ((iword >> 19) & 0x3f);
1036            cc = (iword >> 20) & 3;
1037            p = (iword >> 19) & 1;
1038    
1039          switch (main_opcode) {          switch (main_opcode) {
1040    
1041          default:goto bad;          case 0: switch (op2) {
1042    
1043                    case 1: /*  branch (icc or xcc)  */
1044                            tmpi32 = (iword << 13);
1045                            tmpi32 >>= 11;
1046                            ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1047                            /*  rd contains the annul bit concatenated with 4 bits
1048                                of condition code. cc=0 for icc, 2 for xcc:  */
1049                            /*  TODO: samepage  */
1050                            switch (rd + (cc << 5)) {
1051                            case 0x01:      ic->f = instr(be);  break;
1052                            case 0x03:      ic->f = instr(bl);  break;
1053                            case 0x09:      ic->f = instr(bne); break;
1054                            case 0x0a:      ic->f = instr(bg); break;
1055                            case 0x0b:      ic->f = instr(bge); break;
1056                            case 0x19:      ic->f = instr(bne_a); break;
1057                            case 0x41:      ic->f = instr(be_xcc); break;
1058                            case 0x43:      ic->f = instr(bl_xcc); break;
1059                            case 0x4a:      ic->f = instr(bg_xcc); break;
1060                            case 0x4b:      ic->f = instr(bge_xcc); break;
1061                            default:fatal("Unimplemented branch, 0x%x\n",
1062                                        rd + (cc<<5));
1063                                    goto bad;
1064                            }
1065                            break;
1066    
1067                    case 2: /*  branch (32-bit integer comparison)  */
1068                            tmpi32 = (iword << 10);
1069                            tmpi32 >>= 8;
1070                            ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1071                            /*  rd contains the annul bit concatenated with 4 bits
1072                                of condition code:  */
1073                            /*  TODO: samepage  */
1074                            switch (rd) {
1075                            case 0x01:      ic->f = instr(be);  break;
1076                            case 0x03:      ic->f = instr(bl);  break;
1077                            case 0x08:      ic->f = instr(ba);  break;
1078                            case 0x0b:      ic->f = instr(bge); break;
1079                            default:fatal("Unimplemented branch rd=%i\n", rd);
1080                                    goto bad;
1081                            }
1082                            break;
1083    
1084                    case 3: /*  branch on register, 64-bit integer comparison  */
1085                            tmpi32 = ((iword & 0x300000) >> 6) | (iword & 0x3fff);
1086                            tmpi32 <<= 16;
1087                            tmpi32 >>= 14;
1088                            ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1089                            ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs1];
1090                            /*  TODO: samepage  */
1091                            switch (btype) {
1092                            case 0x05:      ic->f = instr(brnz); break;
1093                            default:fatal("Unimplemented branch 0x%x\n", rd);
1094                                    goto bad;
1095                            }
1096                            break;
1097    
1098                    case 4: /*  sethi  */
1099                            ic->arg[0] = (size_t)&cpu->cd.sparc.r[rd];
1100                            ic->arg[1] = (iword & 0x3fffff) << 10;
1101                            ic->f = instr(set);
1102                            if (rd == SPARC_ZEROREG)
1103                                    ic->f = instr(nop);
1104                            break;
1105    
1106                    default:fatal("TODO: unimplemented op2=%i for main "
1107                                "opcode %i\n", op2, main_opcode);
1108                            goto bad;
1109                    }
1110                    break;
1111    
1112            case 1: /*  call and link  */
1113                    tmpi32 = (iword << 2);
1114                    ic->arg[0] = (int32_t)tmpi32;
1115                    ic->arg[1] = addr & 0xffc;
1116                    if (cpu->machine->show_trace_tree)
1117                            ic->f = instr(call_trace);
1118                    else
1119                            ic->f = instr(call);
1120                    /*  TODO: samepage  */
1121                    break;
1122    
1123            case 2: switch (op2) {
1124    
1125                    case 0: /*  add  */
1126                    case 1: /*  and  */
1127                    case 2: /*  or  */
1128                    case 3: /*  xor  */
1129                    case 4: /*  sub  */
1130                    case 14:/*  udiv  */
1131                    case 16:/*  addcc  */
1132                    case 17:/*  andcc  */
1133                    case 20:/*  subcc (cmp)  */
1134                    case 37:/*  sll  */
1135                    case 38:/*  srl  */
1136                    case 39:/*  sra  */
1137                    case 60:/*  save  */
1138                            ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1139                            ic->f = NULL;
1140                            if (use_imm) {
1141                                    ic->arg[1] = siconst;
1142                                    switch (op2) {
1143                                    case 0: ic->f = instr(add_imm); break;
1144                                    case 1: ic->f = instr(and_imm); break;
1145                                    case 2: ic->f = instr(or_imm); break;
1146                                    case 3: ic->f = instr(xor_imm); break;
1147                                    case 4: ic->f = instr(sub_imm); break;
1148                                    case 14:ic->f = instr(udiv_imm); break;
1149                                    case 16:ic->f = instr(addcc_imm); break;
1150                                    case 17:ic->f = instr(andcc_imm); break;
1151                                    case 20:ic->f = instr(subcc_imm); break;
1152                                    case 37:if (siconst & 0x1000) {
1153                                                    ic->f = instr(sllx_imm);
1154                                                    ic->arg[1] &= 63;
1155                                                    x64 = 1;
1156                                            } else {
1157                                                    ic->f = instr(sll_imm);
1158                                                    ic->arg[1] &= 31;
1159                                            }
1160                                            break;
1161                                    case 38:if (siconst & 0x1000) {
1162                                                    ic->f = instr(srlx_imm);
1163                                                    ic->arg[1] &= 63;
1164                                                    x64 = 1;
1165                                            } else {
1166                                                    ic->f = instr(srl_imm);
1167                                                    ic->arg[1] &= 31;
1168                                            }
1169                                            break;
1170                                    case 39:if (siconst & 0x1000) {
1171                                                    ic->f = instr(srax_imm);
1172                                                    ic->arg[1] &= 63;
1173                                                    x64 = 1;
1174                                            } else {
1175                                                    ic->f = instr(sra_imm);
1176                                                    ic->arg[1] &= 31;
1177                                            }
1178                                            break;
1179                                    case 60:switch (cpu->cd.sparc.cpu_type.v) {
1180                                            case 9: ic->f = instr(save_v9_imm);
1181                                                    break;
1182                                            default:fatal("only for v9 so far\n");
1183                                                    goto bad;
1184                                            }
1185                                    }
1186                            } else {
1187                                    ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1188                                    switch (op2) {
1189                                    case 0: ic->f = instr(add); break;
1190                                    case 1: ic->f = instr(and); break;
1191                                    case 2: ic->f = instr(or); break;
1192                                    case 3: ic->f = instr(xor); break;
1193                                    case 4: ic->f = instr(sub); break;
1194                                    case 14:ic->f = instr(udiv); break;
1195                                    case 16:ic->f = instr(addcc); break;
1196                                    case 17:ic->f = instr(andcc); break;
1197                                    case 20:ic->f = instr(subcc); break;
1198                                    case 37:if (siconst & 0x1000) {
1199                                                    ic->f = instr(sllx);
1200                                                    x64 = 1;
1201                                            } else
1202                                                    ic->f = instr(sll);
1203                                            break;
1204                                    case 38:if (siconst & 0x1000) {
1205                                                    ic->f = instr(srlx);
1206                                                    x64 = 1;
1207                                            } else
1208                                                    ic->f = instr(srl);
1209                                            break;
1210                                    case 39:if (siconst & 0x1000) {
1211                                                    ic->f = instr(srax);
1212                                                    x64 = 1;
1213                                            } else
1214                                                    ic->f = instr(sra);
1215                                            break;
1216                                    }
1217                            }
1218                            if (ic->f == NULL) {
1219                                    fatal("TODO: Unimplemented instruction "
1220                                        "(possibly missed use_imm impl.)\n");
1221                                    goto bad;
1222                            }
1223                            ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1224                            if (rd == SPARC_ZEROREG) {
1225                                    /*
1226                                     *  Some opcodes should write to the scratch
1227                                     *  register instead of becoming NOPs, when
1228                                     *  rd is the zero register.
1229                                     *
1230                                     *  Any opcode which updates the condition
1231                                     *  codes, or anything which changes register
1232                                     *  windows.
1233                                     */
1234                                    switch (op2) {
1235                                    case 16:/*  addcc  */
1236                                    case 17:/*  andcc  */
1237                                    case 20:/*  subcc  */
1238                                    case 60:/*  save  */
1239                                            ic->arg[2] = (size_t)
1240                                                &cpu->cd.sparc.scratch;
1241                                            break;
1242                                    default:ic->f = instr(nop);
1243                                    }
1244                            }
1245                            break;
1246    
1247                    case 41:/*  rd %psr,%gpr on pre-sparcv9  */
1248                            if (cpu->is_32bit) {
1249                                    ic->f = instr(rd_psr);
1250                                    ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1251                                    if (rd == SPARC_ZEROREG)
1252                                            ic->f = instr(nop);
1253                            } else {
1254                                    fatal("opcode 2,41 not yet implemented"
1255                                        " for 64-bit cpus\n");
1256                                    goto bad;
1257                            }
1258                            break;
1259    
1260                    case 42:/*  rdpr on sparcv9  */
1261                            if (cpu->is_32bit) {
1262                                    fatal("opcode 2,42 not yet implemented"
1263                                        " for 32-bit cpus\n");
1264                                    goto bad;
1265                            }
1266                            ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1267                            if (rd == SPARC_ZEROREG)
1268                                    ic->f = instr(nop);
1269                            switch (rs1) {
1270                            case  5:  ic->f = instr(rdpr_tba); break;
1271                            case 31:  ic->f = instr(rdpr_ver); break;
1272                            default:fatal("Unimplemented rs1=%i\n", rs1);
1273                                    goto bad;
1274                            }
1275                            break;
1276    
1277                    case 48:/*  wr  (Note: works as xor)  */
1278                            ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1279                            if (use_imm) {
1280                                    ic->arg[1] = siconst;
1281                                    ic->f = instr(xor_imm);
1282                            } else {
1283                                    ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1284                                    ic->f = instr(xor);
1285                            }
1286                            ic->arg[2] = (size_t) NULL;
1287                            switch (rd) {
1288                            case 0: ic->arg[2] = (size_t)&cpu->cd.sparc.y;
1289                                    break;
1290                            case 6: ic->arg[2] = (size_t)&cpu->cd.sparc.fprs;
1291                                    break;
1292                            case 0x17:
1293                                    ic->arg[2] = (size_t)&cpu->cd.sparc.tick_cmpr;
1294                                    break;
1295                            }
1296                            if (ic->arg[2] == (size_t)NULL) {
1297                                    fatal("TODO: Unimplemented wr instruction, "
1298                                        "rd = 0x%02x\n", rd);
1299                                    goto bad;
1300                            }
1301                            break;
1302    
1303                    case 50:/*  wrpr  (Note: works as xor)  */
1304                            ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1305                            ic->f = NULL;
1306                            if (use_imm) {
1307                                    ic->arg[1] = siconst;
1308                                    switch (rd) {
1309                                    case 4: ic->f = instr(wrpr_tick_imm); break;
1310                                    case 6: ic->f = instr(wrpr_pstate_imm); break;
1311                                    case 8: ic->f = instr(wrpr_pil_imm); break;
1312                                    }
1313                            } else {
1314                                    ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1315                                    switch (rd) {
1316                                    case 4: ic->f = instr(wrpr_tick); break;
1317                                    case 6: ic->f = instr(wrpr_pstate); break;
1318                                    case 8: ic->f = instr(wrpr_pil); break;
1319                                    }
1320                            }
1321                            if (ic->f == NULL) {
1322                                    fatal("TODO: Unimplemented wrpr instruction,"
1323                                        " rd = 0x%02x\n", rd);
1324                                    goto bad;
1325                            }
1326                            break;
1327    
1328                    case 56:/*  jump and link  */
1329                            ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1330                            ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1331                            if (rd == SPARC_ZEROREG)
1332                                    ic->arg[2] = (size_t)&cpu->cd.sparc.scratch;
1333    
1334                            if (use_imm) {
1335                                    ic->arg[1] = siconst;
1336                                    if (rd == SPARC_ZEROREG)
1337                                            ic->f = instr(jmpl_imm_no_rd);
1338                                    else
1339                                            ic->f = instr(jmpl_imm);
1340                            } else {
1341                                    ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1342                                    if (rd == SPARC_ZEROREG)
1343                                            ic->f = instr(jmpl_reg_no_rd);
1344                                    else
1345                                            ic->f = instr(jmpl_reg);
1346                            }
1347    
1348                            /*  special trace case:  */
1349                            if (cpu->machine->show_trace_tree) {
1350                                    if (iword == 0x81c3e008)
1351                                            ic->f = instr(retl_trace);
1352                                    else {
1353                                            if (use_imm)
1354                                                    ic->f = instr(jmpl_imm_trace);
1355                                            else
1356                                                    ic->f = instr(jmpl_reg_trace);
1357                                    }
1358                            }
1359                            break;
1360    
1361                    default:fatal("TODO: unimplemented op2=%i for main "
1362                                "opcode %i\n", op2, main_opcode);
1363                            goto bad;
1364                    }
1365                    break;
1366    
1367            case 3: switch (op2) {
1368    
1369                    case  0:/*  lduw  */
1370                    case  1:/*  ldub  */
1371                    case  2:/*  lduh  */
1372                    case  4:/*  st(w) */
1373                    case  5:/*  stb   */
1374                    case  6:/*  sth   */
1375                    case  8:/*  ldsw  */
1376                    case  9:/*  ldsb  */
1377                    case 10:/*  ldsh  */
1378                    case 11:/*  ldx  */
1379                    case 14:/*  stx   */
1380                            store = 1; signedness = 0; size = 3;
1381                            switch (op2) {
1382                            case  0: /*  lduw  */   store=0; size=2; break;
1383                            case  1: /*  ldub  */   store=0; size=0; break;
1384                            case  2: /*  lduh  */   store=0; size=1; break;
1385                            case  4: /*  st  */     size = 2; break;
1386                            case  5: /*  stb  */    size = 0; break;
1387                            case  6: /*  sth  */    size = 1; break;
1388                            case  8: /*  ldsw  */   store=0; size=2; signedness=1;
1389                                                    break;
1390                            case  9: /*  ldsb  */   store=0; size=0; signedness=1;
1391                                                    break;
1392                            case 10: /*  ldsh  */   store=0; size=1; signedness=1;
1393                                                    break;
1394                            case 11: /*  ldx  */    store=0; break;
1395                            case 14: /*  stx  */    break;
1396                            }
1397                            ic->f =
1398    #ifdef MODE32
1399                                sparc32_loadstore
1400    #else
1401                                sparc_loadstore
1402    #endif
1403                                [ use_imm*16 + store*8 + size*2 + signedness ];
1404    
1405                            ic->arg[0] = (size_t)&cpu->cd.sparc.r[rd];
1406                            ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs1];
1407                            if (use_imm)
1408                                    ic->arg[2] = siconst;
1409                            else
1410                                    ic->arg[2] = (size_t)&cpu->cd.sparc.r[rs2];
1411    
1412                            if (!store && rd == SPARC_ZEROREG)
1413                                    ic->arg[0] = (size_t)&cpu->cd.sparc.scratch;
1414    
1415                            break;
1416    
1417                    default:fatal("TODO: unimplemented op2=%i for main "
1418                                "opcode %i\n", op2, main_opcode);
1419                            goto bad;
1420                    }
1421                    break;
1422    
1423            }
1424    
1425    
1426            if (x64 && cpu->is_32bit) {
1427                    fatal("TODO: 64-bit instr on 32-bit cpu\n");
1428                    goto bad;
1429          }          }
1430    
1431    

Legend:
Removed from v.22  
changed lines
  Added in v.30

  ViewVC Help
Powered by ViewVC 1.1.26