mips3264r6.igen revision 1.1 1 1.1 christos 110010,26.OFFSET:POOL32X:32::BC
2 1.1 christos "bc <OFFSET>"
3 1.1 christos *mips32r6:
4 1.1 christos *mips64r6:
5 1.1 christos {
6 1.1 christos NIA = CIA + (EXTEND26 (OFFSET) << 2) + 4;
7 1.1 christos }
8 1.1 christos
9 1.1 christos 111010,26.OFFSET:POOL32X:32::BALC
10 1.1 christos "balc <OFFSET>"
11 1.1 christos *mips32r6:
12 1.1 christos *mips64r6:
13 1.1 christos {
14 1.1 christos RA = CIA + 4;
15 1.1 christos NIA = CIA + (EXTEND26 (OFFSET) << 2) + 4;
16 1.1 christos }
17 1.1 christos
18 1.1 christos 110110,5.RS!0,21.OFFSET:POOL32X:32::BEQZC
19 1.1 christos "beqzc r<RS>, <OFFSET>"
20 1.1 christos *mips32r6:
21 1.1 christos *mips64r6:
22 1.1 christos {
23 1.1 christos if (GPR[RS] == 0)
24 1.1 christos NIA = CIA + (EXTEND21 (OFFSET) << 2) + 4;
25 1.1 christos else
26 1.1 christos FORBIDDEN_SLOT ();
27 1.1 christos }
28 1.1 christos
29 1.1 christos 110110,00000,5.RT,16.OFFSET:POOL32X:32::JIC
30 1.1 christos "jic r<RT>, <OFFSET>"
31 1.1 christos *mips32r6:
32 1.1 christos *mips64r6:
33 1.1 christos {
34 1.1 christos NIA = GPR[RT] + (EXTEND16(OFFSET) << 2);
35 1.1 christos }
36 1.1 christos
37 1.1 christos 111110,5.RS!0,21.OFFSET:POOL32X:32::BNEZC
38 1.1 christos "bnezc r<RS>, <OFFSET>"
39 1.1 christos *mips32r6:
40 1.1 christos *mips64r6:
41 1.1 christos {
42 1.1 christos if (GPR[RS] != 0)
43 1.1 christos NIA = CIA + (EXTEND21 (OFFSET) << 2) + 4;
44 1.1 christos else
45 1.1 christos FORBIDDEN_SLOT ();
46 1.1 christos }
47 1.1 christos
48 1.1 christos 111110,00000,5.RT,16.OFFSET:POOL32X:32::JIALC
49 1.1 christos "jialc r<RT>, <OFFSET>"
50 1.1 christos *mips32r6:
51 1.1 christos *mips64r6:
52 1.1 christos {
53 1.1 christos RA = CIA + 4;
54 1.1 christos NIA = GPR[RT] + EXTEND16(OFFSET);
55 1.1 christos }
56 1.1 christos
57 1.1 christos 010110,5.RS,5.RT,16.OFFSET:POOL32X:32::B1xxC
58 1.1 christos "blezc r<RT>, <OFFSET>": RS==0&&RT!=0
59 1.1 christos "bgezc r<RT>, <OFFSET>":RS!=0&&RS==RT
60 1.1 christos "bgec r<RS>, r<RT>, <OFFSET>"
61 1.1 christos *mips32r6:
62 1.1 christos *mips64r6:
63 1.1 christos {
64 1.1 christos if (RS == 0 && RT != 0)
65 1.1 christos {
66 1.1 christos //BLEZC
67 1.1 christos if ((signed_word)GPR[RT] <= 0)
68 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
69 1.1 christos else
70 1.1 christos FORBIDDEN_SLOT ();
71 1.1 christos }
72 1.1 christos else if (RS != 0 && RS == RT)
73 1.1 christos {
74 1.1 christos //BGEZC
75 1.1 christos if ((signed_word)GPR[RT] >= 0)
76 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
77 1.1 christos else
78 1.1 christos FORBIDDEN_SLOT ();
79 1.1 christos }
80 1.1 christos else
81 1.1 christos {
82 1.1 christos //BGEC
83 1.1 christos if ((signed_word) GPR[RS] >= (signed_word) GPR[RT])
84 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
85 1.1 christos else
86 1.1 christos FORBIDDEN_SLOT ();
87 1.1 christos }
88 1.1 christos }
89 1.1 christos
90 1.1 christos 010111,5.RS,5.RT,16.OFFSET:POOL32X:32::B2xxC
91 1.1 christos "bgtzc r<RT>, <OFFSET>":RS==0&&RT!=0
92 1.1 christos "bltzc r<RT>, <OFFSET>":RS!=0&&RS==RT
93 1.1 christos "bltc r<RS>, r<RT>, <OFFSET>"
94 1.1 christos *mips32r6:
95 1.1 christos *mips64r6:
96 1.1 christos {
97 1.1 christos if (RS == 0 && RT != 0)
98 1.1 christos {
99 1.1 christos //BGTZC
100 1.1 christos if ((signed_word)GPR[RT] > 0)
101 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
102 1.1 christos else
103 1.1 christos FORBIDDEN_SLOT ();
104 1.1 christos }
105 1.1 christos else if (RS != 0 && RS == RT)
106 1.1 christos {
107 1.1 christos //BLTZC
108 1.1 christos if ((signed_word)GPR[RT] < 0)
109 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
110 1.1 christos else
111 1.1 christos FORBIDDEN_SLOT ();
112 1.1 christos }
113 1.1 christos else
114 1.1 christos {
115 1.1 christos //BLTC
116 1.1 christos if ((signed_word) GPR[RS] < (signed_word) GPR[RT])
117 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
118 1.1 christos else
119 1.1 christos FORBIDDEN_SLOT ();
120 1.1 christos }
121 1.1 christos }
122 1.1 christos
123 1.1 christos 000110,5.RS,5.RT!0,16.OFFSET:POOL32X:32::B3xxC
124 1.1 christos "blezalc r<RT>, <OFFSET>":RS==0
125 1.1 christos "bgezalc r<RT>, <OFFSET>":RS!=0&&RS==RT
126 1.1 christos "bgeuc r<RS>, r<RT>, <OFFSET>"
127 1.1 christos *mips32r6:
128 1.1 christos *mips64r6:
129 1.1 christos {
130 1.1 christos if (RS == 0 && RT != 0)
131 1.1 christos {
132 1.1 christos //BLEZALC
133 1.1 christos RA = CIA + 4;
134 1.1 christos if ((signed_word)GPR[RT] <= 0)
135 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
136 1.1 christos else
137 1.1 christos FORBIDDEN_SLOT ();
138 1.1 christos }
139 1.1 christos else if (RS != 0 && RS == RT)
140 1.1 christos {
141 1.1 christos //BGEZALC
142 1.1 christos RA = CIA + 4;
143 1.1 christos if ((signed_word)GPR[RT] >= 0)
144 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
145 1.1 christos else
146 1.1 christos FORBIDDEN_SLOT ();
147 1.1 christos }
148 1.1 christos else
149 1.1 christos {
150 1.1 christos //BGEUC
151 1.1 christos if (GPR[RS] >= GPR[RT])
152 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
153 1.1 christos else
154 1.1 christos FORBIDDEN_SLOT ();
155 1.1 christos }
156 1.1 christos }
157 1.1 christos
158 1.1 christos 000111,5.RS,5.RT!0,16.OFFSET:POOL32X:32::B4xxC
159 1.1 christos "bgtzalc r<RT>, <OFFSET>":RS==0
160 1.1 christos "bltzalc r<RT>, <OFFSET>":RS!=0&&RS==RT
161 1.1 christos "bltuc r<RS>, r<RT>, <OFFSET>"
162 1.1 christos *mips32r6:
163 1.1 christos *mips64r6:
164 1.1 christos {
165 1.1 christos if (RS == 0 && RT != 0)
166 1.1 christos {
167 1.1 christos //BGTZALC
168 1.1 christos RA = CIA + 4;
169 1.1 christos if ((signed_word)GPR[RT] > 0)
170 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
171 1.1 christos else
172 1.1 christos FORBIDDEN_SLOT ();
173 1.1 christos }
174 1.1 christos else if (RS != 0 && RS == RT)
175 1.1 christos {
176 1.1 christos //BLTZALC
177 1.1 christos RA = CIA + 4;
178 1.1 christos if ((signed_word)GPR[RT] < 0)
179 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
180 1.1 christos else
181 1.1 christos FORBIDDEN_SLOT ();
182 1.1 christos }
183 1.1 christos else
184 1.1 christos {
185 1.1 christos //BLTUC
186 1.1 christos if (GPR[RS] < GPR[RT])
187 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
188 1.1 christos else
189 1.1 christos FORBIDDEN_SLOT ();
190 1.1 christos }
191 1.1 christos }
192 1.1 christos
193 1.1 christos 001000,5.RS,5.RT,16.OFFSET:POOL32X:32::BxxxC
194 1.1 christos "bovc r<RS>, r<RT>, <OFFSET>":RS>=RT
195 1.1 christos "beqzalc r<RT>, <OFFSET>":RS==0&&RT>RS
196 1.1 christos "beqc r<RS>, r<RT>, <OFFSET>"
197 1.1 christos *mips32r6:
198 1.1 christos *mips64r6:
199 1.1 christos {
200 1.1 christos if (RS >= RT)
201 1.1 christos {
202 1.1 christos //BOVC
203 1.1 christos ALU32_BEGIN (GPR[RS] & 0x0ffffffff);
204 1.1 christos ALU32_ADD (GPR[RT] & 0x0ffffffff);
205 1.1 christos
206 1.1 christos if (ALU32_HAD_OVERFLOW)
207 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
208 1.1 christos else
209 1.1 christos FORBIDDEN_SLOT ();
210 1.1 christos }
211 1.1 christos else if (RS == 0)
212 1.1 christos {
213 1.1 christos RA = CIA + 4;
214 1.1 christos //BEQZALC
215 1.1 christos if (GPR[RT] == 0)
216 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
217 1.1 christos else
218 1.1 christos FORBIDDEN_SLOT ();
219 1.1 christos }
220 1.1 christos else
221 1.1 christos {
222 1.1 christos //BEQC
223 1.1 christos if (GPR[RS] == GPR[RT])
224 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
225 1.1 christos else
226 1.1 christos FORBIDDEN_SLOT ();
227 1.1 christos }
228 1.1 christos }
229 1.1 christos
230 1.1 christos 011000,5.RS,5.RT,16.OFFSET:POOL32X:32::BNxxxC
231 1.1 christos "bnvc r<RS>, r<RT>, <OFFSET>":RS>=RT
232 1.1 christos "bnezalc r<RT>, <OFFSET>":RS==0&&RT>RS
233 1.1 christos "bnec r<RS>, r<RT>, <OFFSET>"
234 1.1 christos *mips32r6:
235 1.1 christos *mips64r6:
236 1.1 christos {
237 1.1 christos if (RS >= RT)
238 1.1 christos {
239 1.1 christos //BNVC
240 1.1 christos ALU32_BEGIN (GPR[RS] & 0x0ffffffff);
241 1.1 christos ALU32_ADD (GPR[RT] & 0x0ffffffff);
242 1.1 christos
243 1.1 christos if (!ALU32_HAD_OVERFLOW)
244 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
245 1.1 christos else
246 1.1 christos FORBIDDEN_SLOT ();
247 1.1 christos }
248 1.1 christos else if (RS == 0 && RT > RS)
249 1.1 christos {
250 1.1 christos //BNEZALC
251 1.1 christos RA = CIA + 4;
252 1.1 christos if (GPR[RT] != 0)
253 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
254 1.1 christos else
255 1.1 christos FORBIDDEN_SLOT ();
256 1.1 christos }
257 1.1 christos else
258 1.1 christos {
259 1.1 christos //BNEC
260 1.1 christos if (GPR[RT] != GPR[RS])
261 1.1 christos NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
262 1.1 christos else
263 1.1 christos FORBIDDEN_SLOT ();
264 1.1 christos }
265 1.1 christos }
266 1.1 christos
267 1.1 christos :%s::::R6COND:int r6cond
268 1.1 christos {
269 1.1 christos switch (r6cond)
270 1.1 christos {
271 1.1 christos case FP_R6CMP_SAF:
272 1.1 christos return "SAF";
273 1.1 christos case FP_R6CMP_SUN:
274 1.1 christos return "SUN";
275 1.1 christos case FP_R6CMP_SOR:
276 1.1 christos return "SOR";
277 1.1 christos case FP_R6CMP_SEQ:
278 1.1 christos return "SEQ";
279 1.1 christos case FP_R6CMP_SUNE:
280 1.1 christos return "SUNE";
281 1.1 christos case FP_R6CMP_SUEQ:
282 1.1 christos return "SUEQ";
283 1.1 christos case FP_R6CMP_SNE:
284 1.1 christos return "SNE";
285 1.1 christos case FP_R6CMP_SLT:
286 1.1 christos return "SLT";
287 1.1 christos case FP_R6CMP_SULT:
288 1.1 christos return "SULT";
289 1.1 christos case FP_R6CMP_SLE:
290 1.1 christos return "SLE";
291 1.1 christos case FP_R6CMP_SULE:
292 1.1 christos return "SULE";
293 1.1 christos case FP_R6CMP_AF:
294 1.1 christos return "AF";
295 1.1 christos case FP_R6CMP_UN:
296 1.1 christos return "UN";
297 1.1 christos case FP_R6CMP_OR:
298 1.1 christos return "OR";
299 1.1 christos case FP_R6CMP_EQ:
300 1.1 christos return "EQ";
301 1.1 christos case FP_R6CMP_UNE:
302 1.1 christos return "UNE";
303 1.1 christos case FP_R6CMP_UEQ:
304 1.1 christos return "UEQ";
305 1.1 christos case FP_R6CMP_NE:
306 1.1 christos return "NE";
307 1.1 christos case FP_R6CMP_LT:
308 1.1 christos return "LT";
309 1.1 christos case FP_R6CMP_ULT:
310 1.1 christos return "ULT";
311 1.1 christos case FP_R6CMP_LE:
312 1.1 christos return "LE";
313 1.1 christos case FP_R6CMP_ULE:
314 1.1 christos return "ULE";
315 1.1 christos default:
316 1.1 christos abort ();
317 1.1 christos }
318 1.1 christos }
319 1.1 christos
320 1.1 christos 010001,1010,1.FMT,5.FT,5.FS,5.FD,0,5.R6COND:POOL32X:32,f::CMP.cond.fmt
321 1.1 christos "cmp.%s<R6COND>.%s<FMT> f<FD>, f<FS>, f<FT>"
322 1.1 christos *mips32r6:
323 1.1 christos *mips64r6:
324 1.1 christos {
325 1.1 christos uint64_t result;
326 1.1 christos check_fpu (SD_);
327 1.1 christos TRACE_ALU_INPUT2 (ValueFPR (FS, FMT), ValueFPR (FT, FMT));
328 1.1 christos
329 1.1 christos result = R6Compare (ValueFPR (FS, FMT), ValueFPR (FT, FMT), FMT, R6COND);
330 1.1 christos StoreFPR (FD, FMT, result);
331 1.1 christos TRACE_ALU_RESULT (result);
332 1.1 christos }
333 1.1 christos
334 1.1 christos 010001,01001,5.FT,16.OFFSET:POOL32X:32,f::BC1EQZ
335 1.1 christos "bc1eqz f<FT>, <OFFSET>"
336 1.1 christos *mips32r6:
337 1.1 christos *mips64r6:
338 1.1 christos {
339 1.1 christos address_word offset = EXTEND16 (OFFSET) << 2;
340 1.1 christos check_fpu (SD_);
341 1.1 christos TRACE_ALU_INPUT1 (FGR[FT]);
342 1.1 christos if ((FGR[FT] & 0x01) == 0)
343 1.1 christos DELAY_SLOT (NIA + offset);
344 1.1 christos }
345 1.1 christos
346 1.1 christos 010001,01101,5.FT,16.OFFSET:POOL32X:32,f::BC1NEZ
347 1.1 christos "bc1nez f<FT>, <OFFSET>"
348 1.1 christos *mips32r6:
349 1.1 christos *mips64r6:
350 1.1 christos {
351 1.1 christos address_word offset = EXTEND16 (OFFSET) << 2;
352 1.1 christos check_fpu (SD_);
353 1.1 christos TRACE_ALU_INPUT1 (FGR[FT]);
354 1.1 christos if ((FGR[FT] & 0x01) != 0)
355 1.1 christos DELAY_SLOT (NIA + offset);
356 1.1 christos }
357 1.1 christos 010001,1000,1.FMT,5.FT,5.FS,5.FD,011000:POOLX:32,f::MADDF.fmt
358 1.1 christos "maddf.%s<FMT> f<FD>, f<FS>, f<FT>"
359 1.1 christos *mips32r6:
360 1.1 christos *mips64r6:
361 1.1 christos {
362 1.1 christos int fmt = FMT;
363 1.1 christos check_fpu (SD_);
364 1.1 christos check_u64 (SD_, instruction_0);
365 1.1 christos check_fmt_p (SD_, fmt, instruction_0);
366 1.1 christos TRACE_ALU_INPUT3 (FGR[FD], FGR[FS], FGR[FT]);
367 1.1 christos StoreFPR (FD, fmt, FusedMultiplyAdd (ValueFPR (FS, fmt),
368 1.1 christos ValueFPR (FT, fmt),
369 1.1 christos ValueFPR (FD, fmt), fmt));
370 1.1 christos TRACE_ALU_RESULT (FGR[FD]);
371 1.1 christos }
372 1.1 christos
373 1.1 christos 010001,1000,1.FMT,5.FT,5.FS,5.FD,011001:POOLX:32,f::MSUBF.fmt
374 1.1 christos "msubf.%s<FMT> f<FD>, f<FS>, f<FT>"
375 1.1 christos *mips32r6:
376 1.1 christos *mips64r6:
377 1.1 christos {
378 1.1 christos int fmt = FMT;
379 1.1 christos check_fpu (SD_);
380 1.1 christos check_u64 (SD_, instruction_0);
381 1.1 christos check_fmt_p (SD_, fmt, instruction_0);
382 1.1 christos TRACE_ALU_INPUT3 (FGR[FD], FGR[FS], FGR[FT]);
383 1.1 christos StoreFPR (FD, fmt, FusedMultiplySub (ValueFPR (FS, fmt),
384 1.1 christos ValueFPR (FT, fmt),
385 1.1 christos ValueFPR (FD, fmt), fmt));
386 1.1 christos TRACE_ALU_RESULT (FGR[FD]);
387 1.1 christos }
388 1.1 christos
389 1.1 christos 000000,5.RS,5.RT,5.RD,000,2.IMM,000101:SPECIAL:32::LSA
390 1.1 christos "lsa r<RD>, r<RS>, r<RT>, <IMM + 1>"
391 1.1 christos *mips32r6:
392 1.1 christos *mips64r6:
393 1.1 christos {
394 1.1 christos uint32_t t = GPR[RS] << (IMM + 1);
395 1.1 christos GPR[RD] = EXTEND32(GPR[RT] + t);
396 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
397 1.1 christos }
398 1.1 christos
399 1.1 christos 000000,5.RS,5.RT,5.RD,000,2.IMM,010101:SPECIAL:64::DLSA
400 1.1 christos "dlsa r<RD>, r<RS>, r<RT>, <IMM + 1>"
401 1.1 christos *mips64r6:
402 1.1 christos {
403 1.1 christos uint64_t t = GPR[RS] << (IMM + 1);
404 1.1 christos GPR[RD] = GPR[RT] + t;
405 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
406 1.1 christos }
407 1.1 christos
408 1.1 christos 001111,5.RS!0,5.RT,16.IMMEDIATE:POOL32X:32::AUI
409 1.1 christos "aui r<RS>, r<RT>, <IMMEDIATE>"
410 1.1 christos *mips32r6:
411 1.1 christos *mips64r6:
412 1.1 christos {
413 1.1 christos TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
414 1.1 christos GPR[RT] = EXTEND32 (GPR[RS] + (EXTEND16 (IMMEDIATE) << 16));
415 1.1 christos TRACE_ALU_RESULT (GPR[RT]);
416 1.1 christos }
417 1.1 christos
418 1.1 christos 011101,5.RS!0,5.RT,16.IMMEDIATE:POOL32X:64::DAUI
419 1.1 christos "daui r<RS>, r<RT>, <IMMEDIATE>"
420 1.1 christos *mips64r6:
421 1.1 christos {
422 1.1 christos TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
423 1.1 christos GPR[RT] = GPR[RS] + (EXTEND16 (IMMEDIATE) << 16);
424 1.1 christos TRACE_ALU_RESULT (GPR[RT]);
425 1.1 christos }
426 1.1 christos
427 1.1 christos 000001,5.RS,00110,16.IMMEDIATE:POOL32X:64::DAHI
428 1.1 christos "dahi r<RS>, <IMMEDIATE>"
429 1.1 christos *mips64r6:
430 1.1 christos {
431 1.1 christos TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
432 1.1 christos GPR[RS] = GPR[RS] + (EXTEND16 (IMMEDIATE) << 32);
433 1.1 christos TRACE_ALU_RESULT (GPR[RS]);
434 1.1 christos }
435 1.1 christos
436 1.1 christos 000001,5.RS,11110,16.IMMEDIATE:POOL32X:64::DATI
437 1.1 christos "dati r<RS>, <IMMEDIATE>"
438 1.1 christos *mips64r6:
439 1.1 christos {
440 1.1 christos TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
441 1.1 christos GPR[RS] = GPR[RS] + (EXTEND16 (IMMEDIATE) << 48);
442 1.1 christos TRACE_ALU_RESULT (GPR[RS]);
443 1.1 christos }
444 1.1 christos
445 1.1 christos 011111,5.RS,5.RT,5.RD,010,2.IMMEDIATE,100000:POOL32X:32::ALIGN
446 1.1 christos "align r<RD>, r<RS>, r<RT>, <IMMEDIATE>"
447 1.1 christos *mips32r6:
448 1.1 christos *mips64r6:
449 1.1 christos {
450 1.1 christos uint32_t rs = GPR[RS];
451 1.1 christos uint32_t rt = GPR[RT];
452 1.1 christos TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
453 1.1 christos GPR[RD] = EXTEND32 (rs >> 8 * (4 - IMMEDIATE) | rt << 8 * IMMEDIATE);
454 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
455 1.1 christos }
456 1.1 christos
457 1.1 christos 011111,5.RS,5.RT,5.RD,01,3.IMMEDIATE,100100:POOL32X:64::DALIGN
458 1.1 christos "dalign r<RD>, r<RS>, r<RT>, <IMMEDIATE>"
459 1.1 christos *mips64r6:
460 1.1 christos {
461 1.1 christos uint64_t rs = GPR[RS];
462 1.1 christos uint64_t rt = GPR[RT];
463 1.1 christos TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
464 1.1 christos GPR[RD] = rs >> 8 * (8 - IMMEDIATE) | rt << 8 * IMMEDIATE;
465 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
466 1.1 christos }
467 1.1 christos
468 1.1 christos 011111,00000,5.RT,5.RD,00000,100000:POOL32X:32::BITSWAP
469 1.1 christos "bitswap r<RD>, r<RT>"
470 1.1 christos *mips32r6:
471 1.1 christos *mips64r6:
472 1.1 christos {
473 1.1 christos /* Taken from: http://graphics.stanford.edu/~seander/bithacks.html */
474 1.1 christos uint32_t v = GPR[RT];
475 1.1 christos
476 1.1 christos TRACE_ALU_INPUT1 (v);
477 1.1 christos v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
478 1.1 christos v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
479 1.1 christos v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
480 1.1 christos GPR[RD] = EXTEND32 (v);
481 1.1 christos TRACE_ALU_RESULT(GPR[RD]);
482 1.1 christos }
483 1.1 christos
484 1.1 christos 011111,00000,5.RT,5.RD,00000,100100:POOL32X:64::DBITSWAP
485 1.1 christos "dbitswap r<RD>, r<RT>"
486 1.1 christos *mips64r6:
487 1.1 christos {
488 1.1 christos /* Taken from: http://graphics.stanford.edu/~seander/bithacks.html */
489 1.1 christos uint64_t v = GPR[RT];
490 1.1 christos
491 1.1 christos TRACE_ALU_INPUT1 (v);
492 1.1 christos v = ((v >> 1) & 0x5555555555555555) | ((v & 0x5555555555555555) << 1);
493 1.1 christos v = ((v >> 2) & 0x3333333333333333) | ((v & 0x3333333333333333) << 2);
494 1.1 christos v = ((v >> 4) & 0x0F0F0F0F0F0F0F0F) | ((v & 0x0F0F0F0F0F0F0F0F) << 4);
495 1.1 christos TRACE_ALU_RESULT(v);
496 1.1 christos GPR[RD] = v;
497 1.1 christos }
498 1.1 christos
499 1.1 christos 111011,5.RS,00,19.IMMEDIATE:POOL32X:32::ADDIUPC
500 1.1 christos "addiupc r<RS>, <IMMEDIATE>"
501 1.1 christos *mips32r6:
502 1.1 christos *mips64r6:
503 1.1 christos {
504 1.1 christos TRACE_ALU_INPUT1 (IMMEDIATE);
505 1.1 christos GPR[RS] = loadstore_ea (SD_, CIA, EXTEND19 (IMMEDIATE) << 2);
506 1.1 christos TRACE_ALU_RESULT (GPR[RS]);
507 1.1 christos }
508 1.1 christos
509 1.1 christos 111011,5.RS,11110,16.IMMEDIATE:POOL32X:32::AUIPC
510 1.1 christos "auipc r<RS>, <IMMEDIATE>"
511 1.1 christos *mips32r6:
512 1.1 christos *mips64r6:
513 1.1 christos {
514 1.1 christos TRACE_ALU_INPUT1 (IMMEDIATE);
515 1.1 christos GPR[RS] = loadstore_ea (SD_, CIA, EXTEND32 (IMMEDIATE << 16));
516 1.1 christos TRACE_ALU_RESULT (GPR[RS]);
517 1.1 christos }
518 1.1 christos
519 1.1 christos 111011,5.RS,11111,16.IMMEDIATE:POOL32X:32::ALUIPC
520 1.1 christos "aluipc r<RS>, <IMMEDIATE>"
521 1.1 christos *mips32r6:
522 1.1 christos *mips64r6:
523 1.1 christos {
524 1.1 christos TRACE_ALU_INPUT1 (IMMEDIATE);
525 1.1 christos GPR[RS] = ~0x0FFFF & loadstore_ea (SD_, CIA, EXTEND32 (IMMEDIATE << 16));
526 1.1 christos TRACE_ALU_RESULT (GPR[RS]);
527 1.1 christos }
528 1.1 christos
529 1.1 christos 111011,5.RS,01,19.IMMEDIATE:POOL32X:32::LWPC
530 1.1 christos "lwpc r<RS>, <IMMEDIATE>"
531 1.1 christos *mips32r6:
532 1.1 christos *mips64r6:
533 1.1 christos {
534 1.1 christos uint32_t offset = EXTEND19 (IMMEDIATE) << 2;
535 1.1 christos TRACE_ALU_INPUT1 (IMMEDIATE);
536 1.1 christos GPR[RS] = EXTEND32 (do_load (SD_, AccessLength_WORD, CIA, offset));
537 1.1 christos TRACE_ALU_RESULT (GPR[RS]);
538 1.1 christos }
539 1.1 christos
540 1.1 christos 111011,5.RS,10,19.IMMEDIATE:POOL32X:64::LWUPC
541 1.1 christos "lwupc r<RS>, <IMMEDIATE>"
542 1.1 christos *mips64r6:
543 1.1 christos {
544 1.1 christos uint32_t offset = EXTEND19 (IMMEDIATE) << 2;
545 1.1 christos TRACE_ALU_INPUT1 (CIA + offset);
546 1.1 christos GPR[RS] = do_load (SD_, AccessLength_WORD, CIA, offset);
547 1.1 christos TRACE_ALU_RESULT (GPR[RS]);
548 1.1 christos }
549 1.1 christos
550 1.1 christos 111011,5.RS,110,18.IMMEDIATE:POOL32X:64::LDPC
551 1.1 christos "ldpc r<RS>, <IMMEDIATE>"
552 1.1 christos *mips64r6:
553 1.1 christos {
554 1.1 christos uint32_t offset = EXTEND18 (IMMEDIATE) << 3;
555 1.1 christos TRACE_ALU_INPUT1 (IMMEDIATE);
556 1.1 christos GPR[RS] = do_load (SD_, AccessLength_DOUBLEWORD, CIA, offset);
557 1.1 christos TRACE_ALU_RESULT (GPR[RS]);
558 1.1 christos }
559 1.1 christos 010001,1000,1.FMT,00000,5.FS,5.FD,011010::32,64,f::RINT.fmt
560 1.1 christos "rint.%s<FMT> f<FD>, f<FS>"
561 1.1 christos *mips32r6:
562 1.1 christos *mips64r6:
563 1.1 christos {
564 1.1 christos uint64_t result;
565 1.1 christos int fmt = FMT;
566 1.1 christos check_fpu (SD_);
567 1.1 christos check_u64 (SD_, instruction_0);
568 1.1 christos check_fmt_p (SD_, fmt, instruction_0);
569 1.1 christos TRACE_ALU_INPUT1 (FGR[FS]);
570 1.1 christos RoundToIntegralExact (ValueFPR (FS, fmt), &result, fmt);
571 1.1 christos StoreFPR (FD, fmt, result);
572 1.1 christos TRACE_ALU_RESULT (FGR[FD]);
573 1.1 christos }
574 1.1 christos
575 1.1 christos 010001,1000,1.FMT,00000,5.FS,5.FD,011011::32,64,f::CLASS.fmt
576 1.1 christos "class.%s<FMT> f<FD>, f<FS>"
577 1.1 christos *mips32r6:
578 1.1 christos *mips64r6:
579 1.1 christos {
580 1.1 christos int fmt = FMT;
581 1.1 christos check_fpu (SD_);
582 1.1 christos check_u64 (SD_, instruction_0);
583 1.1 christos check_fmt_p (SD_, fmt, instruction_0);
584 1.1 christos StoreFPR (FD, fmt, Classify (ValueFPR (FS, fmt), fmt));
585 1.1 christos }
586 1.1 christos
587 1.1 christos 010001,1000,1.FMT,5.FT,5.FS,5.FD,011100::32,64,f::MIN.fmt
588 1.1 christos "min.%s<FMT> f<FD>, f<FS>, f<FT>"
589 1.1 christos *mips32r6:
590 1.1 christos *mips64r6:
591 1.1 christos {
592 1.1 christos int fmt = FMT;
593 1.1 christos check_fpu (SD_);
594 1.1 christos check_u64 (SD_, instruction_0);
595 1.1 christos check_fmt_p (SD_, fmt, instruction_0);
596 1.1 christos TRACE_ALU_INPUT2 (FGR[FS], FGR[FT]);
597 1.1 christos StoreFPR (FD, fmt, Min (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
598 1.1 christos TRACE_ALU_RESULT (FGR[FD]);
599 1.1 christos }
600 1.1 christos
601 1.1 christos 010001,1000,1.FMT,5.FT,5.FS,5.FD,011110::32,64,f::MAX.fmt
602 1.1 christos "max.%s<FMT> f<FD>, f<FS>, f<FT>"
603 1.1 christos *mips32r6:
604 1.1 christos *mips64r6:
605 1.1 christos {
606 1.1 christos int fmt = FMT;
607 1.1 christos check_fpu (SD_);
608 1.1 christos check_u64 (SD_, instruction_0);
609 1.1 christos check_fmt_p (SD_, fmt, instruction_0);
610 1.1 christos TRACE_ALU_INPUT2 (FGR[FS], FGR[FT]);
611 1.1 christos StoreFPR (FD, fmt, Max (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
612 1.1 christos TRACE_ALU_RESULT (FGR[FD]);
613 1.1 christos }
614 1.1 christos
615 1.1 christos 010001,1000,1.FMT,5.FT,5.FS,5.FD,011101::32,64,f::MINA.fmt
616 1.1 christos "mina.%s<FMT> f<FD>, f<FS>, f<FT>"
617 1.1 christos *mips32r6:
618 1.1 christos *mips64r6:
619 1.1 christos {
620 1.1 christos int fmt = FMT;
621 1.1 christos check_fpu (SD_);
622 1.1 christos check_u64 (SD_, instruction_0);
623 1.1 christos check_fmt_p (SD_, fmt, instruction_0);
624 1.1 christos TRACE_ALU_INPUT2 (FGR[FS], FGR[FT]);
625 1.1 christos StoreFPR (FD, fmt, MinA (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
626 1.1 christos TRACE_ALU_RESULT (FGR[FD]);
627 1.1 christos }
628 1.1 christos
629 1.1 christos 010001,1000,1.FMT,5.FT,5.FS,5.FD,011111::32,64,f::MAXA.fmt
630 1.1 christos "maxa.%s<FMT> f<FD>, f<FS>, f<FT>"
631 1.1 christos *mips32r6:
632 1.1 christos *mips64r6:
633 1.1 christos {
634 1.1 christos int fmt = FMT;
635 1.1 christos check_fpu (SD_);
636 1.1 christos check_u64 (SD_, instruction_0);
637 1.1 christos check_fmt_p (SD_, fmt, instruction_0);
638 1.1 christos TRACE_ALU_INPUT2 (FGR[FS], FGR[FT]);
639 1.1 christos StoreFPR (FD, fmt, MaxA (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
640 1.1 christos TRACE_ALU_RESULT (FGR[FD]);
641 1.1 christos }
642 1.1 christos 000000,5.RS,5.RT,5.RD,00010,011000:POOL32X:32::MUL
643 1.1 christos "mul r<RD>, r<RS>, r<RT>"
644 1.1 christos *mips32r6:
645 1.1 christos *mips64r6:
646 1.1 christos {
647 1.1 christos int64_t prod;
648 1.1 christos if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
649 1.1 christos Unpredictable ();
650 1.1 christos TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
651 1.1 christos prod = ((int64_t)(int32_t) GPR[RS])
652 1.1 christos * ((int64_t)(int32_t) GPR[RT]);
653 1.1 christos GPR[RD] = EXTEND32 (VL4_8 (prod));
654 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
655 1.1 christos }
656 1.1 christos
657 1.1 christos 000000,5.RS,5.RT,5.RD,00011,011000:POOL32X:32::MUH
658 1.1 christos "muh r<RD>, r<RS>, r<RT>"
659 1.1 christos *mips32r6:
660 1.1 christos *mips64r6:
661 1.1 christos {
662 1.1 christos int64_t prod;
663 1.1 christos if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
664 1.1 christos Unpredictable ();
665 1.1 christos TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
666 1.1 christos prod = ((int64_t)(int32_t) GPR[RS])
667 1.1 christos * ((int64_t)(int32_t) GPR[RT]);
668 1.1 christos GPR[RD] = EXTEND32 (VH4_8 (prod));
669 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
670 1.1 christos }
671 1.1 christos
672 1.1 christos 000000,5.RS,5.RT,5.RD,00010,011001:POOL32X:32::MULU
673 1.1 christos "mulu r<RD>, r<RS>, r<RT>"
674 1.1 christos *mips32r6:
675 1.1 christos *mips64r6:
676 1.1 christos {
677 1.1 christos uint64_t prod;
678 1.1 christos if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
679 1.1 christos Unpredictable ();
680 1.1 christos TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
681 1.1 christos prod = ((uint64_t)(uint32_t) GPR[RS])
682 1.1 christos * ((uint64_t)(uint32_t) GPR[RT]);
683 1.1 christos GPR[RD] = EXTEND32 (VL4_8 (prod));
684 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
685 1.1 christos }
686 1.1 christos
687 1.1 christos 000000,5.RS,5.RT,5.RD,00011,011001:POOL32X:32::MUHU
688 1.1 christos "muhu r<RD>, r<RS>, r<RT>"
689 1.1 christos *mips32r6:
690 1.1 christos *mips64r6:
691 1.1 christos {
692 1.1 christos uint64_t prod;
693 1.1 christos if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
694 1.1 christos Unpredictable ();
695 1.1 christos TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
696 1.1 christos prod = ((uint64_t)(uint32_t) GPR[RS])
697 1.1 christos * ((uint64_t)(uint32_t) GPR[RT]);
698 1.1 christos GPR[RD] = EXTEND32 (VH4_8 (prod));
699 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
700 1.1 christos }
701 1.1 christos
702 1.1 christos 000000,5.RS,5.RT,5.RD,00010,011010:POOL32X:32::DIV
703 1.1 christos "div r<RD>, r<RS>, r<RT>"
704 1.1 christos *mips32r6:
705 1.1 christos *mips64r6:
706 1.1 christos {
707 1.1 christos int32_t n = GPR[RS];
708 1.1 christos int32_t d = GPR[RT];
709 1.1 christos TRACE_ALU_INPUT2 (n,d);
710 1.1 christos if (d == 0)
711 1.1 christos GPR[RD] = EXTEND32 (0x80000000);
712 1.1 christos else if (n == SIGNED32 (0x80000000) && d == -1)
713 1.1 christos GPR[RD] = EXTEND32 (0x80000000);
714 1.1 christos else
715 1.1 christos GPR[RD] = EXTEND32 (n / d);
716 1.1 christos
717 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
718 1.1 christos }
719 1.1 christos
720 1.1 christos 000000,5.RS,5.RT,5.RD,00011,011010:POOL32X:32::MOD
721 1.1 christos "mod r<RD>, r<RS>, r<RT>"
722 1.1 christos *mips32r6:
723 1.1 christos *mips64r6:
724 1.1 christos {
725 1.1 christos int32_t n = GPR[RS];
726 1.1 christos int32_t d = GPR[RT];
727 1.1 christos TRACE_ALU_INPUT2 (n,d);
728 1.1 christos if (d == 0 || (n == SIGNED32 (0x80000000) && d == -1))
729 1.1 christos GPR[RD] = EXTEND32 (0);
730 1.1 christos else
731 1.1 christos GPR[RD] = EXTEND32 (n % d);
732 1.1 christos
733 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
734 1.1 christos }
735 1.1 christos
736 1.1 christos 000000,5.RS,5.RT,5.RD,00010,011011:POOL32X:32::DIVU
737 1.1 christos "divu r<RD>, r<RS>, r<RT>"
738 1.1 christos *mips32r6:
739 1.1 christos *mips64r6:
740 1.1 christos {
741 1.1 christos uint32_t n = GPR[RS];
742 1.1 christos uint32_t d = GPR[RT];
743 1.1 christos TRACE_ALU_INPUT2 (n,d);
744 1.1 christos if (d == 0)
745 1.1 christos GPR[RD] = EXTEND32 (0x80000000);
746 1.1 christos else
747 1.1 christos GPR[RD] = EXTEND32 (n / d);
748 1.1 christos
749 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
750 1.1 christos }
751 1.1 christos
752 1.1 christos 000000,5.RS,5.RT,5.RD,00011,011011:POOL32X:32::MODU
753 1.1 christos "modu r<RD>, r<RS>, r<RT>"
754 1.1 christos *mips32r6:
755 1.1 christos *mips64r6:
756 1.1 christos {
757 1.1 christos uint32_t n = GPR[RS];
758 1.1 christos uint32_t d = GPR[RT];
759 1.1 christos TRACE_ALU_INPUT2 (n,d);
760 1.1 christos if (d == 0)
761 1.1 christos GPR[RD] = EXTEND32 (0);
762 1.1 christos else
763 1.1 christos GPR[RD] = EXTEND32 (n % d);
764 1.1 christos
765 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
766 1.1 christos }
767 1.1 christos
768 1.1 christos 000000,5.RS,5.RT,5.RD,00010,011100:POOL32X:64::DMUL
769 1.1 christos "dmul r<RD>, r<RS>, r<RT>"
770 1.1 christos *mips64r6:
771 1.1 christos {
772 1.1 christos uint64_t lo;
773 1.1 christos uint64_t m00;
774 1.1 christos uint64_t m01;
775 1.1 christos uint64_t m10;
776 1.1 christos uint64_t mid;
777 1.1 christos int sign;
778 1.1 christos uint64_t op1 = GPR[RS];
779 1.1 christos uint64_t op2 = GPR[RT];
780 1.1 christos
781 1.1 christos check_u64 (SD_, instruction_0);
782 1.1 christos TRACE_ALU_INPUT2 (op1, op2);
783 1.1 christos /* make signed multiply unsigned */
784 1.1 christos sign = 0;
785 1.1 christos if ((int64_t) op1 < 0)
786 1.1 christos {
787 1.1 christos op1 = - op1;
788 1.1 christos ++sign;
789 1.1 christos }
790 1.1 christos if ((int64_t) op2 < 0)
791 1.1 christos {
792 1.1 christos op2 = - op2;
793 1.1 christos ++sign;
794 1.1 christos }
795 1.1 christos /* multiply out the sub products */
796 1.1 christos m00 = ((uint64_t) VL4_8 (op1) * (uint64_t) VL4_8 (op2));
797 1.1 christos m10 = ((uint64_t) VH4_8 (op1) * (uint64_t) VL4_8 (op2));
798 1.1 christos m01 = ((uint64_t) VL4_8 (op1) * (uint64_t) VH4_8 (op2));
799 1.1 christos /* add the products */
800 1.1 christos mid = ((uint64_t) VH4_8 (m00)
801 1.1 christos + (uint64_t) VL4_8 (m10)
802 1.1 christos + (uint64_t) VL4_8 (m01));
803 1.1 christos lo = U8_4 (mid, m00);
804 1.1 christos /* fix the sign */
805 1.1 christos if (sign & 1)
806 1.1 christos lo = -lo;
807 1.1 christos
808 1.1 christos GPR[RD] = lo;
809 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
810 1.1 christos }
811 1.1 christos
812 1.1 christos 000000,5.RS,5.RT,5.RD,00011,011100:POOL32X:64::DMUH
813 1.1 christos "dmuh r<RD>, r<RS>, r<RT>"
814 1.1 christos *mips64r6:
815 1.1 christos {
816 1.1 christos uint64_t lo;
817 1.1 christos uint64_t hi;
818 1.1 christos uint64_t m00;
819 1.1 christos uint64_t m01;
820 1.1 christos uint64_t m10;
821 1.1 christos uint64_t m11;
822 1.1 christos uint64_t mid;
823 1.1 christos int sign;
824 1.1 christos uint64_t op1 = GPR[RS];
825 1.1 christos uint64_t op2 = GPR[RT];
826 1.1 christos
827 1.1 christos check_u64 (SD_, instruction_0);
828 1.1 christos TRACE_ALU_INPUT2 (op1, op2);
829 1.1 christos /* make signed multiply unsigned */
830 1.1 christos sign = 0;
831 1.1 christos if ((int64_t) op1 < 0)
832 1.1 christos {
833 1.1 christos op1 = - op1;
834 1.1 christos ++sign;
835 1.1 christos }
836 1.1 christos if ((int64_t) op2 < 0)
837 1.1 christos {
838 1.1 christos op2 = - op2;
839 1.1 christos ++sign;
840 1.1 christos }
841 1.1 christos /* multiply out the 4 sub products */
842 1.1 christos m00 = ((uint64_t) VL4_8 (op1) * (uint64_t) VL4_8 (op2));
843 1.1 christos m10 = ((uint64_t) VH4_8 (op1) * (uint64_t) VL4_8 (op2));
844 1.1 christos m01 = ((uint64_t) VL4_8 (op1) * (uint64_t) VH4_8 (op2));
845 1.1 christos m11 = ((uint64_t) VH4_8 (op1) * (uint64_t) VH4_8 (op2));
846 1.1 christos /* add the products */
847 1.1 christos mid = ((uint64_t) VH4_8 (m00)
848 1.1 christos + (uint64_t) VL4_8 (m10)
849 1.1 christos + (uint64_t) VL4_8 (m01));
850 1.1 christos lo = U8_4 (mid, m00);
851 1.1 christos hi = (m11
852 1.1 christos + (uint64_t) VH4_8 (mid)
853 1.1 christos + (uint64_t) VH4_8 (m01)
854 1.1 christos + (uint64_t) VH4_8 (m10));
855 1.1 christos /* fix the sign */
856 1.1 christos if (sign & 1)
857 1.1 christos {
858 1.1 christos lo = -lo;
859 1.1 christos if (lo == 0)
860 1.1 christos hi = -hi;
861 1.1 christos else
862 1.1 christos hi = -hi - 1;
863 1.1 christos }
864 1.1 christos
865 1.1 christos GPR[RD] = hi;
866 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
867 1.1 christos }
868 1.1 christos
869 1.1 christos 000000,5.RS,5.RT,5.RD,00010,011101:POOL32X:64::DMULU
870 1.1 christos "dmulu r<RD>, r<RS>, r<RT>"
871 1.1 christos *mips64r6:
872 1.1 christos {
873 1.1 christos uint64_t lo;
874 1.1 christos uint64_t m00;
875 1.1 christos uint64_t m01;
876 1.1 christos uint64_t m10;
877 1.1 christos uint64_t mid;
878 1.1 christos uint64_t op1 = GPR[RS];
879 1.1 christos uint64_t op2 = GPR[RT];
880 1.1 christos
881 1.1 christos check_u64 (SD_, instruction_0);
882 1.1 christos TRACE_ALU_INPUT2 (op1, op2);
883 1.1 christos /* multiply out the sub products */
884 1.1 christos m00 = ((uint64_t) VL4_8 (op1) * (uint64_t) VL4_8 (op2));
885 1.1 christos m10 = ((uint64_t) VH4_8 (op1) * (uint64_t) VL4_8 (op2));
886 1.1 christos m01 = ((uint64_t) VL4_8 (op1) * (uint64_t) VH4_8 (op2));
887 1.1 christos /* add the products */
888 1.1 christos mid = ((uint64_t) VH4_8 (m00)
889 1.1 christos + (uint64_t) VL4_8 (m10)
890 1.1 christos + (uint64_t) VL4_8 (m01));
891 1.1 christos lo = U8_4 (mid, m00);
892 1.1 christos
893 1.1 christos GPR[RD] = lo;
894 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
895 1.1 christos }
896 1.1 christos
897 1.1 christos 000000,5.RS,5.RT,5.RD,00011,011101:POOL32X:64::DMUHU
898 1.1 christos "dmuhu r<RD>, r<RS>, r<RT>"
899 1.1 christos *mips64r6:
900 1.1 christos {
901 1.1 christos uint64_t lo;
902 1.1 christos uint64_t hi;
903 1.1 christos uint64_t m00;
904 1.1 christos uint64_t m01;
905 1.1 christos uint64_t m10;
906 1.1 christos uint64_t m11;
907 1.1 christos uint64_t mid;
908 1.1 christos uint64_t op1 = GPR[RS];
909 1.1 christos uint64_t op2 = GPR[RT];
910 1.1 christos
911 1.1 christos check_u64 (SD_, instruction_0);
912 1.1 christos TRACE_ALU_INPUT2 (op1, op2);
913 1.1 christos /* multiply out the 4 sub products */
914 1.1 christos m00 = ((uint64_t) VL4_8 (op1) * (uint64_t) VL4_8 (op2));
915 1.1 christos m10 = ((uint64_t) VH4_8 (op1) * (uint64_t) VL4_8 (op2));
916 1.1 christos m01 = ((uint64_t) VL4_8 (op1) * (uint64_t) VH4_8 (op2));
917 1.1 christos m11 = ((uint64_t) VH4_8 (op1) * (uint64_t) VH4_8 (op2));
918 1.1 christos /* add the products */
919 1.1 christos mid = ((uint64_t) VH4_8 (m00)
920 1.1 christos + (uint64_t) VL4_8 (m10)
921 1.1 christos + (uint64_t) VL4_8 (m01));
922 1.1 christos lo = U8_4 (mid, m00);
923 1.1 christos hi = (m11
924 1.1 christos + (uint64_t) VH4_8 (mid)
925 1.1 christos + (uint64_t) VH4_8 (m01)
926 1.1 christos + (uint64_t) VH4_8 (m10));
927 1.1 christos
928 1.1 christos GPR[RD] = hi;
929 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
930 1.1 christos }
931 1.1 christos
932 1.1 christos 000000,5.RS,5.RT,5.RD,00010,011110:POOL32X:64::DDIV
933 1.1 christos "ddiv r<RD>, r<RS>, r<RT>"
934 1.1 christos *mips64r6:
935 1.1 christos {
936 1.1 christos int64_t n = GPR[RS];
937 1.1 christos int64_t d = GPR[RT];
938 1.1 christos
939 1.1 christos check_u64 (SD_, instruction_0);
940 1.1 christos TRACE_ALU_INPUT2 (n, d);
941 1.1 christos if (d == 0)
942 1.1 christos GPR[RD] = SIGNED64 (0x8000000000000000);
943 1.1 christos else if (d == -1 && n == SIGNED64 (0x8000000000000000))
944 1.1 christos GPR[RD] = SIGNED64 (0x8000000000000000);
945 1.1 christos else
946 1.1 christos GPR[RD] = (n / d);
947 1.1 christos
948 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
949 1.1 christos }
950 1.1 christos
951 1.1 christos 000000,5.RS,5.RT,5.RD,00011,011110:POOL32X:64::DMOD
952 1.1 christos "dmod r<RD>, r<RS>, r<RT>"
953 1.1 christos *mips64r6:
954 1.1 christos {
955 1.1 christos int64_t n = GPR[RS];
956 1.1 christos int64_t d = GPR[RT];
957 1.1 christos
958 1.1 christos check_u64 (SD_, instruction_0);
959 1.1 christos TRACE_ALU_INPUT2 (n, d);
960 1.1 christos if (d == 0 || (d == -1 && n == SIGNED64 (0x8000000000000000)))
961 1.1 christos GPR[RD] = SIGNED64 (0);
962 1.1 christos else
963 1.1 christos GPR[RD] = (n % d);
964 1.1 christos
965 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
966 1.1 christos }
967 1.1 christos
968 1.1 christos 000000,5.RS,5.RT,5.RD,00010,011111:POOL32X:64::DDIVU
969 1.1 christos "ddivu r<RD>, r<RS>, r<RT>"
970 1.1 christos *mips64r6:
971 1.1 christos {
972 1.1 christos uint64_t n = GPR[RS];
973 1.1 christos uint64_t d = GPR[RT];
974 1.1 christos
975 1.1 christos check_u64 (SD_, instruction_0);
976 1.1 christos TRACE_ALU_INPUT2 (n, d);
977 1.1 christos if (d == 0)
978 1.1 christos GPR[RD] = UNSIGNED64 (0x8000000000000000);
979 1.1 christos else
980 1.1 christos GPR[RD] = (n / d);
981 1.1 christos
982 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
983 1.1 christos }
984 1.1 christos
985 1.1 christos 000000,5.RS,5.RT,5.RD,00011,011111:POOL32X:64::DMODU
986 1.1 christos "dmodu r<RD>, r<RS>, r<RT>"
987 1.1 christos *mips64r6:
988 1.1 christos {
989 1.1 christos uint64_t n = GPR[RS];
990 1.1 christos uint64_t d = GPR[RT];
991 1.1 christos
992 1.1 christos check_u64 (SD_, instruction_0);
993 1.1 christos TRACE_ALU_INPUT2 (n, d);
994 1.1 christos if (d == 0)
995 1.1 christos GPR[RD] = UNSIGNED64 (0);
996 1.1 christos else
997 1.1 christos GPR[RD] = (n % d);
998 1.1 christos
999 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
1000 1.1 christos }
1001 1.1 christos
1002 1.1 christos 011111,5.BASE,5.RT,9.OFFSET,0,110110:SPECIAL3:32::LL
1003 1.1 christos "ll r<RT>, <OFFSET>(r<BASE>)"
1004 1.1 christos *mips32r6:
1005 1.1 christos *mips64r6:
1006 1.1 christos {
1007 1.1 christos do_ll (SD_, RT, EXTEND9 (OFFSET), BASE);
1008 1.1 christos }
1009 1.1 christos
1010 1.1 christos 011111,5.BASE,5.RT,5.RD,0000,1,110110:SPECIAL3:32::LLWP
1011 1.1 christos "llwp r<RT>, r<RD>, (r<BASE>)"
1012 1.1 christos *mips32r6:
1013 1.1 christos *mips64r6:
1014 1.1 christos {
1015 1.1 christos int first, second;
1016 1.1 christos int offset;
1017 1.1 christos
1018 1.1 christos if (RT == BASE)
1019 1.1 christos {
1020 1.1 christos first = RD;
1021 1.1 christos second = RT;
1022 1.1 christos offset = BigEndianCPU ? 0 : 4;
1023 1.1 christos }
1024 1.1 christos else
1025 1.1 christos {
1026 1.1 christos first = RT;
1027 1.1 christos second = RD;
1028 1.1 christos offset = BigEndianCPU ? 4 : 0;
1029 1.1 christos }
1030 1.1 christos
1031 1.1 christos do_ll (SD_, first, offset, BASE);
1032 1.1 christos do_ll (SD_, second, offset ^ 4, BASE);
1033 1.1 christos }
1034 1.1 christos
1035 1.1 christos
1036 1.1 christos 011111,5.BASE,5.RT,9.OFFSET,0,100110:SPECIAL3:32::SC
1037 1.1 christos "sc r<RT>, <OFFSET>(r<BASE>)"
1038 1.1 christos *mips32r6:
1039 1.1 christos *mips64r6:
1040 1.1 christos {
1041 1.1 christos do_sc (SD_, RT, EXTEND9 (OFFSET), BASE, instruction_0, 1);
1042 1.1 christos }
1043 1.1 christos
1044 1.1 christos 011111,5.BASE,5.RT,9.OFFSET,0,110111:SPECIAL3:64::LLD
1045 1.1 christos "lld r<RT>, <OFFSET>(r<BASE>)"
1046 1.1 christos *mips64r6:
1047 1.1 christos {
1048 1.1 christos check_u64 (SD_, instruction_0);
1049 1.1 christos do_lld (SD_, RT, EXTEND9 (OFFSET), BASE);
1050 1.1 christos }
1051 1.1 christos
1052 1.1 christos
1053 1.1 christos 011111,5.BASE,5.RT,5.RD,0000,1,100110:SPECIAL3:32::SCWP
1054 1.1 christos "scwp r<RT>, r<RD>, (r<BASE>)"
1055 1.1 christos *mips32r6:
1056 1.1 christos *mips64r6:
1057 1.1 christos {
1058 1.1 christos int offset = BigEndianCPU ? 0 : 4;
1059 1.1 christos
1060 1.1 christos do_sc (SD_, RD, offset, BASE, instruction_0, 0);
1061 1.1 christos do_sc (SD_, RT, offset ^ 4, BASE, instruction_0, 1);
1062 1.1 christos }
1063 1.1 christos
1064 1.1 christos 011111,5.BASE,5.RT,5.RD,0000,1,110111:SPECIAL3:64::LLDP
1065 1.1 christos "lldp r<RT>, r<RD>, (r<BASE>)"
1066 1.1 christos *mips64r6:
1067 1.1 christos {
1068 1.1 christos int first, second;
1069 1.1 christos int offset;
1070 1.1 christos
1071 1.1 christos check_u64 (SD_, instruction_0);
1072 1.1 christos
1073 1.1 christos if (RT == BASE)
1074 1.1 christos {
1075 1.1 christos first = RD;
1076 1.1 christos second = RT;
1077 1.1 christos offset = BigEndianCPU ? 0 : 8;
1078 1.1 christos }
1079 1.1 christos else
1080 1.1 christos {
1081 1.1 christos first = RT;
1082 1.1 christos second = RD;
1083 1.1 christos offset = BigEndianCPU ? 8 : 0;
1084 1.1 christos }
1085 1.1 christos
1086 1.1 christos do_lld (SD_, first, offset, BASE);
1087 1.1 christos do_lld (SD_, second, offset ^ 8, BASE);
1088 1.1 christos }
1089 1.1 christos
1090 1.1 christos 011111,5.BASE,5.RT,9.OFFSET,0,100111:SPECIAL3:64::SCD
1091 1.1 christos "scd r<RT>, <OFFSET>(r<BASE>)"
1092 1.1 christos *mips64r6:
1093 1.1 christos {
1094 1.1 christos check_u64 (SD_, instruction_0);
1095 1.1 christos do_scd (SD_, RT, EXTEND9 (OFFSET), BASE, 1);
1096 1.1 christos }
1097 1.1 christos
1098 1.1 christos 011111,5.BASE,5.RT,5.RD,0000,1,100111:SPECIAL3:64::SCDP
1099 1.1 christos "scdp r<RT>, r<RD>, (r<BASE>)"
1100 1.1 christos *mips64r6:
1101 1.1 christos {
1102 1.1 christos int offset = BigEndianCPU ? 0 : 8;
1103 1.1 christos check_u64 (SD_, instruction_0);
1104 1.1 christos
1105 1.1 christos do_scd (SD_, RD, offset, BASE, 0);
1106 1.1 christos do_scd (SD_, RT, offset ^ 8, BASE, 1);
1107 1.1 christos }
1108 1.1 christos
1109 1.1 christos 011111,5.BASE,5.HINT,9.OFFSET,0,110101:SPECIAL3:32::PREF
1110 1.1 christos "pref <HINT>, <OFFSET>(r<BASE>)"
1111 1.1 christos *mips32r6:
1112 1.1 christos *mips64r6:
1113 1.1 christos {
1114 1.1 christos do_pref (SD_, HINT, EXTEND9 (OFFSET), BASE);
1115 1.1 christos }
1116 1.1 christos
1117 1.1 christos 011111,5.BASE,5.HINT,9.OFFSET,0,100101:SPECIAL3:32::CACHE
1118 1.1 christos "cache <HINT>, <OFFSET>(r<BASE>)"
1119 1.1 christos *mips32r6:
1120 1.1 christos *mips64r6:
1121 1.1 christos {
1122 1.1 christos do_cache (SD_, HINT, BASE, EXTEND9 (OFFSET), instruction_0);
1123 1.1 christos }
1124 1.1 christos
1125 1.1 christos
1126 1.1 christos 000000,5.RS,00000,5.RD,00001,010000:POOL32X:32::CLZ
1127 1.1 christos "clz r<RD>, r<RS>"
1128 1.1 christos *mips32r6:
1129 1.1 christos *mips64r6:
1130 1.1 christos {
1131 1.1 christos do_clz (SD_, RD, RS);
1132 1.1 christos }
1133 1.1 christos
1134 1.1 christos 000000,5.RS,00000,5.RD,00001,010001:POOL32X:32::CLO
1135 1.1 christos "clo r<RD>, r<RS>"
1136 1.1 christos *mips32r6:
1137 1.1 christos *mips64r6:
1138 1.1 christos {
1139 1.1 christos do_clo (SD_, RD, RS);
1140 1.1 christos }
1141 1.1 christos
1142 1.1 christos 000000,5.RS,00000,5.RD,00001,010010:POOL32X:64::DCLZ
1143 1.1 christos "dclz r<RD>, r<RS>"
1144 1.1 christos *mips64r6:
1145 1.1 christos {
1146 1.1 christos check_u64 (SD_, instruction_0);
1147 1.1 christos do_dclz (SD_, RD, RS);
1148 1.1 christos }
1149 1.1 christos
1150 1.1 christos 000000,5.RS,00000,5.RD,00001,010011:POOL32X:64::DCLO
1151 1.1 christos "dclo r<RD>, r<RS>"
1152 1.1 christos *mips64r6:
1153 1.1 christos {
1154 1.1 christos check_u64 (SD_, instruction_0);
1155 1.1 christos do_dclo (SD_, RD, RS);
1156 1.1 christos }
1157 1.1 christos 010001,1000,1.FMT,5.FT,5.FS,5.FD,010000:POOL32X:32,f::SEL.fmt
1158 1.1 christos "sel.%s<FMT> f<FD>, f<FS>, f<FT>"
1159 1.1 christos *mips32r6:
1160 1.1 christos *mips64r6:
1161 1.1 christos {
1162 1.1 christos check_fpu (SD_);
1163 1.1 christos check_fmt_p (SD_, FMT, instruction_0);
1164 1.1 christos TRACE_ALU_INPUT3 (FGR[FD], ValueFPR(FS, FMT), ValueFPR(FT, FMT));
1165 1.1 christos if ((FGR[FD] & 0x01) != 0)
1166 1.1 christos StoreFPR (FD, FMT, ValueFPR (FT, FMT));
1167 1.1 christos else
1168 1.1 christos StoreFPR (FD, FMT, ValueFPR (FS, FMT));
1169 1.1 christos TRACE_ALU_RESULT (ValueFPR(FD, FMT));
1170 1.1 christos }
1171 1.1 christos
1172 1.1 christos 010001,1000,1.FMT,5.FT,5.FS,5.FD,010100:POOL32X:32,f::SELEQZ.fmt
1173 1.1 christos "seleqz.%s<FMT> f<FD>, f<FS>, f<FT>"
1174 1.1 christos *mips32r6:
1175 1.1 christos *mips64r6:
1176 1.1 christos {
1177 1.1 christos check_fpu (SD_);
1178 1.1 christos check_fmt_p (SD_, FMT, instruction_0);
1179 1.1 christos TRACE_ALU_INPUT2 (ValueFPR(FS, FMT), FGR[FT]);
1180 1.1 christos if ((FGR[FT] & 0x01) == 0)
1181 1.1 christos StoreFPR (FD, FMT, ValueFPR (FS, FMT));
1182 1.1 christos else
1183 1.1 christos StoreFPR (FD, FMT, 0);
1184 1.1 christos TRACE_ALU_RESULT (ValueFPR(FD, FMT));
1185 1.1 christos }
1186 1.1 christos
1187 1.1 christos 010001,1000,1.FMT,5.FT,5.FS,5.FD,010111:POOL32X:32,f::SELNEZ.fmt
1188 1.1 christos "selnez.%s<FMT> f<FD>, f<FS>, f<FT>"
1189 1.1 christos *mips32r6:
1190 1.1 christos *mips64r6:
1191 1.1 christos {
1192 1.1 christos check_fpu (SD_);
1193 1.1 christos check_fmt_p (SD_, FMT, instruction_0);
1194 1.1 christos TRACE_ALU_INPUT2 (ValueFPR(FS, FMT), FGR[FT]);
1195 1.1 christos if ((FGR[FT] & 0x01) == 0)
1196 1.1 christos StoreFPR (FD, FMT, 0);
1197 1.1 christos else
1198 1.1 christos StoreFPR (FD, FMT, ValueFPR (FS, FMT));
1199 1.1 christos TRACE_ALU_RESULT (ValueFPR(FD, FMT));
1200 1.1 christos }
1201 1.1 christos
1202 1.1 christos 000000,5.RS,5.RT,5.RD,00000,110101:POOL32X:32::SELEQZ
1203 1.1 christos "seleqz r<RD>, r<RS>, r<RT>"
1204 1.1 christos *mips32r6:
1205 1.1 christos *mips64r6:
1206 1.1 christos {
1207 1.1 christos TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
1208 1.1 christos if (GPR[RT] != 0)
1209 1.1 christos GPR[RD] = 0;
1210 1.1 christos else
1211 1.1 christos GPR[RD] = GPR[RS];
1212 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
1213 1.1 christos }
1214 1.1 christos
1215 1.1 christos 000000,5.RS,5.RT,5.RD,00000,110111:POOL32X:32::SELNEZ
1216 1.1 christos "selnez r<RD>, r<RS>, r<RT>"
1217 1.1 christos *mips32r6:
1218 1.1 christos *mips64r6:
1219 1.1 christos {
1220 1.1 christos TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
1221 1.1 christos if (GPR[RT] != 0)
1222 1.1 christos GPR[RD] = GPR[RS];
1223 1.1 christos else
1224 1.1 christos GPR[RD] = 0;
1225 1.1 christos TRACE_ALU_RESULT (GPR[RD]);
1226 1.1 christos }
1227