/[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 24 by dpavlin, Mon Oct 8 16:19:56 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.18 2006/05/17 20:27:31 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 94  X(call_trace) Line 106  X(call_trace)
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   *  ba
352   *   *
353   *  arg[0] = int32_t displacement compared to the start of the current page   *  arg[0] = int32_t displacement compared to the start of the current page
# Line 117  X(ba) Line 371  X(ba)
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   *  Jump and link
402   *   *
403   *  arg[0] = ptr to rs1   *  arg[0] = ptr to rs1
# Line 325  X(srax)     { reg(ic->arg[2]) = (int64_t Line 606  X(srax)     { reg(ic->arg[2]) = (int64_t
606  X(sra_imm)  { reg(ic->arg[2]) = (int32_t)reg(ic->arg[0]) >> ic->arg[1]; }  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]; }  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:   *  Subtract with ccr update:
# Line 383  X(subcc_imm) Line 835  X(subcc_imm)
835  }  }
836    
837    
838    #include "tmp_sparc_loadstore.c"
839    
840    
841  /*  /*
842   *  rd:  Read special register:   *  rd:  Read special register
843   *   *
844   *  arg[2] = ptr to rd   *  arg[2] = ptr to rd
845   */   */
# Line 395  X(rd_psr) Line 850  X(rd_psr)
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   *  wrpr:  Write to privileged register
869   *   *
870   *  arg[0] = ptr to rs1   *  arg[0] = ptr to rs1
# Line 483  X(end_of_page2) Line 953  X(end_of_page2)
953  X(to_be_translated)  X(to_be_translated)
954  {  {
955          MODE_uint_t addr;          MODE_uint_t addr;
956          int low_pc;          int low_pc, in_crosspage_delayslot = 0;
         int in_crosspage_delayslot = 0;  
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, op2, rd, rs1, rs2, btype, asi, cc, p, use_imm, x64 = 0;          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;          int32_t tmpi32, siconst;
963          /* void (*samepage_function)(struct cpu *, struct sparc_instr_call *);*/          /* void (*samepage_function)(struct cpu *, struct sparc_instr_call *);*/
964    
# Line 570  X(to_be_translated) Line 1040  X(to_be_translated)
1040    
1041          case 0: switch (op2) {          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)  */                  case 2: /*  branch (32-bit integer comparison)  */
1068                          tmpi32 = (iword << 10);                          tmpi32 = (iword << 10);
1069                          tmpi32 >>= 8;                          tmpi32 >>= 8;
# Line 578  X(to_be_translated) Line 1072  X(to_be_translated)
1072                              of condition code:  */                              of condition code:  */
1073                          /*  TODO: samepage  */                          /*  TODO: samepage  */
1074                          switch (rd) {                          switch (rd) {
1075                          case 0x08:/*  ba  */                          case 0x01:      ic->f = instr(be);  break;
1076                                  ic->f = instr(ba);                          case 0x03:      ic->f = instr(bl);  break;
1077                                  break;                          case 0x08:      ic->f = instr(ba);  break;
1078                          default:goto bad;                          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;                          break;
1097    
# Line 617  X(to_be_translated) Line 1127  X(to_be_translated)
1127                  case 2: /*  or  */                  case 2: /*  or  */
1128                  case 3: /*  xor  */                  case 3: /*  xor  */
1129                  case 4: /*  sub  */                  case 4: /*  sub  */
1130                    case 14:/*  udiv  */
1131                    case 16:/*  addcc  */
1132                    case 17:/*  andcc  */
1133                  case 20:/*  subcc (cmp)  */                  case 20:/*  subcc (cmp)  */
1134                  case 37:/*  sll  */                  case 37:/*  sll  */
1135                  case 38:/*  srl  */                  case 38:/*  srl  */
1136                  case 39:/*  sra  */                  case 39:/*  sra  */
1137                    case 60:/*  save  */
1138                          ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];                          ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1139                          ic->f = NULL;                          ic->f = NULL;
1140                          if (use_imm) {                          if (use_imm) {
# Line 631  X(to_be_translated) Line 1145  X(to_be_translated)
1145                                  case 2: ic->f = instr(or_imm); break;                                  case 2: ic->f = instr(or_imm); break;
1146                                  case 3: ic->f = instr(xor_imm); break;                                  case 3: ic->f = instr(xor_imm); break;
1147                                  case 4: ic->f = instr(sub_imm); break;                                  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;                                  case 20:ic->f = instr(subcc_imm); break;
1152                                  case 37:if (siconst & 0x1000) {                                  case 37:if (siconst & 0x1000) {
1153                                                  ic->f = instr(sllx_imm);                                                  ic->f = instr(sllx_imm);
# Line 659  X(to_be_translated) Line 1176  X(to_be_translated)
1176                                                  ic->arg[1] &= 31;                                                  ic->arg[1] &= 31;
1177                                          }                                          }
1178                                          break;                                          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 {                          } else {
1187                                  ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];                                  ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
# Line 668  X(to_be_translated) Line 1191  X(to_be_translated)
1191                                  case 2: ic->f = instr(or); break;                                  case 2: ic->f = instr(or); break;
1192                                  case 3: ic->f = instr(xor); break;                                  case 3: ic->f = instr(xor); break;
1193                                  case 4: ic->f = instr(sub); break;                                  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;                                  case 20:ic->f = instr(subcc); break;
1198                                  case 37:if (siconst & 0x1000) {                                  case 37:if (siconst & 0x1000) {
1199                                                  ic->f = instr(sllx);                                                  ic->f = instr(sllx);
# Line 696  X(to_be_translated) Line 1222  X(to_be_translated)
1222                          }                          }
1223                          ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];                          ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1224                          if (rd == SPARC_ZEROREG) {                          if (rd == SPARC_ZEROREG) {
1225                                  /*  Opcodes which update the ccr should use                                  /*
1226                                      the scratch register instead of being                                   *  Some opcodes should write to the scratch
1227                                      turned into a nop, when the zero register                                   *  register instead of becoming NOPs, when
1228                                      is used as the destination:  */                                   *  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) {                                  switch (op2) {
1235                                    case 16:/*  addcc  */
1236                                    case 17:/*  andcc  */
1237                                  case 20:/*  subcc  */                                  case 20:/*  subcc  */
1238                                    case 60:/*  save  */
1239                                          ic->arg[2] = (size_t)                                          ic->arg[2] = (size_t)
1240                                              &cpu->cd.sparc.scratch;                                              &cpu->cd.sparc.scratch;
1241                                          break;                                          break;
# Line 723  X(to_be_translated) Line 1257  X(to_be_translated)
1257                          }                          }
1258                          break;                          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)  */                  case 48:/*  wr  (Note: works as xor)  */
1278                          ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];                          ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1279                          if (use_imm) {                          if (use_imm) {
# Line 813  X(to_be_translated) Line 1364  X(to_be_translated)
1364                  }                  }
1365                  break;                  break;
1366    
1367          default:fatal("TODO: unimplemented main opcode %i\n", main_opcode);          case 3: switch (op2) {
1368                  goto bad;  
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    

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

  ViewVC Help
Powered by ViewVC 1.1.26