/[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 27 by dpavlin, Mon Oct 8 16:19:56 2007 UTC revision 28 by dpavlin, Mon Oct 8 16:20:26 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.21 2006/07/02 11:01:19 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 327  X(srax_imm) { reg(ic->arg[2]) = (int64_t Line 339  X(srax_imm) { reg(ic->arg[2]) = (int64_t
339    
340    
341  /*  /*
342     *  Save:
343     *
344     *  arg[0] = ptr to rs1
345     *  arg[1] = ptr to rs2 or an immediate value (int32_t)
346     *  arg[2] = ptr to rd (_after_ the register window change)
347     */
348    X(save_v9_imm)
349    {
350            MODE_uint_t rs = reg(ic->arg[0]) + (int32_t)ic->arg[1];
351            int cwp = cpu->cd.sparc.cwp;
352    
353            if (cpu->cd.sparc.cansave == 0) {
354                    fatal("save_v9_imm: spill trap. TODO\n");
355                    exit(1);
356            }
357    
358            if (cpu->cd.sparc.cleanwin - cpu->cd.sparc.canrestore == 0) {
359                    fatal("save_v9_imm: clean_window trap. TODO\n");
360                    exit(1);
361            }
362    
363            /*  Save away old in registers:  */
364            memcpy(&cpu->cd.sparc.r_inout[cwp][0], &cpu->cd.sparc.r[SPARC_REG_I0],
365                sizeof(cpu->cd.sparc.r[SPARC_REG_I0]) * N_SPARC_INOUT_REG);
366    
367            /*  Save away old local registers:  */
368            memcpy(&cpu->cd.sparc.r_local[cwp][0], &cpu->cd.sparc.r[SPARC_REG_L0],
369                sizeof(cpu->cd.sparc.r[SPARC_REG_L0]) * N_SPARC_INOUT_REG);
370    
371            cwp = cpu->cd.sparc.cwp = (cwp + 1) % cpu->cd.sparc.cpu_type.nwindows;
372            cpu->cd.sparc.cansave --;
373            cpu->cd.sparc.canrestore ++;    /*  TODO: modulo here too?  */
374    
375            /*  The out registers become the new in registers:  */
376            memcpy(&cpu->cd.sparc.r[SPARC_REG_I0], &cpu->cd.sparc.r[SPARC_REG_O0],
377                sizeof(cpu->cd.sparc.r[SPARC_REG_O0]) * N_SPARC_INOUT_REG);
378    
379            /*  Read new local registers:  */
380            memcpy(&cpu->cd.sparc.r[SPARC_REG_L0], &cpu->cd.sparc.r_local[cwp][0],
381                sizeof(cpu->cd.sparc.r[SPARC_REG_L0]) * N_SPARC_INOUT_REG);
382    
383            reg(ic->arg[2]) = rs;
384    }
385    
386    
387    /*
388   *  Subtract with ccr update:   *  Subtract with ccr update:
389   *   *
390   *  arg[0] = ptr to rs1   *  arg[0] = ptr to rs1
# Line 383  X(subcc_imm) Line 441  X(subcc_imm)
441  }  }
442    
443    
444    #include "tmp_sparc_loadstore.c"
445    
446    
447  /*  /*
448   *  rd:  Read special register:   *  rd:  Read special register:
449   *   *
# Line 483  X(end_of_page2) Line 544  X(end_of_page2)
544  X(to_be_translated)  X(to_be_translated)
545  {  {
546          MODE_uint_t addr;          MODE_uint_t addr;
547          int low_pc;          int low_pc, in_crosspage_delayslot = 0;
         int in_crosspage_delayslot = 0;  
548          uint32_t iword;          uint32_t iword;
549          unsigned char *page;          unsigned char *page;
550          unsigned char ib[4];          unsigned char ib[4];
551          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;
552            int store, signedness, size;
553          int32_t tmpi32, siconst;          int32_t tmpi32, siconst;
554          /* void (*samepage_function)(struct cpu *, struct sparc_instr_call *);*/          /* void (*samepage_function)(struct cpu *, struct sparc_instr_call *);*/
555    
# Line 621  X(to_be_translated) Line 682  X(to_be_translated)
682                  case 37:/*  sll  */                  case 37:/*  sll  */
683                  case 38:/*  srl  */                  case 38:/*  srl  */
684                  case 39:/*  sra  */                  case 39:/*  sra  */
685                    case 60:/*  save  */
686                          ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];                          ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
687                          ic->f = NULL;                          ic->f = NULL;
688                          if (use_imm) {                          if (use_imm) {
# Line 659  X(to_be_translated) Line 721  X(to_be_translated)
721                                                  ic->arg[1] &= 31;                                                  ic->arg[1] &= 31;
722                                          }                                          }
723                                          break;                                          break;
724                                    case 60:switch (cpu->cd.sparc.cpu_type.v) {
725                                            case 9: ic->f = instr(save_v9_imm);
726                                                    break;
727                                            default:fatal("only for v9 so far\n");
728                                                    goto bad;
729                                            }
730                                  }                                  }
731                          } else {                          } else {
732                                  ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];                                  ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
# Line 696  X(to_be_translated) Line 764  X(to_be_translated)
764                          }                          }
765                          ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];                          ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
766                          if (rd == SPARC_ZEROREG) {                          if (rd == SPARC_ZEROREG) {
767                                  /*  Opcodes which update the ccr should use                                  /*
768                                      the scratch register instead of being                                   *  Some opcodes should write to the scratch
769                                      turned into a nop, when the zero register                                   *  register instead of becoming NOPs, when
770                                      is used as the destination:  */                                   *  rd is the zero register.
771                                     */
772                                  switch (op2) {                                  switch (op2) {
773                                  case 20:/*  subcc  */                                  case 20:/*  subcc  */
774                                    case 60:/*  save  */
775                                          ic->arg[2] = (size_t)                                          ic->arg[2] = (size_t)
776                                              &cpu->cd.sparc.scratch;                                              &cpu->cd.sparc.scratch;
777                                          break;                                          break;
# Line 813  X(to_be_translated) Line 883  X(to_be_translated)
883                  }                  }
884                  break;                  break;
885    
886          default:fatal("TODO: unimplemented main opcode %i\n", main_opcode);          case 3: switch (op2) {
887                  goto bad;  
888                    case  0:/*  lduw  */
889                    case  1:/*  ldub  */
890                    case  2:/*  lduh  */
891                    case  4:/*  st(w) */
892                    case  5:/*  stb   */
893                    case  6:/*  sth   */
894                    case  8:/*  ldsw  */
895                    case  9:/*  ldsb  */
896                    case 10:/*  ldsh  */
897                    case 11:/*  ldx  */
898                    case 14:/*  stx   */
899                            store = 1; signedness = 0; size = 3;
900                            switch (op2) {
901                            case  0: /*  lduw  */   store=0; size=2; break;
902                            case  1: /*  ldub  */   store=0; size=0; break;
903                            case  2: /*  lduh  */   store=0; size=1; break;
904                            case  4: /*  st  */     size = 2; break;
905                            case  5: /*  stb  */    size = 0; break;
906                            case  6: /*  sth  */    size = 1; break;
907                            case  8: /*  ldsw  */   store=0; size=2; signedness=1;
908                                                    break;
909                            case  9: /*  ldsb  */   store=0; size=0; signedness=1;
910                                                    break;
911                            case 10: /*  ldsh  */   store=0; size=1; signedness=1;
912                                                    break;
913                            case 11: /*  ldx  */    store=0; break;
914                            case 14: /*  stx  */    break;
915                            }
916                            ic->f =
917    #ifdef MODE32
918                                sparc32_loadstore
919    #else
920                                sparc_loadstore
921    #endif
922                                [ use_imm*16 + store*8 + size*2 + signedness ];
923    
924                            ic->arg[0] = (size_t)&cpu->cd.sparc.r[rd];
925                            ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs1];
926                            if (use_imm)
927                                    ic->arg[2] = siconst;
928                            else
929                                    ic->arg[2] = (size_t)&cpu->cd.sparc.r[rs2];
930    
931                            if (!store && rd == SPARC_ZEROREG)
932                                    ic->arg[0] = (size_t)&cpu->cd.sparc.scratch;
933    
934                            break;
935    
936                    default:fatal("TODO: unimplemented op2=%i for main "
937                                "opcode %i\n", op2, main_opcode);
938                            goto bad;
939                    }
940                    break;
941    
942          }          }
943    
944    

Legend:
Removed from v.27  
changed lines
  Added in v.28

  ViewVC Help
Powered by ViewVC 1.1.26