/[gxemul]/trunk/src/cpus/cpu_alpha_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_alpha_instr.c

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

revision 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 28 by dpavlin, Mon Oct 8 16:20:26 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_alpha_instr.c,v 1.3 2005/11/06 22:41:11 debug Exp $   *  $Id: cpu_alpha_instr.c,v 1.12 2006/06/30 20:22:53 debug Exp $
29   *   *
30   *  Alpha instructions.   *  Alpha instructions.
31   *   *
# Line 36  Line 36 
36   */   */
37    
38    
39    #include "float_emul.h"
40    
41    
42  /*  /*
43   *  nop:  Do nothing.   *  nop:  Do nothing.
44   */   */
# Line 455  X(bgt_samepage) Line 458  X(bgt_samepage)
458    
459    
460  /*  /*
461     *  cvttq/c:  Convert floating point to quad.
462     *
463     *  arg[0] = pointer to rc  (destination integer)
464     *  arg[2] = pointer to rb  (source float)
465     */
466    X(cvttq_c)
467    {
468            struct ieee_float_value fb;
469            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
470            reg(ic->arg[0]) = fb.nan? 0 : fb.f;
471    }
472    
473    
474    /*
475     *  cvtqt:  Convert quad to floating point.
476     *
477     *  arg[0] = pointer to rc  (destination float)
478     *  arg[2] = pointer to rb  (source quad integer)
479     */
480    X(cvtqt)
481    {
482            reg(ic->arg[0]) = ieee_store_float_value(reg(ic->arg[2]),
483                IEEE_FMT_D, 0);
484    }
485    
486    
487    /*
488     *  fabs, fneg:  Floating point absolute value, or negation.
489     *
490     *  arg[0] = pointer to rc  (destination float)
491     *  arg[2] = pointer to rb  (source quad integer)
492     */
493    X(fabs)
494    {
495            reg(ic->arg[0]) = reg(ic->arg[2]) & 0x7fffffffffffffffULL;
496    }
497    X(fneg)
498    {
499            reg(ic->arg[0]) = reg(ic->arg[2]) ^ 0x8000000000000000ULL;
500    }
501    
502    
503    /*
504     *  addt, subt, mult, divt:  Floating point arithmetic.
505     *
506     *  arg[0] = pointer to rc  (destination)
507     *  arg[1] = pointer to ra  (source)
508     *  arg[2] = pointer to rb  (source)
509     */
510    X(addt)
511    {
512            struct ieee_float_value fa, fb;
513            double res;
514            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
515            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
516            if (fa.nan | fb.nan)
517                    res = 0.0;
518            else
519                    res = fa.f + fb.f;
520            reg(ic->arg[0]) = ieee_store_float_value(res,
521                IEEE_FMT_D, fa.nan | fb.nan);
522    }
523    X(subt)
524    {
525            struct ieee_float_value fa, fb;
526            double res;
527            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
528            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
529            if (fa.nan | fb.nan)
530                    res = 0.0;
531            else
532                    res = fa.f - fb.f;
533            reg(ic->arg[0]) = ieee_store_float_value(res,
534                IEEE_FMT_D, fa.nan | fb.nan);
535    }
536    X(mult)
537    {
538            struct ieee_float_value fa, fb;
539            double res;
540            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
541            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
542            if (fa.nan | fb.nan)
543                    res = 0.0;
544            else
545                    res = fa.f * fb.f;
546            reg(ic->arg[0]) = ieee_store_float_value(res,
547                IEEE_FMT_D, fa.nan | fb.nan);
548    }
549    X(divt)
550    {
551            struct ieee_float_value fa, fb;
552            double res;
553            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
554            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
555            if (fa.nan | fb.nan || fb.f == 0)
556                    res = 0.0;
557            else
558                    res = fa.f / fb.f;
559            reg(ic->arg[0]) = ieee_store_float_value(res,
560                IEEE_FMT_D, fa.nan | fb.nan || fb.f == 0);
561    }
562    X(cmpteq)
563    {
564            struct ieee_float_value fa, fb;
565            int res = 0;
566            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
567            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
568            if (fa.nan | fb.nan)
569                    res = 0;
570            else
571                    res = fa.f == fb.f;
572            reg(ic->arg[0]) = res;
573    }
574    X(cmptlt)
575    {
576            struct ieee_float_value fa, fb;
577            int res = 0;
578            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
579            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
580            if (fa.nan | fb.nan)
581                    res = 0;
582            else
583                    res = fa.f < fb.f;
584            reg(ic->arg[0]) = res;
585    }
586    X(cmptle)
587    {
588            struct ieee_float_value fa, fb;
589            int res = 0;
590            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
591            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
592            if (fa.nan | fb.nan)
593                    res = 0;
594            else
595                    res = fa.f <= fb.f;
596            reg(ic->arg[0]) = res;
597    }
598    
599    
600    /*
601   *  mull:  Signed Multiply 32x32 => 32.   *  mull:  Signed Multiply 32x32 => 32.
602   *   *
603   *  arg[0] = pointer to destination uint64_t   *  arg[0] = pointer to destination uint64_t
# Line 606  X(to_be_translated) Line 749  X(to_be_translated)
749  {  {
750          uint64_t addr, low_pc;          uint64_t addr, low_pc;
751          uint32_t iword;          uint32_t iword;
         struct alpha_vph_page *vph_p;  
752          unsigned char *page;          unsigned char *page;
753          unsigned char ib[4];          unsigned char ib[4];
754          void (*samepage_function)(struct cpu *, struct alpha_instr_call *);          void (*samepage_function)(struct cpu *, struct alpha_instr_call *);
# Line 622  X(to_be_translated) Line 764  X(to_be_translated)
764          cpu->pc = addr;          cpu->pc = addr;
765    
766          /*  Read the instruction word from memory:  */          /*  Read the instruction word from memory:  */
767          if ((addr >> ALPHA_TOPSHIFT) == 0) {          {
768                  vph_p = cpu->cd.alpha.vph_table0[(addr >>                  const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
769                      ALPHA_LEVEL0_SHIFT) & 8191];                  const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
770                  page = vph_p->host_load[(addr >> ALPHA_LEVEL1_SHIFT) & 8191];                  const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
771          } else if ((addr >> ALPHA_TOPSHIFT) == ALPHA_TOP_KERNEL) {                  uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
772                  vph_p = cpu->cd.alpha.vph_table0_kernel[(addr >>                  uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
773                      ALPHA_LEVEL0_SHIFT) & 8191];                  uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
774                  page = vph_p->host_load[(addr >> ALPHA_LEVEL1_SHIFT) & 8191];                      DYNTRANS_L3N)) & mask3;
775          } else                  struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.alpha.l1_64[x1];
776                  page = NULL;                  struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
777                    page = l3->host_load[x3];
778            }
779    
780          if (page != NULL) {          if (page != NULL) {
781                  /*  fatal("TRANSLATION HIT!\n");  */                  /*  fatal("TRANSLATION HIT!\n");  */
# Line 645  X(to_be_translated) Line 789  X(to_be_translated)
789                  }                  }
790          }          }
791    
792  #ifdef HOST_LITTLE_ENDIAN          /*  Alpha instruction words are always little-endian. Convert
793          iword = *((uint32_t *)&ib[0]);              to host order:  */
794  #else          iword = LE32_TO_HOST( *((uint32_t *)&ib[0]) );
         iword = ib[0] + (ib[1]<<8) + (ib[2]<<16) + (ib[3]<<24);  
 #endif  
   
         /*  fatal("{ Alpha: translating pc=0x%016llx iword=0x%08x }\n",  
             (long long)addr, (int)iword);  */  
795    
796    
797  #define DYNTRANS_TO_BE_TRANSLATED_HEAD  #define DYNTRANS_TO_BE_TRANSLATED_HEAD
# Line 740  X(to_be_translated) Line 879  X(to_be_translated)
879                  }                  }
880                  ic->f = alpha_loadstore[                  ic->f = alpha_loadstore[
881                      loadstore_type + (imm==0? 4 : 0) + 8 * load                      loadstore_type + (imm==0? 4 : 0) + 8 * load
882                      + (cpu->machine->dyntrans_alignment_check? 16:0)                      + 16 * llsc];
                     + 32 * llsc];  
883                  /*  Load to the zero register is treated as a prefetch                  /*  Load to the zero register is treated as a prefetch
884                      hint. It is ignored here.  */                      hint. It is ignored here.  */
885                  if (load && ra == ALPHA_ZERO) {                  if (load && ra == ALPHA_ZERO) {
# Line 771  X(to_be_translated) Line 909  X(to_be_translated)
909                  case 0x02: ic->f = instr(s4addl); break;                  case 0x02: ic->f = instr(s4addl); break;
910                  case 0x09: ic->f = instr(subl); break;                  case 0x09: ic->f = instr(subl); break;
911                  case 0x0b: ic->f = instr(s4subl); break;                  case 0x0b: ic->f = instr(s4subl); break;
912                    case 0x0f: ic->f = instr(cmpbge); break;
913                  case 0x12: ic->f = instr(s8addl); break;                  case 0x12: ic->f = instr(s8addl); break;
914                  case 0x1b: ic->f = instr(s8subl); break;                  case 0x1b: ic->f = instr(s8subl); break;
915                  case 0x1d: ic->f = instr(cmpult); break;                  case 0x1d: ic->f = instr(cmpult); break;
# Line 789  X(to_be_translated) Line 928  X(to_be_translated)
928                  case 0x82: ic->f = instr(s4addl_imm); break;                  case 0x82: ic->f = instr(s4addl_imm); break;
929                  case 0x89: ic->f = instr(subl_imm); break;                  case 0x89: ic->f = instr(subl_imm); break;
930                  case 0x8b: ic->f = instr(s4subl_imm); break;                  case 0x8b: ic->f = instr(s4subl_imm); break;
931                    case 0x8f: ic->f = instr(cmpbge_imm); break;
932                  case 0x92: ic->f = instr(s8addl_imm); break;                  case 0x92: ic->f = instr(s8addl_imm); break;
933                  case 0x9b: ic->f = instr(s8subl_imm); break;                  case 0x9b: ic->f = instr(s8subl_imm); break;
934                  case 0x9d: ic->f = instr(cmpult_imm); break;                  case 0x9d: ic->f = instr(cmpult_imm); break;
# Line 957  X(to_be_translated) Line 1097  X(to_be_translated)
1097                  ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];                  ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];
1098                  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];                  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];
1099                  switch (func & 0x7ff) {                  switch (func & 0x7ff) {
1100                    case 0x02f: ic->f = instr(cvttq_c); break;
1101                    case 0x0a0: ic->f = instr(addt); break;
1102                    case 0x0a1: ic->f = instr(subt); break;
1103                    case 0x0a2: ic->f = instr(mult); break;
1104                    case 0x0a3: ic->f = instr(divt); break;
1105                    case 0x0a5: ic->f = instr(cmpteq); break;
1106                    case 0x0a6: ic->f = instr(cmptlt); break;
1107                    case 0x0a7: ic->f = instr(cmptle); break;
1108                    case 0x0be: ic->f = instr(cvtqt); break;
1109                  default:fatal("[ Alpha: unimplemented function 0x%03x for"                  default:fatal("[ Alpha: unimplemented function 0x%03x for"
1110                              " opcode 0x%02x ]\n", func, opcode);                              " opcode 0x%02x ]\n", func, opcode);
1111                          goto bad;                          goto bad;
# Line 972  X(to_be_translated) Line 1121  X(to_be_translated)
1121                  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];                  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];
1122                  switch (func & 0x7ff) {                  switch (func & 0x7ff) {
1123                  case 0x020:                  case 0x020:
1124                          /*  fclr:  */                          /*  fabs (or fclr):  */
1125                          if (ra == 31 && rb == 31)                          if (ra == 31 && rb == 31)
1126                                  ic->f = instr(clear);                                  ic->f = instr(clear);
1127                          else {                          else
1128                                  /*  fabs:  */                                  ic->f = instr(fabs);
1129                                  goto bad;                          break;
1130                          }                  case 0x021:
1131                            ic->f = instr(fneg);
1132                          break;                          break;
1133                  default:fatal("[ Alpha: unimplemented function 0x%03x for"                  default:fatal("[ Alpha: unimplemented function 0x%03x for"
1134                              " opcode 0x%02x ]\n", func, opcode);                              " opcode 0x%02x ]\n", func, opcode);
# Line 1029  X(to_be_translated) Line 1179  X(to_be_translated)
1179                          goto bad;                          goto bad;
1180                  }                  }
1181                  break;                  break;
1182          case 0x30:                                              /*  BR  */          case 0x30:                                              /*  BR    */
1183          case 0x34:                                              /*  BSR  */          case 0x31:                                              /*  FBEQ  */
1184            case 0x34:                                              /*  BSR   */
1185            case 0x35:                                              /*  FBNE  */
1186          case 0x38:                                              /*  BLBC  */          case 0x38:                                              /*  BLBC  */
1187          case 0x39:                                              /*  BEQ  */          case 0x39:                                              /*  BEQ   */
1188          case 0x3a:                                              /*  BLT  */          case 0x3a:                                              /*  BLT   */
1189          case 0x3b:                                              /*  BLE  */          case 0x3b:                                              /*  BLE   */
1190          case 0x3c:                                              /*  BLBS  */          case 0x3c:                                              /*  BLBS  */
1191          case 0x3d:                                              /*  BNE  */          case 0x3d:                                              /*  BNE   */
1192          case 0x3e:                                              /*  BGE  */          case 0x3e:                                              /*  BGE   */
1193          case 0x3f:                                              /*  BGT  */          case 0x3f:                                              /*  BGT   */
1194                  /*  To avoid a GCC warning:  */                  /*  To avoid a GCC warning:  */
1195                  samepage_function = instr(nop);                  samepage_function = instr(nop);
1196                    fp = 0;
1197                  switch (opcode) {                  switch (opcode) {
1198                  case 0x30:                  case 0x30:
1199                  case 0x34:                  case 0x34:
# Line 1055  X(to_be_translated) Line 1208  X(to_be_translated)
1208                          ic->f = instr(blbc);                          ic->f = instr(blbc);
1209                          samepage_function = instr(blbc_samepage);                          samepage_function = instr(blbc_samepage);
1210                          break;                          break;
1211                    case 0x31:
1212                            fp = 1;
1213                  case 0x39:                  case 0x39:
1214                          ic->f = instr(beq);                          ic->f = instr(beq);
1215                          samepage_function = instr(beq_samepage);                          samepage_function = instr(beq_samepage);
# Line 1071  X(to_be_translated) Line 1226  X(to_be_translated)
1226                          ic->f = instr(blbs);                          ic->f = instr(blbs);
1227                          samepage_function = instr(blbs_samepage);                          samepage_function = instr(blbs_samepage);
1228                          break;                          break;
1229                    case 0x35:
1230                            fp = 1;
1231                  case 0x3d:                  case 0x3d:
1232                          ic->f = instr(bne);                          ic->f = instr(bne);
1233                          samepage_function = instr(bne_samepage);                          samepage_function = instr(bne_samepage);
# Line 1084  X(to_be_translated) Line 1241  X(to_be_translated)
1241                          samepage_function = instr(bgt_samepage);                          samepage_function = instr(bgt_samepage);
1242                          break;                          break;
1243                  }                  }
1244                  ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];                  if (fp)
1245                            ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];
1246                    else
1247                            ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];
1248                  ic->arg[0] = (iword & 0x001fffff) << 2;                  ic->arg[0] = (iword & 0x001fffff) << 2;
1249                  /*  Sign-extend:  */                  /*  Sign-extend:  */
1250                  if (ic->arg[0] & 0x00400000)                  if (ic->arg[0] & 0x00400000)

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

  ViewVC Help
Powered by ViewVC 1.1.26