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