/[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 21 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 22 by dpavlin, Mon Oct 8 16:19:37 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.7 2006/02/09 22:40:27 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 611  X(to_be_translated) Line 754  X(to_be_translated)
754          unsigned char ib[4];          unsigned char ib[4];
755          void (*samepage_function)(struct cpu *, struct alpha_instr_call *);          void (*samepage_function)(struct cpu *, struct alpha_instr_call *);
756          int opcode, ra, rb, func, rc, imm, load, loadstore_type, fp, llsc;          int opcode, ra, rb, func, rc, imm, load, loadstore_type, fp, llsc;
757    #ifdef DYNTRANS_BACKEND
758            int simple = 0;
759    #endif
760    
761          /*  Figure out the (virtual) address of the instruction:  */          /*  Figure out the (virtual) address of the instruction:  */
762          low_pc = ((size_t)ic - (size_t)cpu->cd.alpha.cur_ic_page)          low_pc = ((size_t)ic - (size_t)cpu->cd.alpha.cur_ic_page)
# Line 957  X(to_be_translated) Line 1103  X(to_be_translated)
1103                  ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];                  ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];
1104                  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];                  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];
1105                  switch (func & 0x7ff) {                  switch (func & 0x7ff) {
1106                    case 0x02f: ic->f = instr(cvttq_c); break;
1107                    case 0x0a0: ic->f = instr(addt); break;
1108                    case 0x0a1: ic->f = instr(subt); break;
1109                    case 0x0a2: ic->f = instr(mult); break;
1110                    case 0x0a3: ic->f = instr(divt); break;
1111                    case 0x0a5: ic->f = instr(cmpteq); break;
1112                    case 0x0a6: ic->f = instr(cmptlt); break;
1113                    case 0x0a7: ic->f = instr(cmptle); break;
1114                    case 0x0be: ic->f = instr(cvtqt); break;
1115                  default:fatal("[ Alpha: unimplemented function 0x%03x for"                  default:fatal("[ Alpha: unimplemented function 0x%03x for"
1116                              " opcode 0x%02x ]\n", func, opcode);                              " opcode 0x%02x ]\n", func, opcode);
1117                          goto bad;                          goto bad;
# Line 972  X(to_be_translated) Line 1127  X(to_be_translated)
1127                  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];                  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];
1128                  switch (func & 0x7ff) {                  switch (func & 0x7ff) {
1129                  case 0x020:                  case 0x020:
1130                          /*  fclr:  */                          /*  fabs (or fclr):  */
1131                          if (ra == 31 && rb == 31)                          if (ra == 31 && rb == 31)
1132                                  ic->f = instr(clear);                                  ic->f = instr(clear);
1133                          else {                          else
1134                                  /*  fabs:  */                                  ic->f = instr(fabs);
1135                                  goto bad;                          break;
1136                          }                  case 0x021:
1137                            ic->f = instr(fneg);
1138                          break;                          break;
1139                  default:fatal("[ Alpha: unimplemented function 0x%03x for"                  default:fatal("[ Alpha: unimplemented function 0x%03x for"
1140                              " opcode 0x%02x ]\n", func, opcode);                              " opcode 0x%02x ]\n", func, opcode);
# Line 1029  X(to_be_translated) Line 1185  X(to_be_translated)
1185                          goto bad;                          goto bad;
1186                  }                  }
1187                  break;                  break;
1188          case 0x30:                                              /*  BR  */          case 0x30:                                              /*  BR    */
1189          case 0x34:                                              /*  BSR  */          case 0x31:                                              /*  FBEQ  */
1190            case 0x34:                                              /*  BSR   */
1191            case 0x35:                                              /*  FBNE  */
1192          case 0x38:                                              /*  BLBC  */          case 0x38:                                              /*  BLBC  */
1193          case 0x39:                                              /*  BEQ  */          case 0x39:                                              /*  BEQ   */
1194          case 0x3a:                                              /*  BLT  */          case 0x3a:                                              /*  BLT   */
1195          case 0x3b:                                              /*  BLE  */          case 0x3b:                                              /*  BLE   */
1196          case 0x3c:                                              /*  BLBS  */          case 0x3c:                                              /*  BLBS  */
1197          case 0x3d:                                              /*  BNE  */          case 0x3d:                                              /*  BNE   */
1198          case 0x3e:                                              /*  BGE  */          case 0x3e:                                              /*  BGE   */
1199          case 0x3f:                                              /*  BGT  */          case 0x3f:                                              /*  BGT   */
1200                  /*  To avoid a GCC warning:  */                  /*  To avoid a GCC warning:  */
1201                  samepage_function = instr(nop);                  samepage_function = instr(nop);
1202                    fp = 0;
1203                  switch (opcode) {                  switch (opcode) {
1204                  case 0x30:                  case 0x30:
1205                  case 0x34:                  case 0x34:
# Line 1055  X(to_be_translated) Line 1214  X(to_be_translated)
1214                          ic->f = instr(blbc);                          ic->f = instr(blbc);
1215                          samepage_function = instr(blbc_samepage);                          samepage_function = instr(blbc_samepage);
1216                          break;                          break;
1217                    case 0x31:
1218                            fp = 1;
1219                  case 0x39:                  case 0x39:
1220                          ic->f = instr(beq);                          ic->f = instr(beq);
1221                          samepage_function = instr(beq_samepage);                          samepage_function = instr(beq_samepage);
# Line 1071  X(to_be_translated) Line 1232  X(to_be_translated)
1232                          ic->f = instr(blbs);                          ic->f = instr(blbs);
1233                          samepage_function = instr(blbs_samepage);                          samepage_function = instr(blbs_samepage);
1234                          break;                          break;
1235                    case 0x35:
1236                            fp = 1;
1237                  case 0x3d:                  case 0x3d:
1238                          ic->f = instr(bne);                          ic->f = instr(bne);
1239                          samepage_function = instr(bne_samepage);                          samepage_function = instr(bne_samepage);
# Line 1084  X(to_be_translated) Line 1247  X(to_be_translated)
1247                          samepage_function = instr(bgt_samepage);                          samepage_function = instr(bgt_samepage);
1248                          break;                          break;
1249                  }                  }
1250                  ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];                  if (fp)
1251                            ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];
1252                    else
1253                            ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];
1254                  ic->arg[0] = (iword & 0x001fffff) << 2;                  ic->arg[0] = (iword & 0x001fffff) << 2;
1255                  /*  Sign-extend:  */                  /*  Sign-extend:  */
1256                  if (ic->arg[0] & 0x00400000)                  if (ic->arg[0] & 0x00400000)

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

  ViewVC Help
Powered by ViewVC 1.1.26