Home | History | Annotate | Line # | Download | only in mips
      1      1.1  christos // -*- C -*-
      2      1.1  christos //
      3      1.1  christos // NEC specific instructions
      4      1.1  christos //
      5      1.1  christos 
      6      1.1  christos :%s::::MFHI:int hi
      7      1.1  christos {
      8      1.1  christos   return hi ? "hi" : "";
      9      1.1  christos }
     10      1.1  christos 
     11      1.1  christos :%s::::SAT:int s
     12      1.1  christos {
     13      1.1  christos   return s ? "s" : "";
     14      1.1  christos }
     15      1.1  christos 
     16      1.1  christos :%s::::UNS:int u
     17      1.1  christos {
     18      1.1  christos   return u ? "u" : "";
     19      1.1  christos }
     20      1.1  christos 
     21      1.1  christos // Simulate the various kinds of multiply and multiply-accumulate instructions.
     22      1.1  christos // Perform an operation of the form:
     23      1.1  christos //
     24      1.1  christos //	LHS (+/-) GPR[RS] * GPR[RT]
     25      1.1  christos //
     26      1.1  christos // and store it in the 64-bit accumulator.  Optionally copy either LO or
     27      1.1  christos // HI into a general purpose register.
     28      1.1  christos //
     29      1.1  christos // - RD is the destination register of the LO or HI move
     30      1.1  christos // - RS are RT are the multiplication source registers
     31      1.1  christos // - ACCUMULATE_P is true if LHS should be the value of the 64-bit accumulator,
     32      1.1  christos //     false if it should be 0.
     33      1.1  christos // - STORE_HI_P is true if HI should be stored in RD, false if LO should be.
     34      1.1  christos // - UNSIGNED_P is true if the operation should be unsigned.
     35      1.1  christos // - SATURATE_P is true if the result should be saturated to a 32-bit value.
     36      1.1  christos // - SUBTRACT_P is true if the right hand side should be subtraced from LHS,
     37      1.1  christos //     false if it should be added.
     38      1.1  christos // - SHORT_P is true if RS and RT must be 16-bit numbers.
     39      1.1  christos // - DOUBLE_P is true if the 64-bit accumulator is in LO, false it is a
     40      1.1  christos //     concatenation of the low 32 bits of HI and LO.
     41      1.1  christos :function:::void:do_vr_mul_op:int rd, int rs, int rt, int accumulate_p, int store_hi_p, int unsigned_p, int saturate_p, int subtract_p, int short_p, int double_p
     42      1.1  christos {
     43  1.1.1.2  christos   uint64_t lhs, x, y, xcut, ycut, product, result;
     44      1.1  christos 
     45      1.1  christos   check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
     46      1.1  christos 
     47      1.1  christos   lhs = (!accumulate_p ? 0 : double_p ? LO : U8_4 (HI, LO));
     48      1.1  christos   x = GPR[rs];
     49      1.1  christos   y = GPR[rt];
     50      1.1  christos 
     51      1.1  christos   /* Work out the canonical form of X and Y from their significant bits.  */
     52      1.1  christos   if (!short_p)
     53      1.1  christos     {
     54      1.1  christos       /* Normal sign-extension rule for 32-bit operands.  */
     55      1.1  christos       xcut = EXTEND32 (x);
     56      1.1  christos       ycut = EXTEND32 (y);
     57      1.1  christos     }
     58      1.1  christos   else if (unsigned_p)
     59      1.1  christos     {
     60      1.1  christos       /* Operands must be zero-extended 16-bit numbers.  */
     61      1.1  christos       xcut = x & 0xffff;
     62      1.1  christos       ycut = y & 0xffff;
     63      1.1  christos     }
     64      1.1  christos   else
     65      1.1  christos     {
     66      1.1  christos       /* Likewise but sign-extended.  */
     67      1.1  christos       xcut = EXTEND16 (x);
     68      1.1  christos       ycut = EXTEND16 (y);
     69      1.1  christos     }
     70      1.1  christos   if (x != xcut || y != ycut)
     71      1.1  christos     sim_engine_abort (SD, CPU, CIA,
     72      1.1  christos 		      "invalid multiplication operand at 0x%08lx\n",
     73      1.1  christos 		      (long) CIA);
     74      1.1  christos 
     75      1.1  christos   TRACE_ALU_INPUT2 (x, y);
     76      1.1  christos   product = (unsigned_p
     77      1.1  christos 	     ? V8_4 (x, 1) * V8_4 (y, 1)
     78      1.1  christos 	     : EXTEND32 (x) * EXTEND32 (y));
     79      1.1  christos   result = (subtract_p ? lhs - product : lhs + product);
     80      1.1  christos   if (saturate_p)
     81      1.1  christos     {
     82      1.1  christos       /* Saturate the result to 32 bits.  An unsigned, unsaturated
     83      1.1  christos 	 result is zero-extended to 64 bits, but unsigned overflow
     84      1.1  christos 	 causes all 64 bits to be set.  */
     85  1.1.1.2  christos       if (!unsigned_p && (uint64_t) EXTEND32 (result) != result)
     86  1.1.1.2  christos 	result = ((int64_t) result < 0 ? -0x7fffffff - 1 : 0x7fffffff);
     87      1.1  christos       else if (unsigned_p && (result >> 32) != 0)
     88  1.1.1.2  christos 	result = (uint64_t) 0 - 1;
     89      1.1  christos     }
     90      1.1  christos   TRACE_ALU_RESULT (result);
     91      1.1  christos 
     92      1.1  christos   if (double_p)
     93      1.1  christos     LO = result;
     94      1.1  christos   else
     95      1.1  christos     {
     96      1.1  christos       LO = EXTEND32 (result);
     97      1.1  christos       HI = EXTEND32 (VH4_8 (result));
     98      1.1  christos     }
     99      1.1  christos   if (rd != 0)
    100      1.1  christos     GPR[rd] = store_hi_p ? HI : LO;
    101      1.1  christos }
    102      1.1  christos 
    103      1.1  christos // VR4100 instructions.
    104      1.1  christos 
    105      1.1  christos 000000,5.RS,5.RT,00000,00000,101000::32::MADD16
    106      1.1  christos "madd16 r<RS>, r<RT>"
    107      1.1  christos *vr4100:
    108      1.1  christos {
    109      1.1  christos   do_vr_mul_op (SD_, 0, RS, RT,
    110      1.1  christos 		1 /* accumulate */,
    111      1.1  christos 		0 /* store in LO */,
    112      1.1  christos 		0 /* signed arithmetic */,
    113      1.1  christos 		0 /* don't saturate */,
    114      1.1  christos 		0 /* don't subtract */,
    115      1.1  christos 		1 /* short */,
    116      1.1  christos 		0 /* single */);
    117      1.1  christos }
    118      1.1  christos 
    119      1.1  christos 000000,5.RS,5.RT,00000,00000,101001::64::DMADD16
    120      1.1  christos "dmadd16 r<RS>, r<RT>"
    121      1.1  christos *vr4100:
    122      1.1  christos {
    123      1.1  christos   do_vr_mul_op (SD_, 0, RS, RT,
    124      1.1  christos 		1 /* accumulate */,
    125      1.1  christos 		0 /* store in LO */,
    126      1.1  christos 		0 /* signed arithmetic */,
    127      1.1  christos 		0 /* don't saturate */,
    128      1.1  christos 		0 /* don't subtract */,
    129      1.1  christos 		1 /* short */,
    130      1.1  christos 		1 /* double */);
    131      1.1  christos }
    132      1.1  christos 
    133      1.1  christos 
    134      1.1  christos 
    135      1.1  christos // VR4120 and VR4130 instructions.
    136      1.1  christos 
    137      1.1  christos 000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101001::64::DMACC
    138      1.1  christos "dmacc%s<MFHI>%s<UNS>%s<SAT> r<RD>, r<RS>, r<RT>"
    139      1.1  christos *vr4120:
    140      1.1  christos {
    141      1.1  christos   do_vr_mul_op (SD_, RD, RS, RT,
    142      1.1  christos 		1 /* accumulate */,
    143      1.1  christos 		MFHI, UNS, SAT,
    144      1.1  christos 		0 /* don't subtract */,
    145      1.1  christos 		SAT /* short */,
    146      1.1  christos 		1 /* double */);
    147      1.1  christos }
    148      1.1  christos 
    149      1.1  christos 000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101000::32::MACC_4120
    150      1.1  christos "macc%s<MFHI>%s<UNS>%s<SAT> r<RD>, r<RS>, r<RT>"
    151      1.1  christos *vr4120:
    152      1.1  christos {
    153      1.1  christos   do_vr_mul_op (SD_, RD, RS, RT,
    154      1.1  christos 		1 /* accumulate */,
    155      1.1  christos 		MFHI, UNS, SAT,
    156      1.1  christos 		0 /* don't subtract */,
    157      1.1  christos 		SAT /* short */,
    158      1.1  christos 		0 /* single */);
    159      1.1  christos }
    160      1.1  christos 
    161      1.1  christos 
    162      1.1  christos // VR5400 and VR5500 instructions.
    163      1.1  christos 
    164      1.1  christos 000000,5.RS,5.RT,5.RD,0,1.MFHI,001,01100,1.UNS::32::MUL
    165      1.1  christos "mul%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
    166      1.1  christos *vr5400:
    167      1.1  christos *vr5500:
    168      1.1  christos {
    169      1.1  christos   do_vr_mul_op (SD_, RD, RS, RT,
    170      1.1  christos 		0 /* don't accumulate */,
    171      1.1  christos 		MFHI, UNS,
    172      1.1  christos 		0 /* don't saturate */,
    173      1.1  christos 		0 /* don't subtract */,
    174      1.1  christos 		0 /* not short */,
    175      1.1  christos 		0 /* single */);
    176      1.1  christos }
    177      1.1  christos 
    178      1.1  christos 000000,5.RS,5.RT,5.RD,0,1.MFHI,011,01100,1.UNS::32::MULS
    179      1.1  christos "muls%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
    180      1.1  christos *vr5400:
    181      1.1  christos *vr5500:
    182      1.1  christos {
    183      1.1  christos   do_vr_mul_op (SD_, RD, RS, RT,
    184      1.1  christos 		0 /* don't accumulate */,
    185      1.1  christos 		MFHI, UNS,
    186      1.1  christos 		0 /* don't saturate */,
    187      1.1  christos 		1 /* subtract */,
    188      1.1  christos 		0 /* not short */,
    189      1.1  christos 		0 /* single */);
    190      1.1  christos }
    191      1.1  christos 
    192      1.1  christos 000000,5.RS,5.RT,5.RD,0,1.MFHI,101,01100,1.UNS::32::MACC_5xxx
    193      1.1  christos "macc%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
    194      1.1  christos *vr5400:
    195      1.1  christos *vr5500:
    196      1.1  christos {
    197      1.1  christos   do_vr_mul_op (SD_, RD, RS, RT,
    198      1.1  christos 		1 /* accumulate */,
    199      1.1  christos 		MFHI, UNS,
    200      1.1  christos 		0 /* don't saturate */,
    201      1.1  christos 		0 /* don't subtract */,
    202      1.1  christos 		0 /* not short */,
    203      1.1  christos 		0 /* single */);
    204      1.1  christos }
    205      1.1  christos 
    206      1.1  christos 000000,5.RS,5.RT,5.RD,0,1.MFHI,111,01100,1.UNS::32::MSAC
    207      1.1  christos "msac%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
    208      1.1  christos *vr5400:
    209      1.1  christos *vr5500:
    210      1.1  christos {
    211      1.1  christos   do_vr_mul_op (SD_, RD, RS, RT,
    212      1.1  christos 		1 /* accumulate */,
    213      1.1  christos 		MFHI, UNS,
    214      1.1  christos 		0 /* don't saturate */,
    215      1.1  christos 		1 /* subtract */,
    216      1.1  christos 		0 /* not short */,
    217      1.1  christos 		0 /* single */);
    218      1.1  christos }
    219      1.1  christos 
    220      1.1  christos 
    221      1.1  christos 010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:64::LUXC1
    222      1.1  christos "luxc1 f<FD>, r<INDEX>(r<BASE>)"
    223      1.1  christos *vr5500:
    224      1.1  christos {
    225      1.1  christos   check_fpu (SD_);
    226      1.1  christos   COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD,
    227      1.1  christos 			  (GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0));
    228      1.1  christos }
    229      1.1  christos 
    230      1.1  christos 010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:64::SUXC1
    231      1.1  christos "suxc1 f<FS>, r<INDEX>(r<BASE>)"
    232      1.1  christos *vr5500:
    233      1.1  christos {
    234      1.1  christos   check_fpu (SD_);
    235      1.1  christos   do_store (SD_, AccessLength_DOUBLEWORD,
    236      1.1  christos 	    (GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0,
    237      1.1  christos 	    COP_SD (1, FS));
    238      1.1  christos }
    239      1.1  christos 
    240      1.1  christos 010000,1,19.*,100000:COP0:32::WAIT
    241      1.1  christos "wait"
    242      1.1  christos *vr5500:
    243      1.1  christos 
    244      1.1  christos 011100,00000,5.RT,5.DR,00000,111101:SPECIAL:64::MFDR
    245      1.1  christos "mfdr r<RT>, r<DR>"
    246      1.1  christos *vr5400:
    247      1.1  christos *vr5500:
    248      1.1  christos 
    249      1.1  christos 011100,00100,5.RT,5.DR,00000,111101:SPECIAL:64::MTDR
    250      1.1  christos "mtdr r<RT>, r<DR>"
    251      1.1  christos *vr5400:
    252      1.1  christos *vr5500:
    253      1.1  christos 
    254      1.1  christos 011100,00000,00000,00000,00000,111110:SPECIAL:64::DRET
    255      1.1  christos "dret"
    256      1.1  christos *vr5400:
    257      1.1  christos *vr5500:
    258