Home | History | Annotate | Line # | Download | only in mips
vr.igen revision 1.1
      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  christos   unsigned64 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  christos       if (!unsigned_p && (unsigned64) EXTEND32 (result) != result)
     86  1.1  christos 	result = ((signed64) result < 0 ? -0x7fffffff - 1 : 0x7fffffff);
     87  1.1  christos       else if (unsigned_p && (result >> 32) != 0)
     88  1.1  christos 	result = (unsigned64) 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