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