/[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 14 by dpavlin, Mon Oct 8 16:18:51 2007 UTC revision 32 by dpavlin, Mon Oct 8 16:20:58 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.2 2005/09/17 17:14:27 debug Exp $   *  $Id: cpu_alpha_instr.c,v 1.14 2006/08/21 17:02:36 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 62  X(call_pal) Line 65  X(call_pal)
65          alpha_palcode(cpu, ic->arg[0]);          alpha_palcode(cpu, ic->arg[0]);
66    
67          if (!cpu->running) {          if (!cpu->running) {
                 cpu->running_translated = 0;  
68                  cpu->n_translated_instrs --;                  cpu->n_translated_instrs --;
69                  cpu->cd.alpha.next_ic = &nothing_call;                  cpu->cd.alpha.next_ic = &nothing_call;
70          } else if (cpu->pc != old_pc) {          } else if (cpu->pc != old_pc) {
# Line 455  X(bgt_samepage) Line 457  X(bgt_samepage)
457    
458    
459  /*  /*
460     *  cvttq/c:  Convert floating point to quad.
461     *
462     *  arg[0] = pointer to rc  (destination integer)
463     *  arg[2] = pointer to rb  (source float)
464     */
465    X(cvttq_c)
466    {
467            struct ieee_float_value fb;
468            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
469            reg(ic->arg[0]) = fb.nan? 0 : fb.f;
470    }
471    
472    
473    /*
474     *  cvtqt:  Convert quad to floating point.
475     *
476     *  arg[0] = pointer to rc  (destination float)
477     *  arg[2] = pointer to rb  (source quad integer)
478     */
479    X(cvtqt)
480    {
481            reg(ic->arg[0]) = ieee_store_float_value(reg(ic->arg[2]),
482                IEEE_FMT_D, 0);
483    }
484    
485    
486    /*
487     *  fabs, fneg:  Floating point absolute value, or negation.
488     *
489     *  arg[0] = pointer to rc  (destination float)
490     *  arg[2] = pointer to rb  (source quad integer)
491     */
492    X(fabs)
493    {
494            reg(ic->arg[0]) = reg(ic->arg[2]) & 0x7fffffffffffffffULL;
495    }
496    X(fneg)
497    {
498            reg(ic->arg[0]) = reg(ic->arg[2]) ^ 0x8000000000000000ULL;
499    }
500    
501    
502    /*
503     *  addt, subt, mult, divt:  Floating point arithmetic.
504     *
505     *  arg[0] = pointer to rc  (destination)
506     *  arg[1] = pointer to ra  (source)
507     *  arg[2] = pointer to rb  (source)
508     */
509    X(addt)
510    {
511            struct ieee_float_value fa, fb;
512            double res;
513            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
514            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
515            if (fa.nan | fb.nan)
516                    res = 0.0;
517            else
518                    res = fa.f + fb.f;
519            reg(ic->arg[0]) = ieee_store_float_value(res,
520                IEEE_FMT_D, fa.nan | fb.nan);
521    }
522    X(subt)
523    {
524            struct ieee_float_value fa, fb;
525            double res;
526            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
527            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
528            if (fa.nan | fb.nan)
529                    res = 0.0;
530            else
531                    res = fa.f - fb.f;
532            reg(ic->arg[0]) = ieee_store_float_value(res,
533                IEEE_FMT_D, fa.nan | fb.nan);
534    }
535    X(mult)
536    {
537            struct ieee_float_value fa, fb;
538            double res;
539            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
540            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
541            if (fa.nan | fb.nan)
542                    res = 0.0;
543            else
544                    res = fa.f * fb.f;
545            reg(ic->arg[0]) = ieee_store_float_value(res,
546                IEEE_FMT_D, fa.nan | fb.nan);
547    }
548    X(divt)
549    {
550            struct ieee_float_value fa, fb;
551            double res;
552            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
553            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
554            if (fa.nan | fb.nan || fb.f == 0)
555                    res = 0.0;
556            else
557                    res = fa.f / fb.f;
558            reg(ic->arg[0]) = ieee_store_float_value(res,
559                IEEE_FMT_D, fa.nan | fb.nan || fb.f == 0);
560    }
561    X(cmpteq)
562    {
563            struct ieee_float_value fa, fb;
564            int res = 0;
565            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
566            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
567            if (fa.nan | fb.nan)
568                    res = 0;
569            else
570                    res = fa.f == fb.f;
571            reg(ic->arg[0]) = res;
572    }
573    X(cmptlt)
574    {
575            struct ieee_float_value fa, fb;
576            int res = 0;
577            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
578            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
579            if (fa.nan | fb.nan)
580                    res = 0;
581            else
582                    res = fa.f < fb.f;
583            reg(ic->arg[0]) = res;
584    }
585    X(cmptle)
586    {
587            struct ieee_float_value fa, fb;
588            int res = 0;
589            ieee_interpret_float_value(reg(ic->arg[1]), &fa, IEEE_FMT_D);
590            ieee_interpret_float_value(reg(ic->arg[2]), &fb, IEEE_FMT_D);
591            if (fa.nan | fb.nan)
592                    res = 0;
593            else
594                    res = fa.f <= fb.f;
595            reg(ic->arg[0]) = res;
596    }
597    
598    
599    /*
600     *  implver:  Return CPU implver value.
601     *
602     *  arg[0] = pointer to destination uint64_t
603     */
604    X(implver)
605    {
606            reg(ic->arg[0]) = cpu->cd.alpha.cpu_type.implver;
607    }
608    
609    
610    /*
611   *  mull:  Signed Multiply 32x32 => 32.   *  mull:  Signed Multiply 32x32 => 32.
612   *   *
613   *  arg[0] = pointer to destination uint64_t   *  arg[0] = pointer to destination uint64_t
# Line 595  X(end_of_page) Line 748  X(end_of_page)
748    
749    
750  /*  /*
  *  alpha_combine_instructions():  
  *  
  *  Combine two or more instructions, if possible, into a single function call.  
  */  
 void alpha_combine_instructions(struct cpu *cpu, struct alpha_instr_call *ic,  
         uint64_t addr)  
 {  
         int n_back;  
         n_back = (addr >> 2) & (ALPHA_IC_ENTRIES_PER_PAGE-1);  
   
         if (n_back >= 1) {  
         }  
   
         /*  TODO: Combine forward as well  */  
 }  
   
   
 /*****************************************************************************/  
   
   
 /*  
751   *  alpha_instr_to_be_translated():   *  alpha_instr_to_be_translated():
752   *   *
753   *  Translate an instruction word into an alpha_instr_call. ic is filled in with   *  Translate an instruction word into an alpha_instr_call. ic is filled in with
# Line 627  X(to_be_translated) Line 759  X(to_be_translated)
759  {  {
760          uint64_t addr, low_pc;          uint64_t addr, low_pc;
761          uint32_t iword;          uint32_t iword;
         struct alpha_vph_page *vph_p;  
762          unsigned char *page;          unsigned char *page;
763          unsigned char ib[4];          unsigned char ib[4];
764          void (*samepage_function)(struct cpu *, struct alpha_instr_call *);          void (*samepage_function)(struct cpu *, struct alpha_instr_call *);
# Line 643  X(to_be_translated) Line 774  X(to_be_translated)
774          cpu->pc = addr;          cpu->pc = addr;
775    
776          /*  Read the instruction word from memory:  */          /*  Read the instruction word from memory:  */
777          if ((addr >> ALPHA_TOPSHIFT) == 0) {          {
778                  vph_p = cpu->cd.alpha.vph_table0[(addr >>                  const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
779                      ALPHA_LEVEL0_SHIFT) & 8191];                  const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
780                  page = vph_p->host_load[(addr >> ALPHA_LEVEL1_SHIFT) & 8191];                  const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
781          } else if ((addr >> ALPHA_TOPSHIFT) == ALPHA_TOP_KERNEL) {                  uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
782                  vph_p = cpu->cd.alpha.vph_table0_kernel[(addr >>                  uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
783                      ALPHA_LEVEL0_SHIFT) & 8191];                  uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
784                  page = vph_p->host_load[(addr >> ALPHA_LEVEL1_SHIFT) & 8191];                      DYNTRANS_L3N)) & mask3;
785          } else                  struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.alpha.l1_64[x1];
786                  page = NULL;                  struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
787                    page = l3->host_load[x3];
788            }
789    
790          if (page != NULL) {          if (page != NULL) {
791                  /*  fatal("TRANSLATION HIT!\n");  */                  /*  fatal("TRANSLATION HIT!\n");  */
# Line 666  X(to_be_translated) Line 799  X(to_be_translated)
799                  }                  }
800          }          }
801    
802  #ifdef HOST_LITTLE_ENDIAN          /*  Alpha instruction words are always little-endian. Convert
803          iword = *((uint32_t *)&ib[0]);              to host order:  */
804  #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);  */  
805    
806    
807  #define DYNTRANS_TO_BE_TRANSLATED_HEAD  #define DYNTRANS_TO_BE_TRANSLATED_HEAD
# Line 761  X(to_be_translated) Line 889  X(to_be_translated)
889                  }                  }
890                  ic->f = alpha_loadstore[                  ic->f = alpha_loadstore[
891                      loadstore_type + (imm==0? 4 : 0) + 8 * load                      loadstore_type + (imm==0? 4 : 0) + 8 * load
892                      + (cpu->machine->dyntrans_alignment_check? 16:0)                      + 16 * llsc];
                     + 32 * llsc];  
893                  /*  Load to the zero register is treated as a prefetch                  /*  Load to the zero register is treated as a prefetch
894                      hint. It is ignored here.  */                      hint. It is ignored here.  */
895                  if (load && ra == ALPHA_ZERO) {                  if (load && ra == ALPHA_ZERO) {
# Line 792  X(to_be_translated) Line 919  X(to_be_translated)
919                  case 0x02: ic->f = instr(s4addl); break;                  case 0x02: ic->f = instr(s4addl); break;
920                  case 0x09: ic->f = instr(subl); break;                  case 0x09: ic->f = instr(subl); break;
921                  case 0x0b: ic->f = instr(s4subl); break;                  case 0x0b: ic->f = instr(s4subl); break;
922                    case 0x0f: ic->f = instr(cmpbge); break;
923                  case 0x12: ic->f = instr(s8addl); break;                  case 0x12: ic->f = instr(s8addl); break;
924                  case 0x1b: ic->f = instr(s8subl); break;                  case 0x1b: ic->f = instr(s8subl); break;
925                  case 0x1d: ic->f = instr(cmpult); break;                  case 0x1d: ic->f = instr(cmpult); break;
# Line 810  X(to_be_translated) Line 938  X(to_be_translated)
938                  case 0x82: ic->f = instr(s4addl_imm); break;                  case 0x82: ic->f = instr(s4addl_imm); break;
939                  case 0x89: ic->f = instr(subl_imm); break;                  case 0x89: ic->f = instr(subl_imm); break;
940                  case 0x8b: ic->f = instr(s4subl_imm); break;                  case 0x8b: ic->f = instr(s4subl_imm); break;
941                    case 0x8f: ic->f = instr(cmpbge_imm); break;
942                  case 0x92: ic->f = instr(s8addl_imm); break;                  case 0x92: ic->f = instr(s8addl_imm); break;
943                  case 0x9b: ic->f = instr(s8subl_imm); break;                  case 0x9b: ic->f = instr(s8subl_imm); break;
944                  case 0x9d: ic->f = instr(cmpult_imm); break;                  case 0x9d: ic->f = instr(cmpult_imm); break;
# Line 875  X(to_be_translated) Line 1004  X(to_be_translated)
1004                  case 0xc8: ic->f = instr(xornot_imm); break;                  case 0xc8: ic->f = instr(xornot_imm); break;
1005                  case 0xe4: ic->f = instr(cmovle_imm); break;                  case 0xe4: ic->f = instr(cmovle_imm); break;
1006                  case 0xe6: ic->f = instr(cmovgt_imm); break;                  case 0xe6: ic->f = instr(cmovgt_imm); break;
1007                    case 0xec: ic->f = instr(implver); break;
1008                  default:fatal("[ Alpha: unimplemented function 0x%03x for"                  default:fatal("[ Alpha: unimplemented function 0x%03x for"
1009                              " opcode 0x%02x ]\n", func, opcode);                              " opcode 0x%02x ]\n", func, opcode);
1010                          goto bad;                          goto bad;
# Line 978  X(to_be_translated) Line 1108  X(to_be_translated)
1108                  ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];                  ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];
1109                  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];                  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];
1110                  switch (func & 0x7ff) {                  switch (func & 0x7ff) {
1111                    case 0x02f: ic->f = instr(cvttq_c); break;
1112                    case 0x0a0: ic->f = instr(addt); break;
1113                    case 0x0a1: ic->f = instr(subt); break;
1114                    case 0x0a2: ic->f = instr(mult); break;
1115                    case 0x0a3: ic->f = instr(divt); break;
1116                    case 0x0a5: ic->f = instr(cmpteq); break;
1117                    case 0x0a6: ic->f = instr(cmptlt); break;
1118                    case 0x0a7: ic->f = instr(cmptle); break;
1119                    case 0x0be: ic->f = instr(cvtqt); break;
1120                  default:fatal("[ Alpha: unimplemented function 0x%03x for"                  default:fatal("[ Alpha: unimplemented function 0x%03x for"
1121                              " opcode 0x%02x ]\n", func, opcode);                              " opcode 0x%02x ]\n", func, opcode);
1122                          goto bad;                          goto bad;
# Line 993  X(to_be_translated) Line 1132  X(to_be_translated)
1132                  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];                  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];
1133                  switch (func & 0x7ff) {                  switch (func & 0x7ff) {
1134                  case 0x020:                  case 0x020:
1135                          /*  fclr:  */                          /*  fabs (or fclr):  */
1136                          if (ra == 31 && rb == 31)                          if (ra == 31 && rb == 31)
1137                                  ic->f = instr(clear);                                  ic->f = instr(clear);
1138                          else {                          else
1139                                  /*  fabs:  */                                  ic->f = instr(fabs);
1140                                  goto bad;                          break;
1141                          }                  case 0x021:
1142                            ic->f = instr(fneg);
1143                          break;                          break;
1144                  default:fatal("[ Alpha: unimplemented function 0x%03x for"                  default:fatal("[ Alpha: unimplemented function 0x%03x for"
1145                              " opcode 0x%02x ]\n", func, opcode);                              " opcode 0x%02x ]\n", func, opcode);
# Line 1050  X(to_be_translated) Line 1190  X(to_be_translated)
1190                          goto bad;                          goto bad;
1191                  }                  }
1192                  break;                  break;
1193          case 0x30:                                              /*  BR  */          case 0x30:                                              /*  BR    */
1194          case 0x34:                                              /*  BSR  */          case 0x31:                                              /*  FBEQ  */
1195            case 0x34:                                              /*  BSR   */
1196            case 0x35:                                              /*  FBNE  */
1197          case 0x38:                                              /*  BLBC  */          case 0x38:                                              /*  BLBC  */
1198          case 0x39:                                              /*  BEQ  */          case 0x39:                                              /*  BEQ   */
1199          case 0x3a:                                              /*  BLT  */          case 0x3a:                                              /*  BLT   */
1200          case 0x3b:                                              /*  BLE  */          case 0x3b:                                              /*  BLE   */
1201          case 0x3c:                                              /*  BLBS  */          case 0x3c:                                              /*  BLBS  */
1202          case 0x3d:                                              /*  BNE  */          case 0x3d:                                              /*  BNE   */
1203          case 0x3e:                                              /*  BGE  */          case 0x3e:                                              /*  BGE   */
1204          case 0x3f:                                              /*  BGT  */          case 0x3f:                                              /*  BGT   */
1205                  /*  To avoid a GCC warning:  */                  /*  To avoid a GCC warning:  */
1206                  samepage_function = instr(nop);                  samepage_function = instr(nop);
1207                    fp = 0;
1208                  switch (opcode) {                  switch (opcode) {
1209                  case 0x30:                  case 0x30:
1210                  case 0x34:                  case 0x34:
# Line 1076  X(to_be_translated) Line 1219  X(to_be_translated)
1219                          ic->f = instr(blbc);                          ic->f = instr(blbc);
1220                          samepage_function = instr(blbc_samepage);                          samepage_function = instr(blbc_samepage);
1221                          break;                          break;
1222                    case 0x31:
1223                            fp = 1;
1224                  case 0x39:                  case 0x39:
1225                          ic->f = instr(beq);                          ic->f = instr(beq);
1226                          samepage_function = instr(beq_samepage);                          samepage_function = instr(beq_samepage);
# Line 1092  X(to_be_translated) Line 1237  X(to_be_translated)
1237                          ic->f = instr(blbs);                          ic->f = instr(blbs);
1238                          samepage_function = instr(blbs_samepage);                          samepage_function = instr(blbs_samepage);
1239                          break;                          break;
1240                    case 0x35:
1241                            fp = 1;
1242                  case 0x3d:                  case 0x3d:
1243                          ic->f = instr(bne);                          ic->f = instr(bne);
1244                          samepage_function = instr(bne_samepage);                          samepage_function = instr(bne_samepage);
# Line 1105  X(to_be_translated) Line 1252  X(to_be_translated)
1252                          samepage_function = instr(bgt_samepage);                          samepage_function = instr(bgt_samepage);
1253                          break;                          break;
1254                  }                  }
1255                  ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];                  if (fp)
1256                            ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];
1257                    else
1258                            ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];
1259                  ic->arg[0] = (iword & 0x001fffff) << 2;                  ic->arg[0] = (iword & 0x001fffff) << 2;
1260                  /*  Sign-extend:  */                  /*  Sign-extend:  */
1261                  if (ic->arg[0] & 0x00400000)                  if (ic->arg[0] & 0x00400000)

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

  ViewVC Help
Powered by ViewVC 1.1.26