Bug 476331 - clean up generated/distributed filter scripts
[valgrind.git] / VEX / priv / guest_mipsdsp_toIR.c
blob4665333392493aa3a880a7e10ee4c3ac503d27c5
1 #include "libvex_basictypes.h"
2 #include "libvex_ir.h"
3 #include "libvex.h"
4 #include "libvex_guest_mips32.h"
5 #include "libvex_guest_mips64.h"
7 #include "main_util.h"
8 #include "main_globals.h"
9 #include "guest_generic_bb_to_IR.h"
10 #include "guest_mips_defs.h"
11 #include "mips_defs.h"
14 /* Put value to DSPControl register. Expression e is written to DSPControl as
15 is. If only certain bits of DSPControl need to be changed, it should be done
16 before calling putDSPControl(). It could be done by reading DSPControl and
17 ORing it with appropriate mask. */
18 static void putDSPControl(IRExpr * e)
20 vassert(!mode64);
21 stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_DSPControl), e));
24 /* Put value to accumulator(helper function for MIPS32 DSP ASE instructions). */
25 static void putAcc(UInt acNo, IRExpr * e)
27 vassert(!mode64);
28 vassert(acNo <= 3);
29 vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64);
30 stmt(IRStmt_Put(accumulatorGuestRegOffset(acNo), e));
32 /* If acNo = 0, split value to HI and LO regs in order to maintain compatibility
33 between MIPS32 and MIPS DSP ASE insn sets. */
34 if (0 == acNo) {
35 putLO(unop(Iop_64to32, e));
36 putHI(unop(Iop_64HIto32, e));
39 /*------------------------------------------------------------*/
40 /*--- Disassemble a single DSP ASE instruction ---*/
41 /*------------------------------------------------------------*/
43 static UInt disDSPInstr_MIPS_WRK_Special ( UInt cins )
45 IRTemp t1;
46 UInt rs, rt, rd, function, ac, ac_mfhilo;
47 rs = get_rs(cins);
48 rt = get_rt(cins);
49 rd = get_rd(cins);
50 function = get_function(cins);
51 ac = get_acNo(cins);
52 ac_mfhilo = get_acNo_mfhilo(cins);
54 switch (function) {
55 case 0x10: { /* MFHI */
56 DIP("mfhi ac%u r%u", ac_mfhilo, rd);
57 putIReg(rd, unop(Iop_64HIto32, getAcc(ac_mfhilo)));
58 break;
61 case 0x11: { /* MTHI */
62 DIP("mthi ac%u r%u", ac, rs);
63 t1 = newTemp(Ity_I32);
64 assign(t1, unop(Iop_64to32, getAcc(ac)));
65 putAcc(ac, binop(Iop_32HLto64, getIReg(rs), mkexpr(t1)));
66 break;
69 case 0x12: { /* MFLO */
70 DIP("mflo ac%u r%u", ac_mfhilo, rd);
71 putIReg(rd, unop(Iop_64to32, getAcc(ac_mfhilo)));
72 break;
75 case 0x13: { /* MTLO */
76 DIP("mtlo ac%u r%u", ac, rs);
77 t1 = newTemp(Ity_I32);
78 assign(t1, unop(Iop_64HIto32, getAcc(ac)));
79 putAcc(ac, binop(Iop_32HLto64, mkexpr(t1), getIReg(rs)));
80 break;
83 case 0x18: { /* MULT */
84 DIP("mult ac%u r%u, r%u", ac, rs, rt);
85 t1 = newTemp(Ity_I64);
86 assign(t1, binop(Iop_MullS32, mkNarrowTo32(Ity_I32, getIReg(rs)),
87 mkNarrowTo32(Ity_I32, getIReg(rt))));
88 putAcc(ac, mkexpr(t1));
89 break;
92 case 0x19: { /* MULTU */
93 DIP("multu ac%u r%u, r%u", ac, rs, rt);
94 t1 = newTemp(Ity_I64);
95 assign(t1, binop(Iop_MullU32, mkNarrowTo32(Ity_I32, getIReg(rs)),
96 mkNarrowTo32(Ity_I32,
97 getIReg(rt))));
98 putAcc(ac, mkexpr(t1));
99 break;
103 return 0;
107 static UInt disDSPInstr_MIPS_WRK_Special2 ( UInt cins )
109 IRTemp t1 = 0, t2, t3;
110 UInt rs, rt, function, ac;
111 rs = get_rs(cins);
112 rt = get_rt(cins);
113 function = get_function(cins);
114 ac = get_acNo(cins);
116 switch (function) {
117 case 0x00: { /* MADD */
118 DIP("madd ac%u, r%u, r%u", ac, rs, rt);
119 t1 = newTemp(Ity_I64);
120 t2 = newTemp(Ity_I64);
121 t3 = newTemp(Ity_I64);
123 assign(t1, getAcc(ac));
124 assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
125 assign(t3, binop(Iop_Add64, mkexpr(t1), mkexpr(t2)));
127 putAcc(ac, mkexpr(t3));
128 break;
131 case 0x01: { /* MADDU */
132 DIP("maddu ac%u r%u, r%u", ac, rs, rt);
133 t1 = newTemp(Ity_I64);
134 t2 = newTemp(Ity_I64);
135 t3 = newTemp(Ity_I64);
137 assign(t1, getAcc(ac));
138 assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
139 assign(t3, binop(Iop_Add64, mkexpr(t2), mkexpr(t1)));
141 putAcc(ac, mkexpr(t3));
142 break;
145 case 0x04: { /* MSUB */
146 DIP("msub ac%u r%u, r%u", ac, rs, rt);
147 t1 = newTemp(Ity_I64);
148 t2 = newTemp(Ity_I64);
149 t3 = newTemp(Ity_I64);
151 assign(t1, getAcc(ac));
152 assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
153 assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
155 putAcc(ac, mkexpr(t3));
156 break;
159 case 0x05: { /* MSUBU */
160 DIP("msubu ac%u r%u, r%u", ac, rs, rt);
161 t1 = newTemp(Ity_I64);
162 t2 = newTemp(Ity_I64);
163 t3 = newTemp(Ity_I64);
165 assign(t1, getAcc(ac));
166 assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
167 assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
169 putAcc(ac, mkexpr(t3));
170 break;
174 return 0;
177 static UInt disDSPInstr_MIPS_WRK_Special3_ABSQ_SPH( UInt cins )
179 IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
180 t15, t16, t17;
181 UInt rt, rd, sa, dsp_imm;
183 rt = get_rt(cins);
184 rd = get_rd(cins);
185 sa = get_sa(cins);
186 dsp_imm = get_dspImm(cins);
188 switch (sa) {
189 case 0x1: { /* ABSQ_S.QB */
190 DIP("absq_s.qb r%u, r%u", rd, rt);
191 vassert(!mode64);
192 t0 = newTemp(Ity_I8);
193 t1 = newTemp(Ity_I1);
194 t2 = newTemp(Ity_I1);
195 t3 = newTemp(Ity_I8);
196 t4 = newTemp(Ity_I8);
197 t5 = newTemp(Ity_I1);
198 t6 = newTemp(Ity_I1);
199 t7 = newTemp(Ity_I8);
200 t8 = newTemp(Ity_I8);
201 t9 = newTemp(Ity_I1);
202 t10 = newTemp(Ity_I1);
203 t11 = newTemp(Ity_I8);
204 t12 = newTemp(Ity_I8);
205 t13 = newTemp(Ity_I1);
206 t14 = newTemp(Ity_I1);
207 t15 = newTemp(Ity_I8);
208 t16 = newTemp(Ity_I32);
209 t17 = newTemp(Ity_I32);
211 /* Absolute value of the rightmost byte (bits 7-0). */
212 /* t0 - rightmost byte. */
213 assign(t0, unop(Iop_16to8, unop(Iop_32to16, getIReg(rt))));
214 /* t1 holds 1 if t0 is equal to 0x80, or 0 otherwise. */
215 assign(t1, binop(Iop_CmpEQ32,
216 unop(Iop_8Uto32, mkexpr(t0)),
217 mkU32(0x00000080)));
218 /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
219 assign(t2, unop(Iop_32to1,
220 binop(Iop_Shr32,
221 binop(Iop_And32,
222 getIReg(rt),
223 mkU32(0x00000080)),
224 mkU8(0x7))));
225 /* t3 holds abs(t0). */
226 assign(t3, IRExpr_ITE(mkexpr(t1),
227 mkU8(0x7F),
228 IRExpr_ITE(mkexpr(t2),
229 binop(Iop_Add8,
230 unop(Iop_Not8,
231 mkexpr(t0)),
232 mkU8(0x1)),
233 mkexpr(t0))));
235 /* Absolute value of bits 15-8. */
236 /* t4 - input byte. */
237 assign(t4,
238 unop(Iop_16HIto8, unop(Iop_32to16, getIReg(rt))));
239 /* t5 holds 1 if t4 is equal to 0x80, or 0 otherwise. */
240 assign(t5, binop(Iop_CmpEQ32,
241 unop(Iop_8Uto32, mkexpr(t4)),
242 mkU32(0x00000080)));
243 /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
244 assign(t6, unop(Iop_32to1,
245 binop(Iop_Shr32,
246 binop(Iop_And32,
247 getIReg(rt),
248 mkU32(0x00008000)),
249 mkU8(15))));
250 /* t3 holds abs(t4). */
251 assign(t7, IRExpr_ITE(mkexpr(t5),
252 mkU8(0x7F),
253 IRExpr_ITE(mkexpr(t6),
254 binop(Iop_Add8,
255 unop(Iop_Not8,
256 mkexpr(t4)),
257 mkU8(0x1)),
258 mkexpr(t4))));
260 /* Absolute value of bits 23-15. */
261 /* t8 - input byte. */
262 assign(t8,
263 unop(Iop_16to8, unop(Iop_32HIto16, getIReg(rt))));
264 /* t9 holds 1 if t8 is equal to 0x80, or 0 otherwise. */
265 assign(t9, binop(Iop_CmpEQ32,
266 unop(Iop_8Uto32, mkexpr(t8)),
267 mkU32(0x00000080)));
268 /* t6 holds 1 if value in t8 is negative, 0 otherwise. */
269 assign(t10, unop(Iop_32to1,
270 binop(Iop_Shr32,
271 binop(Iop_And32,
272 getIReg(rt),
273 mkU32(0x00800000)),
274 mkU8(23))));
275 /* t3 holds abs(t8). */
276 assign(t11, IRExpr_ITE(mkexpr(t9),
277 mkU8(0x7F),
278 IRExpr_ITE(mkexpr(t10),
279 binop(Iop_Add8,
280 unop(Iop_Not8,
281 mkexpr(t8)),
282 mkU8(0x1)),
283 mkexpr(t8))));
285 /* Absolute value of bits 31-24. */
286 /* t12 - input byte. */
287 assign(t12,
288 unop(Iop_16HIto8, unop(Iop_32HIto16, getIReg(rt))));
289 /* t13 holds 1 if t12 is equal to 0x80, or 0 otherwise. */
290 assign(t13, binop(Iop_CmpEQ32,
291 unop(Iop_8Uto32, mkexpr(t12)),
292 mkU32(0x00000080)));
293 /* t14 holds 1 if value in t12 is negative, 0 otherwise. */
294 assign(t14, unop(Iop_32to1,
295 binop(Iop_Shr32,
296 binop(Iop_And32,
297 getIReg(rt),
298 mkU32(0x80000000)),
299 mkU8(31))));
300 /* t15 holds abs(t12). */
301 assign(t15, IRExpr_ITE(mkexpr(t13),
302 mkU8(0x7F),
303 IRExpr_ITE(mkexpr(t14),
304 binop(Iop_Add8,
305 unop(Iop_Not8,
306 mkexpr(t12)),
307 mkU8(0x1)),
308 mkexpr(t12))));
310 /* t16 holds !0 if any of input bytes is 0x80 or 0
311 otherwise. */
312 assign(t16,
313 binop(Iop_Or32,
314 binop(Iop_Or32,
315 binop(Iop_Or32,
316 unop(Iop_1Sto32, mkexpr(t13)),
317 unop(Iop_1Sto32, mkexpr(t9))),
318 unop(Iop_1Sto32, mkexpr(t5))),
319 unop(Iop_1Sto32, mkexpr(t1))));
321 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
322 mkexpr(t16),
323 mkU32(0x0)),
324 getDSPControl(),
325 binop(Iop_Or32,
326 getDSPControl(),
327 mkU32(0x00100000))));
329 /* t17 = t15|t11|t7|t3 */
330 assign(t17,
331 binop(Iop_16HLto32,
332 binop(Iop_8HLto16, mkexpr(t15), mkexpr(t11)),
333 binop(Iop_8HLto16, mkexpr(t7), mkexpr(t3))));
335 putIReg(rd, mkexpr(t17));
336 break;
339 case 0x2: { /* REPL.QB */
340 DIP("repl.qb r%u, %u", rd, dsp_imm);
341 vassert(!mode64);
343 putIReg(rd, mkU32((dsp_imm << 24) | (dsp_imm << 16) |
344 (dsp_imm << 8) | (dsp_imm)));
345 break;
348 case 0x3: { /* REPLV.QB */
349 DIP("replv.qb r%u, r%u", rd, rt);
350 vassert(!mode64);
351 t0 = newTemp(Ity_I8);
353 assign(t0, unop(Iop_32to8,
354 binop(Iop_And32, getIReg(rt), mkU32(0xff))));
355 putIReg(rd,
356 binop(Iop_16HLto32,
357 binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)),
358 binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0))));
359 break;
362 case 0x4: { /* PRECEQU.PH.QBL */
363 DIP("precequ.ph.qbl r%u, r%u", rd, rt);
364 vassert(!mode64);
366 putIReg(rd, binop(Iop_Or32,
367 binop(Iop_Shr32,
368 binop(Iop_And32,
369 getIReg(rt),
370 mkU32(0xff000000)),
371 mkU8(1)),
372 binop(Iop_Shr32,
373 binop(Iop_And32,
374 getIReg(rt),
375 mkU32(0x00ff0000)),
376 mkU8(9))));
377 break;
380 case 0x5: { /* PRECEQU.PH.QBR */
381 DIP("precequ.ph.qbr r%u, r%u", rd, rt);
382 vassert(!mode64);
384 putIReg(rd, binop(Iop_Or32,
385 binop(Iop_Shl32,
386 binop(Iop_And32,
387 getIReg(rt),
388 mkU32(0x0000ff00)),
389 mkU8(15)),
390 binop(Iop_Shl32,
391 binop(Iop_And32,
392 getIReg(rt),
393 mkU32(0x000000ff)),
394 mkU8(7))));
395 break;
398 case 0x6: { /* PRECEQU.PH.QBLA */
399 DIP("precequ.ph.qbla r%u, r%u", rd, rt);
400 vassert(!mode64);
402 putIReg(rd, binop(Iop_Or32,
403 binop(Iop_Shr32,
404 binop(Iop_And32,
405 getIReg(rt),
406 mkU32(0xff000000)),
407 mkU8(1)),
408 binop(Iop_Shr32,
409 binop(Iop_And32,
410 getIReg(rt),
411 mkU32(0x0000ff00)),
412 mkU8(1))));
413 break;
416 case 0x7: { /* PRECEQU.PH.QBRA */
417 DIP("precequ.ph.qbra r%u, r%u", rd, rt);
418 vassert(!mode64);
420 putIReg(rd, binop(Iop_Or32,
421 binop(Iop_Shl32,
422 binop(Iop_And32,
423 getIReg(rt),
424 mkU32(0x00ff0000)),
425 mkU8(7)),
426 binop(Iop_Shl32,
427 binop(Iop_And32,
428 getIReg(rt),
429 mkU32(0x000000ff)),
430 mkU8(7))));
431 break;
434 case 0x9: { /* ABSQ_S.PH */
435 DIP("absq_s.ph r%u, r%u", rd, rt);
436 vassert(!mode64);
437 t0 = newTemp(Ity_I16);
438 t1 = newTemp(Ity_I1);
439 t2 = newTemp(Ity_I1);
440 t3 = newTemp(Ity_I16);
441 t4 = newTemp(Ity_I16);
442 t5 = newTemp(Ity_I1);
443 t6 = newTemp(Ity_I1);
444 t7 = newTemp(Ity_I16);
445 t8 = newTemp(Ity_I32);
446 t9 = newTemp(Ity_I32);
448 /* t0 holds lower 16 bits of value in rt. */
449 assign(t0, unop(Iop_32to16, getIReg(rt)));
450 /* t1 holds 1 if t0 is equal to 0x8000. */
451 assign(t1, binop(Iop_CmpEQ32,
452 unop(Iop_16Uto32, mkexpr(t0)),
453 mkU32(0x00008000)));
454 /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
455 assign(t2, unop(Iop_32to1,
456 binop(Iop_Shr32,
457 binop(Iop_And32,
458 getIReg(rt),
459 mkU32(0x00008000)),
460 mkU8(15))));
461 /* t3 holds abs(t0). */
462 assign(t3, IRExpr_ITE(mkexpr(t1),
463 mkU16(0x7FFF),
464 IRExpr_ITE(mkexpr(t2),
465 binop(Iop_Add16,
466 unop(Iop_Not16,
467 mkexpr(t0)),
468 mkU16(0x1)),
469 mkexpr(t0))));
471 /* t4 holds lower 16 bits of value in rt. */
472 assign(t4, unop(Iop_32HIto16, getIReg(rt)));
473 /* t5 holds 1 if t4 is equal to 0x8000. */
474 assign(t5, binop(Iop_CmpEQ32,
475 unop(Iop_16Uto32, mkexpr(t4)),
476 mkU32(0x00008000)));
477 /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
478 assign(t6, unop(Iop_32to1,
479 binop(Iop_Shr32,
480 binop(Iop_And32,
481 getIReg(rt),
482 mkU32(0x80000000)),
483 mkU8(31))));
484 /* t7 holds abs(t4). */
485 assign(t7, IRExpr_ITE(mkexpr(t5),
486 mkU16(0x7FFF),
487 IRExpr_ITE(mkexpr(t6),
488 binop(Iop_Add16,
489 unop(Iop_Not16,
490 mkexpr(t4)),
491 mkU16(0x1)),
492 mkexpr(t4))));
493 /* If any of the two input halfwords is equal 0x8000,
494 set bit 20 in DSPControl register. */
495 assign(t8, binop(Iop_Or32,
496 unop(Iop_1Sto32, mkexpr(t5)),
497 unop(Iop_1Sto32, mkexpr(t1))));
499 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
500 mkexpr(t8),
501 mkU32(0x0)),
502 getDSPControl(),
503 binop(Iop_Or32,
504 getDSPControl(),
505 mkU32(0x00100000))));
507 /* t9 = t7|t3 */
508 assign(t9, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
510 putIReg(rd, mkexpr(t9));
511 break;
514 case 0xA: { /* REPL.PH */
515 DIP("repl.ph r%u, %u", rd, dsp_imm);
516 vassert(!mode64);
517 UShort immediate = extend_s_10to16(dsp_imm);
519 putIReg(rd, mkU32(immediate << 16 | immediate));
520 break;
523 case 0xB: { /* REPLV.PH */
524 DIP("replv.ph r%u, r%u", rd, rt);
525 vassert(!mode64);
527 putIReg(rd, binop(Iop_16HLto32,
528 unop(Iop_32to16, getIReg(rt)),
529 unop(Iop_32to16, getIReg(rt))));
530 break;
533 case 0xC: { /* PRECEQ.W.PHL */
534 DIP("preceq.w.phl r%u, r%u", rd, rt);
535 vassert(!mode64);
536 putIReg(rd, binop(Iop_And32,
537 getIReg(rt),
538 mkU32(0xffff0000)));
539 break;
542 case 0xD: { /* PRECEQ.W.PHR */
543 DIP("preceq.w.phr r%u, r%u", rd, rt);
544 vassert(!mode64);
545 putIReg(rd, binop(Iop_16HLto32,
546 unop(Iop_32to16, getIReg(rt)),
547 mkU16(0x0)));
548 break;
551 case 0x11: { /* ABSQ_S.W */
552 DIP("absq_s.w r%u, r%u", rd, rt);
553 vassert(!mode64);
554 t0 = newTemp(Ity_I1);
555 t1 = newTemp(Ity_I1);
556 t2 = newTemp(Ity_I32);
558 assign(t0,
559 binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
561 putDSPControl(IRExpr_ITE(mkexpr(t0),
562 binop(Iop_Or32,
563 getDSPControl(),
564 mkU32(0x00100000)),
565 getDSPControl()));
567 assign(t1, binop(Iop_CmpLT32S, getIReg(rt), mkU32(0x0)));
569 assign(t2, IRExpr_ITE(mkexpr(t0),
570 mkU32(0x7FFFFFFF),
571 IRExpr_ITE(mkexpr(t1),
572 binop(Iop_Add32,
573 unop(Iop_Not32,
574 getIReg(rt)),
575 mkU32(0x1)),
576 getIReg(rt))));
577 putIReg(rd, mkexpr(t2));
578 break;
581 case 0x1B: { /* BITREV */
582 DIP("bitrev r%u, r%u", rd, rt);
583 vassert(!mode64);
584 /* 32bit reversal as seen on Bit Twiddling Hacks site
585 http://graphics.stanford.edu/~seander/bithacks.html
586 section ReverseParallel */
587 t1 = newTemp(Ity_I32);
588 t2 = newTemp(Ity_I32);
589 t3 = newTemp(Ity_I32);
590 t4 = newTemp(Ity_I32);
591 t5 = newTemp(Ity_I32);
593 assign(t1, binop(Iop_Or32,
594 binop(Iop_Shr32,
595 binop(Iop_And32,
596 getIReg(rt),
597 mkU32(0xaaaaaaaa)),
598 mkU8(0x1)),
599 binop(Iop_Shl32,
600 binop(Iop_And32,
601 getIReg(rt),
602 mkU32(0x55555555)),
603 mkU8(0x1))));
604 assign(t2, binop(Iop_Or32,
605 binop(Iop_Shr32,
606 binop(Iop_And32,
607 mkexpr(t1),
608 mkU32(0xcccccccc)),
609 mkU8(0x2)),
610 binop(Iop_Shl32,
611 binop(Iop_And32,
612 mkexpr(t1),
613 mkU32(0x33333333)),
614 mkU8(0x2))));
615 assign(t3, binop(Iop_Or32,
616 binop(Iop_Shr32,
617 binop(Iop_And32,
618 mkexpr(t2),
619 mkU32(0xf0f0f0f0)),
620 mkU8(0x4)),
621 binop(Iop_Shl32,
622 binop(Iop_And32,
623 mkexpr(t2),
624 mkU32(0x0f0f0f0f)),
625 mkU8(0x4))));
626 assign(t4, binop(Iop_Or32,
627 binop(Iop_Shr32,
628 binop(Iop_And32,
629 mkexpr(t3),
630 mkU32(0xff00ff00)),
631 mkU8(0x8)),
632 binop(Iop_Shl32,
633 binop(Iop_And32,
634 mkexpr(t3),
635 mkU32(0x00ff00ff)),
636 mkU8(0x8))));
637 assign(t5, binop(Iop_Or32,
638 binop(Iop_Shr32,
639 mkexpr(t4),
640 mkU8(0x10)),
641 binop(Iop_Shl32,
642 mkexpr(t4),
643 mkU8(0x10))));
644 putIReg(rd, binop(Iop_Shr32,
645 mkexpr(t5),
646 mkU8(16)));
647 break;
650 case 0x1C: { /* PRECEU.PH.QBL */
651 DIP("preceu.ph.qbl r%u, r%u", rd, rt);
652 vassert(!mode64);
654 putIReg(rd, binop(Iop_Or32,
655 binop(Iop_Shr32,
656 binop(Iop_And32,
657 getIReg(rt),
658 mkU32(0xff000000)),
659 mkU8(8)),
660 binop(Iop_Shr32,
661 binop(Iop_And32,
662 getIReg(rt),
663 mkU32(0x00ff0000)),
664 mkU8(16))));
665 break;
668 case 0x1E: { /* PRECEU.PH.QBLA */
669 DIP("preceu.ph.qbla r%u, r%u", rd, rt);
670 vassert(!mode64);
672 putIReg(rd, binop(Iop_Or32,
673 binop(Iop_Shr32,
674 binop(Iop_And32,
675 getIReg(rt),
676 mkU32(0xff000000)),
677 mkU8(8)),
678 binop(Iop_Shr32,
679 binop(Iop_And32,
680 getIReg(rt),
681 mkU32(0x0000ff00)),
682 mkU8(8))));
683 break;
686 case 0x1D: { /* PRECEU.PH.QBR */
687 DIP("preceu.ph.qbr r%u, r%u", rd, rt);
688 vassert(!mode64);
690 putIReg(rd, binop(Iop_Or32,
691 binop(Iop_Shl32,
692 binop(Iop_And32,
693 getIReg(rt),
694 mkU32(0x0000ff00)),
695 mkU8(8)),
696 binop(Iop_And32,
697 getIReg(rt),
698 mkU32(0x000000ff))));
699 break;
702 case 0x1F: { /* PRECEU.PH.QBRA */
703 DIP("preceu.ph.qbra r%u, r%u", rd, rt);
704 vassert(!mode64);
706 putIReg(rd, binop(Iop_Or32,
707 binop(Iop_And32,
708 getIReg(rt),
709 mkU32(0x00ff0000)),
710 binop(Iop_And32,
711 getIReg(rt),
712 mkU32(0x000000ff))));
713 break;
716 default:
717 return -1;
720 return 0;
723 static UInt disDSPInstr_MIPS_WRK_Special3_EXTR_W( UInt cins )
725 IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
726 t15, t16, t17;
727 UInt rs, rt, rd, sa, ac, rddsp_mask,
728 wrdsp_mask, shift;
730 rs = get_rs(cins);
731 rt = get_rt(cins);
732 rd = get_rd(cins);
733 sa = get_sa(cins);
734 ac = get_acNo(cins);
735 rddsp_mask = get_rddspMask(cins);
736 wrdsp_mask = get_wrdspMask(cins);
737 shift = get_shift(cins);
739 switch (sa) {
740 case 0x0: { /* EXTR.W */
741 DIP("extr.w r%u, ac%u, %u", rt, ac, rs);
742 vassert(!mode64);
743 t0 = newTemp(Ity_I64);
744 t1 = newTemp(Ity_I64);
745 t2 = newTemp(Ity_I32);
746 t3 = newTemp(Ity_I1);
747 t4 = newTemp(Ity_I1);
748 t5 = newTemp(Ity_I1);
749 t6 = newTemp(Ity_I1);
750 t7 = newTemp(Ity_I32);
751 t8 = newTemp(Ity_I64);
752 t9 = newTemp(Ity_I64);
753 t10 = newTemp(Ity_I1);
754 t11 = newTemp(Ity_I1);
755 t12 = newTemp(Ity_I1);
756 t13 = newTemp(Ity_I1);
757 t14 = newTemp(Ity_I32);
759 assign(t0, getAcc(ac));
761 if (0 == rs) {
762 assign(t1, mkexpr(t0));
763 } else {
764 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
767 /* Check if bits 63..31 of the result in t1 aren't 0. */
768 assign(t3, binop(Iop_CmpNE32,
769 unop(Iop_64HIto32,
770 mkexpr(t1)),
771 mkU32(0)));
772 assign(t4, binop(Iop_CmpNE32,
773 binop(Iop_And32,
774 unop(Iop_64to32,
775 mkexpr(t1)),
776 mkU32(0x80000000)),
777 mkU32(0)));
778 /* Check if bits 63..31 of the result in t1 aren't
779 0x1ffffffff. */
780 assign(t5, binop(Iop_CmpNE32,
781 unop(Iop_64HIto32,
782 mkexpr(t1)),
783 mkU32(0xffffffff)));
784 assign(t6, binop(Iop_CmpNE32,
785 binop(Iop_And32,
786 unop(Iop_64to32,
787 mkexpr(t1)),
788 mkU32(0x80000000)),
789 mkU32(0x80000000)));
790 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
791 control register. */
792 assign(t7, binop(Iop_And32,
793 binop(Iop_Or32,
794 unop(Iop_1Sto32, mkexpr(t3)),
795 unop(Iop_1Sto32, mkexpr(t4))),
796 binop(Iop_Or32,
797 unop(Iop_1Sto32, mkexpr(t5)),
798 unop(Iop_1Sto32, mkexpr(t6)))));
799 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
800 mkexpr(t7),
801 mkU32(0)),
802 binop(Iop_Or32,
803 getDSPControl(),
804 mkU32(0x00800000)),
805 getDSPControl()));
807 /* If the last discarded bit is 1, there would be carry
808 when rounding, otherwise there wouldn't. We use that
809 fact and just add the value of the last discarded bit
810 to the least sifgnificant bit of the shifted value
811 from acc. */
812 if (0 == rs) {
813 assign(t8, mkU64(0x0ULL));
814 } else {
815 assign(t8, binop(Iop_And64,
816 binop(Iop_Shr64,
817 mkexpr(t0),
818 mkU8(rs - 1)),
819 mkU64(0x1ULL)));
822 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
824 /* Repeat previous steps for the rounded value. */
825 assign(t10, binop(Iop_CmpNE32,
826 unop(Iop_64HIto32,
827 mkexpr(t9)),
828 mkU32(0)));
829 assign(t11, binop(Iop_CmpNE32,
830 binop(Iop_And32,
831 unop(Iop_64to32,
832 mkexpr(t9)),
833 mkU32(0x80000000)),
834 mkU32(0)));
836 assign(t12, binop(Iop_CmpNE32,
837 unop(Iop_64HIto32,
838 mkexpr(t9)),
839 mkU32(0xffffffff)));
840 assign(t13, binop(Iop_CmpNE32,
841 binop(Iop_And32,
842 unop(Iop_64to32,
843 mkexpr(t9)),
844 mkU32(0x80000000)),
845 mkU32(0x80000000)));
847 assign(t14, binop(Iop_And32,
848 binop(Iop_Or32,
849 unop(Iop_1Sto32, mkexpr(t10)),
850 unop(Iop_1Sto32, mkexpr(t11))),
851 binop(Iop_Or32,
852 unop(Iop_1Sto32, mkexpr(t12)),
853 unop(Iop_1Sto32, mkexpr(t13)))));
854 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
855 mkexpr(t14),
856 mkU32(0)),
857 binop(Iop_Or32,
858 getDSPControl(),
859 mkU32(0x00800000)),
860 getDSPControl()));
862 if (0 == rs) {
863 putIReg(rt, unop(Iop_64to32, mkexpr(t0)));
864 } else {
865 putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
868 break;
871 case 0x1: { /* EXTRV.W */
872 DIP("extrv.w r%u, ac%u, r%u", rt, ac, rs);
873 vassert(!mode64);
874 t0 = newTemp(Ity_I64);
875 t1 = newTemp(Ity_I64);
876 t2 = newTemp(Ity_I32);
877 t3 = newTemp(Ity_I1);
878 t4 = newTemp(Ity_I1);
879 t5 = newTemp(Ity_I1);
880 t6 = newTemp(Ity_I1);
881 t7 = newTemp(Ity_I32);
882 t8 = newTemp(Ity_I64);
883 t9 = newTemp(Ity_I64);
884 t10 = newTemp(Ity_I1);
885 t11 = newTemp(Ity_I1);
886 t12 = newTemp(Ity_I1);
887 t13 = newTemp(Ity_I1);
888 t14 = newTemp(Ity_I32);
889 t15 = newTemp(Ity_I8);
891 assign(t15, unop(Iop_32to8,
892 binop(Iop_And32,
893 getIReg(rs),
894 mkU32(0x1f))));
895 assign(t0, getAcc(ac));
896 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
897 putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
898 unop(Iop_8Uto32,
899 mkexpr(t15)),
900 mkU32(0)),
901 unop(Iop_64to32, mkexpr(t0)),
902 unop(Iop_64to32, mkexpr(t1))));
904 /* Check if bits 63..31 of the result in t1 aren't 0. */
905 assign(t3, binop(Iop_CmpNE32,
906 unop(Iop_64HIto32,
907 mkexpr(t1)),
908 mkU32(0)));
909 assign(t4, binop(Iop_CmpNE32,
910 binop(Iop_And32,
911 unop(Iop_64to32,
912 mkexpr(t1)),
913 mkU32(0x80000000)),
914 mkU32(0)));
915 /* Check if bits 63..31 of the result in t1 aren't
916 0x1ffffffff. */
917 assign(t5, binop(Iop_CmpNE32,
918 unop(Iop_64HIto32,
919 mkexpr(t1)),
920 mkU32(0xffffffff)));
921 assign(t6, binop(Iop_CmpNE32,
922 binop(Iop_And32,
923 unop(Iop_64to32,
924 mkexpr(t1)),
925 mkU32(0x80000000)),
926 mkU32(0x80000000)));
927 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
928 control register. */
929 assign(t7, binop(Iop_And32,
930 binop(Iop_Or32,
931 unop(Iop_1Sto32, mkexpr(t3)),
932 unop(Iop_1Sto32, mkexpr(t4))),
933 binop(Iop_Or32,
934 unop(Iop_1Sto32, mkexpr(t5)),
935 unop(Iop_1Sto32, mkexpr(t6)))));
936 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
937 mkexpr(t7),
938 mkU32(0)),
939 binop(Iop_Or32,
940 getDSPControl(),
941 mkU32(0x00800000)),
942 getDSPControl()));
944 /* If the last discarded bit is 1, there would be carry
945 when rounding, otherwise there wouldn't. We use that
946 fact and just add the value of the last discarded bit
947 to the least sifgnificant bit of the shifted value
948 from acc. */
949 assign(t8,
950 IRExpr_ITE(binop(Iop_CmpEQ32,
951 unop(Iop_8Uto32,
952 mkexpr(t15)),
953 mkU32(0)),
954 mkU64(0x0ULL),
955 binop(Iop_And64,
956 binop(Iop_Shr64,
957 mkexpr(t0),
958 unop(Iop_32to8,
959 binop(Iop_Sub32,
960 unop(Iop_8Uto32,
961 mkexpr(t15)),
962 mkU32(1)))),
963 mkU64(0x1ULL))));
965 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
967 /* Repeat previous steps for the rounded value. */
968 assign(t10, binop(Iop_CmpNE32,
969 unop(Iop_64HIto32,
970 mkexpr(t9)),
971 mkU32(0)));
972 assign(t11, binop(Iop_CmpNE32,
973 binop(Iop_And32,
974 unop(Iop_64to32,
975 mkexpr(t9)),
976 mkU32(0x80000000)),
977 mkU32(0)));
979 assign(t12, binop(Iop_CmpNE32,
980 unop(Iop_64HIto32,
981 mkexpr(t9)),
982 mkU32(0xffffffff)));
983 assign(t13, binop(Iop_CmpNE32,
984 binop(Iop_And32,
985 unop(Iop_64to32,
986 mkexpr(t9)),
987 mkU32(0x80000000)),
988 mkU32(0x80000000)));
990 assign(t14, binop(Iop_And32,
991 binop(Iop_Or32,
992 unop(Iop_1Sto32, mkexpr(t10)),
993 unop(Iop_1Sto32, mkexpr(t11))),
994 binop(Iop_Or32,
995 unop(Iop_1Sto32, mkexpr(t12)),
996 unop(Iop_1Sto32, mkexpr(t13)))));
997 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
998 mkexpr(t14),
999 mkU32(0)),
1000 binop(Iop_Or32,
1001 getDSPControl(),
1002 mkU32(0x00800000)),
1003 getDSPControl()));
1004 break;
1007 case 0x2: { /* EXTP */
1008 DIP("extp r%u, ac%u, %u", rt, ac, rs);
1009 vassert(!mode64);
1010 t0 = newTemp(Ity_I64);
1011 t1 = newTemp(Ity_I32);
1012 t2 = newTemp(Ity_I1);
1013 t3 = newTemp(Ity_I1);
1014 t4 = newTemp(Ity_I8);
1015 t5 = newTemp(Ity_I64);
1016 t6 = newTemp(Ity_I64);
1017 t7 = newTemp(Ity_I32);
1019 assign(t0, getAcc(ac));
1020 /* Extract pos field of DSPControl register. */
1021 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
1023 /* Check if (pos - size) >= 0 [size <= pos]
1024 if (pos < size)
1025 put 1 to EFI field of DSPControl register
1026 else
1027 extract bits from acc and put 0 to EFI field of
1028 DSPCtrl */
1029 assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
1031 putDSPControl(IRExpr_ITE(mkexpr(t2),
1032 binop(Iop_Or32,
1033 binop(Iop_And32,
1034 getDSPControl(),
1035 mkU32(0xffffbfff)),
1036 mkU32(0x4000)),
1037 binop(Iop_And32,
1038 getDSPControl(),
1039 mkU32(0xffffbfff))));
1041 /* If pos <= 31, shift right the value from the acc
1042 (pos-size) times and take (size+1) bits from the least
1043 significant positions. Otherwise, shift left the value
1044 (63-pos) times, take (size+1) bits from the most
1045 significant positions and shift right (31-size) times.*/
1046 assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
1048 assign(t4,
1049 IRExpr_ITE(mkexpr(t3),
1050 unop(Iop_32to8,
1051 binop(Iop_Sub32,
1052 mkexpr(t1), mkU32(rs))),
1053 unop(Iop_32to8,
1054 binop(Iop_Sub32,
1055 mkU32(63), mkexpr(t1)))));
1057 assign(t5, IRExpr_ITE(mkexpr(t3),
1058 binop(Iop_Shr64,
1059 mkexpr(t0), mkexpr(t4)),
1060 binop(Iop_Shl64,
1061 mkexpr(t0), mkexpr(t4))));
1063 /* t6 holds a mask for bit extraction */
1064 assign(t6,
1065 IRExpr_ITE(mkexpr(t3),
1066 unop(Iop_Not64,
1067 binop(Iop_Shl64,
1068 mkU64(0xffffffffffffffffULL),
1069 mkU8(rs + 1))),
1070 unop(Iop_Not64,
1071 binop(Iop_Shr64,
1072 mkU64(0xffffffffffffffffULL),
1073 mkU8(rs + 1)))));
1075 assign(t7, IRExpr_ITE(mkexpr(t3),
1076 unop(Iop_64to32,
1077 binop(Iop_And64,
1078 mkexpr(t5),
1079 mkexpr(t6))),
1080 binop(Iop_Shr32,
1081 unop(Iop_64HIto32,
1082 binop(Iop_And64,
1083 mkexpr(t5),
1084 mkexpr(t6))),
1085 mkU8(31 - rs))));
1087 putIReg(rt, mkexpr(t7));
1088 break;
1091 case 0x3: { /* EXTPV */
1092 DIP("extpv r%u, ac%u, r%u", rt, ac, rs);
1093 vassert(!mode64);
1094 t0 = newTemp(Ity_I64);
1095 t1 = newTemp(Ity_I32);
1096 t2 = newTemp(Ity_I1);
1097 t3 = newTemp(Ity_I1);
1098 t4 = newTemp(Ity_I8);
1099 t5 = newTemp(Ity_I64);
1100 t6 = newTemp(Ity_I64);
1101 t7 = newTemp(Ity_I32);
1102 t8 = newTemp(Ity_I32);
1104 assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
1105 assign(t0, getAcc(ac));
1106 /* Extract pos field of DSPControl register. */
1107 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
1109 /* Check if (pos - size) >= 0 [size <= pos]
1110 if (pos < size)
1111 put 1 to EFI field of DSPControl register
1112 else
1113 extract bits from acc and put 0 to EFI field of
1114 DSPCtrl */
1115 assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
1117 putDSPControl(IRExpr_ITE(mkexpr(t2),
1118 binop(Iop_Or32,
1119 binop(Iop_And32,
1120 getDSPControl(),
1121 mkU32(0xffffbfff)),
1122 mkU32(0x4000)),
1123 binop(Iop_And32,
1124 getDSPControl(),
1125 mkU32(0xffffbfff))));
1127 /* If pos <= 31, shift right the value from the acc
1128 (pos-size) times and take (size+1) bits from the least
1129 significant positions. Otherwise, shift left the value
1130 (63-pos) times, take (size+1) bits from the most
1131 significant positions and shift right (31-size)
1132 times. */
1133 assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
1135 assign(t4,
1136 IRExpr_ITE(mkexpr(t3),
1137 unop(Iop_32to8,
1138 binop(Iop_Sub32,
1139 mkexpr(t1), mkexpr(t8))),
1140 unop(Iop_32to8,
1141 binop(Iop_Sub32,
1142 mkU32(63), mkexpr(t1)))));
1144 assign(t5, IRExpr_ITE(mkexpr(t3),
1145 binop(Iop_Shr64,
1146 mkexpr(t0), mkexpr(t4)),
1147 binop(Iop_Shl64,
1148 mkexpr(t0), mkexpr(t4))));
1150 /* t6 holds a mask for bit extraction. */
1151 assign(t6,
1152 IRExpr_ITE(mkexpr(t3),
1153 unop(Iop_Not64,
1154 binop(Iop_Shl64,
1155 mkU64(0xffffffffffffffffULL),
1156 unop(Iop_32to8,
1157 binop(Iop_Add32,
1158 mkexpr(t8),
1159 mkU32(1))))),
1160 unop(Iop_Not64,
1161 binop(Iop_Shr64,
1162 mkU64(0xffffffffffffffffULL),
1163 unop(Iop_32to8,
1164 binop(Iop_Add32,
1165 mkexpr(t8),
1166 mkU32(1)))))));
1168 assign(t7, IRExpr_ITE(mkexpr(t3),
1169 unop(Iop_64to32,
1170 binop(Iop_And64,
1171 mkexpr(t5),
1172 mkexpr(t6))),
1173 binop(Iop_Shr32,
1174 unop(Iop_64HIto32,
1175 binop(Iop_And64,
1176 mkexpr(t5),
1177 mkexpr(t6))),
1178 unop(Iop_32to8,
1179 binop(Iop_Sub32,
1180 mkU32(31),
1181 mkexpr(t8))))));
1183 putIReg(rt, mkexpr(t7));
1184 break;
1187 case 0x4: { /* EXTR_R.W */
1188 DIP("extr_r.w r%u, ac%u, %u", rt, ac, rs);
1189 vassert(!mode64);
1190 t0 = newTemp(Ity_I64);
1191 t1 = newTemp(Ity_I64);
1192 t2 = newTemp(Ity_I32);
1193 t3 = newTemp(Ity_I1);
1194 t4 = newTemp(Ity_I1);
1195 t5 = newTemp(Ity_I1);
1196 t6 = newTemp(Ity_I1);
1197 t7 = newTemp(Ity_I32);
1198 t8 = newTemp(Ity_I64);
1199 t9 = newTemp(Ity_I64);
1200 t10 = newTemp(Ity_I1);
1201 t11 = newTemp(Ity_I1);
1202 t12 = newTemp(Ity_I1);
1203 t13 = newTemp(Ity_I1);
1204 t14 = newTemp(Ity_I32);
1205 t15 = newTemp(Ity_I64);
1206 t16 = newTemp(Ity_I1);
1208 assign(t0, getAcc(ac));
1209 assign(t16, binop(Iop_CmpEQ32,
1210 mkU32(rs),
1211 mkU32(0)));
1212 assign(t1, IRExpr_ITE(mkexpr(t16),
1213 mkexpr(t0),
1214 binop(Iop_Sar64,
1215 mkexpr(t0),
1216 mkU8(rs))));
1217 /* If the last discarded bit is 1, there would be carry
1218 when rounding, otherwise there wouldn't. We use that
1219 fact and just add the value of the last discarded bit
1220 to the least significant bit of the shifted value
1221 from acc. */
1222 assign(t15, binop(Iop_Shr64,
1223 mkexpr(t0),
1224 unop(Iop_32to8,
1225 binop(Iop_Sub32,
1226 binop(Iop_And32,
1227 mkU32(rs),
1228 mkU32(0x1f)),
1229 mkU32(1)))));
1231 assign(t8,
1232 IRExpr_ITE(mkexpr(t16),
1233 mkU64(0x0ULL),
1234 binop(Iop_And64,
1235 mkexpr(t15),
1236 mkU64(0x0000000000000001ULL))));
1237 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
1238 putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
1240 /* Check if bits 63..31 of the result in t1 aren't 0. */
1241 assign(t3, binop(Iop_CmpNE32,
1242 unop(Iop_64HIto32,
1243 mkexpr(t1)),
1244 mkU32(0)));
1245 assign(t4, binop(Iop_CmpNE32,
1246 binop(Iop_And32,
1247 unop(Iop_64to32,
1248 mkexpr(t1)),
1249 mkU32(0x80000000)),
1250 mkU32(0)));
1252 /* Check if bits 63..31 of the result in t1 aren't
1253 0x1ffffffff. */
1254 assign(t5, binop(Iop_CmpNE32,
1255 unop(Iop_64HIto32,
1256 mkexpr(t1)),
1257 mkU32(0xffffffff)));
1258 assign(t6, binop(Iop_CmpNE32,
1259 binop(Iop_And32,
1260 unop(Iop_64to32,
1261 mkexpr(t1)),
1262 mkU32(0x80000000)),
1263 mkU32(0x80000000)));
1264 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
1265 control register. */
1266 assign(t7, binop(Iop_And32,
1267 binop(Iop_Or32,
1268 unop(Iop_1Sto32, mkexpr(t3)),
1269 unop(Iop_1Sto32, mkexpr(t4))),
1270 binop(Iop_Or32,
1271 unop(Iop_1Sto32, mkexpr(t5)),
1272 unop(Iop_1Sto32, mkexpr(t6)))));
1273 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
1274 mkexpr(t7),
1275 mkU32(0)),
1276 binop(Iop_Or32,
1277 getDSPControl(),
1278 mkU32(0x00800000)),
1279 getDSPControl()));
1281 /* Repeat previous steps for the rounded value. */
1282 assign(t10, binop(Iop_CmpNE32,
1283 unop(Iop_64HIto32,
1284 mkexpr(t9)),
1285 mkU32(0)));
1286 assign(t11, binop(Iop_CmpNE32,
1287 binop(Iop_And32,
1288 unop(Iop_64to32,
1289 mkexpr(t9)),
1290 mkU32(0x80000000)),
1291 mkU32(0)));
1293 assign(t12, binop(Iop_CmpNE32,
1294 unop(Iop_64HIto32,
1295 mkexpr(t9)),
1296 mkU32(0xffffffff)));
1297 assign(t13, binop(Iop_CmpNE32,
1298 binop(Iop_And32,
1299 unop(Iop_64to32,
1300 mkexpr(t9)),
1301 mkU32(0x80000000)),
1302 mkU32(0x80000000)));
1304 assign(t14, binop(Iop_And32,
1305 binop(Iop_Or32,
1306 unop(Iop_1Sto32, mkexpr(t10)),
1307 unop(Iop_1Sto32, mkexpr(t11))),
1308 binop(Iop_Or32,
1309 unop(Iop_1Sto32, mkexpr(t12)),
1310 unop(Iop_1Sto32, mkexpr(t13)))));
1311 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
1312 mkexpr(t14),
1313 mkU32(0)),
1314 binop(Iop_Or32,
1315 getDSPControl(),
1316 mkU32(0x00800000)),
1317 getDSPControl()));
1318 break;
1321 case 0x5: { /* EXTRV_R.W */
1322 DIP("extrv_r.w r%u, ac%u, r%u", rt, ac, rs);
1323 vassert(!mode64);
1324 t0 = newTemp(Ity_I64);
1325 t1 = newTemp(Ity_I64);
1326 t2 = newTemp(Ity_I32);
1327 t3 = newTemp(Ity_I1);
1328 t4 = newTemp(Ity_I1);
1329 t5 = newTemp(Ity_I1);
1330 t6 = newTemp(Ity_I1);
1331 t7 = newTemp(Ity_I32);
1332 t8 = newTemp(Ity_I64);
1333 t9 = newTemp(Ity_I64);
1334 t10 = newTemp(Ity_I1);
1335 t11 = newTemp(Ity_I1);
1336 t12 = newTemp(Ity_I1);
1337 t13 = newTemp(Ity_I1);
1338 t14 = newTemp(Ity_I32);
1339 t15 = newTemp(Ity_I8);
1341 assign(t15, unop(Iop_32to8,
1342 binop(Iop_And32,
1343 getIReg(rs),
1344 mkU32(0x1f))));
1345 assign(t0, getAcc(ac));
1346 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
1348 /* Check if bits 63..31 of the result in t1 aren't 0. */
1349 assign(t3, binop(Iop_CmpNE32,
1350 unop(Iop_64HIto32,
1351 mkexpr(t1)),
1352 mkU32(0)));
1353 assign(t4, binop(Iop_CmpNE32,
1354 binop(Iop_And32,
1355 unop(Iop_64to32,
1356 mkexpr(t1)),
1357 mkU32(0x80000000)),
1358 mkU32(0)));
1359 /* Check if bits 63..31 of the result in t1 aren't
1360 0x1ffffffff. */
1361 assign(t5, binop(Iop_CmpNE32,
1362 unop(Iop_64HIto32,
1363 mkexpr(t1)),
1364 mkU32(0xffffffff)));
1365 assign(t6, binop(Iop_CmpNE32,
1366 binop(Iop_And32,
1367 unop(Iop_64to32,
1368 mkexpr(t1)),
1369 mkU32(0x80000000)),
1370 mkU32(0x80000000)));
1371 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
1372 control register. */
1373 assign(t7, binop(Iop_And32,
1374 binop(Iop_Or32,
1375 unop(Iop_1Sto32, mkexpr(t3)),
1376 unop(Iop_1Sto32, mkexpr(t4))),
1377 binop(Iop_Or32,
1378 unop(Iop_1Sto32, mkexpr(t5)),
1379 unop(Iop_1Sto32, mkexpr(t6)))));
1380 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
1381 mkexpr(t7),
1382 mkU32(0)),
1383 binop(Iop_Or32,
1384 getDSPControl(),
1385 mkU32(0x00800000)),
1386 getDSPControl()));
1388 /* If the last discarded bit is 1, there would be carry
1389 when rounding, otherwise there wouldn't. We use that
1390 fact and just add the value of the last discarded bit
1391 to the least sifgnificant bit of the shifted value
1392 from acc. */
1393 assign(t8,
1394 IRExpr_ITE(binop(Iop_CmpEQ32,
1395 unop(Iop_8Uto32,
1396 mkexpr(t15)),
1397 mkU32(0)),
1398 mkU64(0x0ULL),
1399 binop(Iop_And64,
1400 binop(Iop_Shr64,
1401 mkexpr(t0),
1402 unop(Iop_32to8,
1403 binop(Iop_Sub32,
1404 unop(Iop_8Uto32,
1405 mkexpr(t15)),
1406 mkU32(1)))),
1407 mkU64(0x1ULL))));
1409 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
1410 /* Put rounded value in destination register. */
1411 putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
1413 /* Repeat previous steps for the rounded value. */
1414 assign(t10, binop(Iop_CmpNE32,
1415 unop(Iop_64HIto32,
1416 mkexpr(t9)),
1417 mkU32(0)));
1418 assign(t11, binop(Iop_CmpNE32,
1419 binop(Iop_And32,
1420 unop(Iop_64to32,
1421 mkexpr(t9)),
1422 mkU32(0x80000000)),
1423 mkU32(0)));
1425 assign(t12, binop(Iop_CmpNE32,
1426 unop(Iop_64HIto32,
1427 mkexpr(t9)),
1428 mkU32(0xffffffff)));
1429 assign(t13, binop(Iop_CmpNE32,
1430 binop(Iop_And32,
1431 unop(Iop_64to32,
1432 mkexpr(t9)),
1433 mkU32(0x80000000)),
1434 mkU32(0x80000000)));
1436 assign(t14, binop(Iop_And32,
1437 binop(Iop_Or32,
1438 unop(Iop_1Sto32, mkexpr(t10)),
1439 unop(Iop_1Sto32, mkexpr(t11))),
1440 binop(Iop_Or32,
1441 unop(Iop_1Sto32, mkexpr(t12)),
1442 unop(Iop_1Sto32, mkexpr(t13)))));
1443 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
1444 mkexpr(t14),
1445 mkU32(0)),
1446 binop(Iop_Or32,
1447 getDSPControl(),
1448 mkU32(0x00800000)),
1449 getDSPControl()));
1450 break;
1453 case 0x6: { /* EXTR_RS.W */
1454 DIP("extr_rs.w r%u, ac%u, %u", rt, ac, rs);
1455 vassert(!mode64);
1456 t0 = newTemp(Ity_I64);
1457 t1 = newTemp(Ity_I64);
1458 t2 = newTemp(Ity_I32);
1459 t3 = newTemp(Ity_I1);
1460 t4 = newTemp(Ity_I1);
1461 t5 = newTemp(Ity_I1);
1462 t6 = newTemp(Ity_I1);
1463 t7 = newTemp(Ity_I32);
1464 t8 = newTemp(Ity_I64);
1465 t9 = newTemp(Ity_I64);
1466 t10 = newTemp(Ity_I1);
1467 t11 = newTemp(Ity_I1);
1468 t12 = newTemp(Ity_I1);
1469 t13 = newTemp(Ity_I1);
1470 t14 = newTemp(Ity_I32);
1471 t16 = newTemp(Ity_I32);
1473 assign(t0, getAcc(ac));
1475 if (0 == rs) {
1476 assign(t1, mkexpr(t0));
1477 } else {
1478 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
1481 /* Check if bits 63..31 of the result in t1 aren't 0. */
1482 assign(t3, binop(Iop_CmpNE32,
1483 unop(Iop_64HIto32,
1484 mkexpr(t1)),
1485 mkU32(0)));
1486 assign(t4, binop(Iop_CmpNE32,
1487 binop(Iop_And32,
1488 unop(Iop_64to32,
1489 mkexpr(t1)),
1490 mkU32(0x80000000)),
1491 mkU32(0)));
1492 /* Check if bits 63..31 of the result in t1 aren't
1493 0x1ffffffff. */
1494 assign(t5, binop(Iop_CmpNE32,
1495 unop(Iop_64HIto32,
1496 mkexpr(t1)),
1497 mkU32(0xffffffff)));
1498 assign(t6, binop(Iop_CmpNE32,
1499 binop(Iop_And32,
1500 unop(Iop_64to32,
1501 mkexpr(t1)),
1502 mkU32(0x80000000)),
1503 mkU32(0x80000000)));
1504 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
1505 control register. */
1506 assign(t7, binop(Iop_And32,
1507 binop(Iop_Or32,
1508 unop(Iop_1Sto32, mkexpr(t3)),
1509 unop(Iop_1Sto32, mkexpr(t4))),
1510 binop(Iop_Or32,
1511 unop(Iop_1Sto32, mkexpr(t5)),
1512 unop(Iop_1Sto32, mkexpr(t6)))));
1513 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
1514 mkexpr(t7),
1515 mkU32(0)),
1516 binop(Iop_Or32,
1517 getDSPControl(),
1518 mkU32(0x00800000)),
1519 getDSPControl()));
1521 /* If the last discarded bit is 1, there would be carry
1522 when rounding, otherwise there wouldn't. We use that
1523 fact and just add the value of the last discarded bit
1524 to the least sifgnificant bit of the shifted value
1525 from acc. */
1526 if (0 == rs) {
1527 assign(t8, mkU64(0x0ULL));
1528 } else {
1529 assign(t8, binop(Iop_And64,
1530 binop(Iop_Shr64,
1531 mkexpr(t0),
1532 mkU8(rs - 1)),
1533 mkU64(0x1ULL)));
1536 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
1538 /* Repeat previous steps for the rounded value. */
1539 assign(t10, binop(Iop_CmpNE32,
1540 unop(Iop_64HIto32,
1541 mkexpr(t9)),
1542 mkU32(0)));
1543 assign(t11, binop(Iop_CmpNE32,
1544 binop(Iop_And32,
1545 unop(Iop_64to32,
1546 mkexpr(t9)),
1547 mkU32(0x80000000)),
1548 mkU32(0)));
1550 assign(t12, binop(Iop_CmpNE32,
1551 unop(Iop_64HIto32,
1552 mkexpr(t9)),
1553 mkU32(0xffffffff)));
1554 assign(t13, binop(Iop_CmpNE32,
1555 binop(Iop_And32,
1556 unop(Iop_64to32,
1557 mkexpr(t9)),
1558 mkU32(0x80000000)),
1559 mkU32(0x80000000)));
1561 assign(t14, binop(Iop_And32,
1562 binop(Iop_Or32,
1563 unop(Iop_1Sto32, mkexpr(t10)),
1564 unop(Iop_1Sto32, mkexpr(t11))),
1565 binop(Iop_Or32,
1566 unop(Iop_1Sto32, mkexpr(t12)),
1567 unop(Iop_1Sto32, mkexpr(t13)))));
1568 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
1569 mkexpr(t14),
1570 mkU32(0)),
1571 binop(Iop_Or32,
1572 getDSPControl(),
1573 mkU32(0x00800000)),
1574 getDSPControl()));
1576 assign(t16, binop(Iop_And32,
1577 unop(Iop_64HIto32,
1578 mkexpr(t9)),
1579 mkU32(0x80000000)));
1580 putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
1581 mkexpr(t14),
1582 mkU32(0)),
1583 IRExpr_ITE(binop(Iop_CmpEQ32,
1584 mkexpr(t16),
1585 mkU32(0)),
1586 mkU32(0x7fffffff),
1587 mkU32(0x80000000)),
1588 unop(Iop_64to32, mkexpr(t9))));
1589 break;
1592 case 0x7: { /* EXTRV_RS.W */
1593 DIP("extrv_rs.w r%u, ac%u, r%u", rt, ac, rs);
1594 vassert(!mode64);
1595 t0 = newTemp(Ity_I64);
1596 t1 = newTemp(Ity_I64);
1597 t2 = newTemp(Ity_I32);
1598 t3 = newTemp(Ity_I1);
1599 t4 = newTemp(Ity_I1);
1600 t5 = newTemp(Ity_I1);
1601 t6 = newTemp(Ity_I1);
1602 t7 = newTemp(Ity_I32);
1603 t8 = newTemp(Ity_I64);
1604 t9 = newTemp(Ity_I64);
1605 t10 = newTemp(Ity_I1);
1606 t11 = newTemp(Ity_I1);
1607 t12 = newTemp(Ity_I1);
1608 t13 = newTemp(Ity_I1);
1609 t14 = newTemp(Ity_I32);
1610 t15 = newTemp(Ity_I32);
1611 t16 = newTemp(Ity_I32);
1612 t17 = newTemp(Ity_I1);
1614 assign(t15, binop(Iop_And32,
1615 getIReg(rs),
1616 mkU32(0x1f)));
1617 assign(t17, binop(Iop_CmpEQ32,
1618 mkexpr(t15),
1619 mkU32(0)));
1620 assign(t0, getAcc(ac));
1621 assign(t1, IRExpr_ITE(mkexpr(t17),
1622 mkexpr(t0),
1623 binop(Iop_Sar64,
1624 mkexpr(t0),
1625 unop(Iop_32to8,
1626 mkexpr(t15)))));
1628 /* Check if bits 63..31 of the result in t1 aren't 0. */
1629 assign(t3, binop(Iop_CmpNE32,
1630 unop(Iop_64HIto32,
1631 mkexpr(t1)),
1632 mkU32(0)));
1633 assign(t4, binop(Iop_CmpNE32,
1634 binop(Iop_And32,
1635 unop(Iop_64to32,
1636 mkexpr(t1)),
1637 mkU32(0x80000000)),
1638 mkU32(0)));
1639 /* Check if bits 63..31 of the result in t1 aren't
1640 0x1ffffffff. */
1641 assign(t5, binop(Iop_CmpNE32,
1642 unop(Iop_64HIto32,
1643 mkexpr(t1)),
1644 mkU32(0xffffffff)));
1645 assign(t6, binop(Iop_CmpNE32,
1646 binop(Iop_And32,
1647 unop(Iop_64to32,
1648 mkexpr(t1)),
1649 mkU32(0x80000000)),
1650 mkU32(0x80000000)));
1651 /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
1652 control register. */
1653 assign(t7, binop(Iop_And32,
1654 binop(Iop_Or32,
1655 unop(Iop_1Sto32, mkexpr(t3)),
1656 unop(Iop_1Sto32, mkexpr(t4))),
1657 binop(Iop_Or32,
1658 unop(Iop_1Sto32, mkexpr(t5)),
1659 unop(Iop_1Sto32, mkexpr(t6)))));
1660 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
1661 mkexpr(t7),
1662 mkU32(0)),
1663 binop(Iop_Or32,
1664 getDSPControl(),
1665 mkU32(0x00800000)),
1666 getDSPControl()));
1668 /* If the last discarded bit is 1, there would be carry
1669 when rounding, otherwise there wouldn't. We use that
1670 fact and just add the value of the last discarded bit
1671 to the least sifgnificant bit of the shifted value
1672 from acc. */
1673 assign(t8,
1674 IRExpr_ITE(mkexpr(t17),
1675 mkU64(0x0ULL),
1676 binop(Iop_And64,
1677 binop(Iop_Shr64,
1678 mkexpr(t0),
1679 unop(Iop_32to8,
1680 binop(Iop_Sub32,
1681 mkexpr(t15),
1682 mkU32(1)))),
1683 mkU64(0x1ULL))));
1685 assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
1687 /* Repeat previous steps for the rounded value. */
1688 assign(t10, binop(Iop_CmpNE32,
1689 unop(Iop_64HIto32,
1690 mkexpr(t9)),
1691 mkU32(0)));
1692 assign(t11, binop(Iop_CmpNE32,
1693 binop(Iop_And32,
1694 unop(Iop_64to32,
1695 mkexpr(t9)),
1696 mkU32(0x80000000)),
1697 mkU32(0)));
1699 assign(t12, binop(Iop_CmpNE32,
1700 unop(Iop_64HIto32,
1701 mkexpr(t9)),
1702 mkU32(0xffffffff)));
1703 assign(t13, binop(Iop_CmpNE32,
1704 binop(Iop_And32,
1705 unop(Iop_64to32,
1706 mkexpr(t9)),
1707 mkU32(0x80000000)),
1708 mkU32(0x80000000)));
1710 assign(t14, binop(Iop_And32,
1711 binop(Iop_Or32,
1712 unop(Iop_1Sto32, mkexpr(t10)),
1713 unop(Iop_1Sto32, mkexpr(t11))),
1714 binop(Iop_Or32,
1715 unop(Iop_1Sto32, mkexpr(t12)),
1716 unop(Iop_1Sto32, mkexpr(t13)))));
1717 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
1718 mkexpr(t14),
1719 mkU32(0)),
1720 binop(Iop_Or32,
1721 getDSPControl(),
1722 mkU32(0x00800000)),
1723 getDSPControl()));
1725 assign(t16, binop(Iop_And32,
1726 unop(Iop_64HIto32,
1727 mkexpr(t9)),
1728 mkU32(0x80000000)));
1729 putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
1730 mkexpr(t14),
1731 mkU32(0)),
1732 IRExpr_ITE(binop(Iop_CmpEQ32,
1733 mkexpr(t16),
1734 mkU32(0)),
1735 mkU32(0x7fffffff),
1736 mkU32(0x80000000)),
1737 unop(Iop_64to32, mkexpr(t9))));
1738 break;
1741 case 0xA: { /* EXTPDP */
1742 DIP("extpdp r%u, ac%u, %u", rt, ac, rs);
1743 vassert(!mode64);
1744 t0 = newTemp(Ity_I64);
1745 t1 = newTemp(Ity_I32);
1746 t2 = newTemp(Ity_I1);
1747 t3 = newTemp(Ity_I1);
1748 t4 = newTemp(Ity_I8);
1749 t5 = newTemp(Ity_I64);
1750 t6 = newTemp(Ity_I64);
1751 t7 = newTemp(Ity_I32);
1752 t8 = newTemp(Ity_I32);
1754 assign(t0, getAcc(ac));
1755 /* Extract pos field of DSPControl register. */
1756 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
1758 /* Check if (pos - size) >= 0 [size <= pos]
1759 if (pos < size)
1760 put 1 to EFI field of DSPControl register
1761 else
1762 extract bits from acc and put 0 to EFI field of
1763 DSPCtrl */
1764 assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
1766 assign(t8, binop(Iop_Or32,
1767 binop(Iop_And32,
1768 getDSPControl(),
1769 mkU32(0xffffbfc0)),
1770 binop(Iop_And32,
1771 binop(Iop_Sub32,
1772 binop(Iop_And32,
1773 getDSPControl(),
1774 mkU32(0x3f)),
1775 mkU32(rs + 1)),
1776 mkU32(0x3f))));
1777 putDSPControl(IRExpr_ITE(mkexpr(t2),
1778 binop(Iop_Or32,
1779 binop(Iop_And32,
1780 getDSPControl(),
1781 mkU32(0xffffbfff)),
1782 mkU32(0x4000)),
1783 mkexpr(t8)));
1785 /* If pos <= 31, shift right the value from the acc
1786 (pos-size) times and take (size+1) bits from the least
1787 significant positions. Otherwise, shift left the value
1788 (63-pos) times, take (size+1) bits from the most
1789 significant positions and shift right (31-size) times.
1791 assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
1793 assign(t4,
1794 IRExpr_ITE(mkexpr(t3),
1795 unop(Iop_32to8,
1796 binop(Iop_Sub32,
1797 mkexpr(t1), mkU32(rs))),
1798 unop(Iop_32to8,
1799 binop(Iop_Sub32,
1800 mkU32(63), mkexpr(t1)))));
1802 assign(t5, IRExpr_ITE(mkexpr(t3),
1803 binop(Iop_Shr64,
1804 mkexpr(t0), mkexpr(t4)),
1805 binop(Iop_Shl64,
1806 mkexpr(t0), mkexpr(t4))));
1808 /* t6 holds a mask for bit extraction. */
1809 assign(t6,
1810 IRExpr_ITE(mkexpr(t3),
1811 unop(Iop_Not64,
1812 binop(Iop_Shl64,
1813 mkU64(0xffffffffffffffffULL),
1814 mkU8(rs + 1))),
1815 unop(Iop_Not64,
1816 binop(Iop_Shr64,
1817 mkU64(0xffffffffffffffffULL),
1818 mkU8(rs + 1)))));
1820 assign(t7, IRExpr_ITE(mkexpr(t3),
1821 unop(Iop_64to32,
1822 binop(Iop_And64,
1823 mkexpr(t5),
1824 mkexpr(t6))),
1825 binop(Iop_Shr32,
1826 unop(Iop_64HIto32,
1827 binop(Iop_And64,
1828 mkexpr(t5),
1829 mkexpr(t6))),
1830 mkU8(31 - rs))));
1832 putIReg(rt, mkexpr(t7));
1833 break;
1836 case 0xB: { /* EXTPDPV */
1837 DIP("extpdpv r%u, ac%u, r%u", rt, ac, rs);
1838 vassert(!mode64);
1839 t0 = newTemp(Ity_I64);
1840 t1 = newTemp(Ity_I32);
1841 t2 = newTemp(Ity_I1);
1842 t3 = newTemp(Ity_I1);
1843 t4 = newTemp(Ity_I8);
1844 t5 = newTemp(Ity_I64);
1845 t6 = newTemp(Ity_I64);
1846 t7 = newTemp(Ity_I32);
1847 t8 = newTemp(Ity_I32);
1848 t9 = newTemp(Ity_I32);
1850 assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
1851 assign(t0, getAcc(ac));
1852 /* Extract pos field of DSPControl register. */
1853 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
1855 /* Check if (pos - size) >= 0 [size <= pos]
1856 if (pos < size)
1857 put 1 to EFI field of DSPControl register
1858 else
1859 extract bits from acc and put 0 to EFI field of
1860 DSPCtrl */
1861 assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
1863 assign(t9, binop(Iop_Or32,
1864 binop(Iop_And32,
1865 getDSPControl(),
1866 mkU32(0xffffbfc0)),
1867 binop(Iop_And32,
1868 binop(Iop_Sub32,
1869 binop(Iop_And32,
1870 getDSPControl(),
1871 mkU32(0x3f)),
1872 binop(Iop_Add32,
1873 mkexpr(t8),
1874 mkU32(0x1))),
1875 mkU32(0x3f))));
1876 putDSPControl(IRExpr_ITE(mkexpr(t2),
1877 binop(Iop_Or32,
1878 binop(Iop_And32,
1879 getDSPControl(),
1880 mkU32(0xffffbfff)),
1881 mkU32(0x4000)),
1882 mkexpr(t9)));
1884 /* If pos <= 31, shift right the value from the acc
1885 (pos-size) times and take (size+1) bits from the least
1886 significant positions. Otherwise, shift left the value
1887 (63-pos) times, take (size+1) bits from the most
1888 significant positions and shift right (31-size) times.
1890 assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
1892 assign(t4,
1893 IRExpr_ITE(mkexpr(t3),
1894 unop(Iop_32to8,
1895 binop(Iop_Sub32,
1896 mkexpr(t1), mkexpr(t8))),
1897 unop(Iop_32to8,
1898 binop(Iop_Sub32,
1899 mkU32(63), mkexpr(t1)))));
1901 assign(t5, IRExpr_ITE(mkexpr(t3),
1902 binop(Iop_Shr64,
1903 mkexpr(t0), mkexpr(t4)),
1904 binop(Iop_Shl64,
1905 mkexpr(t0), mkexpr(t4))));
1907 /* t6 holds a mask for bit extraction. */
1908 assign(t6,
1909 IRExpr_ITE(mkexpr(t3),
1910 unop(Iop_Not64,
1911 binop(Iop_Shl64,
1912 mkU64(0xffffffffffffffffULL),
1913 unop(Iop_32to8,
1914 binop(Iop_Add32,
1915 mkexpr(t8),
1916 mkU32(1))))),
1917 unop(Iop_Not64,
1918 binop(Iop_Shr64,
1919 mkU64(0xffffffffffffffffULL),
1920 unop(Iop_32to8,
1921 binop(Iop_Add32,
1922 mkexpr(t8),
1923 mkU32(1)))))));
1925 assign(t7, IRExpr_ITE(mkexpr(t3),
1926 unop(Iop_64to32,
1927 binop(Iop_And64,
1928 mkexpr(t5),
1929 mkexpr(t6))),
1930 binop(Iop_Shr32,
1931 unop(Iop_64HIto32,
1932 binop(Iop_And64,
1933 mkexpr(t5),
1934 mkexpr(t6))),
1935 unop(Iop_32to8,
1936 binop(Iop_Sub32,
1937 mkU32(31),
1938 mkexpr(t8))))));
1940 putIReg(rt, mkexpr(t7));
1941 break;
1944 case 0xE: { /* EXTR_S.H */
1945 DIP("extr_s.h r%u, ac%u, %u", rt, ac, rs);
1946 vassert(!mode64);
1947 t0 = newTemp(Ity_I64);
1948 t1 = newTemp(Ity_I64);
1949 t2 = newTemp(Ity_I32);
1950 t3 = newTemp(Ity_I64);
1951 t4 = newTemp(Ity_I32);
1952 t5 = newTemp(Ity_I32);
1953 t6 = newTemp(Ity_I64);
1954 t7 = newTemp(Ity_I32);
1956 assign(t0, getAcc(ac));
1958 assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
1960 assign(t2, binop(Iop_Or32,
1961 getDSPControl(), mkU32(0x00800000)));
1963 assign(t5, binop(Iop_And32,
1964 unop(Iop_64to32,
1965 mkexpr(t1)),
1966 mkU32(0x80000000)));
1967 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
1968 mkexpr(t5),
1969 binop(Iop_And32,
1970 unop(Iop_64HIto32,
1971 mkexpr(t0)),
1972 mkU32(0x80000000))),
1973 mkexpr(t2),
1974 getDSPControl()));
1976 /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
1977 1. subtract 0x7fff from t1
1978 2. if the resulting number is positive (sign bit = 0)
1979 and any of the other bits is 1, the value is > 0. */
1980 assign(t3, binop(Iop_Sub64,
1981 mkexpr(t1),
1982 mkU64(0x0000000000007fffULL)));
1983 assign(t4, binop(Iop_And32,
1984 binop(Iop_Or32,
1985 unop(Iop_1Sto32,
1986 binop(Iop_CmpNE32,
1987 mkU32(0),
1988 binop(Iop_And32,
1989 unop(Iop_64HIto32,
1990 mkexpr(t3)),
1991 mkU32(0x7fffffff)))),
1992 unop(Iop_1Sto32,
1993 binop(Iop_CmpNE32,
1994 mkU32(0),
1995 unop(Iop_64to32,
1996 mkexpr(t3))))),
1997 unop(Iop_1Sto32,
1998 binop(Iop_CmpEQ32,
1999 binop(Iop_And32,
2000 unop(Iop_64HIto32,
2001 mkexpr(t3)),
2002 mkU32(0x80000000)),
2003 mkU32(0)))));
2004 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
2005 mkU32(0),
2006 mkexpr(t4)),
2007 binop(Iop_Or32,
2008 getDSPControl(),
2009 mkU32(0x00800000)),
2010 getDSPControl()));
2011 /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
2012 1. subtract t1 from 0xffffffffffff8000
2013 2. if the resulting number is positive (sign bit = 0)
2014 and any of the other bits is 1, the value is > 0 */
2015 assign(t6, binop(Iop_Sub64,
2016 mkU64(0xffffffffffff8000ULL),
2017 mkexpr(t1)));
2018 assign(t7, binop(Iop_And32,
2019 binop(Iop_Or32,
2020 unop(Iop_1Sto32,
2021 binop(Iop_CmpNE32,
2022 mkU32(0),
2023 binop(Iop_And32,
2024 unop(Iop_64HIto32,
2025 mkexpr(t6)),
2026 mkU32(0x7fffffff)))),
2027 unop(Iop_1Sto32,
2028 binop(Iop_CmpNE32,
2029 mkU32(0),
2030 unop(Iop_64to32,
2031 mkexpr(t6))))),
2032 unop(Iop_1Sto32,
2033 binop(Iop_CmpEQ32,
2034 binop(Iop_And32,
2035 unop(Iop_64HIto32,
2036 mkexpr(t6)),
2037 mkU32(0x80000000)),
2038 mkU32(0)))));
2039 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
2040 mkU32(0),
2041 mkexpr(t7)),
2042 binop(Iop_Or32,
2043 getDSPControl(),
2044 mkU32(0x00800000)),
2045 getDSPControl()));
2046 putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
2047 mkU32(0),
2048 mkexpr(t4)),
2049 mkU32(0x00007fff),
2050 IRExpr_ITE(binop(Iop_CmpNE32,
2051 mkU32(0),
2052 mkexpr(t7)),
2053 mkU32(0xffff8000),
2054 unop(Iop_64to32,
2055 mkexpr(t1)))));
2056 break;
2059 case 0xF: { /* EXTRV_S.H */
2060 DIP("extrv_s.h r%u, ac%u, %u", rt, ac, rs);
2061 vassert(!mode64);
2062 t0 = newTemp(Ity_I64);
2063 t1 = newTemp(Ity_I64);
2064 t2 = newTemp(Ity_I32);
2065 t3 = newTemp(Ity_I64);
2066 t4 = newTemp(Ity_I32);
2067 t5 = newTemp(Ity_I32);
2068 t6 = newTemp(Ity_I64);
2069 t7 = newTemp(Ity_I32);
2071 assign(t0, getAcc(ac));
2073 assign(t1, binop(Iop_Sar64,
2074 mkexpr(t0),
2075 unop(Iop_32to8,
2076 binop(Iop_And32,
2077 getIReg(rs),
2078 mkU32(0x1f)))));
2080 assign(t2, binop(Iop_Or32,
2081 getDSPControl(), mkU32(0x00800000)));
2083 assign(t5, binop(Iop_And32,
2084 unop(Iop_64to32,
2085 mkexpr(t1)),
2086 mkU32(0x80000000)));
2087 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
2088 mkexpr(t5),
2089 binop(Iop_And32,
2090 unop(Iop_64HIto32,
2091 mkexpr(t0)),
2092 mkU32(0x80000000))),
2093 mkexpr(t2),
2094 getDSPControl()));
2096 /* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
2097 1. subtract 0x7fff from t1
2098 2. if the resulting number is positive (sign bit = 0)
2099 and any of the other bits is 1, the value is > 0. */
2100 assign(t3, binop(Iop_Sub64,
2101 mkexpr(t1),
2102 mkU64(0x0000000000007fffULL)));
2103 assign(t4, binop(Iop_And32,
2104 binop(Iop_Or32,
2105 unop(Iop_1Sto32,
2106 binop(Iop_CmpNE32,
2107 mkU32(0),
2108 binop(Iop_And32,
2109 unop(Iop_64HIto32,
2110 mkexpr(t3)),
2111 mkU32(0x7fffffff)))),
2112 unop(Iop_1Sto32,
2113 binop(Iop_CmpNE32,
2114 mkU32(0),
2115 unop(Iop_64to32,
2116 mkexpr(t3))))),
2117 unop(Iop_1Sto32,
2118 binop(Iop_CmpEQ32,
2119 binop(Iop_And32,
2120 unop(Iop_64HIto32,
2121 mkexpr(t3)),
2122 mkU32(0x80000000)),
2123 mkU32(0)))));
2124 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
2125 mkU32(0),
2126 mkexpr(t4)),
2127 binop(Iop_Or32,
2128 getDSPControl(),
2129 mkU32(0x00800000)),
2130 getDSPControl()));
2131 /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
2132 1. subtract t1 from 0xffffffffffff8000
2133 2. if the resulting number is positive (sign bit = 0)
2134 and any of the other bits is 1, the value is > 0 */
2135 assign(t6, binop(Iop_Sub64,
2136 mkU64(0xffffffffffff8000ULL),
2137 mkexpr(t1)));
2138 assign(t7, binop(Iop_And32,
2139 binop(Iop_Or32,
2140 unop(Iop_1Sto32,
2141 binop(Iop_CmpNE32,
2142 mkU32(0),
2143 binop(Iop_And32,
2144 unop(Iop_64HIto32,
2145 mkexpr(t6)),
2146 mkU32(0x7fffffff)))),
2147 unop(Iop_1Sto32,
2148 binop(Iop_CmpNE32,
2149 mkU32(0),
2150 unop(Iop_64to32,
2151 mkexpr(t6))))),
2152 unop(Iop_1Sto32,
2153 binop(Iop_CmpEQ32,
2154 binop(Iop_And32,
2155 unop(Iop_64HIto32,
2156 mkexpr(t6)),
2157 mkU32(0x80000000)),
2158 mkU32(0)))));
2159 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
2160 mkU32(0),
2161 mkexpr(t7)),
2162 binop(Iop_Or32,
2163 getDSPControl(),
2164 mkU32(0x00800000)),
2165 getDSPControl()));
2166 putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
2167 mkU32(0),
2168 mkexpr(t4)),
2169 mkU32(0x00007fff),
2170 IRExpr_ITE(binop(Iop_CmpNE32,
2171 mkU32(0),
2172 mkexpr(t7)),
2173 mkU32(0xffff8000),
2174 unop(Iop_64to32,
2175 mkexpr(t1)))));
2176 break;
2179 case 0x12: { /* RDDSP*/
2180 DIP("rddsp r%u, mask 0x%x", rd, rddsp_mask);
2181 vassert(!mode64);
2183 putIReg(rd, mkU32(0x0));
2185 if ((rddsp_mask & 0x1) == 0x1) {
2186 /* Read pos field (bits 5-0) of DSPControl register. */
2187 putIReg(rd, binop(Iop_Or32,
2188 getIReg(rd),
2189 binop(Iop_And32,
2190 getDSPControl(),
2191 mkU32(0x0000003F))));
2194 if ((rddsp_mask & 0x2) == 0x2) {
2195 /* Read scount field (bits 12-7) of DSPControl
2196 register. */
2197 putIReg(rd, binop(Iop_Or32,
2198 getIReg(rd),
2199 binop(Iop_And32,
2200 getDSPControl(),
2201 mkU32(0x00001F80))));
2204 if ((rddsp_mask & 0x4) == 0x4) {
2205 /* Read C field (bit 13) of DSPControl register. */
2206 putIReg(rd, binop(Iop_Or32,
2207 getIReg(rd),
2208 binop(Iop_And32,
2209 getDSPControl(),
2210 mkU32(0x00002000))));
2213 if ((rddsp_mask & 0x8) == 0x8) {
2214 /* Read outflag field (bit s 23-16) of DSPControl
2215 register. */
2216 putIReg(rd, binop(Iop_Or32,
2217 getIReg(rd),
2218 binop(Iop_And32,
2219 getDSPControl(),
2220 mkU32(0x00FF0000))));
2223 if ((rddsp_mask & 0x10) == 0x10) {
2224 /* Read ccond field (bits 31-24) of DSPControl
2225 register. */
2226 putIReg(rd, binop(Iop_Or32,
2227 getIReg(rd),
2228 binop(Iop_And32,
2229 getDSPControl(),
2230 mkU32(0xFF000000))));
2233 if ((rddsp_mask & 0x20) == 0x20) {
2234 /* Read EFI field (bit 14) of DSPControl register. */
2235 putIReg(rd, binop(Iop_Or32,
2236 getIReg(rd),
2237 binop(Iop_And32,
2238 getDSPControl(),
2239 mkU32(0x00004000))));
2242 if ((rddsp_mask & 0x3f) == 0x3f) {
2243 /* Read all fields of DSPControl register. */
2244 putIReg(rd, getDSPControl());
2247 break;
2250 case 0x13: { /* WRDSP */
2251 DIP("wrdsp r%u, mask 0x%x", rs, wrdsp_mask);
2252 vassert(!mode64);
2254 if ((wrdsp_mask & 0x3f) == 0x3f) {
2255 /* If mips64 put all fields of rs, except bit 15 and bit
2256 6, to DSPControl register, otherwise put all except
2257 bits 15, 6 and bits 31..28. */
2258 putDSPControl(mode64 ?
2259 binop(Iop_And32,
2260 getIReg(rs),
2261 mkU32(0xffff7fbf)) :
2262 binop(Iop_And32,
2263 getIReg(rs),
2264 mkU32(0x0fff7fbf)));
2265 } else {
2266 if ((wrdsp_mask & 0x1) == 0x1) {
2267 /* Put bits 5-0 of rs to DSPControl register pos
2268 field. */
2269 putDSPControl(binop(Iop_Or32,
2270 binop(Iop_And32,
2271 getDSPControl(),
2272 mkU32(0xFFFF7F40)),
2273 binop(Iop_And32,
2274 getIReg(rs),
2275 mkU32(0x0000003F))));
2278 if ((wrdsp_mask & 0x2) == 0x2) {
2279 /* Put bits 12-7 of rs to DSPControl scount field. */
2280 putDSPControl(binop(Iop_Or32,
2281 binop(Iop_And32,
2282 getDSPControl(),
2283 mkU32(0xFFFFE03F)),
2284 binop(Iop_And32,
2285 getIReg(rs),
2286 mkU32(0x00001F80))));
2289 if ((wrdsp_mask & 0x4) == 0x4) {
2290 /* Put bit 13 of rs to DSPControl register C
2291 field. */
2292 putDSPControl(binop(Iop_Or32,
2293 binop(Iop_And32,
2294 getDSPControl(),
2295 mkU32(0xFFFF5FBF)),
2296 binop(Iop_And32,
2297 getIReg(rs),
2298 mkU32(0x00002000))));
2301 if ((wrdsp_mask & 0x8) == 0x8) {
2302 /* Put bits 23-16 of rs to DSPControl reg outflag
2303 field. */
2304 putDSPControl(binop(Iop_Or32,
2305 binop(Iop_And32,
2306 getDSPControl(),
2307 mkU32(0xFF007FBF)),
2308 binop(Iop_And32,
2309 getIReg(rs),
2310 mkU32(0x00FF0000))));
2313 if ((wrdsp_mask & 0x10) == 0x10) {
2314 /* Put bits 31-24 of rs to DSPControl reg ccond
2315 field. */
2316 putDSPControl(binop(Iop_Or32,
2317 binop(Iop_And32,
2318 getDSPControl(),
2319 mkU32(0x00FF7FBF)),
2320 binop(Iop_And32,
2321 getIReg(rs),
2322 mode64 ? mkU32(0xFF000000)
2323 : mkU32(0x0F000000))
2328 if ((wrdsp_mask & 0x20) == 0x20) {
2329 /* Put bit 14 of rs to DSPControl register EFI
2330 field. */
2331 putDSPControl(binop(Iop_Or32,
2332 binop(Iop_And32,
2333 getDSPControl(),
2334 mkU32(0xFFFF3FBF)),
2335 binop(Iop_And32,
2336 getIReg(rs),
2337 mkU32(0x00004000))));
2341 break;
2344 case 0x1A: { /* SHILO */
2345 DIP("shilo ac%u, %u", ac, shift);
2346 vassert(!mode64);
2347 t0 = newTemp(Ity_I64);
2348 t1 = newTemp(Ity_I64);
2350 assign(t0, getAcc(ac));
2352 putAcc(ac, mkexpr(t0));
2354 if (0x20 == (shift & 0x3f)) {
2355 putAcc(ac, binop(Iop_32HLto64,
2356 unop(Iop_64to32, mkexpr(t0)),
2357 mkU32(0x0)));
2358 } else if (0x20 == (shift & 0x20)) {
2359 assign(t1, binop(Iop_Shl64,
2360 mkexpr(t0),
2361 unop(Iop_32to8,
2362 binop(Iop_Add32,
2363 unop(Iop_Not32,
2364 mkU32(shift)),
2365 mkU32(0x1)))));
2367 putAcc(ac, mkexpr(t1));
2368 } else {
2369 assign(t1, binop(Iop_Shr64, mkexpr(t0), mkU8(shift)));
2371 putAcc(ac, mkexpr(t1));
2374 break;
2377 case 0x1B: { /* SHILOV */
2378 DIP("shilov ac%u, r%u", ac, rs);
2379 vassert(!mode64);
2380 t0 = newTemp(Ity_I64);
2381 t1 = newTemp(Ity_I32);
2382 t2 = newTemp(Ity_I1);
2383 t3 = newTemp(Ity_I64);
2384 t4 = newTemp(Ity_I64);
2386 assign(t0, getAcc(ac));
2387 assign(t1, binop(Iop_And32, getIReg(rs), mkU32(0x3f)));
2388 assign(t2, binop(Iop_CmpEQ32, mkexpr(t1), mkU32(0x20)));
2389 assign(t3, binop(Iop_Shl64,
2390 mkexpr(t0),
2391 unop(Iop_32to8,
2392 binop(Iop_Add32,
2393 unop(Iop_Not32,
2394 mkexpr(t1)),
2395 mkU32(0x1)))));
2396 assign(t4, binop(Iop_Shr64,
2397 mkexpr(t0),
2398 unop(Iop_32to8,
2399 mkexpr(t1))));
2401 putAcc(ac,
2402 IRExpr_ITE(mkexpr(t2),
2403 binop(Iop_32HLto64,
2404 unop(Iop_64to32, mkexpr(t0)),
2405 mkU32(0x0)),
2406 IRExpr_ITE(binop(Iop_CmpEQ32,
2407 binop(Iop_And32,
2408 mkexpr(t1),
2409 mkU32(0x20)),
2410 mkU32(0x20)),
2411 mkexpr(t3),
2412 mkexpr(t4))));
2413 break;
2416 case 0x1F: { /* MTHLIP */
2417 DIP("mthlip r%u, ac%u", rs, ac);
2418 vassert(!mode64);
2419 t0 = newTemp(Ity_I64);
2420 t1 = newTemp(Ity_I32);
2422 assign(t0, getAcc(ac));
2423 putAcc(ac, binop(Iop_32HLto64,
2424 unop(Iop_64to32, mkexpr(t0)),
2425 getIReg(rs)));
2426 assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
2427 putDSPControl(IRExpr_ITE(binop(Iop_CmpLE32U,
2428 mkU32(32),
2429 mkexpr(t1)),
2430 binop(Iop_Or32,
2431 binop(Iop_Sub32,
2432 mkexpr(t1),
2433 mkU32(32)),
2434 binop(Iop_And32,
2435 getDSPControl(),
2436 mkU32(0xffffffc0))),
2437 binop(Iop_Or32,
2438 binop(Iop_Add32,
2439 mkexpr(t1),
2440 mkU32(32)),
2441 binop(Iop_And32,
2442 getDSPControl(),
2443 mkU32(0xffffffc0)))));
2444 break;
2447 default:
2448 return -1;
2451 return 0;
2454 static UInt disDSPInstr_MIPS_WRK_Special3_LX( UInt cins )
2456 IRTemp t0;
2457 UInt rs, rt, rd, sa;
2459 rs = get_rs(cins);
2460 rt = get_rt(cins);
2461 rd = get_rd(cins);
2462 sa = get_sa(cins);
2464 switch (sa) {
2465 case 0x0: { /* LWX */
2466 DIP("lwx r%u, r%u(r%u)", rd, rt, rs);
2467 vassert(!mode64);
2468 t0 = newTemp(Ity_I32);
2470 assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
2472 putIReg(rd, load(Ity_I32, mkexpr(t0)));
2473 break;
2476 case 0x4: { /* LHX */
2477 DIP("lhx r%u, r%u(r%u)", rd, rt, rs);
2478 vassert(!mode64);
2479 t0 = newTemp(Ity_I32);
2481 assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
2483 putIReg(rd, unop(Iop_16Sto32, load(Ity_I16, mkexpr(t0))));
2484 break;
2487 case 0x6: { /* LBUX */
2488 DIP("lbux r%u, r%u(r%u)", rd, rt, rs);
2489 vassert(!mode64);
2490 t0 = newTemp(Ity_I32);
2492 assign(t0, binop(Iop_Add32, getIReg(rt), getIReg(rs)));
2494 putIReg(rd, unop(Iop_8Uto32, load(Ity_I8, mkexpr(t0))));
2495 break;
2498 default:
2499 return -1;
2502 return 0;
2505 static UInt disDSPInstr_MIPS_WRK_Special3_INSV( UInt cins )
2507 IRTemp t0, t1 = 0, t2, t3, t6, t7, t8;
2508 UInt rs, rt, sa;
2510 rs = get_rs(cins);
2511 rt = get_rt(cins);
2512 sa = get_sa(cins);
2514 switch (sa) {
2515 case 0x0: { /* INSV */
2516 DIP("insv r%u, r%u", rt, rs);
2517 vassert(!mode64);
2519 t0 = newTemp(Ity_I32);
2520 t1 = newTemp(Ity_I32);
2521 t2 = newTemp(Ity_I8);
2522 t3 = newTemp(Ity_I8);
2523 t6 = newTemp(Ity_I32);
2524 t7 = newTemp(Ity_I32);
2525 t8 = newTemp(Ity_I32);
2527 /* t0 <- pos field of DSPControl register. */
2528 assign(t0, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
2529 /* t1 <- scount field of DSPControl register. */
2530 assign(t1, binop(Iop_Shr32,
2531 binop(Iop_And32,
2532 getDSPControl(),
2533 mkU32(0x1f80)),
2534 mkU8(7)));
2536 assign(t2, unop(Iop_32to8,
2537 binop(Iop_Add32,
2538 mkexpr(t1),
2539 mkexpr(t0))));
2541 /* 32-(pos+size) most significant bits of rt. */
2542 assign(t6, binop(Iop_Shl32,
2543 binop(Iop_Shr32,
2544 getIReg(rt),
2545 mkexpr(t2)),
2546 mkexpr(t2)));
2548 assign(t3, unop(Iop_32to8,
2549 binop(Iop_Sub32,
2550 mkU32(32),
2551 mkexpr(t0))));
2552 /* Pos least significant bits of rt. */
2553 assign(t7, binop(Iop_Shr32,
2554 binop(Iop_Shl32,
2555 getIReg(rt),
2556 mkexpr(t3)),
2557 mkexpr(t3)));
2559 /* Size least significant bits of rs,
2560 shifted to appropriate position. */
2561 assign(t8, binop(Iop_Shl32,
2562 binop(Iop_And32,
2563 getIReg(rs),
2564 unop(Iop_Not32,
2565 binop(Iop_Shl32,
2566 mkU32(0xffffffff),
2567 unop(Iop_32to8,
2568 mkexpr(t1))))),
2569 unop(Iop_32to8,
2570 mkexpr(t0))));
2572 putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
2573 mkexpr(t0),
2574 mkU32(0)),
2575 IRExpr_ITE(binop(Iop_CmpEQ32,
2576 mkexpr(t1),
2577 mkU32(32)),
2578 getIReg(rs),
2579 binop(Iop_Or32,
2580 mkexpr(t6),
2581 mkexpr(t8))),
2582 IRExpr_ITE(binop(Iop_CmpEQ32,
2583 unop(Iop_8Uto32,
2584 mkexpr(t2)),
2585 mkU32(32)),
2586 binop(Iop_Or32,
2587 mkexpr(t7),
2588 mkexpr(t8)),
2589 binop(Iop_Or32,
2590 binop(Iop_Or32,
2591 mkexpr(t6),
2592 mkexpr(t7)),
2593 mkexpr(t8)))));
2594 break;
2597 default:
2598 return -1;
2601 return 0;
2604 static UInt disDSPInstr_MIPS_WRK_Special3_ADDU_QB( UInt cins )
2606 IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12;
2607 UInt rs, rt, rd, sa;
2609 rs = get_rs(cins);
2610 rt = get_rt(cins);
2611 rd = get_rd(cins);
2612 sa = get_sa(cins);
2614 switch (sa) {
2615 case 0x00: { /* ADDU.QB */
2616 DIP("addu.qb r%u, r%u, r%u", rd, rs, rt);
2617 vassert(!mode64);
2618 t0 = newTemp(Ity_I32);
2619 t1 = newTemp(Ity_I1);
2620 t2 = newTemp(Ity_I32);
2621 t3 = newTemp(Ity_I1);
2622 t4 = newTemp(Ity_I32);
2623 t5 = newTemp(Ity_I1);
2624 t6 = newTemp(Ity_I32);
2625 t7 = newTemp(Ity_I1);
2626 t8 = newTemp(Ity_I32);
2628 /* Add rightmost bytes of rs and rt. */
2629 assign(t0,
2630 binop(Iop_Add32,
2631 unop(Iop_8Uto32,
2632 unop(Iop_16to8,
2633 unop(Iop_32to16, getIReg(rs)))),
2634 unop(Iop_8Uto32,
2635 unop(Iop_16to8,
2636 unop(Iop_32to16, getIReg(rt))))));
2637 /* t1 will be 1 if there is overflow, 0 otherwise. */
2638 assign(t1, binop(Iop_CmpEQ32,
2639 binop(Iop_And32,
2640 mkexpr(t0),
2641 mkU32(0x00000100)),
2642 mkU32(0x00000100)));
2644 /* Add bits 15-8 of rs and rt. */
2645 assign(t2,
2646 binop(Iop_Add32,
2647 unop(Iop_8Uto32,
2648 unop(Iop_16HIto8,
2649 unop(Iop_32to16, getIReg(rs)))),
2650 unop(Iop_8Uto32,
2651 unop(Iop_16HIto8,
2652 unop(Iop_32to16, getIReg(rt))))));
2653 /* t3 will be 1 if there is overflow, 0 otherwise. */
2654 assign(t3, binop(Iop_CmpEQ32,
2655 binop(Iop_And32,
2656 mkexpr(t2),
2657 mkU32(0x00000100)),
2658 mkU32(0x00000100)));
2660 /* Add bits 15-8 of rs and rt. */
2661 assign(t4,
2662 binop(Iop_Add32,
2663 unop(Iop_8Uto32,
2664 unop(Iop_16to8,
2665 unop(Iop_32HIto16, getIReg(rs)))),
2666 unop(Iop_8Uto32,
2667 unop(Iop_16to8,
2668 unop(Iop_32HIto16, getIReg(rt))))));
2669 /* t5 will be 1 if there is overflow, 0 otherwise. */
2670 assign(t5, binop(Iop_CmpEQ32,
2671 binop(Iop_And32,
2672 mkexpr(t4),
2673 mkU32(0x00000100)),
2674 mkU32(0x00000100)));
2676 /* Add bits 15-8 of rs and rt. */
2677 assign(t6,
2678 binop(Iop_Add32,
2679 unop(Iop_8Uto32,
2680 unop(Iop_16HIto8,
2681 unop(Iop_32HIto16, getIReg(rs)))),
2682 unop(Iop_8Uto32,
2683 unop(Iop_16HIto8,
2684 unop(Iop_32HIto16, getIReg(rt))))));
2685 /* t7 will be 1 if there is overflow, 0 otherwise. */
2686 assign(t7, binop(Iop_CmpEQ32,
2687 binop(Iop_And32,
2688 mkexpr(t6),
2689 mkU32(0x00000100)),
2690 mkU32(0x00000100)));
2692 assign(t8,
2693 binop(Iop_Or32,
2694 binop(Iop_Or32,
2695 binop(Iop_Or32,
2696 unop(Iop_1Sto32, mkexpr(t7)),
2697 unop(Iop_1Sto32, mkexpr(t5))),
2698 unop(Iop_1Sto32, mkexpr(t3))),
2699 unop(Iop_1Sto32, mkexpr(t1))));
2701 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
2702 mkexpr(t8),
2703 mkU32(0x0)),
2704 getDSPControl(),
2705 binop(Iop_Or32,
2706 getDSPControl(),
2707 mkU32(0x00100000))));
2709 putIReg(rd, binop(Iop_16HLto32,
2710 binop(Iop_8HLto16,
2711 unop(Iop_32to8, mkexpr(t6)),
2712 unop(Iop_32to8, mkexpr(t4))),
2713 binop(Iop_8HLto16,
2714 unop(Iop_32to8, mkexpr(t2)),
2715 unop(Iop_32to8, mkexpr(t0)))));
2716 break;
2719 case 0x1: { /* SUBU.QB */
2720 DIP("subu.qb r%u, r%u, r%u", rd, rs, rt);
2721 vassert(!mode64);
2722 t0 = newTemp(Ity_I32);
2723 t1 = newTemp(Ity_I1);
2724 t2 = newTemp(Ity_I32);
2725 t3 = newTemp(Ity_I1);
2726 t4 = newTemp(Ity_I32);
2727 t5 = newTemp(Ity_I1);
2728 t6 = newTemp(Ity_I32);
2729 t7 = newTemp(Ity_I1);
2730 t8 = newTemp(Ity_I32);
2732 /* Subtract rightmost bytes of rs and rt. */
2733 assign(t0,
2734 binop(Iop_Sub32,
2735 unop(Iop_8Uto32,
2736 unop(Iop_16to8,
2737 unop(Iop_32to16, getIReg(rs)))),
2738 unop(Iop_8Uto32,
2739 unop(Iop_16to8,
2740 unop(Iop_32to16, getIReg(rt))))));
2741 /* t1 will be 1 if there is overflow, 0 otherwise. */
2742 assign(t1, binop(Iop_CmpEQ32,
2743 binop(Iop_And32,
2744 mkexpr(t0),
2745 mkU32(0x00000100)),
2746 mkU32(0x00000100)));
2748 /* Subtract bits 15-8 of rs and rt. */
2749 assign(t2,
2750 binop(Iop_Sub32,
2751 unop(Iop_8Uto32,
2752 unop(Iop_16HIto8,
2753 unop(Iop_32to16, getIReg(rs)))),
2754 unop(Iop_8Uto32,
2755 unop(Iop_16HIto8,
2756 unop(Iop_32to16, getIReg(rt))))));
2757 /* t3 will be 1 if there is overflow, 0 otherwise. */
2758 assign(t3, binop(Iop_CmpEQ32,
2759 binop(Iop_And32,
2760 mkexpr(t2),
2761 mkU32(0x00000100)),
2762 mkU32(0x00000100)));
2764 /* Subtract bits 15-8 of rs and rt. */
2765 assign(t4,
2766 binop(Iop_Sub32,
2767 unop(Iop_8Uto32,
2768 unop(Iop_16to8,
2769 unop(Iop_32HIto16, getIReg(rs)))),
2770 unop(Iop_8Uto32,
2771 unop(Iop_16to8,
2772 unop(Iop_32HIto16, getIReg(rt))))));
2773 /* t5 will be 1 if there is overflow, 0 otherwise. */
2774 assign(t5, binop(Iop_CmpEQ32,
2775 binop(Iop_And32,
2776 mkexpr(t4),
2777 mkU32(0x00000100)),
2778 mkU32(0x00000100)));
2780 /* Subtract bits 15-8 of rs and rt. */
2781 assign(t6,
2782 binop(Iop_Sub32,
2783 unop(Iop_8Uto32,
2784 unop(Iop_16HIto8,
2785 unop(Iop_32HIto16, getIReg(rs)))),
2786 unop(Iop_8Uto32,
2787 unop(Iop_16HIto8,
2788 unop(Iop_32HIto16, getIReg(rt))))));
2789 /* t7 will be 1 if there is overflow, 0 otherwise. */
2790 assign(t7, binop(Iop_CmpEQ32,
2791 binop(Iop_And32,
2792 mkexpr(t6),
2793 mkU32(0x00000100)),
2794 mkU32(0x00000100)));
2796 assign(t8, binop(Iop_Or32,
2797 binop(Iop_Or32,
2798 binop(Iop_Or32,
2799 unop(Iop_1Sto32, mkexpr(t7)),
2800 unop(Iop_1Sto32, mkexpr(t5))),
2801 unop(Iop_1Sto32, mkexpr(t3))),
2802 unop(Iop_1Sto32, mkexpr(t1))));
2804 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
2805 mkexpr(t8),
2806 mkU32(0x0)),
2807 getDSPControl(),
2808 binop(Iop_Or32,
2809 getDSPControl(),
2810 mkU32(0x00100000))));
2812 putIReg(rd, binop(Iop_16HLto32,
2813 binop(Iop_8HLto16,
2814 unop(Iop_32to8, mkexpr(t6)),
2815 unop(Iop_32to8, mkexpr(t4))),
2816 binop(Iop_8HLto16,
2817 unop(Iop_32to8, mkexpr(t2)),
2818 unop(Iop_32to8, mkexpr(t0)))));
2819 break;
2822 case 0x04: { /* ADDU_S.QB */
2823 DIP("addu_s.qb r%u, r%u, r%u", rd, rs, rt);
2824 vassert(!mode64);
2825 t0 = newTemp(Ity_I32);
2826 t1 = newTemp(Ity_I1);
2827 t2 = newTemp(Ity_I8);
2828 t3 = newTemp(Ity_I32);
2829 t4 = newTemp(Ity_I1);
2830 t5 = newTemp(Ity_I8);
2831 t6 = newTemp(Ity_I32);
2832 t7 = newTemp(Ity_I1);
2833 t8 = newTemp(Ity_I8);
2834 t9 = newTemp(Ity_I32);
2835 t10 = newTemp(Ity_I1);
2836 t11 = newTemp(Ity_I8);
2837 t12 = newTemp(Ity_I32);
2839 /* Add rightmost bytes of rs and rt. */
2840 assign(t0,
2841 binop(Iop_Add32,
2842 unop(Iop_8Uto32,
2843 unop(Iop_16to8,
2844 unop(Iop_32to16, getIReg(rs)))),
2845 unop(Iop_8Uto32,
2846 unop(Iop_16to8,
2847 unop(Iop_32to16, getIReg(rt))))));
2848 /* t1 will be 1 if there is overflow, 0 otherwise. */
2849 assign(t1, binop(Iop_CmpEQ32,
2850 binop(Iop_And32,
2851 mkexpr(t0),
2852 mkU32(0x00000100)),
2853 mkU32(0x00000100)));
2854 /* Saturate if necessary. */
2855 assign(t2, IRExpr_ITE(mkexpr(t1),
2856 mkU8(0xff),
2857 unop(Iop_32to8, mkexpr(t0))));
2859 /* Add bits 15-8 of rs and rt. */
2860 assign(t3,
2861 binop(Iop_Add32,
2862 unop(Iop_8Uto32,
2863 unop(Iop_16HIto8,
2864 unop(Iop_32to16, getIReg(rs)))),
2865 unop(Iop_8Uto32,
2866 unop(Iop_16HIto8,
2867 unop(Iop_32to16, getIReg(rt))))));
2868 /* t4 will be 1 if there is overflow, 0 otherwise. */
2869 assign(t4, binop(Iop_CmpEQ32,
2870 binop(Iop_And32,
2871 mkexpr(t3),
2872 mkU32(0x00000100)),
2873 mkU32(0x00000100)));
2874 /* Saturate if necessary. */
2875 assign(t5, IRExpr_ITE(mkexpr(t4),
2876 mkU8(0xff),
2877 unop(Iop_32to8, mkexpr(t3))));
2879 /* Add bits 15-8 of rs and rt. */
2880 assign(t6,
2881 binop(Iop_Add32,
2882 unop(Iop_8Uto32,
2883 unop(Iop_16to8,
2884 unop(Iop_32HIto16, getIReg(rs)))),
2885 unop(Iop_8Uto32,
2886 unop(Iop_16to8,
2887 unop(Iop_32HIto16, getIReg(rt))))));
2888 /* t7 will be 1 if there is overflow, 0 otherwise. */
2889 assign(t7, binop(Iop_CmpEQ32,
2890 binop(Iop_And32,
2891 mkexpr(t6),
2892 mkU32(0x00000100)),
2893 mkU32(0x00000100)));
2894 /* Saturate if necessary. */
2895 assign(t8, IRExpr_ITE(mkexpr(t7),
2896 mkU8(0xff),
2897 unop(Iop_32to8, mkexpr(t6))));
2899 /* Add bits 15-8 of rs and rt. */
2900 assign(t9,
2901 binop(Iop_Add32,
2902 unop(Iop_8Uto32,
2903 unop(Iop_16HIto8,
2904 unop(Iop_32HIto16, getIReg(rs)))),
2905 unop(Iop_8Uto32,
2906 unop(Iop_16HIto8,
2907 unop(Iop_32HIto16, getIReg(rt))))));
2908 /* t10 will be 1 if there is overflow, 0 otherwise. */
2909 assign(t10, binop(Iop_CmpEQ32,
2910 binop(Iop_And32,
2911 mkexpr(t9),
2912 mkU32(0x00000100)),
2913 mkU32(0x00000100)));
2914 /* Saturate if necessary. */
2915 assign(t11, IRExpr_ITE(mkexpr(t10),
2916 mkU8(0xff),
2917 unop(Iop_32to8, mkexpr(t9))));
2919 assign(t12,
2920 binop(Iop_Or32,
2921 binop(Iop_Or32,
2922 binop(Iop_Or32,
2923 unop(Iop_1Sto32, mkexpr(t10)),
2924 unop(Iop_1Sto32, mkexpr(t7))),
2925 unop(Iop_1Sto32, mkexpr(t4))),
2926 unop(Iop_1Sto32, mkexpr(t1))));
2928 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
2929 mkexpr(t12),
2930 mkU32(0x0)),
2931 getDSPControl(),
2932 binop(Iop_Or32,
2933 getDSPControl(),
2934 mkU32(0x00100000))));
2936 putIReg(rd,
2937 binop(Iop_16HLto32,
2938 binop(Iop_8HLto16, mkexpr(t11), mkexpr(t8)),
2939 binop(Iop_8HLto16, mkexpr(t5), mkexpr(t2))));
2940 break;
2943 case 0x05: { /* SUBU_S.QB */
2944 DIP("subu_s.qb r%u, r%u, r%u", rd, rs, rt);
2945 vassert(!mode64);
2946 t1 = newTemp(Ity_I32);
2947 t2 = newTemp(Ity_I1);
2948 t3 = newTemp(Ity_I1);
2949 t4 = newTemp(Ity_I1);
2950 t5 = newTemp(Ity_I1);
2951 t6 = newTemp(Ity_I32);
2952 t7 = newTemp(Ity_I32);
2953 t8 = newTemp(Ity_I32);
2954 t9 = newTemp(Ity_I32);
2956 /* Use C function to easily calculate the result
2957 and write it in the register more conveniently
2958 Underflow is checked using step by step subtraction. */
2959 assign(t1, binop(Iop_QSub8Ux4, getIReg(rs), getIReg(rt)));
2961 /* Subtract each byte of rs and rt. */
2962 assign(t6,
2963 binop(Iop_Sub32,
2964 unop(Iop_8Uto32,
2965 unop(Iop_16to8,
2966 unop(Iop_32to16, getIReg(rs)))),
2967 unop(Iop_8Uto32,
2968 unop(Iop_16to8,
2969 unop(Iop_32to16, getIReg(rt))))));
2970 assign(t7,
2971 binop(Iop_Sub32,
2972 unop(Iop_8Uto32,
2973 unop(Iop_16HIto8,
2974 unop(Iop_32to16, getIReg(rs)))),
2975 unop(Iop_8Uto32,
2976 unop(Iop_16HIto8,
2977 unop(Iop_32to16, getIReg(rt))))));
2978 assign(t8,
2979 binop(Iop_Sub32,
2980 unop(Iop_8Uto32,
2981 unop(Iop_16to8,
2982 unop(Iop_32HIto16, getIReg(rs)))),
2983 unop(Iop_8Uto32,
2984 unop(Iop_16to8,
2985 unop(Iop_32HIto16, getIReg(rt))))));
2986 assign(t9,
2987 binop(Iop_Sub32,
2988 unop(Iop_8Uto32,
2989 unop(Iop_16HIto8,
2990 unop(Iop_32HIto16, getIReg(rs)))),
2991 unop(Iop_8Uto32,
2992 unop(Iop_16HIto8,
2993 unop(Iop_32HIto16, getIReg(rt))))));
2995 /* Put 1 to bit 20 in DSPControl if there is underflow
2996 in either byte. */
2997 assign(t2, binop(Iop_CmpEQ32,
2998 binop(Iop_And32,
2999 mkexpr(t6),
3000 mkU32(0x00000100)),
3001 mkU32(0x00000100)));
3002 putDSPControl(IRExpr_ITE(mkexpr(t2),
3003 binop(Iop_Or32,
3004 getDSPControl(),
3005 mkU32(0x00100000)),
3006 getDSPControl()));
3007 assign(t3, binop(Iop_CmpEQ32,
3008 binop(Iop_And32,
3009 mkexpr(t7),
3010 mkU32(0x00000100)),
3011 mkU32(0x00000100)));
3012 putDSPControl(IRExpr_ITE(mkexpr(t3),
3013 binop(Iop_Or32,
3014 getDSPControl(),
3015 mkU32(0x00100000)),
3016 getDSPControl()));
3017 assign(t4, binop(Iop_CmpEQ32,
3018 binop(Iop_And32,
3019 mkexpr(t8),
3020 mkU32(0x00000100)),
3021 mkU32(0x00000100)));
3022 putDSPControl(IRExpr_ITE(mkexpr(t4),
3023 binop(Iop_Or32,
3024 getDSPControl(),
3025 mkU32(0x00100000)),
3026 getDSPControl()));
3027 assign(t5, binop(Iop_CmpEQ32,
3028 binop(Iop_And32,
3029 mkexpr(t9),
3030 mkU32(0x00000100)),
3031 mkU32(0x00000100)));
3032 putDSPControl(IRExpr_ITE(mkexpr(t5),
3033 binop(Iop_Or32,
3034 getDSPControl(),
3035 mkU32(0x00100000)),
3036 getDSPControl()));
3037 putIReg(rd, mkexpr(t1));
3038 break;
3041 case 0x6: { /* MULEU_S.PH.QBL */
3042 DIP("muleu_s.ph.qbl r%u, r%u, r%u", rd, rs, rt);
3043 vassert(!mode64);
3044 t0 = newTemp(Ity_I32);
3045 t1 = newTemp(Ity_I32);
3046 t2 = newTemp(Ity_I1);
3047 t3 = newTemp(Ity_I1);
3049 assign(t0,
3050 unop(Iop_64to32,
3051 binop(Iop_MullU32,
3052 unop(Iop_8Uto32,
3053 unop(Iop_16HIto8,
3054 unop(Iop_32HIto16,
3055 getIReg(rs)))),
3056 unop(Iop_16Uto32,
3057 unop(Iop_32HIto16, getIReg(rt))))));
3058 assign(t1,
3059 unop(Iop_64to32,
3060 binop(Iop_MullU32,
3061 unop(Iop_8Uto32,
3062 unop(Iop_16to8,
3063 unop(Iop_32HIto16,
3064 getIReg(rs)))),
3065 unop(Iop_16Uto32,
3066 unop(Iop_32to16, getIReg(rt))))));
3068 assign(t2, binop(Iop_CmpNE32,
3069 mkU32(0x0),
3070 binop(Iop_And32,
3071 mkexpr(t0),
3072 mkU32(0x03ff0000))));
3073 assign(t3, binop(Iop_CmpNE32,
3074 mkU32(0x0),
3075 binop(Iop_And32,
3076 mkexpr(t1),
3077 mkU32(0x03ff0000))));
3078 putDSPControl(IRExpr_ITE(mkexpr(t2),
3079 binop(Iop_Or32,
3080 getDSPControl(),
3081 mkU32(0x200000)),
3082 IRExpr_ITE(mkexpr(t3),
3083 binop(Iop_Or32,
3084 getDSPControl(),
3085 mkU32(0x200000)),
3086 getDSPControl())));
3087 putIReg(rd,
3088 binop(Iop_16HLto32,
3089 IRExpr_ITE(mkexpr(t2),
3090 mkU16(0xffff),
3091 unop(Iop_32to16, mkexpr(t0))),
3092 IRExpr_ITE(mkexpr(t3),
3093 mkU16(0xffff),
3094 unop(Iop_32to16, mkexpr(t1)))));
3095 break;
3098 case 0x7: { /* MULEU_S.PH.QBR */
3099 DIP("muleu_s.ph.qbr r%u, r%u, r%u", rd, rs, rt);
3100 vassert(!mode64);
3101 t0 = newTemp(Ity_I32);
3102 t1 = newTemp(Ity_I32);
3103 t2 = newTemp(Ity_I1);
3104 t3 = newTemp(Ity_I1);
3106 assign(t0, unop(Iop_64to32,
3107 binop(Iop_MullU32,
3108 unop(Iop_8Uto32,
3109 unop(Iop_16HIto8,
3110 unop(Iop_32to16,
3111 getIReg(rs)))),
3112 unop(Iop_16Uto32,
3113 unop(Iop_32HIto16,
3114 getIReg(rt))))));
3115 assign(t1, unop(Iop_64to32,
3116 binop(Iop_MullU32,
3117 unop(Iop_8Uto32,
3118 unop(Iop_16to8,
3119 unop(Iop_32to16,
3120 getIReg(rs)))),
3121 unop(Iop_16Uto32,
3122 unop(Iop_32to16,
3123 getIReg(rt))))));
3125 assign(t2, binop(Iop_CmpNE32,
3126 mkU32(0x0),
3127 binop(Iop_And32,
3128 mkexpr(t0),
3129 mkU32(0x03ff0000))));
3130 assign(t3, binop(Iop_CmpNE32,
3131 mkU32(0x0),
3132 binop(Iop_And32,
3133 mkexpr(t1),
3134 mkU32(0x03ff0000))));
3135 putDSPControl(IRExpr_ITE(mkexpr(t2),
3136 binop(Iop_Or32,
3137 getDSPControl(),
3138 mkU32(0x200000)),
3139 IRExpr_ITE(mkexpr(t3),
3140 binop(Iop_Or32,
3141 getDSPControl(),
3142 mkU32(0x200000)),
3143 getDSPControl())));
3144 putIReg(rd, binop(Iop_16HLto32,
3145 IRExpr_ITE(mkexpr(t2),
3146 mkU16(0xffff),
3147 unop(Iop_32to16,
3148 mkexpr(t0))),
3149 IRExpr_ITE(mkexpr(t3),
3150 mkU16(0xffff),
3151 unop(Iop_32to16,
3152 mkexpr(t1)))));
3153 break;
3156 case 0x08: { /* ADDU.PH */
3157 DIP("addu.ph r%u, r%u, r%u", rd, rs, rt);
3158 vassert(!mode64);
3159 t0 = newTemp(Ity_I32);
3160 t1 = newTemp(Ity_I1);
3161 t2 = newTemp(Ity_I32);
3162 t3 = newTemp(Ity_I1);
3164 /* Add lower halves. */
3165 assign(t0, binop(Iop_Add32,
3166 unop(Iop_16Uto32,
3167 unop(Iop_32to16, getIReg(rs))),
3168 unop(Iop_16Uto32,
3169 unop(Iop_32to16, getIReg(rt)))));
3171 /* Detect overflow. */
3172 assign(t1, binop(Iop_CmpLT32U,
3173 unop(Iop_16Uto32,
3174 unop(Iop_32to16, mkexpr(t0))),
3175 unop(Iop_16Uto32,
3176 unop(Iop_32to16, getIReg(rs)))));
3178 putDSPControl(IRExpr_ITE(mkexpr(t1),
3179 binop(Iop_Or32,
3180 getDSPControl(),
3181 mkU32(0x00100000)),
3182 getDSPControl()));
3184 /* Add higher halves. */
3185 assign(t2, binop(Iop_Add32,
3186 unop(Iop_16Uto32,
3187 unop(Iop_32HIto16, getIReg(rs))),
3188 unop(Iop_16Uto32,
3189 unop(Iop_32HIto16, getIReg(rt)))));
3191 /* Detect overflow. */
3192 assign(t3, binop(Iop_CmpLT32U,
3193 unop(Iop_16Uto32,
3194 unop(Iop_32to16, mkexpr(t2))),
3195 unop(Iop_16Uto32,
3196 unop(Iop_32HIto16,
3197 getIReg(rs)))));
3199 putDSPControl(IRExpr_ITE(mkexpr(t3),
3200 binop(Iop_Or32,
3201 getDSPControl(),
3202 mkU32(0x00100000)),
3203 getDSPControl()));
3205 putIReg(rd, binop(Iop_16HLto32,
3206 unop(Iop_32to16, mkexpr(t2)),
3207 unop(Iop_32to16, mkexpr(t0))));
3208 break;
3211 case 0x9: { /* SUBU.PH */
3212 DIP("subu.ph r%u, r%u, r%u", rd, rs, rt);
3213 vassert(!mode64);
3214 t0 = newTemp(Ity_I32);
3215 t1 = newTemp(Ity_I1);
3216 t2 = newTemp(Ity_I32);
3217 t3 = newTemp(Ity_I1);
3219 /* Substract lower halves. */
3220 assign(t0, binop(Iop_Sub32,
3221 unop(Iop_16Uto32,
3222 unop(Iop_32to16, getIReg(rs))),
3223 unop(Iop_16Uto32,
3224 unop(Iop_32to16, getIReg(rt)))));
3226 /* Detect underflow. */
3227 assign(t1, binop(Iop_CmpNE32,
3228 binop(Iop_And32,
3229 mkexpr(t0),
3230 mkU32(0x00010000)),
3231 mkU32(0x0)));
3233 putDSPControl(IRExpr_ITE(mkexpr(t1),
3234 binop(Iop_Or32,
3235 getDSPControl(),
3236 mkU32(0x00100000)),
3237 getDSPControl()));
3239 /* Subtract higher halves. */
3240 assign(t2, binop(Iop_Sub32,
3241 unop(Iop_16Uto32,
3242 unop(Iop_32HIto16, getIReg(rs))),
3243 unop(Iop_16Uto32,
3244 unop(Iop_32HIto16, getIReg(rt)))));
3246 /* Detect underflow. */
3247 assign(t3, binop(Iop_CmpNE32,
3248 binop(Iop_And32,
3249 mkexpr(t2),
3250 mkU32(0x00010000)),
3251 mkU32(0x0)));
3253 putDSPControl(IRExpr_ITE(mkexpr(t3),
3254 binop(Iop_Or32,
3255 getDSPControl(),
3256 mkU32(0x00100000)),
3257 getDSPControl()));
3259 putIReg(rd, binop(Iop_16HLto32,
3260 unop(Iop_32to16, mkexpr(t2)),
3261 unop(Iop_32to16, mkexpr(t0))));
3262 break;
3265 case 0xA: { /* ADDQ.PH */
3266 DIP("addq.ph r%u, r%u, r%u", rd, rs, rt);
3267 vassert(!mode64);
3268 t0 = newTemp(Ity_I32);
3269 t1 = newTemp(Ity_I1);
3270 t2 = newTemp(Ity_I32);
3271 t3 = newTemp(Ity_I1);
3272 t6 = newTemp(Ity_I32);
3273 t7 = newTemp(Ity_I32);
3275 /* Add lower halves. */
3276 assign(t0, binop(Iop_Add32,
3277 unop(Iop_16Sto32,
3278 unop(Iop_32to16, getIReg(rs))),
3279 unop(Iop_16Sto32,
3280 unop(Iop_32to16, getIReg(rt)))));
3282 /* Bit 16 of the result. */
3283 assign(t6, binop(Iop_And32,
3284 unop(Iop_16Uto32,
3285 unop(Iop_32HIto16, mkexpr(t0))),
3286 mkU32(0x1)));
3287 /* Detect overflow. */
3288 assign(t1, binop(Iop_CmpNE32,
3289 binop(Iop_Shr32,
3290 binop(Iop_And32,
3291 mkexpr(t0),
3292 mkU32(0x8000)),
3293 mkU8(15)),
3294 mkexpr(t6)));
3296 putDSPControl(IRExpr_ITE(mkexpr(t1),
3297 binop(Iop_Or32,
3298 getDSPControl(),
3299 mkU32(0x00100000)),
3300 getDSPControl()));
3302 /* Add higher halves. */
3303 assign(t2, binop(Iop_Add32,
3304 unop(Iop_16Sto32,
3305 unop(Iop_32HIto16, getIReg(rs))),
3306 unop(Iop_16Sto32,
3307 unop(Iop_32HIto16, getIReg(rt)))));
3309 /* Bit 16 of the result. */
3310 assign(t7, binop(Iop_And32,
3311 unop(Iop_16Uto32,
3312 unop(Iop_32HIto16, mkexpr(t2))),
3313 mkU32(0x1)));
3314 /* Detect overflow. */
3315 assign(t3, binop(Iop_CmpNE32,
3316 binop(Iop_Shr32,
3317 binop(Iop_And32,
3318 mkexpr(t2),
3319 mkU32(0x00008000)),
3320 mkU8(15)),
3321 mkexpr(t7)));
3323 putDSPControl(IRExpr_ITE(mkexpr(t3),
3324 binop(Iop_Or32,
3325 getDSPControl(),
3326 mkU32(0x00100000)),
3327 getDSPControl()));
3329 putIReg(rd, binop(Iop_16HLto32,
3330 unop(Iop_32to16, mkexpr(t2)),
3331 unop(Iop_32to16, mkexpr(t0))));
3332 break;
3335 case 0xB: { /* SUBQ.PH */
3336 DIP("subq.ph r%u, r%u, r%u", rd, rs, rt);
3337 vassert(!mode64);
3338 t0 = newTemp(Ity_I32);
3339 t1 = newTemp(Ity_I1);
3340 t2 = newTemp(Ity_I32);
3341 t3 = newTemp(Ity_I1);
3342 t6 = newTemp(Ity_I32);
3343 t7 = newTemp(Ity_I32);
3345 /* Subtract lower halves. */
3346 assign(t0, binop(Iop_Sub32,
3347 unop(Iop_16Sto32,
3348 unop(Iop_32to16, getIReg(rs))),
3349 unop(Iop_16Sto32,
3350 unop(Iop_32to16, getIReg(rt)))));
3352 /* Bit 16 of the result. */
3353 assign(t6, binop(Iop_And32,
3354 unop(Iop_16Uto32,
3355 unop(Iop_32HIto16, mkexpr(t0))),
3356 mkU32(0x1)));
3357 /* Compare the signs of input value and the result. */
3358 assign(t1, binop(Iop_CmpNE32,
3359 binop(Iop_Shr32,
3360 binop(Iop_And32,
3361 mkexpr(t0),
3362 mkU32(0x8000)),
3363 mkU8(15)),
3364 mkexpr(t6)));
3366 putDSPControl(IRExpr_ITE(mkexpr(t1),
3367 binop(Iop_Or32,
3368 getDSPControl(),
3369 mkU32(0x00100000)),
3370 getDSPControl()));
3372 /* Subtract higher halves. */
3373 assign(t2, binop(Iop_Sub32,
3374 unop(Iop_16Sto32,
3375 unop(Iop_32HIto16, getIReg(rs))),
3376 unop(Iop_16Sto32,
3377 unop(Iop_32HIto16, getIReg(rt)))));
3379 /* Bit 16 of the result. */
3380 assign(t7, binop(Iop_And32,
3381 unop(Iop_16Uto32,
3382 unop(Iop_32HIto16, mkexpr(t2))),
3383 mkU32(0x1)));
3384 /* Compare the signs of input value and the result. */
3385 assign(t3, binop(Iop_CmpNE32,
3386 binop(Iop_Shr32,
3387 binop(Iop_And32,
3388 mkexpr(t2),
3389 mkU32(0x00008000)),
3390 mkU8(15)),
3391 mkexpr(t7)));
3393 putDSPControl(IRExpr_ITE(mkexpr(t3),
3394 binop(Iop_Or32,
3395 getDSPControl(),
3396 mkU32(0x00100000)),
3397 getDSPControl()));
3399 putIReg(rd, binop(Iop_16HLto32,
3400 unop(Iop_32to16, mkexpr(t2)),
3401 unop(Iop_32to16, mkexpr(t0))));
3402 break;
3405 case 0xC: { /* ADDU_S.PH */
3406 DIP("addu_s.ph r%u, r%u, r%u", rd, rs, rt);
3407 vassert(!mode64);
3408 t0 = newTemp(Ity_I32);
3409 t1 = newTemp(Ity_I1);
3410 t2 = newTemp(Ity_I32);
3411 t3 = newTemp(Ity_I1);
3413 /* Add lower halves. */
3414 assign(t0, binop(Iop_Add32,
3415 unop(Iop_16Uto32,
3416 unop(Iop_32to16, getIReg(rs))),
3417 unop(Iop_16Uto32,
3418 unop(Iop_32to16, getIReg(rt)))));
3420 /* Detect overflow. */
3421 assign(t1, binop(Iop_CmpLT32U,
3422 unop(Iop_16Uto32,
3423 unop(Iop_32to16, mkexpr(t0))),
3424 unop(Iop_16Uto32,
3425 unop(Iop_32to16, getIReg(rs)))));
3427 putDSPControl(IRExpr_ITE(mkexpr(t1),
3428 binop(Iop_Or32,
3429 getDSPControl(),
3430 mkU32(0x00100000)),
3431 getDSPControl()));
3433 /* Add higher halves. */
3434 assign(t2, binop(Iop_Add32,
3435 unop(Iop_16Uto32,
3436 unop(Iop_32HIto16, getIReg(rs))),
3437 unop(Iop_16Uto32,
3438 unop(Iop_32HIto16, getIReg(rt)))));
3440 /* Detect overflow. */
3441 assign(t3, binop(Iop_CmpLT32U,
3442 unop(Iop_16Uto32,
3443 unop(Iop_32to16, mkexpr(t2))),
3444 unop(Iop_16Uto32,
3445 unop(Iop_32HIto16, getIReg(rs)))));
3447 putDSPControl(IRExpr_ITE(mkexpr(t3),
3448 binop(Iop_Or32,
3449 getDSPControl(),
3450 mkU32(0x00100000)),
3451 getDSPControl()));
3453 putIReg(rd, binop(Iop_16HLto32,
3454 IRExpr_ITE(mkexpr(t3),
3455 mkU16(0xffff),
3456 unop(Iop_32to16,
3457 mkexpr(t2))),
3458 IRExpr_ITE(mkexpr(t1),
3459 mkU16(0xffff),
3460 unop(Iop_32to16,
3461 mkexpr(t0)))));
3462 break;
3465 case 0xD: { /* SUBU_S.PH */
3466 DIP("subu_s.ph r%u, r%u, r%u", rd, rs, rt);
3467 vassert(!mode64);
3468 t0 = newTemp(Ity_I32);
3469 t1 = newTemp(Ity_I1);
3470 t2 = newTemp(Ity_I32);
3471 t3 = newTemp(Ity_I1);
3473 /* Subtract lower halves. */
3474 assign(t0, binop(Iop_Sub32,
3475 unop(Iop_16Uto32,
3476 unop(Iop_32to16, getIReg(rs))),
3477 unop(Iop_16Uto32,
3478 unop(Iop_32to16, getIReg(rt)))));
3480 /* Detect underflow. */
3481 assign(t1, binop(Iop_CmpNE32,
3482 binop(Iop_And32,
3483 mkexpr(t0), mkU32(0x00010000)),
3484 mkU32(0x0)));
3486 putDSPControl(IRExpr_ITE(mkexpr(t1),
3487 binop(Iop_Or32,
3488 getDSPControl(),
3489 mkU32(0x00100000)),
3490 getDSPControl()));
3492 /* Subtract higher halves. */
3493 assign(t2, binop(Iop_Sub32,
3494 unop(Iop_16Uto32,
3495 unop(Iop_32HIto16, getIReg(rs))),
3496 unop(Iop_16Uto32,
3497 unop(Iop_32HIto16, getIReg(rt)))));
3499 /* Detect underflow. */
3500 assign(t3, binop(Iop_CmpNE32,
3501 binop(Iop_And32,
3502 mkexpr(t2), mkU32(0x00010000)),
3503 mkU32(0x0)));
3505 putDSPControl(IRExpr_ITE(mkexpr(t3),
3506 binop(Iop_Or32,
3507 getDSPControl(),
3508 mkU32(0x00100000)),
3509 getDSPControl()));
3511 putIReg(rd,
3512 binop(Iop_16HLto32,
3513 IRExpr_ITE(mkexpr(t3),
3514 mkU16(0x0000),
3515 unop(Iop_32to16, mkexpr(t2))),
3516 IRExpr_ITE(mkexpr(t1),
3517 mkU16(0x0000),
3518 unop(Iop_32to16, mkexpr(t0)))));
3519 break;
3522 case 0xE: { /* ADDQ_S.PH */
3523 DIP("addq_s.ph r%u r%u, r%u", rd, rs, rt);
3524 vassert(!mode64);
3525 t0 = newTemp(Ity_I32);
3526 t1 = newTemp(Ity_I1);
3527 t2 = newTemp(Ity_I32);
3528 t3 = newTemp(Ity_I1);
3529 t4 = newTemp(Ity_I16);
3530 t5 = newTemp(Ity_I16);
3531 t6 = newTemp(Ity_I32);
3532 t7 = newTemp(Ity_I32);
3534 /* Add lower halves. */
3535 assign(t0, binop(Iop_Add32,
3536 unop(Iop_16Sto32,
3537 unop(Iop_32to16, getIReg(rs))),
3538 unop(Iop_16Sto32,
3539 unop(Iop_32to16, getIReg(rt)))));
3541 /* Bit 16 of the result. */
3542 assign(t6, binop(Iop_And32,
3543 unop(Iop_16Uto32,
3544 unop(Iop_32HIto16, mkexpr(t0))),
3545 mkU32(0x1)));
3546 /* Detect overflow. */
3547 assign(t1, binop(Iop_CmpNE32,
3548 binop(Iop_Shr32,
3549 binop(Iop_And32,
3550 mkexpr(t0),
3551 mkU32(0x8000)),
3552 mkU8(15)),
3553 mkexpr(t6)));
3555 putDSPControl(IRExpr_ITE(mkexpr(t1),
3556 binop(Iop_Or32,
3557 getDSPControl(),
3558 mkU32(0x00100000)),
3559 getDSPControl()));
3560 /* Saturate if needed. */
3561 assign(t4, IRExpr_ITE(mkexpr(t1),
3562 IRExpr_ITE(binop(Iop_CmpEQ32,
3563 mkexpr(t6),
3564 mkU32(0x0)),
3565 mkU16(0x7fff),
3566 mkU16(0x8000)),
3567 unop(Iop_32to16, mkexpr(t0))));
3569 /* Add higher halves. */
3570 assign(t2, binop(Iop_Add32,
3571 unop(Iop_16Sto32,
3572 unop(Iop_32HIto16, getIReg(rs))),
3573 unop(Iop_16Sto32,
3574 unop(Iop_32HIto16, getIReg(rt)))));
3576 /* Bit 16 of the result. */
3577 assign(t7, binop(Iop_And32,
3578 unop(Iop_16Uto32,
3579 unop(Iop_32HIto16, mkexpr(t2))),
3580 mkU32(0x1)));
3581 /* Detect overflow. */
3582 assign(t3, binop(Iop_CmpNE32,
3583 binop(Iop_Shr32,
3584 binop(Iop_And32,
3585 mkexpr(t2),
3586 mkU32(0x00008000)),
3587 mkU8(15)),
3588 mkexpr(t7)));
3590 putDSPControl(IRExpr_ITE(mkexpr(t3),
3591 binop(Iop_Or32,
3592 getDSPControl(),
3593 mkU32(0x00100000)),
3594 getDSPControl()));
3595 /* Saturate if needed. */
3596 assign(t5, IRExpr_ITE(mkexpr(t3),
3597 IRExpr_ITE(binop(Iop_CmpEQ32,
3598 mkexpr(t7),
3599 mkU32(0x0)),
3600 mkU16(0x7fff),
3601 mkU16(0x8000)),
3602 unop(Iop_32to16, mkexpr(t2))));
3604 putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
3605 break;
3608 case 0xF: { /* SUBQ_S.PH */
3609 DIP("subq_s.ph r%u r%u, r%u", rd, rs, rt);
3610 vassert(!mode64);
3611 t0 = newTemp(Ity_I32);
3612 t1 = newTemp(Ity_I1);
3613 t2 = newTemp(Ity_I32);
3614 t3 = newTemp(Ity_I1);
3615 t4 = newTemp(Ity_I16);
3616 t5 = newTemp(Ity_I16);
3617 t6 = newTemp(Ity_I32);
3618 t7 = newTemp(Ity_I32);
3620 /* Subtract lower halves. */
3621 assign(t0, binop(Iop_Sub32,
3622 unop(Iop_16Sto32,
3623 unop(Iop_32to16, getIReg(rs))),
3624 unop(Iop_16Sto32,
3625 unop(Iop_32to16, getIReg(rt)))));
3627 /* Bit 16 of the result. */
3628 assign(t6, binop(Iop_And32,
3629 unop(Iop_16Uto32,
3630 unop(Iop_32HIto16, mkexpr(t0))),
3631 mkU32(0x1)));
3632 /* Detect overflow or underflow. */
3633 assign(t1, binop(Iop_CmpNE32,
3634 binop(Iop_Shr32,
3635 binop(Iop_And32,
3636 mkexpr(t0),
3637 mkU32(0x8000)),
3638 mkU8(15)),
3639 mkexpr(t6)));
3641 putDSPControl(IRExpr_ITE(mkexpr(t1),
3642 binop(Iop_Or32,
3643 getDSPControl(),
3644 mkU32(0x00100000)),
3645 getDSPControl()));
3646 /* Saturate if needed. */
3647 assign(t4, IRExpr_ITE(mkexpr(t1),
3648 IRExpr_ITE(binop(Iop_CmpEQ32,
3649 mkexpr(t6),
3650 mkU32(0x0)),
3651 mkU16(0x7fff),
3652 mkU16(0x8000)),
3653 unop(Iop_32to16, mkexpr(t0))));
3655 /* Subtract higher halves. */
3656 assign(t2, binop(Iop_Sub32,
3657 unop(Iop_16Sto32,
3658 unop(Iop_32HIto16, getIReg(rs))),
3659 unop(Iop_16Sto32,
3660 unop(Iop_32HIto16, getIReg(rt)))));
3662 /* Bit 16 of the result. */
3663 assign(t7, binop(Iop_And32,
3664 unop(Iop_16Uto32,
3665 unop(Iop_32HIto16, mkexpr(t2))),
3666 mkU32(0x1)));
3667 /* Detect overflow or underflow. */
3668 assign(t3, binop(Iop_CmpNE32,
3669 binop(Iop_Shr32,
3670 binop(Iop_And32,
3671 mkexpr(t2),
3672 mkU32(0x00008000)),
3673 mkU8(15)),
3674 mkexpr(t7)));
3676 putDSPControl(IRExpr_ITE(mkexpr(t3),
3677 binop(Iop_Or32,
3678 getDSPControl(),
3679 mkU32(0x00100000)),
3680 getDSPControl()));
3681 /* Saturate if needed. */
3682 assign(t5, IRExpr_ITE(mkexpr(t3),
3683 IRExpr_ITE(binop(Iop_CmpEQ32,
3684 mkexpr(t7),
3685 mkU32(0x0)),
3686 mkU16(0x7fff),
3687 mkU16(0x8000)),
3688 unop(Iop_32to16, mkexpr(t2))));
3690 putIReg(rd, binop(Iop_16HLto32, mkexpr(t5), mkexpr(t4)));
3691 break;
3694 case 0x10: { /* ADDSC */
3695 DIP("addsc r%u, r%u, r%u", rd, rs, rt);
3696 vassert(!mode64);
3697 t0 = newTemp(Ity_I64);
3698 t1 = newTemp(Ity_I1);
3700 /* The carry bit result out of the addition operation is
3701 written to bit 13(the c field) of the DSPControl reg. */
3702 assign(t0, binop(Iop_Add64,
3703 unop(Iop_32Uto64, getIReg(rs)),
3704 unop(Iop_32Uto64, getIReg(rt))));
3706 assign(t1, binop(Iop_CmpEQ32,
3707 binop(Iop_And32,
3708 unop(Iop_64HIto32, mkexpr(t0)),
3709 mkU32(0x1)),
3710 mkU32(0x1)));
3711 putDSPControl(IRExpr_ITE(mkexpr(t1),
3712 binop(Iop_Or32,
3713 getDSPControl(),
3714 mkU32(0x2000)),
3715 binop(Iop_And32,
3716 getDSPControl(),
3717 mkU32(0xffffdfff))));
3719 putIReg(rd, unop(Iop_64to32, mkexpr(t0)));
3720 break;
3723 case 0x11: { /* ADDWC */
3724 DIP("addwc r%u, r%u, r%u", rd, rs, rt);
3725 vassert(!mode64);
3726 t0 = newTemp(Ity_I32);
3727 t1 = newTemp(Ity_I64);
3728 t2 = newTemp(Ity_I32);
3729 t3 = newTemp(Ity_I32);
3730 t4 = newTemp(Ity_I1);
3732 /* Get carry bit from DSPControl register. */
3733 assign(t0, binop(Iop_Shr32,
3734 binop(Iop_And32,
3735 getDSPControl(),
3736 mkU32(0x2000)),
3737 mkU8(0xd)));
3738 assign(t1, binop(Iop_Add64,
3739 unop(Iop_32Sto64, getIReg(rs)),
3740 unop(Iop_32Sto64,
3741 binop(Iop_Add32,
3742 getIReg(rt),
3743 mkexpr(t0)))));
3745 /* Extract bits 32 and 31. */
3746 assign(t2, binop(Iop_And32,
3747 unop(Iop_64HIto32, mkexpr(t1)),
3748 mkU32(0x1)));
3749 assign(t3, binop(Iop_Shr32,
3750 binop(Iop_And32,
3751 unop(Iop_64to32, mkexpr(t1)),
3752 mkU32(0x80000000)),
3753 mkU8(31)));
3754 assign(t4, binop(Iop_CmpNE32, mkexpr(t2), mkexpr(t3)));
3756 putDSPControl(IRExpr_ITE(mkexpr(t4),
3757 binop(Iop_Or32,
3758 getDSPControl(),
3759 mkU32(0x00100000)),
3760 getDSPControl()));
3761 putIReg(rd, unop(Iop_64to32, mkexpr(t1)));
3762 break;
3765 case 0x12: { /* MODSUB */
3766 DIP("modsub r%u, r%u, r%u", rd, rs, rt);
3767 vassert(!mode64);
3768 t0 = newTemp(Ity_I32);
3769 t1 = newTemp(Ity_I32);
3770 t2 = newTemp(Ity_I32);
3772 /* decr_7..0 */
3773 assign(t0,
3774 unop(Iop_8Uto32,
3775 unop(Iop_16to8,
3776 unop(Iop_32to16, getIReg(rt)))));
3778 /* lastindex_15..0 */
3779 assign(t1,
3780 unop(Iop_16Uto32,
3781 binop(Iop_8HLto16,
3782 unop(Iop_16to8,
3783 unop(Iop_32HIto16, getIReg(rt))),
3784 unop(Iop_16HIto8,
3785 unop(Iop_32to16, getIReg(rt))))));
3786 /* temp_15..0 */
3787 assign(t2,
3788 IRExpr_ITE(binop(Iop_CmpEQ32,
3789 getIReg(rs),
3790 mkU32(0x00000000)),
3791 mkexpr(t1),
3792 binop(Iop_Sub32,
3793 getIReg(rs), mkexpr(t0))));
3794 putIReg(rd, mkexpr(t2));
3795 break;
3798 case 0x14: { /* RADDU.W.QB */
3799 DIP("raddu.w.qb r%u, r%u", rd, rs);
3800 vassert(!mode64);
3801 putIReg(rd, binop(Iop_Add32,
3802 binop(Iop_Add32,
3803 unop(Iop_8Uto32,
3804 unop(Iop_16to8,
3805 unop(Iop_32to16,
3806 getIReg(rs)))),
3807 unop(Iop_8Uto32,
3808 unop(Iop_16HIto8,
3809 unop(Iop_32to16,
3810 getIReg(rs))))),
3811 binop(Iop_Add32,
3812 unop(Iop_8Uto32,
3813 unop(Iop_16to8,
3814 unop(Iop_32HIto16,
3815 getIReg(rs)))),
3816 unop(Iop_8Uto32,
3817 unop(Iop_16HIto8,
3818 unop(Iop_32HIto16,
3819 getIReg(rs)))))));
3820 break;
3823 case 0x16: { /* ADDQ_S.W */
3824 DIP("addq_s.w r%u, r%u, r%u", rd, rs, rt);
3825 vassert(!mode64);
3826 t0 = newTemp(Ity_I64);
3827 t1 = newTemp(Ity_I1);
3828 t2 = newTemp(Ity_I32);
3830 assign(t0, binop(Iop_Add64,
3831 unop(Iop_32Sto64, getIReg(rs)),
3832 unop(Iop_32Sto64, getIReg(rt))));
3834 assign(t2, binop(Iop_And32,
3835 unop(Iop_64HIto32, mkexpr(t0)),
3836 mkU32(0x1)));
3837 assign(t1, binop(Iop_CmpNE32,
3838 binop(Iop_Shr32,
3839 binop(Iop_And32,
3840 unop(Iop_64to32, mkexpr(t0)),
3841 mkU32(0x80000000)),
3842 mkU8(31)),
3843 mkexpr(t2)));
3845 putDSPControl(IRExpr_ITE(mkexpr(t1),
3846 binop(Iop_Or32,
3847 getDSPControl(),
3848 mkU32(0x00100000)),
3849 getDSPControl()));
3851 putIReg(rd, IRExpr_ITE(mkexpr(t1),
3852 IRExpr_ITE(binop(Iop_CmpEQ32,
3853 mkexpr(t2),
3854 mkU32(0x0)),
3855 mkU32(0x7fffffff),
3856 mkU32(0x80000000)),
3857 unop(Iop_64to32, mkexpr(t0))));
3858 break;
3861 case 0x17: { /* SUBQ_S.W */
3862 DIP("subq_s.w r%u, r%u, r%u", rd, rs, rt);
3863 vassert(!mode64);
3864 t0 = newTemp(Ity_I64);
3865 t1 = newTemp(Ity_I1);
3866 t2 = newTemp(Ity_I32);
3868 assign(t0, binop(Iop_Sub64,
3869 unop(Iop_32Sto64, getIReg(rs)),
3870 unop(Iop_32Sto64, getIReg(rt))));
3872 assign(t2, binop(Iop_And32,
3873 unop(Iop_64HIto32, mkexpr(t0)),
3874 mkU32(0x1)));
3875 assign(t1, binop(Iop_CmpNE32,
3876 binop(Iop_Shr32,
3877 binop(Iop_And32,
3878 unop(Iop_64to32, mkexpr(t0)),
3879 mkU32(0x80000000)),
3880 mkU8(31)),
3881 mkexpr(t2)));
3883 putDSPControl(IRExpr_ITE(mkexpr(t1),
3884 binop(Iop_Or32,
3885 getDSPControl(),
3886 mkU32(0x00100000)),
3887 getDSPControl()));
3889 putIReg(rd, IRExpr_ITE(mkexpr(t1),
3890 IRExpr_ITE(binop(Iop_CmpEQ32,
3891 mkexpr(t2),
3892 mkU32(0x0)),
3893 mkU32(0x7fffffff),
3894 mkU32(0x80000000)),
3895 unop(Iop_64to32, mkexpr(t0))));
3896 break;
3899 case 0x1C: { /* MULEQ_S.W.PHL */
3900 DIP("muleq_s.w.phl r%u, r%u, r%u", rd, rs, rt);
3901 vassert(!mode64);
3902 t0 = newTemp(Ity_I32);
3903 t1 = newTemp(Ity_I1);
3904 t2 = newTemp(Ity_I1);
3905 t3 = newTemp(Ity_I32);
3907 assign(t0,
3908 binop(Iop_Shl32,
3909 binop(Iop_Mul32,
3910 unop(Iop_16Sto32,
3911 unop(Iop_32HIto16, getIReg(rt))),
3912 unop(Iop_16Sto32,
3913 unop(Iop_32HIto16, getIReg(rs)))),
3914 mkU8(0x1)));
3915 assign(t1, binop(Iop_CmpEQ32,
3916 binop(Iop_And32,
3917 getIReg(rt),
3918 mkU32(0xffff0000)),
3919 mkU32(0x80000000)));
3920 assign(t2, binop(Iop_CmpEQ32,
3921 binop(Iop_And32,
3922 getIReg(rs),
3923 mkU32(0xffff0000)),
3924 mkU32(0x80000000)));
3925 assign(t3, IRExpr_ITE(mkexpr(t1),
3926 IRExpr_ITE(mkexpr(t2),
3927 binop(Iop_Or32,
3928 getDSPControl(),
3929 mkU32(0x00200000)),
3930 getDSPControl()),
3931 getDSPControl()));
3932 putDSPControl(mkexpr(t3));
3934 putIReg(rd, IRExpr_ITE(mkexpr(t1),
3935 IRExpr_ITE(mkexpr(t2),
3936 mkU32(0x7fffffff),
3937 mkexpr(t0)),
3938 mkexpr(t0)));
3939 break;
3942 case 0x1D: { /* MULEQ_S.W.PHR */
3943 DIP("muleq_s.w.phr r%u, r%u, r%u", rd, rs, rt);
3944 vassert(!mode64);
3945 t0 = newTemp(Ity_I32);
3946 t1 = newTemp(Ity_I1);
3947 t2 = newTemp(Ity_I1);
3949 assign(t0,
3950 binop(Iop_Shl32,
3951 binop(Iop_Mul32,
3952 unop(Iop_16Sto32,
3953 unop(Iop_32to16, getIReg(rt))),
3954 unop(Iop_16Sto32,
3955 unop(Iop_32to16, getIReg(rs)))),
3956 mkU8(0x1)));
3957 assign(t1, binop(Iop_CmpEQ32,
3958 binop(Iop_And32,
3959 getIReg(rt),
3960 mkU32(0xffff)),
3961 mkU32(0x8000)));
3962 assign(t2, binop(Iop_CmpEQ32,
3963 binop(Iop_And32,
3964 getIReg(rs),
3965 mkU32(0xffff)),
3966 mkU32(0x8000)));
3967 putDSPControl(IRExpr_ITE(mkexpr(t1),
3968 IRExpr_ITE(mkexpr(t2),
3969 binop(Iop_Or32,
3970 getDSPControl(),
3971 mkU32(0x00200000)
3973 getDSPControl()),
3974 getDSPControl()));
3975 putIReg(rd, IRExpr_ITE(mkexpr(t1),
3976 IRExpr_ITE(mkexpr(t2),
3977 mkU32(0x7fffffff),
3978 mkexpr(t0)),
3979 mkexpr(t0)));
3980 break;
3983 case 0x1E: { /* MULQ_S.PH */
3984 DIP("mulq_s.ph r%u, r%u, r%u", rd, rs, rt);
3985 vassert(!mode64);
3986 t0 = newTemp(Ity_I32);
3987 t1 = newTemp(Ity_I32);
3988 t2 = newTemp(Ity_I16);
3989 t3 = newTemp(Ity_I16);
3990 t5 = newTemp(Ity_I32);
3991 t6 = newTemp(Ity_I32);
3992 t7 = newTemp(Ity_I32);
3993 t8 = newTemp(Ity_I32);
3995 assign(t5,
3996 unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rs))));
3997 assign(t6,
3998 unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rt))));
4000 assign(t7,
4001 unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rs))));
4002 assign(t8,
4003 unop(Iop_16Sto32, unop(Iop_32HIto16, getIReg(rt))));
4005 assign(t0, binop(Iop_And32,
4006 unop(Iop_1Sto32,
4007 binop(Iop_CmpEQ32,
4008 binop(Iop_And32,
4009 mkexpr(t5),
4010 mkU32(0xffff)),
4011 mkU32(0x8000))),
4012 unop(Iop_1Sto32,
4013 binop(Iop_CmpEQ32,
4014 binop(Iop_And32,
4015 mkexpr(t6),
4016 mkU32(0xffff)),
4017 mkU32(0x8000)))));
4018 assign(t1, binop(Iop_And32,
4019 unop(Iop_1Sto32,
4020 binop(Iop_CmpEQ32,
4021 binop(Iop_And32,
4022 mkexpr(t7),
4023 mkU32(0xffff)),
4024 mkU32(0x8000))),
4025 unop(Iop_1Sto32,
4026 binop(Iop_CmpEQ32,
4027 binop(Iop_And32,
4028 mkexpr(t8),
4029 mkU32(0xffff)),
4030 mkU32(0x8000)))));
4032 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
4033 binop(Iop_Or32,
4034 mkexpr(t0),
4035 mkexpr(t1)),
4036 mkU32(0x0)),
4037 getDSPControl(),
4038 binop(Iop_Or32,
4039 getDSPControl(),
4040 mkU32(0x200000))));
4042 assign(t2, unop(Iop_32HIto16,
4043 binop(Iop_Shl32,
4044 unop(Iop_64to32,
4045 binop(Iop_MullS32,
4046 mkexpr(t7),
4047 mkexpr(t8))),
4048 mkU8(0x1))));
4049 assign(t3, unop(Iop_32HIto16,
4050 binop(Iop_Shl32,
4051 unop(Iop_64to32,
4052 binop(Iop_MullS32,
4053 mkexpr(t5),
4054 mkexpr(t6))),
4055 mkU8(0x1))));
4056 putIReg(rd, binop(Iop_16HLto32,
4057 IRExpr_ITE(binop(Iop_CmpEQ32,
4058 mkexpr(t1),
4059 mkU32(0x0)),
4060 mkexpr(t2),
4061 mkU16(0x7fff)),
4062 IRExpr_ITE(binop(Iop_CmpEQ32,
4063 mkexpr(t0),
4064 mkU32(0x0)),
4065 mkexpr(t3),
4066 mkU16(0x7fff))));
4067 break;
4070 case 0x1F: { /* MULQ_RS.PH */
4071 DIP("mulq_rs.ph r%u, r%u, r%u", rd, rs, rt);
4072 vassert(!mode64);
4073 t0 = newTemp(Ity_I32);
4074 t1 = newTemp(Ity_I1);
4075 t2 = newTemp(Ity_I1);
4076 t3 = newTemp(Ity_I16);
4077 t4 = newTemp(Ity_I32);
4078 t5 = newTemp(Ity_I1);
4079 t6 = newTemp(Ity_I1);
4080 t7 = newTemp(Ity_I16);
4082 /* Multiply and round lower halfwords. */
4083 assign(t0, binop(Iop_Add32,
4084 binop(Iop_Shl32,
4085 binop(Iop_Mul32,
4086 unop(Iop_16Sto32,
4087 unop(Iop_32to16,
4088 getIReg(rt))),
4089 unop(Iop_16Sto32,
4090 unop(Iop_32to16,
4091 getIReg(rs)))),
4092 mkU8(0x1)),
4093 mkU32(0x00008000)));
4094 assign(t1, binop(Iop_CmpEQ32,
4095 binop(Iop_And32,
4096 getIReg(rt), mkU32(0xffff)),
4097 mkU32(0x8000)));
4098 assign(t2, binop(Iop_CmpEQ32,
4099 binop(Iop_And32,
4100 getIReg(rs), mkU32(0xffff)),
4101 mkU32(0x8000)));
4102 putDSPControl(IRExpr_ITE(mkexpr(t1),
4103 IRExpr_ITE(mkexpr(t2),
4104 binop(Iop_Or32,
4105 getDSPControl(),
4106 mkU32(0x00200000)
4108 getDSPControl()),
4109 getDSPControl()));
4110 assign(t3, IRExpr_ITE(mkexpr(t1),
4111 IRExpr_ITE(mkexpr(t2),
4112 mkU16(0x7fff),
4113 unop(Iop_32HIto16,
4114 mkexpr(t0))),
4115 unop(Iop_32HIto16, mkexpr(t0))));
4117 /* Multiply and round higher halfwords. */
4118 assign(t4, binop(Iop_Add32,
4119 binop(Iop_Shl32,
4120 binop(Iop_Mul32,
4121 unop(Iop_16Sto32,
4122 unop(Iop_32HIto16,
4123 getIReg(rt))),
4124 unop(Iop_16Sto32,
4125 unop(Iop_32HIto16,
4126 getIReg(rs)))),
4127 mkU8(0x1)),
4128 mkU32(0x00008000)));
4129 assign(t5, binop(Iop_CmpEQ32,
4130 binop(Iop_And32,
4131 getIReg(rt),
4132 mkU32(0xffff0000)),
4133 mkU32(0x80000000)));
4134 assign(t6, binop(Iop_CmpEQ32,
4135 binop(Iop_And32,
4136 getIReg(rs),
4137 mkU32(0xffff0000)),
4138 mkU32(0x80000000)));
4139 putDSPControl(IRExpr_ITE(mkexpr(t5),
4140 IRExpr_ITE(mkexpr(t6),
4141 binop(Iop_Or32,
4142 getDSPControl(),
4143 mkU32(0x00200000)),
4144 getDSPControl()),
4145 getDSPControl()));
4146 assign(t7, IRExpr_ITE(mkexpr(t5),
4147 IRExpr_ITE(mkexpr(t6),
4148 mkU16(0x7fff),
4149 unop(Iop_32HIto16,
4150 mkexpr(t4))),
4151 unop(Iop_32HIto16, mkexpr(t4))));
4153 putIReg(rd, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
4154 break;
4157 default:
4158 return -1;
4161 return 0;
4164 static UInt disDSPInstr_MIPS_WRK_Special3_CMPU_EQ_QB( UInt cins )
4166 IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
4167 t15;
4168 UInt rs, rt, rd, sa;
4170 rs = get_rs(cins);
4171 rt = get_rt(cins);
4172 rd = get_rd(cins);
4173 sa = get_sa(cins);
4175 switch (sa) {
4176 case 0x0: { /* CMPU.EQ.QB */
4177 DIP("cmpu.eq.qb r%u, r%u", rs, rt);
4178 vassert(!mode64);
4179 t1 = newTemp(Ity_I1);
4180 t2 = newTemp(Ity_I1);
4181 t3 = newTemp(Ity_I1);
4182 t4 = newTemp(Ity_I1);
4184 assign(t1,
4185 binop(Iop_CmpEQ32,
4186 binop(Iop_And32, getIReg(rs), mkU32(0xff)),
4187 binop(Iop_And32, getIReg(rt), mkU32(0xff))));
4188 putDSPControl(IRExpr_ITE(mkexpr(t1),
4189 binop(Iop_Or32,
4190 getDSPControl(),
4191 mkU32(0x01000000)),
4192 binop(Iop_And32,
4193 getDSPControl(),
4194 mkU32(0xfeffffff))));
4196 assign(t2, binop(Iop_CmpEQ32,
4197 unop(Iop_8Uto32,
4198 unop(Iop_16HIto8,
4199 unop(Iop_32to16,
4200 getIReg(rs)))),
4201 unop(Iop_8Uto32,
4202 unop(Iop_16HIto8,
4203 unop(Iop_32to16,
4204 getIReg(rt))))));
4205 putDSPControl(IRExpr_ITE(mkexpr(t2),
4206 binop(Iop_Or32,
4207 getDSPControl(),
4208 mkU32(0x02000000)),
4209 binop(Iop_And32,
4210 getDSPControl(),
4211 mkU32(0xfdffffff))));
4213 assign(t3, binop(Iop_CmpEQ32,
4214 unop(Iop_8Uto32,
4215 unop(Iop_16to8,
4216 unop(Iop_32HIto16,
4217 getIReg(rs)))),
4218 unop(Iop_8Uto32,
4219 unop(Iop_16to8,
4220 unop(Iop_32HIto16,
4221 getIReg(rt))))));
4222 putDSPControl(IRExpr_ITE(mkexpr(t3),
4223 binop(Iop_Or32,
4224 getDSPControl(),
4225 mkU32(0x04000000)),
4226 binop(Iop_And32,
4227 getDSPControl(),
4228 mkU32(0xfbffffff))));
4230 assign(t4, binop(Iop_CmpEQ32,
4231 unop(Iop_8Uto32,
4232 unop(Iop_16HIto8,
4233 unop(Iop_32HIto16,
4234 getIReg(rs)))),
4235 unop(Iop_8Uto32,
4236 unop(Iop_16HIto8,
4237 unop(Iop_32HIto16,
4238 getIReg(rt))))));
4239 putDSPControl(IRExpr_ITE(mkexpr(t4),
4240 binop(Iop_Or32,
4241 getDSPControl(),
4242 mkU32(0x08000000)),
4243 binop(Iop_And32,
4244 getDSPControl(),
4245 mkU32(0xf7ffffff))));
4246 break;
4249 case 0x1: { /* CMPU.LT.QB */
4250 DIP("cmpu.lt.qb r%u, r%u", rs, rt);
4251 vassert(!mode64);
4252 t1 = newTemp(Ity_I1);
4253 t2 = newTemp(Ity_I1);
4254 t3 = newTemp(Ity_I1);
4255 t4 = newTemp(Ity_I1);
4257 assign(t1, binop(Iop_CmpLT32U,
4258 unop(Iop_8Uto32,
4259 unop(Iop_16to8,
4260 unop(Iop_32to16,
4261 getIReg(rs)))),
4262 unop(Iop_8Uto32,
4263 unop(Iop_16to8,
4264 unop(Iop_32to16,
4265 getIReg(rt))))));
4266 putDSPControl(IRExpr_ITE(mkexpr(t1),
4267 binop(Iop_Or32,
4268 getDSPControl(),
4269 mkU32(0x01000000)),
4270 binop(Iop_And32,
4271 getDSPControl(),
4272 mkU32(0xfeffffff))));
4274 assign(t2, binop(Iop_CmpLT32U,
4275 unop(Iop_8Uto32,
4276 unop(Iop_16HIto8,
4277 unop(Iop_32to16,
4278 getIReg(rs)))),
4279 unop(Iop_8Uto32,
4280 unop(Iop_16HIto8,
4281 unop(Iop_32to16,
4282 getIReg(rt))))));
4283 putDSPControl(IRExpr_ITE(mkexpr(t2),
4284 binop(Iop_Or32,
4285 getDSPControl(),
4286 mkU32(0x02000000)),
4287 binop(Iop_And32,
4288 getDSPControl(),
4289 mkU32(0xfdffffff))));
4291 assign(t3, binop(Iop_CmpLT32U,
4292 unop(Iop_8Uto32,
4293 unop(Iop_16to8,
4294 unop(Iop_32HIto16,
4295 getIReg(rs)))),
4296 unop(Iop_8Uto32,
4297 unop(Iop_16to8,
4298 unop(Iop_32HIto16,
4299 getIReg(rt))))));
4300 putDSPControl(IRExpr_ITE(mkexpr(t3),
4301 binop(Iop_Or32,
4302 getDSPControl(),
4303 mkU32(0x04000000)),
4304 binop(Iop_And32,
4305 getDSPControl(),
4306 mkU32(0xfbffffff))));
4308 assign(t4, binop(Iop_CmpLT32U,
4309 unop(Iop_8Uto32,
4310 unop(Iop_16HIto8,
4311 unop(Iop_32HIto16,
4312 getIReg(rs)))),
4313 unop(Iop_8Uto32,
4314 unop(Iop_16HIto8,
4315 unop(Iop_32HIto16,
4316 getIReg(rt))))));
4317 putDSPControl(IRExpr_ITE(mkexpr(t4),
4318 binop(Iop_Or32,
4319 getDSPControl(),
4320 mkU32(0x08000000)),
4321 binop(Iop_And32,
4322 getDSPControl(),
4323 mkU32(0xf7ffffff))));
4324 break;
4327 case 0x2: { /* CMPU.LE.QB */
4328 DIP("cmpu.le.qb r%u, r%u", rs, rt);
4329 vassert(!mode64);
4330 t1 = newTemp(Ity_I1);
4331 t2 = newTemp(Ity_I1);
4332 t3 = newTemp(Ity_I1);
4333 t4 = newTemp(Ity_I1);
4335 assign(t1, binop(Iop_CmpLE32U,
4336 unop(Iop_8Uto32,
4337 unop(Iop_16to8,
4338 unop(Iop_32to16,
4339 getIReg(rs)))),
4340 unop(Iop_8Uto32,
4341 unop(Iop_16to8,
4342 unop(Iop_32to16,
4343 getIReg(rt))))));
4344 putDSPControl(IRExpr_ITE(mkexpr(t1),
4345 binop(Iop_Or32,
4346 getDSPControl(),
4347 mkU32(0x01000000)),
4348 binop(Iop_And32,
4349 getDSPControl(),
4350 mkU32(0xfeffffff))));
4352 assign(t2, binop(Iop_CmpLE32U,
4353 unop(Iop_8Uto32,
4354 unop(Iop_16HIto8,
4355 unop(Iop_32to16,
4356 getIReg(rs)))),
4357 unop(Iop_8Uto32,
4358 unop(Iop_16HIto8,
4359 unop(Iop_32to16,
4360 getIReg(rt))))));
4361 putDSPControl(IRExpr_ITE(mkexpr(t2),
4362 binop(Iop_Or32,
4363 getDSPControl(),
4364 mkU32(0x02000000)),
4365 binop(Iop_And32,
4366 getDSPControl(),
4367 mkU32(0xfdffffff))));
4369 assign(t3, binop(Iop_CmpLE32U,
4370 unop(Iop_8Uto32,
4371 unop(Iop_16to8,
4372 unop(Iop_32HIto16,
4373 getIReg(rs)))),
4374 unop(Iop_8Uto32,
4375 unop(Iop_16to8,
4376 unop(Iop_32HIto16,
4377 getIReg(rt))))));
4378 putDSPControl(IRExpr_ITE(mkexpr(t3),
4379 binop(Iop_Or32,
4380 getDSPControl(),
4381 mkU32(0x04000000)),
4382 binop(Iop_And32,
4383 getDSPControl(),
4384 mkU32(0xfbffffff))));
4386 assign(t4, binop(Iop_CmpLE32U,
4387 unop(Iop_8Uto32,
4388 unop(Iop_16HIto8,
4389 unop(Iop_32HIto16,
4390 getIReg(rs)))),
4391 unop(Iop_8Uto32,
4392 unop(Iop_16HIto8,
4393 unop(Iop_32HIto16,
4394 getIReg(rt))))));
4395 putDSPControl(IRExpr_ITE(mkexpr(t4),
4396 binop(Iop_Or32,
4397 getDSPControl(),
4398 mkU32(0x08000000)),
4399 binop(Iop_And32,
4400 getDSPControl(),
4401 mkU32(0xf7ffffff))));
4402 break;
4405 case 0x3: { /* PICK.QB */
4406 DIP("pick.qb r%u, r%u, r%u", rd, rs, rt);
4407 vassert(!mode64);
4408 t0 = newTemp(Ity_I32);
4409 t1 = newTemp(Ity_I8);
4410 t2 = newTemp(Ity_I8);
4411 t3 = newTemp(Ity_I8);
4412 t4 = newTemp(Ity_I8);
4414 assign(t0, getDSPControl());
4415 assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
4416 binop(Iop_And32,
4417 mkexpr(t0),
4418 mkU32(0x01000000)),
4419 mkU32(0x0)),
4420 unop(Iop_16to8,
4421 unop(Iop_32to16,
4422 getIReg(rs))),
4423 unop(Iop_16to8,
4424 unop(Iop_32to16,
4425 getIReg(rt)))));
4426 assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
4427 binop(Iop_And32,
4428 mkexpr(t0),
4429 mkU32(0x02000000)),
4430 mkU32(0x0)),
4431 unop(Iop_16HIto8,
4432 unop(Iop_32to16, getIReg(rs))),
4433 unop(Iop_16HIto8,
4434 unop(Iop_32to16,
4435 getIReg(rt)))));
4436 assign(t3, IRExpr_ITE(binop(Iop_CmpNE32,
4437 binop(Iop_And32,
4438 mkexpr(t0),
4439 mkU32(0x04000000)),
4440 mkU32(0x0)),
4441 unop(Iop_16to8,
4442 unop(Iop_32HIto16,
4443 getIReg(rs))),
4444 unop(Iop_16to8,
4445 unop(Iop_32HIto16,
4446 getIReg(rt)))));
4447 assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
4448 binop(Iop_And32,
4449 mkexpr(t0),
4450 mkU32(0x08000000)),
4451 mkU32(0x0)),
4452 unop(Iop_16HIto8,
4453 unop(Iop_32HIto16,
4454 getIReg(rs))),
4455 unop(Iop_16HIto8,
4456 unop(Iop_32HIto16,
4457 getIReg(rt)))));
4458 putIReg(rd,
4459 binop(Iop_16HLto32,
4460 binop(Iop_8HLto16, mkexpr(t4), mkexpr(t3)),
4461 binop(Iop_8HLto16, mkexpr(t2), mkexpr(t1))));
4462 break;
4465 case 0x4: { /* CMPGU.EQ.QB */
4466 DIP("cmpgu.eq.qb r%u, r%u, r%u", rd, rs, rt);
4467 vassert(!mode64);
4468 t1 = newTemp(Ity_I1);
4469 t2 = newTemp(Ity_I1);
4470 t3 = newTemp(Ity_I1);
4471 t4 = newTemp(Ity_I1);
4472 t5 = newTemp(Ity_I32);
4473 t6 = newTemp(Ity_I32);
4474 t7 = newTemp(Ity_I32);
4475 t8 = newTemp(Ity_I32);
4477 assign(t1, binop(Iop_CmpEQ32,
4478 unop(Iop_8Uto32,
4479 unop(Iop_16to8,
4480 unop(Iop_32to16, getIReg(rs)))),
4481 unop(Iop_8Uto32,
4482 unop(Iop_16to8,
4483 unop(Iop_32to16,
4484 getIReg(rt))))));
4485 assign(t5, IRExpr_ITE(mkexpr(t1),
4486 mkU32(0x00000001), mkU32(0)));
4488 assign(t2, binop(Iop_CmpEQ32,
4489 unop(Iop_8Uto32,
4490 unop(Iop_16HIto8,
4491 unop(Iop_32to16, getIReg(rs)))),
4492 unop(Iop_8Uto32,
4493 unop(Iop_16HIto8,
4494 unop(Iop_32to16,
4495 getIReg(rt))))));
4496 assign(t6, IRExpr_ITE(mkexpr(t2),
4497 mkU32(0x00000002), mkU32(0)));
4499 assign(t3, binop(Iop_CmpEQ32,
4500 unop(Iop_8Uto32,
4501 unop(Iop_16to8,
4502 unop(Iop_32HIto16,
4503 getIReg(rs)))),
4504 unop(Iop_8Uto32,
4505 unop(Iop_16to8,
4506 unop(Iop_32HIto16,
4507 getIReg(rt))))));
4508 assign(t7, IRExpr_ITE(mkexpr(t3),
4509 mkU32(0x00000004), mkU32(0)));
4511 assign(t4, binop(Iop_CmpEQ32,
4512 unop(Iop_8Uto32,
4513 unop(Iop_16HIto8,
4514 unop(Iop_32HIto16,
4515 getIReg(rs)))),
4516 unop(Iop_8Uto32,
4517 unop(Iop_16HIto8,
4518 unop(Iop_32HIto16,
4519 getIReg(rt))))));
4520 assign(t8, IRExpr_ITE(mkexpr(t4),
4521 mkU32(0x00000008), mkU32(0)));
4523 putIReg(rd, binop(Iop_Or32,
4524 binop(Iop_Or32,
4525 binop(Iop_Or32,
4526 mkexpr(t5), mkexpr(t6)),
4527 mkexpr(t7)),
4528 mkexpr(t8)));
4529 break;
4532 case 0x5: { /* CMPGU.LT.QB */
4533 DIP("cmpgu.lt.qb r%u, r%u, r%u", rd, rs, rt);
4534 vassert(!mode64);
4535 t1 = newTemp(Ity_I1);
4536 t2 = newTemp(Ity_I1);
4537 t3 = newTemp(Ity_I1);
4538 t4 = newTemp(Ity_I1);
4539 t5 = newTemp(Ity_I32);
4540 t6 = newTemp(Ity_I32);
4541 t7 = newTemp(Ity_I32);
4542 t8 = newTemp(Ity_I32);
4544 assign(t1, binop(Iop_CmpLT32U,
4545 unop(Iop_8Uto32,
4546 unop(Iop_16to8,
4547 unop(Iop_32to16, getIReg(rs)))),
4548 unop(Iop_8Uto32,
4549 unop(Iop_16to8,
4550 unop(Iop_32to16,
4551 getIReg(rt))))));
4552 assign(t5, IRExpr_ITE(mkexpr(t1),
4553 mkU32(0x00000001), mkU32(0)));
4555 assign(t2, binop(Iop_CmpLT32U,
4556 unop(Iop_8Uto32,
4557 unop(Iop_16HIto8,
4558 unop(Iop_32to16, getIReg(rs)))),
4559 unop(Iop_8Uto32,
4560 unop(Iop_16HIto8,
4561 unop(Iop_32to16,
4562 getIReg(rt))))));
4563 assign(t6, IRExpr_ITE(mkexpr(t2),
4564 mkU32(0x00000002), mkU32(0)));
4566 assign(t3, binop(Iop_CmpLT32U,
4567 unop(Iop_8Uto32,
4568 unop(Iop_16to8,
4569 unop(Iop_32HIto16,
4570 getIReg(rs)))),
4571 unop(Iop_8Uto32,
4572 unop(Iop_16to8,
4573 unop(Iop_32HIto16,
4574 getIReg(rt))))));
4575 assign(t7, IRExpr_ITE(mkexpr(t3),
4576 mkU32(0x00000004), mkU32(0)));
4578 assign(t4, binop(Iop_CmpLT32U,
4579 unop(Iop_8Uto32,
4580 unop(Iop_16HIto8,
4581 unop(Iop_32HIto16,
4582 getIReg(rs)))),
4583 unop(Iop_8Uto32,
4584 unop(Iop_16HIto8,
4585 unop(Iop_32HIto16,
4586 getIReg(rt))))));
4587 assign(t8, IRExpr_ITE(mkexpr(t4),
4588 mkU32(0x00000008), mkU32(0)));
4589 putIReg(rd, binop(Iop_Or32,
4590 binop(Iop_Or32,
4591 binop(Iop_Or32,
4592 mkexpr(t5), mkexpr(t6)),
4593 mkexpr(t7)),
4594 mkexpr(t8)));
4595 break;
4598 case 0x6: { /* CMPGU.LE.QB */
4599 DIP("cmpgu.le.qb r%u, r%u, r%u", rd, rs, rt);
4600 vassert(!mode64);
4601 t1 = newTemp(Ity_I1);
4602 t2 = newTemp(Ity_I1);
4603 t3 = newTemp(Ity_I1);
4604 t4 = newTemp(Ity_I1);
4605 t5 = newTemp(Ity_I32);
4606 t6 = newTemp(Ity_I32);
4607 t7 = newTemp(Ity_I32);
4608 t8 = newTemp(Ity_I32);
4610 assign(t1, binop(Iop_CmpLE32U,
4611 unop(Iop_8Uto32,
4612 unop(Iop_16to8,
4613 unop(Iop_32to16, getIReg(rs)))),
4614 unop(Iop_8Uto32,
4615 unop(Iop_16to8,
4616 unop(Iop_32to16,
4617 getIReg(rt))))));
4618 assign(t5, IRExpr_ITE(mkexpr(t1),
4619 mkU32(0x00000001), mkU32(0)));
4621 assign(t2, binop(Iop_CmpLE32U,
4622 unop(Iop_8Uto32,
4623 unop(Iop_16HIto8,
4624 unop(Iop_32to16, getIReg(rs)))),
4625 unop(Iop_8Uto32,
4626 unop(Iop_16HIto8,
4627 unop(Iop_32to16,
4628 getIReg(rt))))));
4629 assign(t6, IRExpr_ITE(mkexpr(t2),
4630 mkU32(0x00000002), mkU32(0)));
4632 assign(t3, binop(Iop_CmpLE32U,
4633 unop(Iop_8Uto32,
4634 unop(Iop_16to8,
4635 unop(Iop_32HIto16,
4636 getIReg(rs)))),
4637 unop(Iop_8Uto32,
4638 unop(Iop_16to8,
4639 unop(Iop_32HIto16,
4640 getIReg(rt))))));
4641 assign(t7, IRExpr_ITE(mkexpr(t3),
4642 mkU32(0x00000004), mkU32(0)));
4644 assign(t4, binop(Iop_CmpLE32U,
4645 unop(Iop_8Uto32,
4646 unop(Iop_16HIto8,
4647 unop(Iop_32HIto16,
4648 getIReg(rs)))),
4649 unop(Iop_8Uto32,
4650 unop(Iop_16HIto8,
4651 unop(Iop_32HIto16,
4652 getIReg(rt))))));
4653 assign(t8, IRExpr_ITE(mkexpr(t4),
4654 mkU32(0x00000008), mkU32(0)));
4655 putIReg(rd, binop(Iop_Or32,
4656 binop(Iop_Or32,
4657 binop(Iop_Or32,
4658 mkexpr(t5), mkexpr(t6)),
4659 mkexpr(t7)),
4660 mkexpr(t8)));
4661 break;
4664 case 0x8: { /* CMP.EQ.PH */
4665 DIP("cmp.eq.ph r%u, r%u", rs, rt);
4666 vassert(!mode64);
4667 t1 = newTemp(Ity_I1);
4668 t2 = newTemp(Ity_I1);
4670 assign(t1, binop(Iop_CmpEQ16,
4671 unop(Iop_32to16, getIReg(rs)),
4672 unop(Iop_32to16, getIReg(rt))));
4673 putDSPControl(IRExpr_ITE(mkexpr(t1),
4674 binop(Iop_Or32,
4675 getDSPControl(),
4676 mkU32(0x01000000)),
4677 binop(Iop_And32,
4678 getDSPControl(),
4679 mkU32(0xfeffffff))));
4680 assign(t2, binop(Iop_CmpEQ16,
4681 unop(Iop_32HIto16, getIReg(rs)),
4682 unop(Iop_32HIto16, getIReg(rt))));
4683 putDSPControl(IRExpr_ITE(mkexpr(t2),
4684 binop(Iop_Or32,
4685 getDSPControl(),
4686 mkU32(0x02000000)),
4687 binop(Iop_And32,
4688 getDSPControl(),
4689 mkU32(0xfdffffff))));
4690 break;
4693 case 0x9: { /* CMP.LT.PH */
4694 DIP("cmp.lt.ph r%u, r%u", rs, rt);
4695 vassert(!mode64);
4696 t1 = newTemp(Ity_I1);
4697 t2 = newTemp(Ity_I1);
4699 assign(t1, binop(Iop_CmpLT32S,
4700 unop(Iop_16Sto32,
4701 unop(Iop_32to16, getIReg(rs))),
4702 unop(Iop_16Sto32,
4703 unop(Iop_32to16, getIReg(rt)))));
4704 putDSPControl(IRExpr_ITE(mkexpr(t1),
4705 binop(Iop_Or32,
4706 getDSPControl(),
4707 mkU32(0x01000000)),
4708 binop(Iop_And32,
4709 getDSPControl(),
4710 mkU32(0xfeffffff))));
4712 assign(t2, binop(Iop_CmpLT32S,
4713 unop(Iop_16Sto32,
4714 unop(Iop_32HIto16, getIReg(rs))),
4715 unop(Iop_16Sto32,
4716 unop(Iop_32HIto16, getIReg(rt)))));
4717 putDSPControl(IRExpr_ITE(mkexpr(t2),
4718 binop(Iop_Or32,
4719 getDSPControl(),
4720 mkU32(0x02000000)),
4721 binop(Iop_And32,
4722 getDSPControl(),
4723 mkU32(0xfdffffff))));
4724 break;
4727 case 0xA: { /* CMP.LE.PH */
4728 DIP("cmp.le.ph r%u, r%u", rs, rt);
4729 vassert(!mode64);
4730 t1 = newTemp(Ity_I1);
4731 t2 = newTemp(Ity_I1);
4733 assign(t1, binop(Iop_CmpLE32S,
4734 unop(Iop_16Sto32,
4735 unop(Iop_32to16, getIReg(rs))),
4736 unop(Iop_16Sto32,
4737 unop(Iop_32to16, getIReg(rt)))));
4738 putDSPControl(IRExpr_ITE(mkexpr(t1),
4739 binop(Iop_Or32,
4740 getDSPControl(),
4741 mkU32(0x01000000)),
4742 binop(Iop_And32,
4743 getDSPControl(),
4744 mkU32(0xfeffffff))));
4746 assign(t2, binop(Iop_CmpLE32S,
4747 unop(Iop_16Sto32,
4748 unop(Iop_32HIto16, getIReg(rs))),
4749 unop(Iop_16Sto32,
4750 unop(Iop_32HIto16, getIReg(rt)))));
4751 putDSPControl(IRExpr_ITE(mkexpr(t2),
4752 binop(Iop_Or32,
4753 getDSPControl(),
4754 mkU32(0x02000000)),
4755 binop(Iop_And32,
4756 getDSPControl(),
4757 mkU32(0xfdffffff))));
4758 break;
4761 case 0xB: { /* PICK.PH */
4762 DIP("pick.qb r%u, r%u, r%u", rd, rs, rt);
4763 vassert(!mode64);
4764 t0 = newTemp(Ity_I32);
4765 t1 = newTemp(Ity_I16);
4766 t2 = newTemp(Ity_I16);
4768 assign(t0, getDSPControl());
4770 assign(t1, IRExpr_ITE(binop(Iop_CmpNE32,
4771 binop(Iop_And32,
4772 mkexpr(t0),
4773 mkU32(0x01000000)),
4774 mkU32(0x0)),
4775 unop(Iop_32to16, getIReg(rs)),
4776 unop(Iop_32to16, getIReg(rt))));
4778 assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
4779 binop(Iop_And32,
4780 mkexpr(t0),
4781 mkU32(0x02000000)),
4782 mkU32(0x0)),
4783 unop(Iop_32HIto16, getIReg(rs)),
4784 unop(Iop_32HIto16, getIReg(rt))));
4786 putIReg(rd, binop(Iop_16HLto32, mkexpr(t2), mkexpr(t1)));
4787 break;
4790 case 0xC: { /* PRECRQ.QB.PH */
4791 DIP("precrq.qb.ph r%u, r%u, %u", rd, rs, rt);
4792 vassert(!mode64);
4793 putIReg(rd,
4794 binop(Iop_16HLto32,
4795 binop(Iop_8HLto16,
4796 unop(Iop_16HIto8,
4797 unop(Iop_32HIto16, getIReg(rs))),
4798 unop(Iop_16HIto8,
4799 unop(Iop_32to16, getIReg(rs)))),
4800 binop(Iop_8HLto16,
4801 unop(Iop_16HIto8,
4802 unop(Iop_32HIto16, getIReg(rt))),
4803 unop(Iop_16HIto8,
4804 unop(Iop_32to16, getIReg(rt))))));
4805 break;
4808 case 0xD: { /* PRECR.QB.PH */
4809 DIP("precr.qb.ph r%u, r%u, r%u", rd, rs, rt);
4810 vassert(!mode64);
4812 putIReg(rd,
4813 binop(Iop_16HLto32,
4814 binop(Iop_8HLto16,
4815 unop(Iop_16to8,
4816 unop(Iop_32HIto16, getIReg(rs))),
4817 unop(Iop_16to8,
4818 unop(Iop_32to16, getIReg(rs)))),
4819 binop(Iop_8HLto16,
4820 unop(Iop_16to8,
4821 unop(Iop_32HIto16, getIReg(rt))),
4822 unop(Iop_16to8,
4823 unop(Iop_32to16, getIReg(rt))))));
4824 break;
4827 case 0xF: { /* PRECRQU_S.QB.PH */
4828 DIP("precrqu_s.qb.ph r%u, r%u, %u", rd, rs, rt);
4829 vassert(!mode64);
4830 t0 = newTemp(Ity_I8);
4831 t1 = newTemp(Ity_I8);
4832 t2 = newTemp(Ity_I8);
4833 t3 = newTemp(Ity_I8);
4834 t4 = newTemp(Ity_I8);
4835 t5 = newTemp(Ity_I32);
4836 t6 = newTemp(Ity_I1);
4837 t7 = newTemp(Ity_I8);
4838 t8 = newTemp(Ity_I1);
4839 t9 = newTemp(Ity_I32);
4840 t10 = newTemp(Ity_I8);
4841 t11 = newTemp(Ity_I1);
4842 t12 = newTemp(Ity_I32);
4843 t13 = newTemp(Ity_I8);
4844 t14 = newTemp(Ity_I1);
4845 t15 = newTemp(Ity_I32);
4847 assign(t4, IRExpr_ITE(binop(Iop_CmpLT32U,
4848 mkU32(0x7f80),
4849 binop(Iop_And32,
4850 unop(Iop_16Uto32,
4851 unop(Iop_32to16,
4852 getIReg(rs))),
4853 mkU32(0x7fff))),
4854 mkU8(0xff),
4855 unop(Iop_16HIto8,
4856 unop(Iop_32to16,
4857 binop(Iop_Shl32,
4858 getIReg(rs),
4859 mkU8(1))))));
4860 assign(t0, IRExpr_ITE(binop(Iop_CmpEQ32,
4861 binop(Iop_And32,
4862 unop(Iop_16Uto32,
4863 unop(Iop_32to16,
4864 getIReg(rs))),
4865 mkU32(0x00008000)),
4866 mkU32(0x0)),
4867 mkexpr(t4),
4868 mkU8(0x0)));
4869 assign(t5, binop(Iop_And32,
4870 unop(Iop_16Uto32,
4871 unop(Iop_32to16,
4872 getIReg(rs))),
4873 mkU32(0x00008000)));
4874 assign(t6, binop(Iop_CmpLT32U,
4875 mkU32(0x7f80),
4876 binop(Iop_And32,
4877 unop(Iop_16Uto32,
4878 unop(Iop_32to16,
4879 getIReg(rs))),
4880 mkU32(0x7fff))));
4881 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
4882 mkexpr(t5),
4883 mkU32(0x0)),
4884 IRExpr_ITE(mkexpr(t6),
4885 binop(Iop_Or32,
4886 getDSPControl(),
4887 mkU32(0x00400000)
4889 getDSPControl()),
4890 binop(Iop_Or32,
4891 getDSPControl(),
4892 mkU32(0x00400000))));
4894 assign(t7, IRExpr_ITE(binop(Iop_CmpLT32U,
4895 mkU32(0x7f80),
4896 binop(Iop_And32,
4897 unop(Iop_16Uto32,
4898 unop(Iop_32HIto16,
4899 getIReg(rs))),
4900 mkU32(0x7fff))),
4901 mkU8(0xff),
4902 unop(Iop_16HIto8,
4903 unop(Iop_32HIto16,
4904 binop(Iop_Shl32,
4905 getIReg(rs),
4906 mkU8(1))))));
4907 assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
4908 binop(Iop_And32,
4909 unop(Iop_16Uto32,
4910 unop(Iop_32HIto16,
4911 getIReg(rs))),
4912 mkU32(0x00008000)),
4913 mkU32(0x0)),
4914 mkexpr(t7),
4915 mkU8(0x0)));
4916 assign(t8, binop(Iop_CmpEQ32,
4917 binop(Iop_And32,
4918 unop(Iop_16Uto32,
4919 unop(Iop_32HIto16,
4920 getIReg(rs))),
4921 mkU32(0x00008000)),
4922 mkU32(0x0)));
4923 assign(t9, IRExpr_ITE(binop(Iop_CmpLT32U,
4924 mkU32(0x7f80),
4925 binop(Iop_And32,
4926 unop(Iop_16Uto32,
4927 unop(Iop_32HIto16,
4928 getIReg(rs))),
4929 mkU32(0x7fff))),
4930 binop(Iop_Or32,
4931 getDSPControl(),
4932 mkU32(0x00400000)),
4933 getDSPControl()));
4934 putDSPControl(IRExpr_ITE(mkexpr(t8),
4935 mkexpr(t9),
4936 binop(Iop_Or32,
4937 getDSPControl(),
4938 mkU32(0x00400000))));
4940 assign(t10, IRExpr_ITE(binop(Iop_CmpLT32U,
4941 mkU32(0x7f80),
4942 binop(Iop_And32,
4943 unop(Iop_16Uto32,
4944 unop(Iop_32to16,
4945 getIReg(rt))),
4946 mkU32(0x7fff))),
4947 mkU8(0xff),
4948 unop(Iop_16HIto8,
4949 unop(Iop_32to16,
4950 binop(Iop_Shl32,
4951 getIReg(rt),
4952 mkU8(1))))));
4953 assign(t2, IRExpr_ITE(binop(Iop_CmpEQ32,
4954 binop(Iop_And32,
4955 unop(Iop_16Uto32,
4956 unop(Iop_32to16,
4957 getIReg(rt))),
4958 mkU32(0x00008000)),
4959 mkU32(0x0)),
4960 mkexpr(t10),
4961 mkU8(0x0)));
4962 assign(t11, binop(Iop_CmpEQ32,
4963 binop(Iop_And32,
4964 unop(Iop_16Uto32,
4965 unop(Iop_32to16,
4966 getIReg(rt))),
4967 mkU32(0x00008000)),
4968 mkU32(0x0)));
4969 assign(t12, IRExpr_ITE(binop(Iop_CmpLT32U,
4970 mkU32(0x7f80),
4971 binop(Iop_And32,
4972 unop(Iop_16Uto32,
4973 unop(Iop_32to16,
4974 getIReg(rt))),
4975 mkU32(0x7fff))),
4976 binop(Iop_Or32,
4977 getDSPControl(),
4978 mkU32(0x00400000)),
4979 getDSPControl()));
4980 putDSPControl(IRExpr_ITE(mkexpr(t11),
4981 mkexpr(t12),
4982 binop(Iop_Or32,
4983 getDSPControl(),
4984 mkU32(0x00400000))));
4986 assign(t13, IRExpr_ITE(binop(Iop_CmpLT32U,
4987 mkU32(0x7f80),
4988 binop(Iop_And32,
4989 unop(Iop_16Uto32,
4990 unop(Iop_32HIto16,
4991 getIReg(rt))),
4992 mkU32(0x7fff))),
4993 mkU8(0xff),
4994 unop(Iop_16HIto8,
4995 unop(Iop_32HIto16,
4996 binop(Iop_Shl32,
4997 getIReg(rt),
4998 mkU8(1))))));
4999 assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
5000 binop(Iop_And32,
5001 unop(Iop_16Uto32,
5002 unop(Iop_32HIto16,
5003 getIReg(rt))),
5004 mkU32(0x00008000)),
5005 mkU32(0x0)),
5006 mkexpr(t13),
5007 mkU8(0x0)));
5008 assign(t14, binop(Iop_CmpEQ32,
5009 binop(Iop_And32,
5010 unop(Iop_16Uto32,
5011 unop(Iop_32HIto16,
5012 getIReg(rt))),
5013 mkU32(0x00008000)),
5014 mkU32(0x0)));
5015 assign(t15, IRExpr_ITE(binop(Iop_CmpLT32U,
5016 mkU32(0x7f80),
5017 binop(Iop_And32,
5018 unop(Iop_16Uto32,
5019 unop(Iop_32HIto16,
5020 getIReg(rt))),
5021 mkU32(0x7fff))),
5022 binop(Iop_Or32,
5023 getDSPControl(),
5024 mkU32(0x00400000)),
5025 getDSPControl()));
5026 putDSPControl(IRExpr_ITE(mkexpr(t14),
5027 mkexpr(t15),
5028 binop(Iop_Or32,
5029 getDSPControl(),
5030 mkU32(0x00400000))));
5032 putIReg(rd, binop(Iop_16HLto32,
5033 binop(Iop_8HLto16,
5034 mkexpr(t1), mkexpr(t0)),
5035 binop(Iop_8HLto16,
5036 mkexpr(t3), mkexpr(t2))));
5037 break;
5040 case 0x14: { /* PRECRQ.PH.W */
5041 DIP("precrq.ph.w r%u, r%u, %u", rd, rs, rt);
5042 vassert(!mode64);
5043 putIReg(rd, binop(Iop_16HLto32,
5044 unop(Iop_32HIto16, getIReg(rs)),
5045 unop(Iop_32HIto16, getIReg(rt))));
5046 break;
5049 case 0x15: { /* PRECRQ_RS.PH.W */
5050 DIP("precrq_rs.ph.w r%u, r%u, %u", rd, rs, rt);
5051 vassert(!mode64);
5052 t0 = newTemp(Ity_I64);
5053 t1 = newTemp(Ity_I1);
5054 t2 = newTemp(Ity_I32);
5055 t3 = newTemp(Ity_I64);
5056 t4 = newTemp(Ity_I1);
5057 t5 = newTemp(Ity_I32);
5059 assign(t0, binop(Iop_Add64,
5060 binop(Iop_32HLto64,
5061 binop(Iop_Shr32,
5062 binop(Iop_And32,
5063 getIReg(rs),
5064 mkU32(0x80000000)),
5065 mkU8(31)),
5066 getIReg(rs)),
5067 mkU64(0x0000000000008000ULL)));
5068 assign(t1, binop(Iop_CmpNE32,
5069 binop(Iop_And32,
5070 unop(Iop_64HIto32, mkexpr(t0)),
5071 mkU32(0x1)),
5072 binop(Iop_And32,
5073 binop(Iop_Shr32,
5074 unop(Iop_64to32, mkexpr(t0)),
5075 mkU8(31)),
5076 mkU32(0x1))));
5077 assign(t2, IRExpr_ITE(mkexpr(t1),
5078 mkU32(0x7fffffff),
5079 unop(Iop_64to32, mkexpr(t0))));
5080 putDSPControl(IRExpr_ITE(mkexpr(t1),
5081 binop(Iop_Or32,
5082 getDSPControl(),
5083 mkU32(0x400000)),
5084 getDSPControl()));
5085 assign(t3, binop(Iop_Add64,
5086 binop(Iop_32HLto64,
5087 binop(Iop_Shr32,
5088 binop(Iop_And32,
5089 getIReg(rt),
5090 mkU32(0x80000000)),
5091 mkU8(31)),
5092 getIReg(rt)),
5093 mkU64(0x0000000000008000ULL)));
5094 assign(t4, binop(Iop_CmpNE32,
5095 binop(Iop_And32,
5096 unop(Iop_64HIto32, mkexpr(t3)),
5097 mkU32(0x1)),
5098 binop(Iop_And32,
5099 binop(Iop_Shr32,
5100 unop(Iop_64to32, mkexpr(t3)),
5101 mkU8(31)),
5102 mkU32(0x1))));
5103 assign(t5, IRExpr_ITE(mkexpr(t4),
5104 mkU32(0x7fffffff),
5105 unop(Iop_64to32, mkexpr(t3))));
5106 putDSPControl(IRExpr_ITE(mkexpr(t4),
5107 binop(Iop_Or32,
5108 getDSPControl(),
5109 mkU32(0x400000)),
5110 getDSPControl()));
5111 putIReg(rd, binop(Iop_16HLto32,
5112 unop(Iop_32HIto16, mkexpr(t2)),
5113 unop(Iop_32HIto16, mkexpr(t5))));
5114 break;
5117 case 0x1E: { /* PRECR_SRA.PH.W */
5118 DIP("precr_sra.ph.w r%u, r%u, %u", rt, rs, rd);
5119 vassert(!mode64);
5121 if (0 == rd) {
5122 putIReg(rt, binop(Iop_16HLto32,
5123 unop(Iop_32to16, getIReg(rt)),
5124 unop(Iop_32to16, getIReg(rs))));
5125 } else {
5126 putIReg(rt, binop(Iop_16HLto32,
5127 unop(Iop_32to16, binop(Iop_Sar32,
5128 getIReg(rt),
5129 mkU8(rd))),
5130 unop(Iop_32to16, binop(Iop_Sar32,
5131 getIReg(rs),
5132 mkU8(rd)))));
5135 break;
5138 case 0x1F: { /* PRECR_SRA_R.PH.W */
5139 DIP("precr_sra_r.ph.w r%u, r%u, %u", rt, rs, rd);
5140 vassert(!mode64);
5142 t0 = newTemp(Ity_I32);
5143 t1 = newTemp(Ity_I32);
5145 if (0 == rd) {
5146 putIReg(rt, binop(Iop_16HLto32,
5147 unop(Iop_32to16, getIReg(rt)),
5148 unop(Iop_32to16, getIReg(rs))));
5149 } else {
5150 assign(t0, binop(Iop_Shr32,
5151 binop(Iop_Add32,
5152 binop(Iop_Sar32,
5153 getIReg(rt),
5154 mkU8(rd - 1)),
5155 mkU32(0x1)),
5156 mkU8(0x1)));
5157 assign(t1, binop(Iop_Shr32,
5158 binop(Iop_Add32,
5159 binop(Iop_Sar32,
5160 getIReg(rs),
5161 mkU8(rd - 1)),
5162 mkU32(0x1)),
5163 mkU8(0x1)));
5164 putIReg(rt, binop(Iop_16HLto32,
5165 unop(Iop_32to16, mkexpr(t0)),
5166 unop(Iop_32to16, mkexpr(t1))));
5169 break;
5172 case 0xE: { /* PACKRL.PH */
5173 DIP("packrl.ph r%u, r%u, r%u", rd, rs, rt);
5174 vassert(!mode64);
5176 putIReg(rd, binop(Iop_16HLto32,
5177 unop(Iop_32to16, getIReg(rs)),
5178 unop(Iop_32HIto16, getIReg(rt))));
5179 break;
5182 case 0x18: { /* CMPGDU.EQ.QB */
5183 DIP("cmpgdu.eq.qb r%u, r%u, r%u", rd, rs, rt);
5184 vassert(!mode64);
5185 t1 = newTemp(Ity_I1);
5186 t2 = newTemp(Ity_I1);
5187 t3 = newTemp(Ity_I1);
5188 t4 = newTemp(Ity_I1);
5189 t5 = newTemp(Ity_I32);
5190 t6 = newTemp(Ity_I32);
5191 t7 = newTemp(Ity_I32);
5192 t8 = newTemp(Ity_I32);
5194 assign(t1,
5195 binop(Iop_CmpEQ32,
5196 unop(Iop_8Uto32,
5197 unop(Iop_16to8,
5198 unop(Iop_32to16, getIReg(rs)))),
5199 unop(Iop_8Uto32,
5200 unop(Iop_16to8,
5201 unop(Iop_32to16, getIReg(rt))))));
5202 assign(t5, IRExpr_ITE(mkexpr(t1),
5203 mkU32(0x00000001), mkU32(0)));
5204 putDSPControl(IRExpr_ITE(mkexpr(t1),
5205 binop(Iop_Or32,
5206 getDSPControl(),
5207 mkU32(0x01000000)),
5208 binop(Iop_And32,
5209 getDSPControl(),
5210 mkU32(0xfeffffff))));
5212 assign(t2, binop(Iop_CmpEQ32,
5213 unop(Iop_8Uto32,
5214 unop(Iop_16HIto8,
5215 unop(Iop_32to16, getIReg(rs)))),
5216 unop(Iop_8Uto32,
5217 unop(Iop_16HIto8,
5218 unop(Iop_32to16,
5219 getIReg(rt))))));
5220 assign(t6, IRExpr_ITE(mkexpr(t2),
5221 mkU32(0x00000002), mkU32(0)));
5222 putDSPControl(IRExpr_ITE(mkexpr(t2),
5223 binop(Iop_Or32,
5224 getDSPControl(),
5225 mkU32(0x02000000)),
5226 binop(Iop_And32,
5227 getDSPControl(),
5228 mkU32(0xfdffffff))));
5230 assign(t3, binop(Iop_CmpEQ32,
5231 unop(Iop_8Uto32,
5232 unop(Iop_16to8,
5233 unop(Iop_32HIto16,
5234 getIReg(rs)))),
5235 unop(Iop_8Uto32,
5236 unop(Iop_16to8,
5237 unop(Iop_32HIto16,
5238 getIReg(rt))))));
5239 assign(t7, IRExpr_ITE(mkexpr(t3),
5240 mkU32(0x00000004), mkU32(0)));
5241 putDSPControl(IRExpr_ITE(mkexpr(t3),
5242 binop(Iop_Or32,
5243 getDSPControl(),
5244 mkU32(0x04000000)),
5245 binop(Iop_And32,
5246 getDSPControl(),
5247 mkU32(0xfbffffff))));
5249 assign(t4, binop(Iop_CmpEQ32,
5250 unop(Iop_8Uto32,
5251 unop(Iop_16HIto8,
5252 unop(Iop_32HIto16,
5253 getIReg(rs)))),
5254 unop(Iop_8Uto32,
5255 unop(Iop_16HIto8,
5256 unop(Iop_32HIto16,
5257 getIReg(rt))))));
5258 assign(t8, IRExpr_ITE(mkexpr(t4),
5259 mkU32(0x00000008), mkU32(0)));
5260 putDSPControl(IRExpr_ITE(mkexpr(t4),
5261 binop(Iop_Or32,
5262 getDSPControl(),
5263 mkU32(0x08000000)),
5264 binop(Iop_And32,
5265 getDSPControl(),
5266 mkU32(0xf7ffffff))));
5268 putIReg(rd, binop(Iop_Or32,
5269 binop(Iop_Or32,
5270 binop(Iop_Or32,
5271 mkexpr(t5), mkexpr(t6)),
5272 mkexpr(t7)),
5273 mkexpr(t8)));
5274 break;
5277 case 0x19: { /* CMPGDU.LT.QB */
5278 DIP("cmpgdu.lt.qb r%u, r%u, r%u", rd, rs, rt);
5279 vassert(!mode64);
5280 t1 = newTemp(Ity_I1);
5281 t2 = newTemp(Ity_I1);
5282 t3 = newTemp(Ity_I1);
5283 t4 = newTemp(Ity_I1);
5284 t5 = newTemp(Ity_I32);
5285 t6 = newTemp(Ity_I32);
5286 t7 = newTemp(Ity_I32);
5287 t8 = newTemp(Ity_I32);
5289 assign(t1, binop(Iop_CmpLT32U,
5290 unop(Iop_8Uto32,
5291 unop(Iop_16to8,
5292 unop(Iop_32to16, getIReg(rs)))),
5293 unop(Iop_8Uto32,
5294 unop(Iop_16to8,
5295 unop(Iop_32to16,
5296 getIReg(rt))))));
5297 assign(t5, IRExpr_ITE(mkexpr(t1),
5298 mkU32(0x00000001), mkU32(0)));
5299 putDSPControl(IRExpr_ITE(mkexpr(t1),
5300 binop(Iop_Or32,
5301 getDSPControl(),
5302 mkU32(0x01000000)),
5303 binop(Iop_And32,
5304 getDSPControl(),
5305 mkU32(0xfeffffff))));
5307 assign(t2, binop(Iop_CmpLT32U,
5308 unop(Iop_8Uto32,
5309 unop(Iop_16HIto8,
5310 unop(Iop_32to16, getIReg(rs)))),
5311 unop(Iop_8Uto32,
5312 unop(Iop_16HIto8,
5313 unop(Iop_32to16,
5314 getIReg(rt))))));
5315 assign(t6, IRExpr_ITE(mkexpr(t2),
5316 mkU32(0x00000002), mkU32(0)));
5317 putDSPControl(IRExpr_ITE(mkexpr(t2),
5318 binop(Iop_Or32,
5319 getDSPControl(),
5320 mkU32(0x02000000)),
5321 binop(Iop_And32,
5322 getDSPControl(),
5323 mkU32(0xfdffffff))));
5325 assign(t3, binop(Iop_CmpLT32U,
5326 unop(Iop_8Uto32,
5327 unop(Iop_16to8,
5328 unop(Iop_32HIto16,
5329 getIReg(rs)))),
5330 unop(Iop_8Uto32,
5331 unop(Iop_16to8,
5332 unop(Iop_32HIto16,
5333 getIReg(rt))))));
5334 assign(t7, IRExpr_ITE(mkexpr(t3),
5335 mkU32(0x00000004), mkU32(0)));
5336 putDSPControl(IRExpr_ITE(mkexpr(t3),
5337 binop(Iop_Or32,
5338 getDSPControl(),
5339 mkU32(0x04000000)),
5340 binop(Iop_And32,
5341 getDSPControl(),
5342 mkU32(0xfbffffff))));
5344 assign(t4, binop(Iop_CmpLT32U,
5345 unop(Iop_8Uto32,
5346 unop(Iop_16HIto8,
5347 unop(Iop_32HIto16,
5348 getIReg(rs)))),
5349 unop(Iop_8Uto32,
5350 unop(Iop_16HIto8,
5351 unop(Iop_32HIto16,
5352 getIReg(rt))))));
5353 assign(t8, IRExpr_ITE(mkexpr(t4),
5354 mkU32(0x00000008), mkU32(0)));
5355 putDSPControl(IRExpr_ITE(mkexpr(t4),
5356 binop(Iop_Or32,
5357 getDSPControl(),
5358 mkU32(0x08000000)),
5359 binop(Iop_And32,
5360 getDSPControl(),
5361 mkU32(0xf7ffffff))));
5363 putIReg(rd, binop(Iop_Or32,
5364 binop(Iop_Or32,
5365 binop(Iop_Or32,
5366 mkexpr(t5), mkexpr(t6)),
5367 mkexpr(t7)),
5368 mkexpr(t8)));
5369 break;
5372 case 0x1A: { /* CMPGDU.LE.QB */
5373 DIP("cmpgdu.le.qb r%u, r%u, r%u", rd, rs, rt);
5374 vassert(!mode64);
5375 t1 = newTemp(Ity_I1);
5376 t2 = newTemp(Ity_I1);
5377 t3 = newTemp(Ity_I1);
5378 t4 = newTemp(Ity_I1);
5379 t5 = newTemp(Ity_I32);
5380 t6 = newTemp(Ity_I32);
5381 t7 = newTemp(Ity_I32);
5382 t8 = newTemp(Ity_I32);
5384 assign(t1, binop(Iop_CmpLE32U,
5385 unop(Iop_8Uto32,
5386 unop(Iop_16to8,
5387 unop(Iop_32to16, getIReg(rs)))),
5388 unop(Iop_8Uto32,
5389 unop(Iop_16to8,
5390 unop(Iop_32to16,
5391 getIReg(rt))))));
5392 assign(t5, IRExpr_ITE(mkexpr(t1),
5393 mkU32(0x00000001),
5394 mkU32(0)));
5395 putDSPControl(IRExpr_ITE(mkexpr(t1),
5396 binop(Iop_Or32,
5397 getDSPControl(),
5398 mkU32(0x01000000)),
5399 binop(Iop_And32,
5400 getDSPControl(),
5401 mkU32(0xfeffffff))));
5403 assign(t2, binop(Iop_CmpLE32U,
5404 unop(Iop_8Uto32,
5405 unop(Iop_16HIto8,
5406 unop(Iop_32to16, getIReg(rs)))),
5407 unop(Iop_8Uto32,
5408 unop(Iop_16HIto8,
5409 unop(Iop_32to16,
5410 getIReg(rt))))));
5411 assign(t6, IRExpr_ITE(mkexpr(t2),
5412 mkU32(0x00000002), mkU32(0)));
5413 putDSPControl(IRExpr_ITE(mkexpr(t2),
5414 binop(Iop_Or32,
5415 getDSPControl(),
5416 mkU32(0x02000000)),
5417 binop(Iop_And32,
5418 getDSPControl(),
5419 mkU32(0xfdffffff))));
5421 assign(t3, binop(Iop_CmpLE32U,
5422 unop(Iop_8Uto32,
5423 unop(Iop_16to8,
5424 unop(Iop_32HIto16,
5425 getIReg(rs)))),
5426 unop(Iop_8Uto32,
5427 unop(Iop_16to8,
5428 unop(Iop_32HIto16,
5429 getIReg(rt))))));
5430 assign(t7, IRExpr_ITE(mkexpr(t3),
5431 mkU32(0x00000004), mkU32(0)));
5432 putDSPControl(IRExpr_ITE(mkexpr(t3),
5433 binop(Iop_Or32,
5434 getDSPControl(),
5435 mkU32(0x04000000)),
5436 binop(Iop_And32,
5437 getDSPControl(),
5438 mkU32(0xfbffffff))));
5440 assign(t4, binop(Iop_CmpLE32U,
5441 unop(Iop_8Uto32,
5442 unop(Iop_16HIto8,
5443 unop(Iop_32HIto16,
5444 getIReg(rs)))),
5445 unop(Iop_8Uto32,
5446 unop(Iop_16HIto8,
5447 unop(Iop_32HIto16,
5448 getIReg(rt))))));
5449 assign(t8, IRExpr_ITE(mkexpr(t4),
5450 mkU32(0x00000008), mkU32(0)));
5451 putDSPControl(IRExpr_ITE(mkexpr(t4),
5452 binop(Iop_Or32,
5453 getDSPControl(),
5454 mkU32(0x08000000)),
5455 binop(Iop_And32,
5456 getDSPControl(),
5457 mkU32(0xf7ffffff))));
5459 putIReg(rd, binop(Iop_Or32,
5460 binop(Iop_Or32,
5461 binop(Iop_Or32,
5462 mkexpr(t5), mkexpr(t6)),
5463 mkexpr(t7)),
5464 mkexpr(t8)));
5465 break;
5468 default:
5469 return -1;
5472 return 0;
5475 static UInt disDSPInstr_MIPS_WRK_Special3_SHLL_QB( UInt cins )
5477 IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
5478 t15, t16, t17;
5479 UInt rs, rt, rd, sa;
5482 rs = get_rs(cins);
5483 rt = get_rt(cins);
5484 rd = get_rd(cins);
5485 sa = get_sa(cins);
5487 switch (sa) {
5488 case 0x0: { /* SHLL.QB */
5489 DIP("shll.qb r%u, r%u, %u", rd, rt, rs);
5490 vassert(!mode64);
5491 t0 = newTemp(Ity_I32);
5492 t1 = newTemp(Ity_I1);
5493 t2 = newTemp(Ity_I1);
5494 t3 = newTemp(Ity_I32);
5495 t4 = newTemp(Ity_I1);
5496 t5 = newTemp(Ity_I1);
5497 t6 = newTemp(Ity_I32);
5498 t7 = newTemp(Ity_I1);
5499 t8 = newTemp(Ity_I1);
5500 t9 = newTemp(Ity_I1);
5501 t10 = newTemp(Ity_I1);
5503 if (0 == rs) {
5504 putIReg(rd, getIReg(rt));
5505 } else {
5506 /* Shift bits 7..0 and 23..16. */
5507 assign(t0, binop(Iop_Shl32,
5508 binop(Iop_And32,
5509 getIReg(rt),
5510 mkU32(0x00ff00ff)),
5511 mkU8(rs)));
5512 assign(t1, binop(Iop_CmpNE32,
5513 binop(Iop_And32,
5514 mkexpr(t0),
5515 mkU32(0xff000000)),
5516 mkU32(0x00000000)));
5517 assign(t2, binop(Iop_CmpNE32,
5518 binop(Iop_And32,
5519 mkexpr(t0),
5520 mkU32(0xff000000)),
5521 mkU32(0xff000000)));
5522 assign(t7, binop(Iop_CmpNE32,
5523 binop(Iop_And32,
5524 mkexpr(t0),
5525 mkU32(0x0000ff00)),
5526 mkU32(0x00000000)));
5527 assign(t8, binop(Iop_CmpNE32,
5528 binop(Iop_And32,
5529 mkexpr(t0),
5530 mkU32(0x0000ff00)),
5531 mkU32(0x000ff00)));
5532 /* Shift bits 15..8 and 31..24. */
5533 assign(t3, binop(Iop_Shl32,
5534 binop(Iop_Shr32,
5535 binop(Iop_And32,
5536 getIReg(rt),
5537 mkU32(0xff00ff00)),
5538 mkU8(8)),
5539 mkU8(rs)));
5540 assign(t4, binop(Iop_CmpNE32,
5541 binop(Iop_And32,
5542 mkexpr(t3),
5543 mkU32(0xff000000)),
5544 mkU32(0x00000000)));
5545 assign(t5, binop(Iop_CmpNE32,
5546 binop(Iop_And32,
5547 mkexpr(t3),
5548 mkU32(0xff000000)),
5549 mkU32(0xff000000)));
5550 assign(t9, binop(Iop_CmpNE32,
5551 binop(Iop_And32,
5552 mkexpr(t3),
5553 mkU32(0x0000ff00)),
5554 mkU32(0x00000000)));
5555 assign(t10, binop(Iop_CmpNE32,
5556 binop(Iop_And32,
5557 mkexpr(t3),
5558 mkU32(0x0000ff00)),
5559 mkU32(0x0000ff00)));
5561 assign(t6, binop(Iop_Or32,
5562 binop(Iop_Or32,
5563 binop(Iop_And32,
5564 unop(Iop_1Uto32,
5565 mkexpr(t1)),
5566 unop(Iop_1Uto32,
5567 mkexpr(t2))),
5568 binop(Iop_And32,
5569 unop(Iop_1Uto32,
5570 mkexpr(t7)),
5571 unop(Iop_1Uto32,
5572 mkexpr(t8)))),
5573 binop(Iop_Or32,
5574 binop(Iop_And32,
5575 unop(Iop_1Uto32,
5576 mkexpr(t4)),
5577 unop(Iop_1Uto32,
5578 mkexpr(t5))),
5579 binop(Iop_And32,
5580 unop(Iop_1Uto32,
5581 mkexpr(t9)),
5582 unop(Iop_1Uto32,
5583 mkexpr(t10))))));
5585 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
5586 mkexpr(t6),
5587 mkU32(0x0)),
5588 binop(Iop_Or32,
5589 getDSPControl(),
5590 mkU32(0x400000)),
5591 getDSPControl()));
5592 putIReg(rd, binop(Iop_Or32,
5593 binop(Iop_Shl32,
5594 binop(Iop_And32,
5595 mkexpr(t3),
5596 mkU32(0x00ff00ff)),
5597 mkU8(8)),
5598 binop(Iop_And32,
5599 mkexpr(t0),
5600 mkU32(0x00ff00ff))));
5603 break;
5606 case 0x3: { /* SHRL.QB */
5607 DIP("shrl.qb r%u, r%u, %u", rd, rt, rs);
5608 vassert(!mode64);
5609 t0 = newTemp(Ity_I32);
5610 t1 = newTemp(Ity_I8);
5611 t2 = newTemp(Ity_I32);
5612 t3 = newTemp(Ity_I8);
5613 t4 = newTemp(Ity_I32);
5614 t5 = newTemp(Ity_I8);
5615 t6 = newTemp(Ity_I32);
5616 t7 = newTemp(Ity_I8);
5617 t9 = newTemp(Ity_I32);
5619 assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
5620 assign(t0, unop(Iop_8Uto32,
5621 unop(Iop_16to8,
5622 unop(Iop_32to16, getIReg(rt)))));
5623 assign(t1, unop(Iop_32to8,
5624 binop(Iop_Shr32,
5625 mkexpr(t0),
5626 unop(Iop_32to8, mkexpr(t9)))));
5628 assign(t2, unop(Iop_8Uto32,
5629 unop(Iop_16HIto8,
5630 unop(Iop_32to16, getIReg(rt)))));
5631 assign(t3, unop(Iop_32to8,
5632 binop(Iop_Shr32,
5633 mkexpr(t2),
5634 unop(Iop_32to8, mkexpr(t9)))));
5636 assign(t4, unop(Iop_8Uto32,
5637 unop(Iop_16to8,
5638 unop(Iop_32HIto16, getIReg(rt)))));
5639 assign(t5, unop(Iop_32to8,
5640 binop(Iop_Shr32,
5641 mkexpr(t4),
5642 unop(Iop_32to8, mkexpr(t9)))));
5644 assign(t6, unop(Iop_8Uto32,
5645 unop(Iop_16HIto8,
5646 unop(Iop_32HIto16, getIReg(rt)))));
5647 assign(t7, unop(Iop_32to8,
5648 binop(Iop_Shr32,
5649 mkexpr(t6),
5650 unop(Iop_32to8, mkexpr(t9)))));
5651 putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
5652 mkexpr(t9),
5653 mkU32(0x0)),
5654 getIReg(rt),
5655 binop(Iop_16HLto32,
5656 binop(Iop_8HLto16,
5657 mkexpr(t7),
5658 mkexpr(t5)),
5659 binop(Iop_8HLto16,
5660 mkexpr(t3),
5661 mkexpr(t1)))));
5662 break;
5665 case 0x2: { /* SHLLV.QB */
5666 DIP("shllv.qb r%u, r%u, r%u", rd, rt, rs);
5667 vassert(!mode64);
5668 t0 = newTemp(Ity_I32);
5669 t1 = newTemp(Ity_I1);
5670 t2 = newTemp(Ity_I1);
5671 t3 = newTemp(Ity_I32);
5672 t4 = newTemp(Ity_I1);
5673 t5 = newTemp(Ity_I1);
5674 t6 = newTemp(Ity_I32);
5675 t7 = newTemp(Ity_I1);
5676 t8 = newTemp(Ity_I1);
5677 t9 = newTemp(Ity_I1);
5678 t10 = newTemp(Ity_I1);
5679 t11 = newTemp(Ity_I8);
5681 assign(t11, unop(Iop_32to8,
5682 binop(Iop_And32,
5683 getIReg(rs),
5684 mkU32(0x7))));
5685 /* Shift bits 7..0 and 23..16. */
5686 assign(t0, binop(Iop_Shl32,
5687 binop(Iop_And32,
5688 getIReg(rt),
5689 mkU32(0x00ff00ff)),
5690 mkexpr(t11)));
5691 assign(t1, binop(Iop_CmpNE32,
5692 binop(Iop_And32,
5693 mkexpr(t0),
5694 mkU32(0xff000000)),
5695 mkU32(0x00000000)));
5696 assign(t2, binop(Iop_CmpNE32,
5697 binop(Iop_And32,
5698 mkexpr(t0),
5699 mkU32(0xff000000)),
5700 mkU32(0xff000000)));
5701 assign(t7, binop(Iop_CmpNE32,
5702 binop(Iop_And32,
5703 mkexpr(t0),
5704 mkU32(0x0000ff00)),
5705 mkU32(0x00000000)));
5706 assign(t8, binop(Iop_CmpNE32,
5707 binop(Iop_And32,
5708 mkexpr(t0),
5709 mkU32(0x0000ff00)),
5710 mkU32(0x000ff00)));
5711 /* Shift bits 15..8 and 31..24. */
5712 assign(t3, binop(Iop_Shl32,
5713 binop(Iop_Shr32,
5714 binop(Iop_And32,
5715 getIReg(rt),
5716 mkU32(0xff00ff00)),
5717 mkU8(8)),
5718 mkexpr(t11)));
5719 assign(t4, binop(Iop_CmpNE32,
5720 binop(Iop_And32,
5721 mkexpr(t3),
5722 mkU32(0xff000000)),
5723 mkU32(0x00000000)));
5724 assign(t5, binop(Iop_CmpNE32,
5725 binop(Iop_And32,
5726 mkexpr(t3),
5727 mkU32(0xff000000)),
5728 mkU32(0xff000000)));
5729 assign(t9, binop(Iop_CmpNE32,
5730 binop(Iop_And32,
5731 mkexpr(t3),
5732 mkU32(0x0000ff00)),
5733 mkU32(0x00000000)));
5734 assign(t10, binop(Iop_CmpNE32,
5735 binop(Iop_And32,
5736 mkexpr(t3),
5737 mkU32(0x0000ff00)),
5738 mkU32(0x0000ff00)));
5740 assign(t6, binop(Iop_Or32,
5741 binop(Iop_Or32,
5742 binop(Iop_And32,
5743 unop(Iop_1Uto32,
5744 mkexpr(t1)),
5745 unop(Iop_1Uto32,
5746 mkexpr(t2))),
5747 binop(Iop_And32,
5748 unop(Iop_1Uto32,
5749 mkexpr(t7)),
5750 unop(Iop_1Uto32,
5751 mkexpr(t8)))),
5752 binop(Iop_Or32,
5753 binop(Iop_And32,
5754 unop(Iop_1Uto32,
5755 mkexpr(t4)),
5756 unop(Iop_1Uto32,
5757 mkexpr(t5))),
5758 binop(Iop_And32,
5759 unop(Iop_1Uto32,
5760 mkexpr(t9)),
5761 unop(Iop_1Uto32,
5762 mkexpr(t10))))));
5764 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
5765 mkexpr(t6),
5766 mkU32(0x0)),
5767 binop(Iop_Or32,
5768 getDSPControl(),
5769 mkU32(0x400000)),
5770 getDSPControl()));
5771 putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
5772 unop(Iop_8Uto32, mkexpr(t11)),
5773 mkU32(0)),
5774 getIReg(rt),
5775 binop(Iop_Or32,
5776 binop(Iop_Shl32,
5777 binop(Iop_And32,
5778 mkexpr(t3),
5779 mkU32(0xff00ff)),
5780 mkU8(8)),
5781 binop(Iop_And32,
5782 mkexpr(t0),
5783 mkU32(0x00ff00ff)))));
5784 break;
5787 case 0x1: { /* SHRLV.QB */
5788 DIP("shrlv.qb r%u, r%u, r%u", rd, rt, rs);
5789 vassert(!mode64);
5790 t0 = newTemp(Ity_I8);
5791 t1 = newTemp(Ity_I8);
5792 t2 = newTemp(Ity_I8);
5793 t3 = newTemp(Ity_I8);
5795 assign(t0, unop(Iop_32to8,
5796 binop(Iop_Shr32,
5797 unop(Iop_8Uto32,
5798 unop(Iop_32to8, getIReg(rt))),
5799 mkU8(rs))));
5800 assign(t1, unop(Iop_32to8,
5801 binop(Iop_Shr32,
5802 unop(Iop_8Uto32,
5803 unop(Iop_16HIto8,
5804 unop(Iop_32to16,
5805 getIReg(rt)))),
5806 mkU8(rs))));
5807 assign(t2, unop(Iop_32to8,
5808 binop(Iop_Shr32,
5809 unop(Iop_8Uto32,
5810 unop(Iop_16to8,
5811 unop(Iop_32HIto16,
5812 getIReg(rt)))),
5813 mkU8(rs))));
5814 assign(t3, unop(Iop_32to8,
5815 binop(Iop_Shr32,
5816 unop(Iop_8Uto32,
5817 unop(Iop_16HIto8,
5818 unop(Iop_32HIto16,
5819 getIReg(rt)))),
5820 mkU8(rs))));
5821 putIReg(rd,
5822 binop(Iop_16HLto32,
5823 binop(Iop_8HLto16, mkexpr(t3), mkexpr(t2)),
5824 binop(Iop_8HLto16, mkexpr(t1), mkexpr(t0))));
5825 break;
5828 case 0x4: { /* SHRA.QB */
5829 DIP("shra.qb r%u, r%u, %u", rd, rt, rs);
5830 vassert(!mode64);
5831 t0 = newTemp(Ity_I32);
5832 t1 = newTemp(Ity_I32);
5833 t2 = newTemp(Ity_I32);
5834 t3 = newTemp(Ity_I32);
5835 t4 = newTemp(Ity_I32);
5836 t5 = newTemp(Ity_I32);
5837 t6 = newTemp(Ity_I32);
5838 t7 = newTemp(Ity_I32);
5839 t8 = newTemp(Ity_I32);
5840 t9 = newTemp(Ity_I32);
5841 t10 = newTemp(Ity_I32);
5842 t11 = newTemp(Ity_I32);
5844 /* ========== GPR[rt]_31..24 ========== */
5845 assign(t1,
5846 unop(Iop_8Uto32,
5847 unop(Iop_16HIto8,
5848 unop(Iop_32HIto16, getIReg(rt)))));
5849 assign(t2,
5850 binop(Iop_Shr32, mkexpr(t1), mkU8(rs)));
5851 /* tempD_7..0 */
5852 assign(t0,
5853 binop(Iop_Or32,
5854 mkexpr(t2),
5855 binop(Iop_Shl32,
5856 IRExpr_ITE(binop(Iop_CmpEQ32,
5857 binop(Iop_And32,
5858 mkexpr(t1),
5859 mkU32(0x00000080)
5861 mkU32(0x00000080)),
5862 mkU32(0xFFFFFFFF),
5863 mkU32(0x00000000)),
5864 binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
5866 /* ========== GPR[rt]_23..16 ========== */
5867 assign(t4,
5868 unop(Iop_8Uto32,
5869 unop(Iop_16to8,
5870 unop(Iop_32HIto16, getIReg(rt)))));
5871 assign(t5, binop(Iop_Shr32, mkexpr(t4), mkU8(rs)));
5872 /* tempC_7..0 */
5873 assign(t3,
5874 binop(Iop_Or32,
5875 mkexpr(t5),
5876 binop(Iop_Shl32,
5877 IRExpr_ITE(binop(Iop_CmpEQ32,
5878 binop(Iop_And32,
5879 mkexpr(t4),
5880 mkU32(0x00000080)
5882 mkU32(0x00000080)),
5883 mkU32(0xFFFFFFFF),
5884 mkU32(0x00000000)),
5885 binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
5887 /* ========== GPR[rt]_15..8 ========== */
5888 assign(t7,
5889 unop(Iop_8Uto32,
5890 unop(Iop_16HIto8,
5891 unop(Iop_32to16, getIReg(rt)))));
5892 assign(t8, binop(Iop_Shr32, mkexpr(t7), mkU8(rs)));
5893 /* tempB_7..0 */
5894 assign(t6,
5895 binop(Iop_Or32,
5896 mkexpr(t8),
5897 binop(Iop_Shl32,
5898 IRExpr_ITE(binop(Iop_CmpEQ32,
5899 binop(Iop_And32,
5900 mkexpr(t7),
5901 mkU32(0x00000080)
5903 mkU32(0x00000080)),
5904 mkU32(0xFFFFFFFF),
5905 mkU32(0x00000000)),
5906 binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
5908 /* ========== GPR[rt]_7..0 ========== */
5909 assign(t10,
5910 unop(Iop_8Uto32,
5911 unop(Iop_16to8,
5912 unop(Iop_32to16, getIReg(rt)))));
5913 assign(t11, binop(Iop_Shr32, mkexpr(t10), mkU8(rs)));
5914 /* tempB_7..0 */
5915 assign(t9,
5916 binop(Iop_Or32,
5917 mkexpr(t11),
5918 binop(Iop_Shl32,
5919 IRExpr_ITE(binop(Iop_CmpEQ32,
5920 binop(Iop_And32,
5921 mkexpr(t10),
5922 mkU32(0x00000080)
5924 mkU32(0x00000080)),
5925 mkU32(0xFFFFFFFF),
5926 mkU32(0x00000000)),
5927 binop(Iop_Sub8, mkU8(0x8), mkU8(rs)))));
5929 putIReg(rd,
5930 binop(Iop_16HLto32,
5931 binop(Iop_8HLto16,
5932 unop(Iop_32to8, mkexpr(t0)),
5933 unop(Iop_32to8, mkexpr(t3))),
5934 binop(Iop_8HLto16,
5935 unop(Iop_32to8, mkexpr(t6)),
5936 unop(Iop_32to8, mkexpr(t9)))));
5937 break;
5940 case 0x5: { /* SHRA_R.QB */
5941 DIP("shra_r.qb r%u, r%u, %u", rd, rt, rs);
5942 vassert(!mode64);
5943 t0 = newTemp(Ity_I32);
5944 t1 = newTemp(Ity_I8);
5945 t2 = newTemp(Ity_I32);
5946 t3 = newTemp(Ity_I8);
5947 t4 = newTemp(Ity_I32);
5948 t5 = newTemp(Ity_I8);
5949 t6 = newTemp(Ity_I32);
5950 t7 = newTemp(Ity_I8);
5952 if (0 == rs) {
5953 putIReg(rd, getIReg(rt));
5954 } else {
5955 assign(t0, unop(Iop_8Sto32,
5956 unop(Iop_16to8,
5957 unop(Iop_32to16, getIReg(rt)))));
5958 assign(t1, unop(Iop_32to8,
5959 binop(Iop_Sar32,
5960 binop(Iop_Add32,
5961 mkexpr(t0),
5962 binop(Iop_Shl32,
5963 mkU32(0x1),
5964 mkU8(rs - 1))),
5965 mkU8(rs))));
5967 assign(t2, unop(Iop_8Sto32,
5968 unop(Iop_16HIto8,
5969 unop(Iop_32to16, getIReg(rt)))));
5970 assign(t3, unop(Iop_32to8,
5971 binop(Iop_Sar32,
5972 binop(Iop_Add32,
5973 mkexpr(t2),
5974 binop(Iop_Shl32,
5975 mkU32(0x1),
5976 mkU8(rs - 1))),
5977 mkU8(rs))));
5979 assign(t4, unop(Iop_8Sto32,
5980 unop(Iop_16to8,
5981 unop(Iop_32HIto16, getIReg(rt)))));
5982 assign(t5, unop(Iop_32to8,
5983 binop(Iop_Sar32,
5984 binop(Iop_Add32,
5985 mkexpr(t4),
5986 binop(Iop_Shl32,
5987 mkU32(0x1),
5988 mkU8(rs - 1))),
5989 mkU8(rs))));
5991 assign(t6, unop(Iop_8Sto32,
5992 unop(Iop_16HIto8,
5993 unop(Iop_32HIto16, getIReg(rt)))));
5994 assign(t7, unop(Iop_32to8,
5995 binop(Iop_Sar32,
5996 binop(Iop_Add32,
5997 mkexpr(t6),
5998 binop(Iop_Shl32,
5999 mkU32(0x1),
6000 mkU8(rs - 1))),
6001 mkU8(rs))));
6002 putIReg(rd, binop(Iop_16HLto32,
6003 binop(Iop_8HLto16,
6004 mkexpr(t7), mkexpr(t5)),
6005 binop(Iop_8HLto16,
6006 mkexpr(t3), mkexpr(t1))));
6009 break;
6012 case 0x6: { /* SHRAV.QB */
6013 DIP("shrav.qb r%u, r%u, %u", rd, rt, rs);
6014 vassert(!mode64);
6016 t0 = newTemp(Ity_I32);
6017 t1 = newTemp(Ity_I32);
6018 t2 = newTemp(Ity_I32);
6020 t3 = newTemp(Ity_I32);
6021 t4 = newTemp(Ity_I32);
6022 t5 = newTemp(Ity_I32);
6024 t6 = newTemp(Ity_I32);
6025 t7 = newTemp(Ity_I32);
6026 t8 = newTemp(Ity_I32);
6028 t9 = newTemp(Ity_I32);
6029 t10 = newTemp(Ity_I32);
6030 t11 = newTemp(Ity_I32);
6032 /* ========== GPR[rt]_31..24 ========== */
6033 assign(t1,
6034 unop(Iop_8Uto32,
6035 unop(Iop_16HIto8,
6036 unop(Iop_32HIto16, getIReg(rt)))));
6037 assign(t2,
6038 binop(Iop_Shr32,
6039 mkexpr(t1),
6040 unop(Iop_32to8, binop(Iop_And32,
6041 getIReg(rs),
6042 mkU32(0x7)))));
6043 /* tempD_7..0 */
6044 assign(t0,
6045 binop(Iop_Or32,
6046 mkexpr(t2),
6047 binop(Iop_Shl32,
6048 IRExpr_ITE(binop(Iop_CmpEQ32,
6049 binop(Iop_And32,
6050 mkexpr(t1),
6051 mkU32(0x00000080)
6053 mkU32(0x00000080)),
6054 mkU32(0xFFFFFFFF),
6055 mkU32(0x00000000)),
6056 binop(Iop_Sub8,
6057 mkU8(0x8),
6058 unop(Iop_32to8, binop(Iop_And32,
6059 getIReg(rs),
6060 mkU32(0x7)))
6061 ))));
6063 /* ========== GPR[rt]_23..16 ========== */
6064 assign(t4,
6065 unop(Iop_8Uto32,
6066 unop(Iop_16to8,
6067 unop(Iop_32HIto16, getIReg(rt)))));
6068 assign(t5,
6069 binop(Iop_Shr32,
6070 mkexpr(t4),
6071 unop(Iop_32to8, binop(Iop_And32,
6072 getIReg(rs),
6073 mkU32(0x7)))));
6074 /* tempC_7..0 */
6075 assign(t3,
6076 binop(Iop_Or32,
6077 mkexpr(t5),
6078 binop(Iop_Shl32,
6079 IRExpr_ITE(binop(Iop_CmpEQ32,
6080 binop(Iop_And32,
6081 mkexpr(t4),
6082 mkU32(0x00000080)
6084 mkU32(0x00000080)),
6085 mkU32(0xFFFFFFFF),
6086 mkU32(0x00000000)),
6087 binop(Iop_Sub8,
6088 mkU8(0x8),
6089 unop(Iop_32to8, binop(Iop_And32,
6090 getIReg(rs),
6091 mkU32(0x7)))
6092 ))));
6094 /* ========== GPR[rt]_15..8 ========== */
6095 assign(t7,
6096 unop(Iop_8Uto32,
6097 unop(Iop_16HIto8,
6098 unop(Iop_32to16, getIReg(rt)))));
6099 assign(t8,
6100 binop(Iop_Shr32,
6101 mkexpr(t7),
6102 unop(Iop_32to8, binop(Iop_And32,
6103 getIReg(rs),
6104 mkU32(0x7)))));
6105 /* tempB_7..0 */
6106 assign(t6,
6107 binop(Iop_Or32,
6108 mkexpr(t8),
6109 binop(Iop_Shl32,
6110 IRExpr_ITE(binop(Iop_CmpEQ32,
6111 binop(Iop_And32,
6112 mkexpr(t7),
6113 mkU32(0x00000080)
6115 mkU32(0x00000080)),
6116 mkU32(0xFFFFFFFF),
6117 mkU32(0x00000000)),
6118 binop(Iop_Sub8,
6119 mkU8(0x8),
6120 unop(Iop_32to8, binop(Iop_And32,
6121 getIReg(rs),
6122 mkU32(0x7)))
6123 ))));
6125 /* ========== GPR[rt]_7..0 ========== */
6126 assign(t10,
6127 unop(Iop_8Uto32,
6128 unop(Iop_16to8,
6129 unop(Iop_32to16, getIReg(rt)))));
6130 assign(t11,
6131 binop(Iop_Shr32,
6132 mkexpr(t10),
6133 unop(Iop_32to8, binop(Iop_And32,
6134 getIReg(rs),
6135 mkU32(0x7)))));
6136 /* tempB_7..0 */
6137 assign(t9,
6138 binop(Iop_Or32,
6139 mkexpr(t11),
6140 binop(Iop_Shl32,
6141 IRExpr_ITE(binop(Iop_CmpEQ32,
6142 binop(Iop_And32,
6143 mkexpr(t10),
6144 mkU32(0x00000080)
6146 mkU32(0x00000080)),
6147 mkU32(0xFFFFFFFF),
6148 mkU32(0x00000000)),
6149 binop(Iop_Sub8,
6150 mkU8(0x8),
6151 unop(Iop_32to8, binop(Iop_And32,
6152 getIReg(rs),
6153 mkU32(0x7)))
6154 ))));
6156 putIReg(rd,
6157 binop(Iop_16HLto32,
6158 binop(Iop_8HLto16,
6159 unop(Iop_32to8,
6160 IRExpr_ITE(binop(Iop_CmpEQ32,
6161 binop(Iop_And32,
6162 mkU32(rs),
6163 mkU32(0x7)
6165 mkU32(0x0)),
6166 mkexpr(t1),
6167 mkexpr(t0))),
6168 unop(Iop_32to8,
6169 IRExpr_ITE(binop(Iop_CmpEQ32,
6170 binop(Iop_And32,
6171 mkU32(rs),
6172 mkU32(0x7)
6174 mkU32(0x0)),
6175 mkexpr(t2),
6176 mkexpr(t3)))),
6177 binop(Iop_8HLto16,
6178 unop(Iop_32to8,
6179 IRExpr_ITE(binop(Iop_CmpEQ32,
6180 binop(Iop_And32,
6181 mkU32(rs),
6182 mkU32(0x7)
6184 mkU32(0x0)),
6185 mkexpr(t5),
6186 mkexpr(t6))),
6187 unop(Iop_32to8,
6188 IRExpr_ITE(binop(Iop_CmpEQ32,
6189 binop(Iop_And32,
6190 mkU32(rs),
6191 mkU32(0x7)
6193 mkU32(0x0)),
6194 mkexpr(t8),
6195 mkexpr(t9))))));
6196 break;
6199 case 0x7: { /* SHRAV_R.QB */
6200 DIP("shrav_r.qb r%u, r%u, r%u", rd, rt, rs);
6201 vassert(!mode64);
6202 t0 = newTemp(Ity_I32);
6203 t1 = newTemp(Ity_I8);
6204 t2 = newTemp(Ity_I32);
6205 t3 = newTemp(Ity_I8);
6206 t4 = newTemp(Ity_I32);
6207 t5 = newTemp(Ity_I8);
6208 t6 = newTemp(Ity_I32);
6209 t7 = newTemp(Ity_I8);
6210 t8 = newTemp(Ity_I8);
6211 t9 = newTemp(Ity_I32);
6213 assign(t9, binop(Iop_And32, getIReg(rs), mkU32(0x7)));
6214 assign(t8, unop(Iop_32to8,
6215 binop(Iop_Sub32, mkexpr(t9), mkU32(0x1))));
6216 assign(t0, unop(Iop_8Sto32,
6217 unop(Iop_16to8,
6218 unop(Iop_32to16, getIReg(rt)))));
6219 assign(t1, unop(Iop_32to8,
6220 binop(Iop_Sar32,
6221 binop(Iop_Add32,
6222 mkexpr(t0),
6223 binop(Iop_Shl32,
6224 mkU32(0x1),
6225 mkexpr(t8))),
6226 unop(Iop_32to8,
6227 mkexpr(t9)))));
6229 assign(t2, unop(Iop_8Sto32,
6230 unop(Iop_16HIto8,
6231 unop(Iop_32to16, getIReg(rt)))));
6232 assign(t3, unop(Iop_32to8,
6233 binop(Iop_Sar32,
6234 binop(Iop_Add32,
6235 mkexpr(t2),
6236 binop(Iop_Shl32,
6237 mkU32(0x1),
6238 mkexpr(t8))),
6239 unop(Iop_32to8, mkexpr(t9)))));
6241 assign(t4, unop(Iop_8Sto32,
6242 unop(Iop_16to8,
6243 unop(Iop_32HIto16, getIReg(rt)))));
6244 assign(t5, unop(Iop_32to8,
6245 binop(Iop_Sar32,
6246 binop(Iop_Add32,
6247 mkexpr(t4),
6248 binop(Iop_Shl32,
6249 mkU32(0x1),
6250 mkexpr(t8))),
6251 unop(Iop_32to8, mkexpr(t9)))));
6253 assign(t6, unop(Iop_8Sto32,
6254 unop(Iop_16HIto8,
6255 unop(Iop_32HIto16, getIReg(rt)))));
6256 assign(t7, unop(Iop_32to8,
6257 binop(Iop_Sar32,
6258 binop(Iop_Add32,
6259 mkexpr(t6),
6260 binop(Iop_Shl32,
6261 mkU32(0x1),
6262 mkexpr(t8))),
6263 unop(Iop_32to8, mkexpr(t9)))));
6264 putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
6265 mkexpr(t9),
6266 mkU32(0x0)),
6267 getIReg(rt),
6268 binop(Iop_16HLto32,
6269 binop(Iop_8HLto16,
6270 mkexpr(t7),
6271 mkexpr(t5)),
6272 binop(Iop_8HLto16,
6273 mkexpr(t3),
6274 mkexpr(t1)))));
6275 break;
6278 case 0x8: { /* SHLL.PH */
6279 DIP("shll.ph r%u, r%u, %u", rd, rt, rs);
6280 vassert(!mode64);
6281 t0 = newTemp(Ity_I32);
6282 t1 = newTemp(Ity_I32);
6283 t2 = newTemp(Ity_I32);
6284 t3 = newTemp(Ity_I32);
6285 t4 = newTemp(Ity_I32);
6286 t5 = newTemp(Ity_I32);
6287 t6 = newTemp(Ity_I32);
6288 t7 = newTemp(Ity_I32);
6290 if (0 == rs) {
6291 putIReg(rd, getIReg(rt));
6292 } else {
6293 /* Shift lower 16 bits. */
6294 assign(t0, binop(Iop_Shl32,
6295 unop(Iop_16Sto32,
6296 unop(Iop_32to16, getIReg(rt))),
6297 mkU8(rs)));
6299 assign(t1, unop(Iop_1Uto32,
6300 binop(Iop_CmpNE32,
6301 binop(Iop_Sar32,
6302 mkexpr(t0),
6303 mkU8(16)),
6304 mkU32(0))));
6305 assign(t2, unop(Iop_1Uto32,
6306 binop(Iop_CmpNE32,
6307 binop(Iop_Sar32,
6308 mkexpr(t0),
6309 mkU8(16)),
6310 mkU32(0xffffffff))));
6311 assign(t3, binop(Iop_And32,
6312 mkexpr(t1),
6313 mkexpr(t2)));
6314 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
6315 mkexpr(t3),
6316 mkU32(0x1)),
6317 binop(Iop_Or32,
6318 getDSPControl(),
6319 mkU32(0x400000)),
6320 getDSPControl()));
6321 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
6322 binop(Iop_And32,
6323 getIReg(rt),
6324 mkU32(0x00008000)),
6325 binop(Iop_And32,
6326 mkexpr(t0),
6327 mkU32(0x00008000))
6329 getDSPControl(),
6330 binop(Iop_Or32,
6331 getDSPControl(),
6332 mkU32(0x400000))));
6333 /* Shift higher 16 bits. */
6334 assign(t4, binop(Iop_Shl32,
6335 unop(Iop_16Sto32,
6336 unop(Iop_32HIto16, getIReg(rt))),
6337 mkU8(rs)));
6339 assign(t5, unop(Iop_1Uto32,
6340 binop(Iop_CmpNE32,
6341 binop(Iop_Sar32,
6342 mkexpr(t4),
6343 mkU8(16)),
6344 mkU32(0))));
6345 assign(t6, unop(Iop_1Uto32,
6346 binop(Iop_CmpNE32,
6347 binop(Iop_Sar32,
6348 mkexpr(t4),
6349 mkU8(16)),
6350 mkU32(0xffffffff))));
6351 assign(t7, binop(Iop_And32,
6352 mkexpr(t5),
6353 mkexpr(t6)));
6354 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
6355 mkexpr(t7),
6356 mkU32(0x1)),
6357 binop(Iop_Or32,
6358 getDSPControl(),
6359 mkU32(0x400000)),
6360 getDSPControl()));
6361 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
6362 mkexpr(t7),
6363 mkU32(0x1)),
6364 binop(Iop_Or32,
6365 getDSPControl(),
6366 mkU32(0x400000)),
6367 getDSPControl()));
6368 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
6369 binop(Iop_And32,
6370 getIReg(rt),
6371 mkU32(0x80000000)),
6372 binop(Iop_Shl32,
6373 binop(Iop_And32,
6374 mkexpr(t4),
6375 mkU32(0x00008000)),
6376 mkU8(16))
6378 getDSPControl(),
6379 binop(Iop_Or32,
6380 getDSPControl(),
6381 mkU32(0x400000))));
6382 putIReg(rd, binop(Iop_16HLto32,
6383 unop(Iop_32to16, mkexpr(t4)),
6384 unop(Iop_32to16, mkexpr(t0))));
6387 break;
6390 case 0x9: { /* SHRA.PH */
6391 DIP("shra.ph r%u, r%u, %u", rd, rt, rs);
6392 vassert(!mode64);
6393 t0 = newTemp(Ity_I32);
6394 t1 = newTemp(Ity_I32);
6396 if (0 == rs) {
6397 putIReg(rd, getIReg(rt));
6398 } else {
6399 assign(t0, binop(Iop_Sar32,
6400 unop(Iop_16Sto32,
6401 unop(Iop_32to16, getIReg(rt))),
6402 mkU8(rs)));
6403 assign(t1, binop(Iop_Sar32,
6404 unop(Iop_16Sto32,
6405 unop(Iop_32HIto16, getIReg(rt))),
6406 mkU8(rs)));
6407 putIReg(rd, binop(Iop_16HLto32,
6408 unop(Iop_32to16, mkexpr(t1)),
6409 unop(Iop_32to16, mkexpr(t0))));
6412 break;
6415 case 0xA: { /* SHLLV.PH */
6416 DIP("shllv.ph r%u, r%u, r%u", rd, rt, rs);
6417 vassert(!mode64);
6418 t0 = newTemp(Ity_I32);
6419 t2 = newTemp(Ity_I32);
6420 t3 = newTemp(Ity_I1);
6421 t4 = newTemp(Ity_I1);
6422 t5 = newTemp(Ity_I32);
6423 t6 = newTemp(Ity_I32);
6424 t7 = newTemp(Ity_I1);
6425 t8 = newTemp(Ity_I1);
6426 t9 = newTemp(Ity_I32);
6427 t10 = newTemp(Ity_I32);
6428 t11 = newTemp(Ity_I32);
6429 t12 = newTemp(Ity_I1);
6430 t13 = newTemp(Ity_I1);
6432 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
6434 /* Shift lower 16 bits. */
6435 assign(t2, binop(Iop_Shl32,
6436 unop(Iop_16Sto32,
6437 unop(Iop_32to16, getIReg(rt))),
6438 unop(Iop_32to8, mkexpr(t0))));
6440 assign(t3, binop(Iop_CmpNE32,
6441 unop(Iop_16Sto32,
6442 unop(Iop_32HIto16, mkexpr(t2))),
6443 mkU32(0x00000000)));
6444 assign(t4, binop(Iop_CmpNE32,
6445 unop(Iop_16Sto32,
6446 unop(Iop_32HIto16, mkexpr(t2))),
6447 mkU32(0xffffffff)));
6448 assign(t10, binop(Iop_And32,
6449 unop(Iop_1Sto32, mkexpr(t3)),
6450 unop(Iop_1Sto32, mkexpr(t4))));
6451 assign(t5, binop(Iop_Shr32,
6452 binop(Iop_And32,
6453 getIReg(rt),
6454 mkU32(0x00008000)),
6455 mkU8(15)));
6456 assign(t12, binop(Iop_CmpEQ32,
6457 mkexpr(t5),
6458 binop(Iop_Shr32,
6459 binop(Iop_And32,
6460 mkexpr(t2),
6461 mkU32(0x00008000)),
6462 mkU8(15))));
6464 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
6465 mkexpr(t10),
6466 mkU32(0x0)),
6467 binop(Iop_Or32,
6468 getDSPControl(),
6469 mkU32(0x400000)),
6470 IRExpr_ITE(mkexpr(t12),
6471 getDSPControl(),
6472 binop(Iop_Or32,
6473 getDSPControl(),
6474 mkU32(0x400000)))
6476 /* Shift higher 16 bits. */
6477 assign(t6, binop(Iop_Shl32,
6478 unop(Iop_16Sto32,
6479 unop(Iop_32HIto16, getIReg(rt))),
6480 unop(Iop_32to8, mkexpr(t0))));
6482 assign(t7, binop(Iop_CmpNE32,
6483 unop(Iop_16Sto32,
6484 unop(Iop_32HIto16, mkexpr(t6))),
6485 mkU32(0x00000000)));
6486 assign(t8, binop(Iop_CmpNE32,
6487 unop(Iop_16Sto32,
6488 unop(Iop_32HIto16, mkexpr(t6))),
6489 mkU32(0xffffffff)));
6490 assign(t11, binop(Iop_And32,
6491 unop(Iop_1Sto32, mkexpr(t7)),
6492 unop(Iop_1Sto32, mkexpr(t8))));
6494 assign(t9, binop(Iop_Shr32,
6495 binop(Iop_And32,
6496 getIReg(rt),
6497 mkU32(0x80000000)),
6498 mkU8(31)));
6499 assign(t13, binop(Iop_CmpEQ32,
6500 mkexpr(t9),
6501 binop(Iop_Shr32,
6502 binop(Iop_And32,
6503 mkexpr(t6),
6504 mkU32(0x00008000)),
6505 mkU8(15))));
6507 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
6508 mkexpr(t11),
6509 mkU32(0x0)),
6510 binop(Iop_Or32,
6511 getDSPControl(),
6512 mkU32(0x400000)),
6513 IRExpr_ITE(mkexpr(t13),
6514 getDSPControl(),
6515 binop(Iop_Or32,
6516 getDSPControl(),
6517 mkU32(0x400000)))
6520 putIReg(rd, binop(Iop_16HLto32,
6521 unop(Iop_32to16, mkexpr(t6)),
6522 unop(Iop_32to16, mkexpr(t2))));
6523 break;
6526 case 0xB: { /* SHRAV.PH */
6527 DIP("shrav.ph r%u, r%u, r%u", rd, rt, rs);
6528 vassert(!mode64);
6529 t0 = newTemp(Ity_I32);
6530 t1 = newTemp(Ity_I1);
6531 t2 = newTemp(Ity_I32);
6532 t3 = newTemp(Ity_I32);
6534 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
6535 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
6536 assign(t2, binop(Iop_Sar32,
6537 unop(Iop_16Sto32,
6538 unop(Iop_32to16, getIReg(rt))),
6539 unop(Iop_32to8, mkexpr(t0))));
6540 assign(t3, binop(Iop_Sar32,
6541 unop(Iop_16Sto32,
6542 unop(Iop_32HIto16, getIReg(rt))),
6543 unop(Iop_32to8, mkexpr(t0))));
6544 putIReg(rd,
6545 binop(Iop_16HLto32,
6546 IRExpr_ITE(mkexpr(t1),
6547 unop(Iop_32HIto16, getIReg(rt)),
6548 unop(Iop_32to16, mkexpr(t3))),
6549 IRExpr_ITE(mkexpr(t1),
6550 unop(Iop_32to16, getIReg(rt)),
6551 unop(Iop_32to16, mkexpr(t2)))));
6552 break;
6555 case 0xC: { /* SHLL_S.PH */
6556 DIP("shll_s.ph r%u, r%u, %u", rd, rt, rs);
6557 vassert(!mode64);
6558 t0 = newTemp(Ity_I32);
6559 t1 = newTemp(Ity_I32);
6560 t2 = newTemp(Ity_I32);
6561 t3 = newTemp(Ity_I32);
6562 t4 = newTemp(Ity_I32);
6563 t5 = newTemp(Ity_I32);
6564 t6 = newTemp(Ity_I32);
6565 t7 = newTemp(Ity_I32);
6566 t8 = newTemp(Ity_I32);
6567 t9 = newTemp(Ity_I32);
6568 t10 = newTemp(Ity_I32);
6569 t11 = newTemp(Ity_I32);
6570 t12 = newTemp(Ity_I32);
6571 t13 = newTemp(Ity_I32);
6572 t14 = newTemp(Ity_I32);
6574 if (0 == rs) {
6575 putIReg(rd, getIReg(rt));
6576 } else {
6577 /* Shift lower 16 bits. */
6578 assign(t0, binop(Iop_Shl32,
6579 unop(Iop_16Sto32,
6580 unop(Iop_32to16, getIReg(rt))),
6581 mkU8(rs)));
6583 assign(t1, unop(Iop_1Uto32,
6584 binop(Iop_CmpNE32,
6585 binop(Iop_Sar32,
6586 mkexpr(t0),
6587 mkU8(16)),
6588 mkU32(0))));
6589 assign(t2, unop(Iop_1Uto32,
6590 binop(Iop_CmpNE32,
6591 binop(Iop_Sar32,
6592 mkexpr(t0),
6593 mkU8(16)),
6594 mkU32(0xffffffff))));
6595 assign(t3, binop(Iop_And32,
6596 mkexpr(t1),
6597 mkexpr(t2)));
6598 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
6599 mkexpr(t3),
6600 mkU32(0x1)),
6601 binop(Iop_Or32,
6602 getDSPControl(),
6603 mkU32(0x400000)),
6604 getDSPControl()));
6605 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
6606 binop(Iop_And32,
6607 getIReg(rt),
6608 mkU32(0x00008000)),
6609 binop(Iop_And32,
6610 mkexpr(t0),
6611 mkU32(0x00008000))
6613 getDSPControl(),
6614 binop(Iop_Or32,
6615 getDSPControl(),
6616 mkU32(0x400000))));
6617 assign(t8,
6618 IRExpr_ITE(binop(Iop_CmpEQ32,
6619 mkexpr(t3),
6620 mkU32(0x1)),
6621 IRExpr_ITE(binop(Iop_CmpEQ32,
6622 binop(Iop_And32,
6623 getIReg(rt),
6624 mkU32(0x8000)),
6625 mkU32(0)),
6626 mkU32(0x00007fff),
6627 mkU32(0x00008000)),
6628 binop(Iop_And32,
6629 mkexpr(t0),
6630 mkU32(0x0000ffff))));
6631 assign(t10,
6632 IRExpr_ITE(binop(Iop_CmpEQ32,
6633 binop(Iop_And32,
6634 getIReg(rt),
6635 mkU32(0x00008000)),
6636 binop(Iop_And32,
6637 mkexpr(t0),
6638 mkU32(0x00008000))),
6639 mkexpr(t8),
6640 IRExpr_ITE(binop(Iop_CmpEQ32,
6641 binop(Iop_And32,
6642 getIReg(rt),
6643 mkU32(0x8000)),
6644 mkU32(0)),
6645 mkU32(0x00007fff),
6646 mkU32(0x00008000))));
6647 /* Shift higher 16 bits. */
6648 assign(t4, binop(Iop_Shl32,
6649 unop(Iop_16Sto32,
6650 unop(Iop_32HIto16, getIReg(rt))),
6651 mkU8(rs)));
6653 assign(t5, unop(Iop_1Uto32,
6654 binop(Iop_CmpNE32,
6655 binop(Iop_Sar32,
6656 mkexpr(t4),
6657 mkU8(16)),
6658 mkU32(0))));
6659 assign(t6, unop(Iop_1Uto32,
6660 binop(Iop_CmpNE32,
6661 binop(Iop_Sar32,
6662 mkexpr(t4),
6663 mkU8(16)),
6664 mkU32(0xffffffff))));
6665 assign(t7, binop(Iop_And32,
6666 mkexpr(t5),
6667 mkexpr(t6)));
6668 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
6669 mkexpr(t7),
6670 mkU32(0x1)),
6671 binop(Iop_Or32,
6672 getDSPControl(),
6673 mkU32(0x400000)),
6674 getDSPControl()));
6675 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
6676 mkexpr(t7),
6677 mkU32(0x1)),
6678 binop(Iop_Or32,
6679 getDSPControl(),
6680 mkU32(0x400000)),
6681 getDSPControl()));
6682 assign(t12, binop(Iop_Shl32,
6683 binop(Iop_And32,
6684 mkexpr(t4),
6685 mkU32(0x8000)),
6686 mkU8(16)));
6687 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
6688 binop(Iop_And32,
6689 getIReg(rt),
6690 mkU32(0x80000000)),
6691 mkexpr(t12)),
6692 getDSPControl(),
6693 binop(Iop_Or32,
6694 getDSPControl(),
6695 mkU32(0x400000))));
6696 assign(t13, IRExpr_ITE(binop(Iop_CmpEQ32,
6697 binop(Iop_And32,
6698 getIReg(rt),
6699 mkU32(0x80000000)),
6700 mkU32(0)),
6701 mkU32(0x7fff0000),
6702 mkU32(0x80000000)));
6703 assign(t9,
6704 IRExpr_ITE(binop(Iop_CmpEQ32,
6705 mkexpr(t7),
6706 mkU32(0x1)),
6707 mkexpr(t13),
6708 binop(Iop_Shl32,
6709 binop(Iop_And32,
6710 mkexpr(t4),
6711 mkU32(0x0000ffff)),
6712 mkU8(16))));
6713 assign(t14, IRExpr_ITE(binop(Iop_CmpEQ32,
6714 binop(Iop_And32,
6715 getIReg(rt),
6716 mkU32(0x80000000)),
6717 mkU32(0)),
6718 mkU32(0x7fff0000),
6719 mkU32(0x80000000)));
6720 assign(t11,
6721 IRExpr_ITE(binop(Iop_CmpEQ32,
6722 binop(Iop_And32,
6723 getIReg(rt),
6724 mkU32(0x80000000)),
6725 binop(Iop_Shl32,
6726 binop(Iop_And32,
6727 mkexpr(t4),
6728 mkU32(0x00008000)),
6729 mkU8(16))),
6730 mkexpr(t9),
6731 mkexpr(t14)));
6732 putIReg(rd, binop(Iop_Or32,
6733 mkexpr(t10),
6734 mkexpr(t11)));
6737 break;
6740 case 0xD: { /* SHRA_R.PH */
6741 DIP("shra.ph r%u, r%u, %u", rd, rt, rs);
6742 vassert(!mode64);
6743 t0 = newTemp(Ity_I32);
6744 t1 = newTemp(Ity_I32);
6746 if (0 == rs) {
6747 putIReg(rd, getIReg(rt));
6748 } else {
6749 assign(t0, binop(Iop_Sar32,
6750 binop(Iop_Add32,
6751 unop(Iop_16Sto32,
6752 unop(Iop_32to16,
6753 getIReg(rt))),
6754 binop(Iop_Shl32,
6755 mkU32(0x1),
6756 mkU8(rs - 1))),
6757 mkU8(rs)));
6758 assign(t1, binop(Iop_Sar32,
6759 binop(Iop_Add32,
6760 unop(Iop_16Sto32,
6761 unop(Iop_32HIto16,
6762 getIReg(rt))),
6763 binop(Iop_Shl32,
6764 mkU32(0x1),
6765 mkU8(rs - 1))),
6766 mkU8(rs)));
6767 putIReg(rd, binop(Iop_16HLto32,
6768 unop(Iop_32to16, mkexpr(t1)),
6769 unop(Iop_32to16, mkexpr(t0))));
6772 break;
6775 case 0xE: { /* SHLLV_S.PH */
6776 DIP("shllv_s.ph r%u, r%u, r%u", rd, rt, rs);
6777 vassert(!mode64);
6778 t0 = newTemp(Ity_I32);
6779 t2 = newTemp(Ity_I32);
6780 t3 = newTemp(Ity_I1);
6781 t4 = newTemp(Ity_I1);
6782 t5 = newTemp(Ity_I32);
6783 t6 = newTemp(Ity_I32);
6784 t7 = newTemp(Ity_I1);
6785 t8 = newTemp(Ity_I1);
6786 t9 = newTemp(Ity_I32);
6787 t10 = newTemp(Ity_I32);
6788 t11 = newTemp(Ity_I32);
6789 t12 = newTemp(Ity_I1);
6790 t13 = newTemp(Ity_I1);
6791 t14 = newTemp(Ity_I16);
6792 t15 = newTemp(Ity_I16);
6793 t16 = newTemp(Ity_I16);
6794 t17 = newTemp(Ity_I16);
6796 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
6798 /* Shift lower 16 bits. */
6799 assign(t2, binop(Iop_Shl32,
6800 unop(Iop_16Sto32,
6801 unop(Iop_32to16, getIReg(rt))),
6802 unop(Iop_32to8, mkexpr(t0))));
6804 assign(t3, binop(Iop_CmpNE32,
6805 unop(Iop_16Sto32,
6806 unop(Iop_32HIto16, mkexpr(t2))),
6807 mkU32(0x00000000)));
6808 assign(t4, binop(Iop_CmpNE32,
6809 unop(Iop_16Sto32,
6810 unop(Iop_32HIto16, mkexpr(t2))),
6811 mkU32(0xffffffff)));
6812 assign(t10, binop(Iop_And32,
6813 unop(Iop_1Sto32, mkexpr(t3)),
6814 unop(Iop_1Sto32, mkexpr(t4))));
6815 assign(t5, binop(Iop_Shr32,
6816 binop(Iop_And32,
6817 getIReg(rt),
6818 mkU32(0x00008000)),
6819 mkU8(15)));
6820 assign(t12, binop(Iop_CmpEQ32,
6821 mkexpr(t5),
6822 binop(Iop_Shr32,
6823 binop(Iop_And32,
6824 mkexpr(t2),
6825 mkU32(0x00008000)),
6826 mkU8(15))));
6828 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
6829 mkexpr(t10),
6830 mkU32(0x0)),
6831 binop(Iop_Or32,
6832 getDSPControl(),
6833 mkU32(0x400000)),
6834 IRExpr_ITE(mkexpr(t12),
6835 getDSPControl(),
6836 binop(Iop_Or32,
6837 getDSPControl(),
6838 mkU32(0x400000)))
6840 assign(t14, IRExpr_ITE(binop(Iop_CmpNE32,
6841 mkexpr(t5),
6842 mkU32(0x0)),
6843 mkU16(0x8000),
6844 mkU16(0x7fff)));
6845 assign(t15, IRExpr_ITE(binop(Iop_CmpNE32,
6846 mkexpr(t10),
6847 mkU32(0x0)),
6848 mkexpr(t14),
6849 IRExpr_ITE(mkexpr(t12),
6850 unop(Iop_32to16,
6851 mkexpr(t2)),
6852 mkexpr(t14))));
6853 /* Shift higher 16 bits. */
6854 assign(t6, binop(Iop_Shl32,
6855 unop(Iop_16Sto32,
6856 unop(Iop_32HIto16, getIReg(rt))),
6857 unop(Iop_32to8, mkexpr(t0))));
6859 assign(t7, binop(Iop_CmpNE32,
6860 unop(Iop_16Sto32,
6861 unop(Iop_32HIto16, mkexpr(t6))),
6862 mkU32(0x00000000)));
6863 assign(t8, binop(Iop_CmpNE32,
6864 unop(Iop_16Sto32,
6865 unop(Iop_32HIto16, mkexpr(t6))),
6866 mkU32(0xffffffff)));
6867 assign(t11, binop(Iop_And32,
6868 unop(Iop_1Sto32, mkexpr(t7)),
6869 unop(Iop_1Sto32, mkexpr(t8))));
6871 assign(t9, binop(Iop_Shr32,
6872 binop(Iop_And32,
6873 getIReg(rt),
6874 mkU32(0x80000000)),
6875 mkU8(31)));
6876 assign(t13, binop(Iop_CmpEQ32,
6877 mkexpr(t9),
6878 binop(Iop_Shr32,
6879 binop(Iop_And32,
6880 mkexpr(t6),
6881 mkU32(0x00008000)),
6882 mkU8(15))));
6884 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
6885 mkexpr(t11),
6886 mkU32(0x0)),
6887 binop(Iop_Or32,
6888 getDSPControl(),
6889 mkU32(0x400000)),
6890 IRExpr_ITE(mkexpr(t13),
6891 getDSPControl(),
6892 binop(Iop_Or32,
6893 getDSPControl(),
6894 mkU32(0x400000)))
6897 assign(t16, IRExpr_ITE(binop(Iop_CmpNE32,
6898 mkexpr(t9),
6899 mkU32(0x0)),
6900 mkU16(0x8000),
6901 mkU16(0x7fff)));
6902 assign(t17, IRExpr_ITE(binop(Iop_CmpNE32,
6903 mkexpr(t11),
6904 mkU32(0x0)),
6905 mkexpr(t16),
6906 IRExpr_ITE(mkexpr(t13),
6907 unop(Iop_32to16,
6908 mkexpr(t6)),
6909 mkexpr(t16))));
6911 putIReg(rd, binop(Iop_16HLto32, mkexpr(t17), mkexpr(t15)));
6912 break;
6915 case 0xF: { /* SHRAV_R.PH */
6916 DIP("shrav_r.ph r%u, r%u, r%u", rd, rt, rs);
6917 vassert(!mode64);
6918 t0 = newTemp(Ity_I32);
6919 t1 = newTemp(Ity_I1);
6920 t2 = newTemp(Ity_I8);
6921 t3 = newTemp(Ity_I32);
6922 t4 = newTemp(Ity_I32);
6924 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
6925 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
6926 assign(t2, unop(Iop_32to8,
6927 binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
6929 assign(t3, binop(Iop_Sar32,
6930 binop(Iop_Add32,
6931 unop(Iop_16Sto32,
6932 unop(Iop_32to16, getIReg(rt))),
6933 binop(Iop_Shl32,
6934 mkU32(0x1),
6935 mkexpr(t2))),
6936 unop(Iop_32to8, mkexpr(t0))));
6937 assign(t4, binop(Iop_Sar32,
6938 binop(Iop_Add32,
6939 unop(Iop_16Sto32,
6940 unop(Iop_32HIto16,
6941 getIReg(rt))),
6942 binop(Iop_Shl32,
6943 mkU32(0x1),
6944 mkexpr(t2))),
6945 unop(Iop_32to8, mkexpr(t0))));
6947 putIReg(rd, binop(Iop_16HLto32,
6948 IRExpr_ITE(mkexpr(t1),
6949 unop(Iop_32HIto16,
6950 getIReg(rt)),
6951 unop(Iop_32to16,
6952 mkexpr(t4))),
6953 IRExpr_ITE(mkexpr(t1),
6954 unop(Iop_32to16, getIReg(rt)),
6955 unop(Iop_32to16,
6956 mkexpr(t3)))));
6957 break;
6960 case 0x14: { /* SHLL_S.W */
6961 DIP("shll_s.w r%u, r%u, %u", rd, rt, rs);
6962 vassert(!mode64);
6963 t0 = newTemp(Ity_I32);
6964 t1 = newTemp(Ity_I32);
6965 t2 = newTemp(Ity_I32);
6966 t3 = newTemp(Ity_I32);
6967 t4 = newTemp(Ity_I32);
6968 t5 = newTemp(Ity_I32);
6970 if (0 == rs) {
6971 putIReg(rd, getIReg(rt));
6972 } else {
6973 /* t0-bits that will be discarded, sign extended to
6974 32bits. */
6975 assign(t0, binop(Iop_Sar32,
6976 binop(Iop_And32,
6977 getIReg(rt),
6978 binop(Iop_Sar32,
6979 mkU32(0x80000000),
6980 mkU8(rs - 1))),
6981 mkU8(32 - rs)));
6983 assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
6984 binop(Iop_And32,
6985 getIReg(rt),
6986 mkU32(0x80000000)),
6987 mkU32(0x0)),
6988 mkU32(0x7fffffff),
6989 mkU32(0x80000000)));
6991 assign(t2, binop(Iop_Shl32, getIReg(rt), mkU8(rs)));
6992 assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
6993 binop(Iop_And32,
6994 getIReg(rt),
6995 mkU32(0x80000000)),
6996 binop(Iop_And32,
6997 mkexpr(t2),
6998 mkU32(0x80000000))),
6999 mkexpr(t2),
7000 mkexpr(t1)));
7002 assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
7003 mkexpr(t0),
7004 mkU32(0x0)),
7005 IRExpr_ITE(binop(Iop_CmpNE32,
7006 mkexpr(t0),
7007 mkU32(0xffffffff)
7009 mkexpr(t1),
7010 mkexpr(t3)),
7011 mkexpr(t3)));
7012 assign(t5, IRExpr_ITE(binop(Iop_CmpNE32,
7013 mkexpr(t0),
7014 mkU32(0xffffffff)),
7015 binop(Iop_Or32,
7016 getDSPControl(),
7017 mkU32(0x400000)),
7018 getDSPControl()));
7019 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
7020 mkexpr(t0),
7021 mkU32(0x0)),
7022 mkexpr(t5),
7023 getDSPControl()));
7024 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
7025 binop(Iop_And32,
7026 getIReg(rt),
7027 mkU32(0x80000000)),
7028 binop(Iop_And32,
7029 mkexpr(t2),
7030 mkU32(0x80000000))
7032 getDSPControl(),
7033 binop(Iop_Or32,
7034 getDSPControl(),
7035 mkU32(0x400000))));
7036 putIReg(rd, mkexpr(t4));
7039 break;
7042 case 0x15: { /* SHRA_R.W */
7043 DIP("shra_r.w r%u, r%u, %u", rd, rt, rs);
7044 vassert(!mode64);
7046 if (0 == rs) {
7047 putIReg(rd, getIReg(rt));
7048 } else {
7049 putIReg(rd, binop(Iop_Add32,
7050 binop(Iop_Sar32,
7051 getIReg(rt), mkU8(rs)),
7052 binop(Iop_Shr32,
7053 binop(Iop_And32,
7054 getIReg(rt),
7055 binop(Iop_Shl32,
7056 mkU32(0x1),
7057 mkU8(rs - 1))),
7058 mkU8(rs - 1))));
7061 break;
7064 case 0x16: { /* SHLLV_S.W */
7065 DIP("shllv_s.w r%u, r%u, r%u", rd, rt, rs);
7066 vassert(!mode64);
7067 t0 = newTemp(Ity_I32);
7068 t1 = newTemp(Ity_I1);
7069 t2 = newTemp(Ity_I32);
7070 t3 = newTemp(Ity_I64);
7071 t4 = newTemp(Ity_I1);
7072 t5 = newTemp(Ity_I1);
7073 t6 = newTemp(Ity_I32);
7074 t7 = newTemp(Ity_I1);
7075 t8 = newTemp(Ity_I32);
7077 /* Check if shift amount is zero. */
7078 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
7079 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
7081 /* t2 = sign of the input value. */
7082 assign(t2, binop(Iop_Shr32,
7083 binop(Iop_And32,
7084 getIReg(rt),
7085 mkU32(0x80000000)),
7086 mkU8(31)));
7087 /* Shift left input value and check for overflow. */
7088 assign(t3, binop(Iop_Shl64,
7089 unop(Iop_32Sto64, getIReg(rt)),
7090 unop(Iop_32to8, mkexpr(t0))));
7091 assign(t4, binop(Iop_CmpNE32,
7092 unop(Iop_64HIto32, mkexpr(t3)),
7093 mkU32(0x00000000)));
7094 assign(t5, binop(Iop_CmpNE32,
7095 unop(Iop_64HIto32, mkexpr(t3)),
7096 mkU32(0xffffffff)));
7097 assign(t6, binop(Iop_And32,
7098 unop(Iop_1Uto32, mkexpr(t4)),
7099 unop(Iop_1Uto32, mkexpr(t5))));
7100 assign(t7, binop(Iop_CmpEQ32,
7101 binop(Iop_Shr32,
7102 binop(Iop_And32,
7103 getIReg(rt),
7104 mkU32(0x80000000)),
7105 mkU8(31)),
7106 binop(Iop_Shr32,
7107 binop(Iop_And32,
7108 unop(Iop_64to32, mkexpr(t3)),
7109 mkU32(0x80000000)),
7110 mkU8(31))));
7112 putDSPControl(IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
7113 binop(Iop_Or32,
7114 getDSPControl(),
7115 mkU32(0x400000)),
7116 IRExpr_ITE(mkexpr(t7),
7117 getDSPControl(),
7118 binop(Iop_Or32,
7119 getDSPControl(),
7120 mkU32(0x400000)))
7123 assign(t8, IRExpr_ITE(unop(Iop_32to1,
7124 mkexpr(t2)),
7125 mkU32(0x80000000),
7126 mkU32(0x7fffffff)));
7127 putIReg(rd, IRExpr_ITE(unop(Iop_32to1, mkexpr(t6)),
7128 IRExpr_ITE(unop(Iop_32to1,
7129 mkexpr(t2)),
7130 mkU32(0x80000000),
7131 mkU32(0x7fffffff)),
7132 IRExpr_ITE(mkexpr(t7),
7133 unop(Iop_64to32,
7134 mkexpr(t3)),
7135 mkexpr(t8))));
7136 break;
7139 case 0x17: { /* SHRAV_R.W */
7140 DIP("shrav_r.w r%u, r%u, r%u", rd, rt, rs);
7141 vassert(!mode64);
7142 t0 = newTemp(Ity_I32);
7143 t1 = newTemp(Ity_I1);
7144 t2 = newTemp(Ity_I8);
7146 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
7147 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
7148 assign(t2, unop(Iop_32to8,
7149 binop(Iop_Sub32, mkexpr(t0), mkU32(1))));
7151 putIReg(rd, IRExpr_ITE(mkexpr(t1),
7152 getIReg(rt),
7153 binop(Iop_Sar32,
7154 binop(Iop_Add32,
7155 binop(Iop_Sar32,
7156 getIReg(rt),
7157 mkexpr(t2)),
7158 mkU32(0x1)),
7159 mkU8(1))));
7160 break;
7163 case 0x19: { /* SHRL.PH */
7164 DIP("shrl.ph r%u, r%u, %u", rd, rt, rs);
7165 vassert(!mode64);
7166 t0 = newTemp(Ity_I32);
7167 t1 = newTemp(Ity_I32);
7168 assign(t0, binop(Iop_Shr32,
7169 unop(Iop_16Uto32,
7170 unop(Iop_32to16, getIReg(rt))),
7171 mkU8(rs)));
7172 assign(t1, binop(Iop_Shr32,
7173 unop(Iop_16Uto32,
7174 unop(Iop_32HIto16, getIReg(rt))),
7175 mkU8(rs)));
7176 putIReg(rd, binop(Iop_16HLto32,
7177 unop(Iop_32to16, mkexpr(t1)),
7178 unop(Iop_32to16, mkexpr(t0))));
7179 break;
7182 case 0x1B: { /* SHRLV.PH */
7183 DIP("shrlv.ph r%u, r%u, r%u", rd, rt, rs);
7184 vassert(!mode64);
7185 t0 = newTemp(Ity_I32);
7186 t1 = newTemp(Ity_I1);
7187 t2 = newTemp(Ity_I32);
7188 t3 = newTemp(Ity_I32);
7189 t4 = newTemp(Ity_I16);
7190 t5 = newTemp(Ity_I16);
7192 /* Get shift amount from lower 5 bits of rs
7193 and check if it is zero. */
7194 assign(t0, binop(Iop_And32, getIReg(rs), mkU32(0x0f)));
7195 assign(t1, binop(Iop_CmpEQ32, mkexpr(t0), mkU32(0x0)));
7197 assign(t2, binop(Iop_Shr32,
7198 unop(Iop_16Uto32,
7199 unop(Iop_32to16, getIReg(rt))),
7200 unop(Iop_32to8, mkexpr(t0))));
7201 assign(t3, binop(Iop_Shr32,
7202 unop(Iop_16Uto32,
7203 unop(Iop_32HIto16, getIReg(rt))),
7204 unop(Iop_32to8, mkexpr(t0))));
7206 assign(t4, IRExpr_ITE(mkexpr(t1),
7207 unop(Iop_32HIto16, getIReg(rt)),
7208 unop(Iop_32to16, mkexpr(t3))));
7209 assign(t5, IRExpr_ITE(mkexpr(t1),
7210 unop(Iop_32to16, getIReg(rt)),
7211 unop(Iop_32to16, mkexpr(t2))));
7212 putIReg(rd, binop(Iop_16HLto32, mkexpr(t4), mkexpr(t5)));
7213 break;
7216 default:
7217 return -1;
7220 return 0;
7223 static UInt disDSPInstr_MIPS_WRK_Special3_ADDUH_QB( UInt cins )
7225 IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12;
7226 UInt rs, rt, rd, sa;
7228 rs = get_rs(cins);
7229 rt = get_rt(cins);
7230 rd = get_rd(cins);
7231 sa = get_sa(cins);
7233 switch (sa) {
7234 case 0x00: { /* ADDUH.QB */
7235 DIP("adduh.qb r%u, r%u, r%u", rd, rs, rt);
7236 vassert(!mode64);
7237 t0 = newTemp(Ity_I32);
7239 assign(t0, binop(Iop_HAdd8Ux4, getIReg(rs), getIReg(rt)));
7241 putIReg(rd, mkexpr(t0));
7242 break;
7245 case 0x1: { /* SUBUH.QB */
7246 DIP("subuh.qb r%u, r%u, r%u", rd, rs, rt);
7247 vassert(!mode64);
7248 t0 = newTemp(Ity_I32);
7250 assign(t0, binop(Iop_HSub8Ux4, getIReg(rs), getIReg(rt)));
7252 putIReg(rd, mkexpr(t0));
7253 break;
7256 case 0x02: { /* ADDUH_R.QB */
7257 DIP("adduh_r.qb r%u, r%u, r%u", rd, rs, rt);
7258 vassert(!mode64);
7259 t0 = newTemp(Ity_I32);
7260 t1 = newTemp(Ity_I32);
7261 t2 = newTemp(Ity_I8);
7262 t3 = newTemp(Ity_I32);
7263 t4 = newTemp(Ity_I32);
7264 t5 = newTemp(Ity_I8);
7265 t6 = newTemp(Ity_I32);
7266 t7 = newTemp(Ity_I32);
7267 t8 = newTemp(Ity_I8);
7268 t9 = newTemp(Ity_I32);
7269 t10 = newTemp(Ity_I32);
7270 t11 = newTemp(Ity_I8);
7272 /* Extract input bytes, add values, add 1 and half the
7273 result. */
7274 assign(t0, unop(Iop_8Uto32,
7275 unop(Iop_16to8,
7276 unop(Iop_32to16, getIReg(rs)))));
7277 assign(t1, unop(Iop_8Uto32,
7278 unop(Iop_16to8,
7279 unop(Iop_32to16, getIReg(rt)))));
7280 assign(t2, unop(Iop_16to8,
7281 unop(Iop_32to16,
7282 binop(Iop_Shr32,
7283 binop(Iop_Add32,
7284 binop(Iop_Add32,
7285 mkexpr(t0),
7286 mkexpr(t1)),
7287 mkU32(0x00000001)),
7288 mkU8(0x01)))));
7290 assign(t3, unop(Iop_8Uto32,
7291 unop(Iop_16HIto8,
7292 unop(Iop_32to16, getIReg(rs)))));
7293 assign(t4, unop(Iop_8Uto32,
7294 unop(Iop_16HIto8,
7295 unop(Iop_32to16, getIReg(rt)))));
7296 assign(t5, unop(Iop_16to8,
7297 unop(Iop_32to16,
7298 binop(Iop_Shr32,
7299 binop(Iop_Add32,
7300 binop(Iop_Add32,
7301 mkexpr(t3),
7302 mkexpr(t4)),
7303 mkU32(0x00000001)),
7304 mkU8(0x01)))));
7306 assign(t6, unop(Iop_8Uto32,
7307 unop(Iop_16to8,
7308 unop(Iop_32HIto16, getIReg(rs)))));
7309 assign(t7, unop(Iop_8Uto32,
7310 unop(Iop_16to8,
7311 unop(Iop_32HIto16, getIReg(rt)))));
7312 assign(t8, unop(Iop_16to8,
7313 unop(Iop_32to16,
7314 binop(Iop_Shr32,
7315 binop(Iop_Add32,
7316 binop(Iop_Add32,
7317 mkexpr(t7),
7318 mkexpr(t6)),
7319 mkU32(0x00000001)),
7320 mkU8(0x01)))));
7322 assign(t9, unop(Iop_8Uto32,
7323 unop(Iop_16HIto8,
7324 unop(Iop_32HIto16, getIReg(rs)))));
7325 assign(t10, unop(Iop_8Uto32,
7326 unop(Iop_16HIto8,
7327 unop(Iop_32HIto16, getIReg(rt)))));
7328 assign(t11, unop(Iop_16to8,
7329 unop(Iop_32to16,
7330 binop(Iop_Shr32,
7331 binop(Iop_Add32,
7332 binop(Iop_Add32,
7333 mkexpr(t9),
7334 mkexpr(t10)),
7335 mkU32(0x00000001)),
7336 mkU8(0x01)))));
7338 putIReg(rd, binop(Iop_16HLto32,
7339 binop(Iop_8HLto16,
7340 mkexpr(t11), mkexpr(t8)),
7341 binop(Iop_8HLto16,
7342 mkexpr(t5), mkexpr(t2))));
7343 break;
7346 case 0x3: { /* SUBUH_R.QB */
7347 DIP("subuh_r.qb r%u, r%u, r%u", rd, rs, rt);
7348 vassert(!mode64);
7349 t1 = newTemp(Ity_I32);
7350 t2 = newTemp(Ity_I32);
7351 t3 = newTemp(Ity_I32);
7352 t4 = newTemp(Ity_I32);
7353 t5 = newTemp(Ity_I32);
7354 t6 = newTemp(Ity_I32);
7355 t7 = newTemp(Ity_I32);
7356 t8 = newTemp(Ity_I32);
7357 t9 = newTemp(Ity_I8);
7358 t10 = newTemp(Ity_I8);
7359 t11 = newTemp(Ity_I8);
7360 t12 = newTemp(Ity_I8);
7362 /* Extract each byte of rs and rt. */
7363 assign(t1, unop(Iop_8Uto32,
7364 unop(Iop_16to8,
7365 unop(Iop_32to16, getIReg(rs)))));
7366 assign(t2, unop(Iop_8Uto32,
7367 unop(Iop_16HIto8,
7368 unop(Iop_32to16, getIReg(rs)))));
7369 assign(t3, unop(Iop_8Uto32,
7370 unop(Iop_16to8,
7371 unop(Iop_32HIto16, getIReg(rs)))));
7372 assign(t4, unop(Iop_8Uto32,
7373 unop(Iop_16HIto8,
7374 unop(Iop_32HIto16, getIReg(rs)))));
7376 assign(t5, unop(Iop_8Uto32,
7377 unop(Iop_16to8,
7378 unop(Iop_32to16, getIReg(rt)))));
7379 assign(t6, unop(Iop_8Uto32,
7380 unop(Iop_16HIto8,
7381 unop(Iop_32to16, getIReg(rt)))));
7382 assign(t7, unop(Iop_8Uto32,
7383 unop(Iop_16to8,
7384 unop(Iop_32HIto16, getIReg(rt)))));
7385 assign(t8, unop(Iop_8Uto32,
7386 unop(Iop_16HIto8,
7387 unop(Iop_32HIto16, getIReg(rt)))));
7389 /* Add 1 to each resulting byte and half the results. */
7390 assign(t9, unop(Iop_16to8,
7391 unop(Iop_32to16,
7392 binop(Iop_Shr32,
7393 binop(Iop_Add32,
7394 binop(Iop_Sub32,
7395 mkexpr(t1),
7396 mkexpr(t5)),
7397 mkU32(0x00000001)),
7398 mkU8(0x01)))));
7399 assign(t10, unop(Iop_16to8,
7400 unop(Iop_32to16,
7401 binop(Iop_Shr32,
7402 binop(Iop_Add32,
7403 binop(Iop_Sub32,
7404 mkexpr(t2),
7405 mkexpr(t6)),
7406 mkU32(0x00000001)),
7407 mkU8(0x01)))));
7408 assign(t11, unop(Iop_16to8,
7409 unop(Iop_32to16,
7410 binop(Iop_Shr32,
7411 binop(Iop_Add32,
7412 binop(Iop_Sub32,
7413 mkexpr(t3),
7414 mkexpr(t7)),
7415 mkU32(0x00000001)),
7416 mkU8(0x01)))));
7417 assign(t12, unop(Iop_16to8,
7418 unop(Iop_32to16,
7419 binop(Iop_Shr32,
7420 binop(Iop_Add32,
7421 binop(Iop_Sub32,
7422 mkexpr(t4),
7423 mkexpr(t8)),
7424 mkU32(0x00000001)),
7425 mkU8(0x01)))));
7427 putIReg(rd, binop(Iop_16HLto32,
7428 binop(Iop_8HLto16,
7429 mkexpr(t12), mkexpr(t11)),
7430 binop(Iop_8HLto16,
7431 mkexpr(t10), mkexpr(t9))));
7432 break;
7435 case 0x8: { /* ADDQH.PH */
7436 DIP("addqh.ph r%u, r%u, r%u", rd, rs, rt);
7437 vassert(!mode64);
7438 t0 = newTemp(Ity_I32);
7439 t1 = newTemp(Ity_I16);
7440 t2 = newTemp(Ity_I32);
7441 t3 = newTemp(Ity_I16);
7443 /* Add lower halfs of rs and rt
7444 and right shift the result by 1. */
7445 assign(t0, binop(Iop_Add32,
7446 unop(Iop_16Sto32,
7447 unop(Iop_32to16, getIReg(rs))),
7448 unop(Iop_16Sto32,
7449 unop(Iop_32to16, getIReg(rt)))));
7450 assign(t1, unop(Iop_32to16,
7451 binop(Iop_Shr32,
7452 binop(Iop_And32,
7453 mkexpr(t0),
7454 mkU32(0x0001fffe)),
7455 mkU8(0x1))));
7456 /* Add higher halfs of rs and rt
7457 and right shift the result by 1. */
7458 assign(t2, binop(Iop_Add32,
7459 unop(Iop_16Sto32,
7460 unop(Iop_32HIto16, getIReg(rs))),
7461 unop(Iop_16Sto32,
7462 unop(Iop_32HIto16, getIReg(rt)))));
7463 assign(t3, unop(Iop_32to16,
7464 binop(Iop_Shr32,
7465 binop(Iop_And32,
7466 mkexpr(t2),
7467 mkU32(0x0001fffe)),
7468 mkU8(0x1))));
7469 putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
7470 break;
7473 case 0x9: { /* SUBQH.PH */
7474 DIP("subqh.ph r%u, r%u, r%u", rd, rs, rt);
7475 vassert(!mode64);
7477 putIReg(rd, binop(Iop_HSub16Sx2,
7478 getIReg(rs), getIReg(rt)));
7479 break;
7482 case 0xA: {/* ADDQH_R.PH */
7483 DIP("addqh_r.ph r%u, r%u, r%u", rd, rs, rt);
7484 vassert(!mode64);
7485 t0 = newTemp(Ity_I32);
7486 t1 = newTemp(Ity_I16);
7487 t2 = newTemp(Ity_I32);
7488 t3 = newTemp(Ity_I16);
7490 /* Add lower halfs of rs and rt, add 1
7491 and right shift the result by 1. */
7492 assign(t0, binop(Iop_Add32,
7493 unop(Iop_16Sto32,
7494 unop(Iop_32to16, getIReg(rs))),
7495 unop(Iop_16Sto32,
7496 unop(Iop_32to16, getIReg(rt)))));
7497 assign(t1, unop(Iop_32to16,
7498 binop(Iop_Shr32,
7499 binop(Iop_And32,
7500 binop(Iop_Add32,
7501 mkexpr(t0),
7502 mkU32(0x1)),
7503 mkU32(0x0001fffe)),
7504 mkU8(0x1))));
7505 /* Add higher halfs of rs and rt, add 1
7506 and right shift the result by 1. */
7507 assign(t2, binop(Iop_Add32,
7508 unop(Iop_16Sto32,
7509 unop(Iop_32HIto16, getIReg(rs))),
7510 unop(Iop_16Sto32,
7511 unop(Iop_32HIto16, getIReg(rt)))));
7512 assign(t3, unop(Iop_32to16,
7513 binop(Iop_Shr32,
7514 binop(Iop_And32,
7515 binop(Iop_Add32,
7516 mkexpr(t2),
7517 mkU32(0x1)),
7518 mkU32(0x0001fffe)),
7519 mkU8(0x1))));
7521 putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
7522 break;
7525 case 0xB: { /* SUBQH_R.PH */
7526 DIP("subqh_r.ph r%u, r%u, r%u", rd, rs, rt);
7527 vassert(!mode64);
7528 t0 = newTemp(Ity_I32);
7529 t1 = newTemp(Ity_I16);
7530 t2 = newTemp(Ity_I32);
7531 t3 = newTemp(Ity_I16);
7533 /* Sub lower halfs of rs and rt, add 1
7534 and right shift the result by 1. */
7535 assign(t0, binop(Iop_Sub32,
7536 unop(Iop_16Sto32,
7537 unop(Iop_32to16, getIReg(rs))),
7538 unop(Iop_16Sto32,
7539 unop(Iop_32to16, getIReg(rt)))));
7540 assign(t1, unop(Iop_32to16,
7541 binop(Iop_Shr32,
7542 binop(Iop_And32,
7543 binop(Iop_Add32,
7544 mkexpr(t0),
7545 mkU32(0x1)),
7546 mkU32(0x0001fffe)),
7547 mkU8(0x1))));
7548 /* Sub higher halfs of rs and rt, add 1
7549 and right shift the result by 1. */
7550 assign(t2, binop(Iop_Sub32,
7551 unop(Iop_16Sto32,
7552 unop(Iop_32HIto16, getIReg(rs))),
7553 unop(Iop_16Sto32,
7554 unop(Iop_32HIto16, getIReg(rt)))));
7555 assign(t3, unop(Iop_32to16,
7556 binop(Iop_Shr32,
7557 binop(Iop_And32,
7558 binop(Iop_Add32,
7559 mkexpr(t2),
7560 mkU32(0x1)),
7561 mkU32(0x0001fffe)),
7562 mkU8(0x1))));
7564 putIReg(rd, binop(Iop_16HLto32, mkexpr(t3), mkexpr(t1)));
7565 break;
7568 case 0xC: { /* MUL.PH */
7569 DIP("mul.ph r%u, r%u, r%u", rd, rs, rt);
7570 vassert(!mode64);
7571 t0 = newTemp(Ity_I32);
7572 t1 = newTemp(Ity_I32);
7573 t2 = newTemp(Ity_I32);
7575 assign(t0,
7576 binop(Iop_Mul32,
7577 unop(Iop_16Sto32,
7578 unop(Iop_32HIto16, getIReg(rs))),
7579 unop(Iop_16Sto32,
7580 unop(Iop_32HIto16, getIReg(rt)))));
7581 /* DSP Control flag. */
7582 putDSPControl(IRExpr_ITE(unop(Iop_Not1,
7583 binop(Iop_CmpLE32S,
7584 mkexpr(t0),
7585 mkU32(0x7FFF))),
7586 binop(Iop_Or32,
7587 getDSPControl(),
7588 mkU32(0x00200000)),
7589 IRExpr_ITE(binop(Iop_CmpLT32S,
7590 mkexpr(t0),
7591 mkU32(0xFFFF8000)
7593 binop(Iop_Or32,
7594 getDSPControl(),
7595 mkU32(0x00200000)
7597 getDSPControl())));
7599 assign(t1,
7600 binop(Iop_Mul32,
7601 unop(Iop_16Sto32,
7602 unop(Iop_32to16, getIReg(rs))),
7603 unop(Iop_16Sto32,
7604 unop(Iop_32to16, getIReg(rt)))));
7605 /* DSP Control flag. */
7606 putDSPControl(IRExpr_ITE(unop(Iop_Not1,
7607 binop(Iop_CmpLE32S,
7608 mkexpr(t1),
7609 mkU32(0x7FFF))),
7610 binop(Iop_Or32,
7611 getDSPControl(),
7612 mkU32(0x00200000)),
7613 IRExpr_ITE(binop(Iop_CmpLT32S,
7614 mkexpr(t1),
7615 mkU32(0xFFFF8000)
7617 binop(Iop_Or32,
7618 getDSPControl(),
7619 mkU32(0x00200000)
7621 getDSPControl())));
7623 assign(t2, binop(Iop_16HLto32,
7624 unop(Iop_32to16, mkexpr(t0)),
7625 unop(Iop_32to16, mkexpr(t1))));
7626 putIReg(rd, mkexpr(t2));
7627 break;
7630 case 0xE: { /* MUL_S.PH */
7631 DIP("mul_s.ph r%u r%u, r%u", rd, rs, rt);
7632 vassert(!mode64);
7634 t0 = newTemp(Ity_I32);
7635 t1 = newTemp(Ity_I32);
7636 t2 = newTemp(Ity_I32);
7637 t3 = newTemp(Ity_I32);
7638 t4 = newTemp(Ity_I32);
7640 /* t0 - signed intermediate result. */
7641 assign(t0,
7642 binop(Iop_Mul32,
7643 unop(Iop_16Sto32,
7644 unop(Iop_32HIto16, getIReg(rs))),
7645 unop(Iop_16Sto32,
7646 unop(Iop_32HIto16, getIReg(rt)))));
7648 assign(t1,
7649 IRExpr_ITE(unop(Iop_Not1,
7650 binop(Iop_CmpLE32S,
7651 mkexpr(t0),
7652 mkU32(0x7FFF))),
7653 mkU32(0x00007FFF),
7654 IRExpr_ITE(binop(Iop_CmpLT32S,
7655 mkexpr(t0),
7656 mkU32(0xFFFF8000)),
7657 mkU32(0xFFFF8000),
7658 mkexpr(t0))));
7660 /* DSP Control flag. */
7661 putDSPControl(IRExpr_ITE(unop(Iop_Not1,
7662 binop(Iop_CmpLE32S,
7663 mkexpr(t0),
7664 mkU32(0x7FFF))),
7665 binop(Iop_Or32,
7666 getDSPControl(),
7667 mkU32(0x00200000)),
7668 IRExpr_ITE(binop(Iop_CmpLT32S,
7669 mkexpr(t0),
7670 mkU32(0xFFFF8000)
7672 binop(Iop_Or32,
7673 getDSPControl(),
7674 mkU32(0x00200000)
7676 getDSPControl())));
7678 /* t2 - signed intermediate result. */
7679 assign(t2, binop(Iop_Mul32,
7680 unop(Iop_16Sto32,
7681 unop(Iop_32to16, getIReg(rs))),
7682 unop(Iop_16Sto32,
7683 unop(Iop_32to16, getIReg(rt)))));
7685 assign(t3, IRExpr_ITE(unop(Iop_Not1,
7686 binop(Iop_CmpLE32S,
7687 mkexpr(t2),
7688 mkU32(0x7FFF))),
7689 mkU32(0x00007FFF),
7690 IRExpr_ITE(binop(Iop_CmpLT32S,
7691 mkexpr(t2),
7692 mkU32(0xFFFF8000)),
7693 mkU32(0xFFFF8000),
7694 mkexpr(t2))));
7696 /* DSP Control flag. */
7697 putDSPControl(IRExpr_ITE(unop(Iop_Not1,
7698 binop(Iop_CmpLE32S,
7699 mkexpr(t2),
7700 mkU32(0x7FFF))),
7701 binop(Iop_Or32,
7702 getDSPControl(),
7703 mkU32(0x00200000)),
7704 IRExpr_ITE(binop(Iop_CmpLT32S,
7705 mkexpr(t2),
7706 mkU32(0xFFFF8000)
7708 binop(Iop_Or32,
7709 getDSPControl(),
7710 mkU32(0x00200000)
7712 getDSPControl())));
7714 assign(t4, binop(Iop_16HLto32,
7715 unop(Iop_32to16, mkexpr(t1)),
7716 unop(Iop_32to16, mkexpr(t3))));
7717 putIReg(rd, mkexpr(t4));
7718 break;
7721 case 0x10: { /* ADDQH.W */
7722 DIP("addqh.w r%u, r%u, r%u", rd, rs, rt);
7723 vassert(!mode64);
7724 t0 = newTemp(Ity_I64);
7725 t1 = newTemp(Ity_I64);
7727 assign(t0, binop(Iop_Add64,
7728 unop(Iop_32Sto64, getIReg(rs)),
7729 unop(Iop_32Sto64, getIReg(rt))));
7730 assign(t1, binop(Iop_And64,
7731 mkexpr(t0),
7732 mkU64(0x00000001fffffffeULL)));
7733 putIReg(rd, unop(Iop_64to32,
7734 binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
7735 break;
7738 case 0x11: { /* SUBQH.W */
7739 DIP("subqh.w r%u, r%u, r%u", rd, rs, rt);
7740 vassert(!mode64);
7741 t0 = newTemp(Ity_I64);
7742 t1 = newTemp(Ity_I64);
7744 assign(t0, binop(Iop_Sub64,
7745 unop(Iop_32Sto64, getIReg(rs)),
7746 unop(Iop_32Sto64, getIReg(rt))));
7747 assign(t1, binop(Iop_And64,
7748 mkexpr(t0),
7749 mkU64(0x00000001fffffffeULL)));
7750 putIReg(rd, unop(Iop_64to32,
7751 binop(Iop_Shr64, mkexpr(t1), mkU8(0x1))));
7752 break;
7755 case 0x12: { /* ADDQH_R.W */
7756 DIP("addqh_r.w r%u, r%u, r%u", rd, rs, rt);
7757 vassert(!mode64);
7758 t0 = newTemp(Ity_I64);
7759 t1 = newTemp(Ity_I64);
7760 t2 = newTemp(Ity_I64);
7762 assign(t0, binop(Iop_Add64,
7763 unop(Iop_32Sto64, getIReg(rs)),
7764 unop(Iop_32Sto64, getIReg(rt))));
7765 assign(t1, binop(Iop_Add64,
7766 mkexpr(t0),
7767 mkU64(0x0000000000000001ULL)));
7768 assign(t2, binop(Iop_And64,
7769 mkexpr(t1),
7770 mkU64(0x00000001fffffffeULL)));
7771 putIReg(rd, unop(Iop_64to32,
7772 binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
7773 break;
7776 case 0x13: { /* SUBQH_R.W */
7777 DIP("subqh_r.w r%u, r%u, r%u", rd, rs, rt);
7778 vassert(!mode64);
7779 t0 = newTemp(Ity_I64);
7780 t1 = newTemp(Ity_I64);
7781 t2 = newTemp(Ity_I64);
7783 assign(t0, binop(Iop_Sub64,
7784 unop(Iop_32Sto64, getIReg(rs)),
7785 unop(Iop_32Sto64, getIReg(rt))));
7786 assign(t1, binop(Iop_Add64,
7787 mkexpr(t0),
7788 mkU64(0x0000000000000001ULL)));
7789 assign(t2, binop(Iop_And64,
7790 mkexpr(t1),
7791 mkU64(0x00000001fffffffeULL)));
7792 putIReg(rd, unop(Iop_64to32,
7793 binop(Iop_Shr64, mkexpr(t2), mkU8(0x1))));
7794 break;
7797 case 0x16: { /* MULQ_S.W */
7798 DIP("mulq_s.w r%u, r%u, r%u", rd, rs, rt);
7799 vassert(!mode64);
7800 t0 = newTemp(Ity_I64);
7801 t1 = newTemp(Ity_I1);
7802 t2 = newTemp(Ity_I1);
7804 assign(t0, binop(Iop_Shl64,
7805 binop(Iop_MullS32,
7806 getIReg(rt), getIReg(rs)),
7807 mkU8(0x1)));
7808 assign(t1, binop(Iop_CmpEQ32,
7809 getIReg(rt), mkU32(0x80000000)));
7810 assign(t2, binop(Iop_CmpEQ32,
7811 getIReg(rs), mkU32(0x80000000)));
7813 putDSPControl(IRExpr_ITE(mkexpr(t1),
7814 IRExpr_ITE(mkexpr(t2),
7815 binop(Iop_Or32,
7816 getDSPControl(),
7817 mkU32(0x00200000)
7819 getDSPControl()),
7820 getDSPControl()));
7821 putIReg(rd, IRExpr_ITE(mkexpr(t1),
7822 IRExpr_ITE(mkexpr(t2),
7823 mkU32(0x7fffffff),
7824 unop(Iop_64HIto32,
7825 mkexpr(t0))),
7826 unop(Iop_64HIto32, mkexpr(t0))));
7827 break;
7830 case 0x17: { /* MULQ_RS.W */
7831 DIP("mulq_rs.w r%u, r%u, r%u", rd, rs, rt);
7832 vassert(!mode64);
7833 t0 = newTemp(Ity_I64);
7834 t1 = newTemp(Ity_I1);
7835 t2 = newTemp(Ity_I1);
7837 assign(t0, binop(Iop_Add64,
7838 binop(Iop_Shl64,
7839 binop(Iop_MullS32,
7840 getIReg(rt),
7841 getIReg(rs)),
7842 mkU8(0x1)),
7843 mkU64(0x0000000080000000ULL)));
7844 assign(t1,
7845 binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
7846 assign(t2,
7847 binop(Iop_CmpEQ32, getIReg(rs), mkU32(0x80000000)));
7848 putDSPControl(IRExpr_ITE(mkexpr(t1),
7849 IRExpr_ITE(mkexpr(t2),
7850 binop(Iop_Or32,
7851 getDSPControl(),
7852 mkU32(0x00200000)
7854 getDSPControl()),
7855 getDSPControl()));
7856 putIReg(rd, IRExpr_ITE(mkexpr(t1),
7857 IRExpr_ITE(mkexpr(t2),
7858 mkU32(0x7fffffff),
7859 unop(Iop_64HIto32,
7860 mkexpr(t0))),
7861 unop(Iop_64HIto32, mkexpr(t0))));
7862 break;
7865 default:
7866 return -1;
7869 return 0;
7872 static UInt disDSPInstr_MIPS_WRK_Special3_DPAW_PH( UInt cins )
7874 IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10;
7875 UInt rs, rt, sa, ac;
7877 rs = get_rs(cins);
7878 rt = get_rt(cins);
7879 sa = get_sa(cins);
7880 ac = get_acNo(cins);
7882 switch (sa) {
7883 case 0x0: { /* DPA.W.PH */
7884 DIP("dpa.w.ph ac%u, r%u, r%u", ac, rs, rt);
7885 vassert(!mode64);
7887 t0 = newTemp(Ity_I64);
7888 t1 = newTemp(Ity_I64);
7889 t2 = newTemp(Ity_I64);
7891 assign(t0,
7892 unop(Iop_32Sto64,
7893 binop(Iop_Mul32,
7894 unop(Iop_16Sto32,
7895 unop(Iop_32HIto16, getIReg(rs))),
7896 unop(Iop_16Sto32,
7897 unop(Iop_32HIto16, getIReg(rt))))));
7898 assign(t1,
7899 unop(Iop_32Sto64,
7900 binop(Iop_Mul32,
7901 unop(Iop_16Sto32,
7902 unop(Iop_32to16, getIReg(rs))),
7903 unop(Iop_16Sto32,
7904 unop(Iop_32to16, getIReg(rt))))));
7905 assign(t2,
7906 binop(Iop_Add64,
7907 getAcc(ac),
7908 binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
7909 putAcc(ac, mkexpr(t2));
7910 break;
7913 case 0x1: { /* DPS.W.PH */
7914 DIP("dps.w.ph ac%u, r%u, r%u", ac, rs, rt);
7915 vassert(!mode64);
7917 t0 = newTemp(Ity_I64);
7918 t1 = newTemp(Ity_I64);
7919 t2 = newTemp(Ity_I64);
7921 assign(t0,
7922 unop(Iop_32Sto64,
7923 binop(Iop_Mul32,
7924 unop(Iop_16Sto32,
7925 unop(Iop_32HIto16, getIReg(rs))),
7926 unop(Iop_16Sto32,
7927 unop(Iop_32HIto16, getIReg(rt))))));
7928 assign(t1,
7929 unop(Iop_32Sto64,
7930 binop(Iop_Mul32,
7931 unop(Iop_16Sto32,
7932 unop(Iop_32to16, getIReg(rs))),
7933 unop(Iop_16Sto32,
7934 unop(Iop_32to16, getIReg(rt))))));
7935 assign(t2,
7936 binop(Iop_Sub64,
7937 getAcc(ac),
7938 binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
7939 putAcc(ac, mkexpr(t2));
7940 break;
7943 case 0x2: { /* MULSA.W.PH */
7944 DIP("mulsa.w.ph ac%u, r%u, r%u", ac, rs, rt);
7945 vassert(!mode64);
7946 t0 = newTemp(Ity_I32);
7947 t1 = newTemp(Ity_I32);
7948 t2 = newTemp(Ity_I32);
7949 t3 = newTemp(Ity_I1);
7950 t4 = newTemp(Ity_I64);
7952 assign(t4, getAcc(ac));
7953 assign(t0, binop(Iop_Mul32,
7954 unop(Iop_16Sto32,
7955 unop(Iop_32to16, getIReg(rt))),
7956 unop(Iop_16Sto32,
7957 unop(Iop_32to16, getIReg(rs)))));
7958 assign(t1, binop(Iop_Mul32,
7959 unop(Iop_16Sto32,
7960 unop(Iop_32HIto16, getIReg(rt))),
7961 unop(Iop_16Sto32,
7962 unop(Iop_32HIto16, getIReg(rs)))));
7963 assign(t2, binop(Iop_Sub32, mkexpr(t1), mkexpr(t0)));
7964 putAcc(ac, binop(Iop_Add64,
7965 mkexpr(t4),
7966 unop(Iop_32Sto64, mkexpr(t2))));
7967 break;
7970 case 0x3: { /* DPAU.H.QBL */
7971 DIP("dpau.h.qbl ac%u, r%u, r%u", ac, rs, rt);
7972 vassert(!mode64);
7973 t0 = newTemp(Ity_I32);
7974 t1 = newTemp(Ity_I32);
7975 t2 = newTemp(Ity_I64);
7976 t3 = newTemp(Ity_I64);
7978 assign(t0,
7979 binop(Iop_Mul32,
7980 unop(Iop_8Uto32,
7981 unop(Iop_16HIto8,
7982 unop(Iop_32HIto16, getIReg(rs)))),
7983 unop(Iop_8Uto32,
7984 unop(Iop_16HIto8,
7985 unop(Iop_32HIto16, getIReg(rt))))));
7986 assign(t1,
7987 binop(Iop_Mul32,
7988 unop(Iop_8Uto32,
7989 unop(Iop_16to8,
7990 unop(Iop_32HIto16, getIReg(rs)))),
7991 unop(Iop_8Uto32,
7992 unop(Iop_16to8,
7993 unop(Iop_32HIto16, getIReg(rt))))));
7994 assign(t2,
7995 unop(Iop_32Uto64,
7996 binop(Iop_Add32,
7997 mkexpr(t0),
7998 mkexpr(t1))));
7999 assign(t3,
8000 binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
8001 putAcc(ac, mkexpr(t3));
8002 break;
8005 case 0x4: { /* DPAQ_S.W.PH */
8006 DIP("dpaq_s.w.ph ac%u, r%u, r%u", ac, rs, rt);
8007 vassert(!mode64);
8008 t0 = newTemp(Ity_I64);
8009 t1 = newTemp(Ity_I64);
8010 t2 = newTemp(Ity_I1);
8011 t3 = newTemp(Ity_I1);
8012 t4 = newTemp(Ity_I64);
8013 t5 = newTemp(Ity_I64);
8014 t6 = newTemp(Ity_I1);
8015 t7 = newTemp(Ity_I1);
8016 t8 = newTemp(Ity_I64);
8017 t9 = newTemp(Ity_I64);
8019 assign(t0, getAcc(ac));
8021 assign(t1, binop(Iop_Shl64,
8022 binop(Iop_MullS32,
8023 unop(Iop_16Sto32,
8024 unop(Iop_32HIto16,
8025 getIReg(rs))),
8026 unop(Iop_16Sto32,
8027 unop(Iop_32HIto16,
8028 getIReg(rt)))),
8029 mkU8(0x1)));
8030 assign(t2, binop(Iop_CmpEQ32,
8031 unop(Iop_16Uto32,
8032 unop(Iop_32HIto16, getIReg(rs))),
8033 mkU32(0x00008000)));
8034 assign(t3, binop(Iop_CmpEQ32,
8035 unop(Iop_16Uto32,
8036 unop(Iop_32HIto16, getIReg(rt))),
8037 mkU32(0x00008000)));
8038 assign(t4,
8039 IRExpr_ITE(mkexpr(t2),
8040 IRExpr_ITE(mkexpr(t3),
8041 mkU64(0x000000007fffffffULL),
8042 mkexpr(t1)),
8043 mkexpr(t1)));
8045 putDSPControl(IRExpr_ITE(mkexpr(t2),
8046 IRExpr_ITE(mkexpr(t3),
8047 binop(Iop_Or32,
8048 getDSPControl(),
8049 binop(Iop_Shl32,
8050 mkU32(0x1),
8051 mkU8(ac + 16)
8054 getDSPControl()),
8055 getDSPControl()));
8057 assign(t5, binop(Iop_Shl64,
8058 binop(Iop_MullS32,
8059 unop(Iop_16Sto32,
8060 unop(Iop_32to16, getIReg(rs))),
8061 unop(Iop_16Sto32,
8062 unop(Iop_32to16, getIReg(rt)))
8064 mkU8(0x1)));
8065 assign(t6, binop(Iop_CmpEQ32,
8066 unop(Iop_16Uto32,
8067 unop(Iop_32to16, getIReg(rs))),
8068 mkU32(0x00008000)));
8069 assign(t7, binop(Iop_CmpEQ32,
8070 unop(Iop_16Uto32,
8071 unop(Iop_32to16, getIReg(rt))),
8072 mkU32(0x00008000)));
8073 assign(t8,
8074 IRExpr_ITE(mkexpr(t6),
8075 IRExpr_ITE(mkexpr(t7),
8076 mkU64(0x000000007fffffffULL),
8077 mkexpr(t5)),
8078 mkexpr(t5)));
8080 putDSPControl(IRExpr_ITE(mkexpr(t6),
8081 IRExpr_ITE(mkexpr(t7),
8082 binop(Iop_Or32,
8083 getDSPControl(),
8084 binop(Iop_Shl32,
8085 mkU32(0x1),
8086 mkU8(ac + 16)
8089 getDSPControl()),
8090 getDSPControl()));
8092 assign(t9, binop(Iop_Add64,
8093 binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
8094 mkexpr(t0)));
8095 putAcc(ac, mkexpr(t9));
8096 break;
8099 case 0x5: { /* DPSQ_S.W.PH */
8100 DIP("dpsq_s.w.ph ac%u r%u, r%u", ac, rs, rt);
8101 vassert(!mode64);
8102 t0 = newTemp(Ity_I64);
8103 t1 = newTemp(Ity_I64);
8104 t2 = newTemp(Ity_I1);
8105 t3 = newTemp(Ity_I1);
8106 t4 = newTemp(Ity_I64);
8107 t5 = newTemp(Ity_I64);
8108 t6 = newTemp(Ity_I1);
8109 t7 = newTemp(Ity_I1);
8110 t8 = newTemp(Ity_I64);
8111 t9 = newTemp(Ity_I64);
8113 assign(t0, getAcc(ac));
8115 assign(t1, binop(Iop_Shl64,
8116 binop(Iop_MullS32,
8117 unop(Iop_16Sto32,
8118 unop(Iop_32HIto16,
8119 getIReg(rs))),
8120 unop(Iop_16Sto32,
8121 unop(Iop_32HIto16,
8122 getIReg(rt)))),
8123 mkU8(0x1)));
8124 assign(t2, binop(Iop_CmpEQ32,
8125 unop(Iop_16Uto32,
8126 unop(Iop_32HIto16, getIReg(rs))),
8127 mkU32(0x00008000)));
8128 assign(t3, binop(Iop_CmpEQ32,
8129 unop(Iop_16Uto32,
8130 unop(Iop_32HIto16, getIReg(rt))),
8131 mkU32(0x00008000)));
8132 assign(t4,
8133 IRExpr_ITE(mkexpr(t2),
8134 IRExpr_ITE(mkexpr(t3),
8135 mkU64(0x000000007fffffffULL),
8136 mkexpr(t1)),
8137 mkexpr(t1)));
8139 putDSPControl(IRExpr_ITE(mkexpr(t2),
8140 IRExpr_ITE(mkexpr(t3),
8141 binop(Iop_Or32,
8142 getDSPControl(),
8143 binop(Iop_Shl32,
8144 mkU32(0x1),
8145 mkU8(ac + 16)
8148 getDSPControl()),
8149 getDSPControl()));
8151 assign(t5,
8152 binop(Iop_Shl64,
8153 binop(Iop_MullS32,
8154 unop(Iop_16Sto32,
8155 unop(Iop_32to16, getIReg(rs))),
8156 unop(Iop_16Sto32,
8157 unop(Iop_32to16, getIReg(rt)))),
8158 mkU8(0x1)));
8159 assign(t6, binop(Iop_CmpEQ32,
8160 unop(Iop_16Uto32,
8161 unop(Iop_32to16, getIReg(rs))),
8162 mkU32(0x00008000)));
8163 assign(t7, binop(Iop_CmpEQ32,
8164 unop(Iop_16Uto32,
8165 unop(Iop_32to16, getIReg(rt))),
8166 mkU32(0x00008000)));
8167 assign(t8,
8168 IRExpr_ITE(mkexpr(t6),
8169 IRExpr_ITE(mkexpr(t7),
8170 mkU64(0x000000007fffffffULL),
8171 mkexpr(t5)),
8172 mkexpr(t5)));
8174 putDSPControl(IRExpr_ITE(mkexpr(t6),
8175 IRExpr_ITE(mkexpr(t7),
8176 binop(Iop_Or32,
8177 getDSPControl(),
8178 binop(Iop_Shl32,
8179 mkU32(0x1),
8180 mkU8(ac + 16)
8183 getDSPControl()),
8184 getDSPControl()));
8186 assign(t9,
8187 binop(Iop_Sub64,
8188 mkexpr(t0),
8189 binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
8190 putAcc(ac, mkexpr(t9));
8191 break;
8194 case 0x6: { /* MULSAQ_S.W.PH */
8195 DIP("mulsaq_s.w.ph ac%u r%u, r%u", ac, rs, rt);
8196 vassert(!mode64);
8198 t0 = newTemp(Ity_I32);
8199 t1 = newTemp(Ity_I32);
8200 t2 = newTemp(Ity_I32);
8201 t3 = newTemp(Ity_I32);
8202 t4 = newTemp(Ity_I32);
8203 t5 = newTemp(Ity_I32);
8204 t6 = newTemp(Ity_I64);
8205 t7 = newTemp(Ity_I64);
8206 t8 = newTemp(Ity_I32);
8207 t9 = newTemp(Ity_I32);
8209 assign(t0, unop(Iop_16Sto32,
8210 unop(Iop_32HIto16, getIReg(rs))));
8211 assign(t1, unop(Iop_16Sto32,
8212 unop(Iop_32HIto16, getIReg(rt))));
8214 assign(t8, binop(Iop_And32,
8215 unop(Iop_1Sto32,
8216 binop(Iop_CmpEQ32,
8217 unop(Iop_16Uto32,
8218 unop(Iop_32HIto16,
8219 getIReg(rs))),
8220 mkU32(0x8000))),
8221 unop(Iop_1Sto32,
8222 binop(Iop_CmpEQ32,
8223 unop(Iop_16Uto32,
8224 unop(Iop_32HIto16,
8225 getIReg(rt))),
8226 mkU32(0x8000)))));
8227 /* DSPControl_outflag:16+acc <- 1 */
8228 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
8229 mkexpr(t8),
8230 mkU32(0x0)),
8231 binop(Iop_Or32,
8232 getDSPControl(),
8233 binop(Iop_Shl32,
8234 mkU32(0x00010000),
8235 mkU8(ac))),
8236 getDSPControl()));
8238 /* tempB_31..0 */
8239 assign(t2,
8240 IRExpr_ITE(binop(Iop_CmpNE32,
8241 mkexpr(t8), mkU32(0x0)),
8242 mkU32(0x7FFFFFFF),
8243 binop(Iop_Shl32,
8244 binop(Iop_Mul32,
8245 mkexpr(t0), mkexpr(t1)),
8246 mkU8(1))));
8248 assign(t3, unop(Iop_16Sto32,
8249 unop(Iop_32to16, getIReg(rs))));
8250 assign(t4, unop(Iop_16Sto32,
8251 unop(Iop_32to16, getIReg(rt))));
8253 assign(t9, binop(Iop_And32,
8254 unop(Iop_1Sto32,
8255 binop(Iop_CmpEQ32,
8256 unop(Iop_16Uto32,
8257 unop(Iop_32to16,
8258 getIReg(rs))),
8259 mkU32(0x8000))),
8260 unop(Iop_1Sto32,
8261 binop(Iop_CmpEQ32,
8262 unop(Iop_16Uto32,
8263 unop(Iop_32to16,
8264 getIReg(rt))),
8265 mkU32(0x8000)))));
8266 /* DSPControl_outflag:16+acc <- 1 */
8267 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
8268 mkexpr(t9),
8269 mkU32(0x0)),
8270 binop(Iop_Or32,
8271 getDSPControl(),
8272 binop(Iop_Shl32,
8273 mkU32(0x00010000),
8274 mkU8(ac))),
8275 getDSPControl()));
8276 /* tempA_31..0 */
8277 assign(t5,
8278 IRExpr_ITE(binop(Iop_CmpNE32,
8279 mkexpr(t9),
8280 mkU32(0x0)),
8281 mkU32(0x7FFFFFFF),
8282 binop(Iop_Shl32,
8283 binop(Iop_Mul32,
8284 mkexpr(t3),
8285 mkexpr(t4)),
8286 mkU8(1))));
8287 /* dotp_63..0 */
8288 assign(t6,
8289 binop(Iop_Sub64,
8290 unop(Iop_32Sto64, mkexpr(t2)),
8291 unop(Iop_32Sto64, mkexpr(t5))));
8292 /* tempC_63..0 */
8293 assign(t7, binop(Iop_Add64, getAcc(ac), mkexpr(t6)));
8295 putAcc(ac, mkexpr(t7));
8296 break;
8299 case 0x7: { /* DPAU.H.QBR */
8300 DIP("dpau.h.qbr ac%u, r%u, r%u", ac, rs, rt);
8301 vassert(!mode64);
8302 t0 = newTemp(Ity_I32);
8303 t1 = newTemp(Ity_I32);
8304 t2 = newTemp(Ity_I64);
8305 t3 = newTemp(Ity_I64);
8307 assign(t0,
8308 binop(Iop_Mul32,
8309 unop(Iop_8Uto32,
8310 unop(Iop_16HIto8,
8311 unop(Iop_32to16, getIReg(rs)))),
8312 unop(Iop_8Uto32,
8313 unop(Iop_16HIto8,
8314 unop(Iop_32to16, getIReg(rt))))));
8315 assign(t1,
8316 binop(Iop_Mul32,
8317 unop(Iop_8Uto32,
8318 unop(Iop_16to8,
8319 unop(Iop_32to16, getIReg(rs)))),
8320 unop(Iop_8Uto32,
8321 unop(Iop_16to8,
8322 unop(Iop_32to16, getIReg(rt))))));
8323 assign(t2, unop(Iop_32Uto64,
8324 binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
8325 assign(t3, binop(Iop_Add64, getAcc(ac), mkexpr(t2)));
8326 putAcc(ac, mkexpr(t3));
8327 break;
8330 case 0x8: { /* DPAX.W.PH */
8331 DIP("dpax.w.ph ac%u, r%u, r%u", ac, rs, rt);
8332 vassert(!mode64);
8333 t0 = newTemp(Ity_I64);
8334 t1 = newTemp(Ity_I64);
8335 t2 = newTemp(Ity_I64);
8337 assign(t0,
8338 unop(Iop_32Sto64,
8339 binop(Iop_Mul32,
8340 unop(Iop_16Sto32,
8341 unop(Iop_32HIto16, getIReg(rs))),
8342 unop(Iop_16Sto32,
8343 unop(Iop_32to16, getIReg(rt))))));
8344 assign(t1,
8345 unop(Iop_32Sto64,
8346 binop(Iop_Mul32,
8347 unop(Iop_16Sto32,
8348 unop(Iop_32to16, getIReg(rs))),
8349 unop(Iop_16Sto32,
8350 unop(Iop_32HIto16, getIReg(rt))))));
8351 assign(t2,
8352 binop(Iop_Add64,
8353 getAcc(ac),
8354 binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
8355 putAcc(ac, mkexpr(t2));
8356 break;
8359 case 0x9: { /* DPSX.W.PH */
8360 DIP("dpsx.w.ph ac%u r%u, r%u", ac, rs, rt);
8361 vassert(!mode64);
8363 t0 = newTemp(Ity_I64);
8364 t1 = newTemp(Ity_I64);
8365 t2 = newTemp(Ity_I64);
8367 assign(t0,
8368 unop(Iop_32Sto64,
8369 binop(Iop_Mul32,
8370 unop(Iop_16Sto32,
8371 unop(Iop_32HIto16, getIReg(rs))),
8372 unop(Iop_16Sto32,
8373 unop(Iop_32to16, getIReg(rt))))));
8374 assign(t1,
8375 unop(Iop_32Sto64,
8376 binop(Iop_Mul32,
8377 unop(Iop_16Sto32,
8378 unop(Iop_32to16, getIReg(rs))),
8379 unop(Iop_16Sto32,
8380 unop(Iop_32HIto16, getIReg(rt))))));
8381 assign(t2,
8382 binop(Iop_Sub64,
8383 getAcc(ac),
8384 binop(Iop_Add64, mkexpr(t0), mkexpr(t1))));
8385 putAcc(ac, mkexpr(t2));
8386 break;
8389 case 0xB: { /* DPSU.H.QBL */
8390 DIP("dpsu.h.qbl ac%u, r%u, r%u", ac, rs, rt);
8391 vassert(!mode64);
8393 t0 = newTemp(Ity_I32);
8394 t1 = newTemp(Ity_I32);
8395 t2 = newTemp(Ity_I64);
8396 t3 = newTemp(Ity_I64);
8398 assign(t0,
8399 binop(Iop_Mul32,
8400 unop(Iop_8Uto32,
8401 unop(Iop_16HIto8,
8402 unop(Iop_32HIto16, getIReg(rs)))),
8403 unop(Iop_8Uto32,
8404 unop(Iop_16HIto8,
8405 unop(Iop_32HIto16, getIReg(rt))))));
8406 assign(t1,
8407 binop(Iop_Mul32,
8408 unop(Iop_8Uto32,
8409 unop(Iop_16to8,
8410 unop(Iop_32HIto16, getIReg(rs)))),
8411 unop(Iop_8Uto32,
8412 unop(Iop_16to8,
8413 unop(Iop_32HIto16, getIReg(rt))))));
8414 assign(t2,
8415 unop(Iop_32Uto64,
8416 binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
8417 assign(t3,
8418 binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
8419 putAcc(ac, mkexpr(t3));
8420 break;
8423 case 0xC: { /* DPAQ_SA.L.W */
8424 DIP("dpaq_sa.l.w ac%u, r%u, r%u", ac, rs, rt);
8425 vassert(!mode64);
8426 t0 = newTemp(Ity_I64);
8427 t1 = newTemp(Ity_I64);
8428 t2 = newTemp(Ity_I1);
8429 t3 = newTemp(Ity_I1);
8430 t4 = newTemp(Ity_I64);
8431 t5 = newTemp(Ity_I64);
8432 t6 = newTemp(Ity_I64);
8433 t7 = newTemp(Ity_I64);
8434 t8 = newTemp(Ity_I1);
8435 t9 = newTemp(Ity_I1);
8437 assign(t0, getAcc(ac));
8439 assign(t1, binop(Iop_Shl64,
8440 binop(Iop_MullS32,
8441 getIReg(rs), getIReg(rt)),
8442 mkU8(0x1)));
8444 assign(t2, binop(Iop_CmpEQ32,
8445 getIReg(rs),
8446 mkU32(0x80000000)));
8447 assign(t3, binop(Iop_CmpEQ32,
8448 getIReg(rt),
8449 mkU32(0x80000000)));
8451 assign(t4,
8452 IRExpr_ITE(mkexpr(t2),
8453 IRExpr_ITE(mkexpr(t3),
8454 mkU64(0x7fffffffffffffffULL),
8455 mkexpr(t1)),
8456 mkexpr(t1)));
8458 putDSPControl(IRExpr_ITE(mkexpr(t2),
8459 IRExpr_ITE(mkexpr(t3),
8460 binop(Iop_Or32,
8461 getDSPControl(),
8462 binop(Iop_Shl32,
8463 mkU32(0x1),
8464 mkU8(ac + 16)
8467 getDSPControl()),
8468 getDSPControl()));
8470 assign(t5, binop(Iop_Add64,
8471 unop(Iop_32Uto64,
8472 unop(Iop_64to32, mkexpr(t0))),
8473 unop(Iop_32Uto64,
8474 unop(Iop_64to32, mkexpr(t4)))));
8475 assign(t6,
8476 binop(Iop_Add64,
8477 binop(Iop_Add64,
8478 unop(Iop_32Sto64,
8479 unop(Iop_64HIto32, mkexpr(t0))),
8480 unop(Iop_32Sto64,
8481 unop(Iop_64HIto32, mkexpr(t4)))),
8482 unop(Iop_32Uto64,
8483 binop(Iop_And32,
8484 unop(Iop_64HIto32, mkexpr(t5)),
8485 mkU32(0x1)))));
8486 assign(t7, binop(Iop_32HLto64,
8487 unop(Iop_64to32, mkexpr(t6)),
8488 unop(Iop_64to32, mkexpr(t5))));
8489 assign(t8, binop(Iop_CmpEQ32,
8490 binop(Iop_Shr32,
8491 binop(Iop_And32,
8492 unop(Iop_64to32, mkexpr(t6)),
8493 mkU32(0x80000000)),
8494 mkU8(31)),
8495 binop(Iop_And32,
8496 unop(Iop_64HIto32, mkexpr(t6)),
8497 mkU32(0x00000001))));
8498 assign(t9, binop(Iop_CmpEQ32,
8499 binop(Iop_And32,
8500 unop(Iop_64HIto32,
8501 mkexpr(t6)),
8502 mkU32(0x00000001)),
8503 mkU32(0x1)));
8504 putDSPControl(IRExpr_ITE(mkexpr(t8),
8505 getDSPControl(),
8506 binop(Iop_Or32,
8507 getDSPControl(),
8508 binop(Iop_Shl32,
8509 mkU32(0x1),
8510 mkU8(ac + 16)))));
8511 putAcc(ac,
8512 IRExpr_ITE(mkexpr(t8),
8513 mkexpr(t7),
8514 IRExpr_ITE(mkexpr(t9),
8515 mkU64(0x8000000000000000ULL),
8516 mkU64(0x7fffffffffffffffULL)))
8518 break;
8521 case 0xD: { /* DPSQ_SA.L.W */
8522 DIP("dpsq_sa.l.w ac%u, r%u, r%u", ac, rs, rt);
8523 vassert(!mode64);
8524 t0 = newTemp(Ity_I64);
8525 t1 = newTemp(Ity_I64);
8526 t2 = newTemp(Ity_I1);
8527 t3 = newTemp(Ity_I1);
8528 t4 = newTemp(Ity_I64);
8529 t5 = newTemp(Ity_I64);
8530 t6 = newTemp(Ity_I64);
8531 t7 = newTemp(Ity_I64);
8532 t8 = newTemp(Ity_I1);
8533 t9 = newTemp(Ity_I1);
8535 assign(t0, getAcc(ac));
8537 assign(t1, binop(Iop_Shl64,
8538 binop(Iop_MullS32,
8539 getIReg(rs), getIReg(rt)),
8540 mkU8(0x1)));
8542 assign(t2, binop(Iop_CmpEQ32,
8543 getIReg(rs),
8544 mkU32(0x80000000)));
8545 assign(t3, binop(Iop_CmpEQ32,
8546 getIReg(rt),
8547 mkU32(0x80000000)));
8549 assign(t4,
8550 IRExpr_ITE(mkexpr(t2),
8551 IRExpr_ITE(mkexpr(t3),
8552 mkU64(0x7fffffffffffffffULL),
8553 mkexpr(t1)),
8554 mkexpr(t1)));
8556 putDSPControl(IRExpr_ITE(mkexpr(t2),
8557 IRExpr_ITE(mkexpr(t3),
8558 binop(Iop_Or32,
8559 getDSPControl(),
8560 binop(Iop_Shl32,
8561 mkU32(0x1),
8562 mkU8(ac + 16)
8565 getDSPControl()),
8566 getDSPControl()));
8568 assign(t5, binop(Iop_Sub64,
8569 unop(Iop_32Uto64,
8570 unop(Iop_64to32, mkexpr(t0))),
8571 unop(Iop_32Uto64,
8572 unop(Iop_64to32, mkexpr(t4)))));
8573 assign(t6, binop(Iop_Sub64,
8574 binop(Iop_Add64,
8575 unop(Iop_32Sto64,
8576 unop(Iop_64HIto32, mkexpr(t0))
8578 unop(Iop_32Sto64,
8579 unop(Iop_1Sto32,
8580 binop(Iop_CmpLT32U,
8581 unop(Iop_64to32,
8582 mkexpr(t0)),
8583 unop(Iop_64to32,
8584 mkexpr(t4)))))),
8585 unop(Iop_32Sto64,
8586 unop(Iop_64HIto32, mkexpr(t4)))));
8587 assign(t7, binop(Iop_32HLto64,
8588 unop(Iop_64to32, mkexpr(t6)),
8589 unop(Iop_64to32, mkexpr(t5))));
8590 assign(t8, binop(Iop_CmpEQ32,
8591 binop(Iop_Shr32,
8592 binop(Iop_And32,
8593 unop(Iop_64to32, mkexpr(t6)),
8594 mkU32(0x80000000)),
8595 mkU8(31)),
8596 binop(Iop_And32,
8597 unop(Iop_64HIto32, mkexpr(t6)),
8598 mkU32(0x00000001))));
8599 assign(t9, binop(Iop_CmpEQ32,
8600 binop(Iop_And32,
8601 unop(Iop_64HIto32, mkexpr(t6)),
8602 mkU32(0x00000001)),
8603 mkU32(0x1)));
8604 putDSPControl(IRExpr_ITE(mkexpr(t8),
8605 getDSPControl(),
8606 binop(Iop_Or32,
8607 getDSPControl(),
8608 binop(Iop_Shl32,
8609 mkU32(0x1),
8610 mkU8(ac + 16)))));
8611 putAcc(ac,
8612 IRExpr_ITE(mkexpr(t8),
8613 mkexpr(t7),
8614 IRExpr_ITE(mkexpr(t9),
8615 mkU64(0x8000000000000000ULL),
8616 mkU64(0x7fffffffffffffffULL)))
8618 break;
8621 case 0xF: { /* DPSU.H.QBR */
8622 DIP("dpsu.h.qbr ac%u r%u, r%u", ac, rs, rt);
8623 vassert(!mode64);
8625 t0 = newTemp(Ity_I32);
8626 t1 = newTemp(Ity_I32);
8627 t2 = newTemp(Ity_I64);
8628 t3 = newTemp(Ity_I64);
8630 assign(t0,
8631 binop(Iop_Mul32,
8632 unop(Iop_8Uto32,
8633 unop(Iop_16HIto8,
8634 unop(Iop_32to16, getIReg(rs)))),
8635 unop(Iop_8Uto32,
8636 unop(Iop_16HIto8,
8637 unop(Iop_32to16, getIReg(rt))))));
8638 assign(t1,
8639 binop(Iop_Mul32,
8640 unop(Iop_8Uto32,
8641 unop(Iop_16to8,
8642 unop(Iop_32to16, getIReg(rs)))),
8643 unop(Iop_8Uto32,
8644 unop(Iop_16to8,
8645 unop(Iop_32to16, getIReg(rt))))));
8646 assign(t2, unop(Iop_32Uto64,
8647 binop(Iop_Add32, mkexpr(t0), mkexpr(t1))));
8648 assign(t3, binop(Iop_Sub64, getAcc(ac), mkexpr(t2)));
8649 putAcc(ac, mkexpr(t3));
8651 break;
8654 case 0x10: { /* MAQ_SA.W.PHL */
8655 DIP("maq_sa.w.phl ac%u, r%u, r%u", ac, rs, rt);
8656 vassert(!mode64);
8657 t0 = newTemp(Ity_I64);
8658 t1 = newTemp(Ity_I64);
8659 t2 = newTemp(Ity_I1);
8660 t3 = newTemp(Ity_I1);
8661 t4 = newTemp(Ity_I64);
8662 t5 = newTemp(Ity_I64);
8663 t6 = newTemp(Ity_I1);
8664 t7 = newTemp(Ity_I64);
8666 assign(t0, getAcc(ac));
8667 assign(t1, unop(Iop_32Sto64,
8668 binop(Iop_Shl32,
8669 binop(Iop_Mul32,
8670 unop(Iop_16Sto32,
8671 unop(Iop_32HIto16,
8672 getIReg(rs))),
8673 unop(Iop_16Sto32,
8674 unop(Iop_32HIto16,
8675 getIReg(rt)))),
8676 mkU8(0x1))));
8678 /* If both input arguments are equal 0x8000, saturate
8679 intermediate product and write to DSPControl register.
8681 assign(t2, binop(Iop_CmpEQ32,
8682 unop(Iop_16Uto32,
8683 unop(Iop_32HIto16, getIReg(rs))),
8684 mkU32(0x00008000)));
8685 assign(t3, binop(Iop_CmpEQ32,
8686 unop(Iop_16Uto32,
8687 unop(Iop_32HIto16, getIReg(rt))),
8688 mkU32(0x00008000)));
8690 assign(t4,
8691 IRExpr_ITE(mkexpr(t2),
8692 IRExpr_ITE(mkexpr(t3),
8693 mkU64(0x000000007fffffffULL),
8694 mkexpr(t1)),
8695 mkexpr(t1)));
8697 putDSPControl(IRExpr_ITE(mkexpr(t2),
8698 IRExpr_ITE(mkexpr(t3),
8699 binop(Iop_Or32,
8700 getDSPControl(),
8701 binop(Iop_Shl32,
8702 mkU32(0x1),
8703 mkU8(ac + 16)
8706 getDSPControl()),
8707 getDSPControl()));
8708 /* Add intermediate product and value in the
8709 accumulator. */
8710 assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
8712 /* Compare bits 31 and 32 of the value in t5. */
8713 assign(t6, binop(Iop_CmpEQ32,
8714 binop(Iop_Shr32,
8715 binop(Iop_And32,
8716 unop(Iop_64to32, mkexpr(t5)),
8717 mkU32(0x80000000)),
8718 mkU8(31)),
8719 binop(Iop_And32,
8720 unop(Iop_64HIto32, mkexpr(t5)),
8721 mkU32(1))));
8722 putDSPControl(IRExpr_ITE(mkexpr(t6),
8723 getDSPControl(),
8724 binop(Iop_Or32,
8725 getDSPControl(),
8726 binop(Iop_Shl32,
8727 mkU32(0x1),
8728 mkU8(ac + 16)))));
8729 assign(t7,
8730 IRExpr_ITE(mkexpr(t6),
8731 mkexpr(t5),
8732 IRExpr_ITE(binop(Iop_CmpEQ32,
8733 binop(Iop_And32,
8734 unop(Iop_64HIto32,
8735 mkexpr(t5)),
8736 mkU32(1)),
8737 mkU32(0x0)),
8738 mkU64(0x000000007fffffffULL),
8739 mkU64(0xffffffff80000000ULL)))
8741 putAcc(ac, mkexpr(t7));
8742 break;
8745 case 0x12: { /* MAQ_SA.W.PHR */
8746 DIP("maq_sa.w.phr ac%u, r%u, r%u", ac, rs, rt);
8747 vassert(!mode64);
8748 t0 = newTemp(Ity_I64);
8749 t1 = newTemp(Ity_I64);
8750 t2 = newTemp(Ity_I1);
8751 t3 = newTemp(Ity_I1);
8752 t4 = newTemp(Ity_I64);
8753 t5 = newTemp(Ity_I64);
8754 t6 = newTemp(Ity_I1);
8755 t7 = newTemp(Ity_I64);
8757 assign(t0, getAcc(ac));
8758 assign(t1, unop(Iop_32Sto64,
8759 binop(Iop_Shl32,
8760 binop(Iop_Mul32,
8761 unop(Iop_16Sto32,
8762 unop(Iop_32to16,
8763 getIReg(rs))),
8764 unop(Iop_16Sto32,
8765 unop(Iop_32to16,
8766 getIReg(rt)))),
8767 mkU8(0x1))));
8769 /* If both input arguments are equal 0x8000, saturate
8770 intermediate product and write to DSPControl
8771 register. */
8772 assign(t2, binop(Iop_CmpEQ32,
8773 unop(Iop_16Uto32,
8774 unop(Iop_32to16, getIReg(rs))),
8775 mkU32(0x00008000)));
8776 assign(t3, binop(Iop_CmpEQ32,
8777 unop(Iop_16Uto32,
8778 unop(Iop_32to16, getIReg(rt))),
8779 mkU32(0x00008000)));
8781 assign(t4,
8782 IRExpr_ITE(mkexpr(t2),
8783 IRExpr_ITE(mkexpr(t3),
8784 mkU64(0x000000007fffffffULL),
8785 mkexpr(t1)),
8786 mkexpr(t1)));
8788 putDSPControl(IRExpr_ITE(mkexpr(t2),
8789 IRExpr_ITE(mkexpr(t3),
8790 binop(Iop_Or32,
8791 getDSPControl(),
8792 binop(Iop_Shl32,
8793 mkU32(0x1),
8794 mkU8(ac + 16)
8797 getDSPControl()),
8798 getDSPControl()));
8799 /* Add intermediate product and value in the
8800 accumulator. */
8801 assign(t5, binop(Iop_Add64, mkexpr(t0), mkexpr(t4)));
8803 /* Compare bits 31 and 32 of the value in t5. */
8804 assign(t6, binop(Iop_CmpEQ32,
8805 binop(Iop_Shr32,
8806 binop(Iop_And32,
8807 unop(Iop_64to32, mkexpr(t5)),
8808 mkU32(0x80000000)),
8809 mkU8(31)),
8810 binop(Iop_And32,
8811 unop(Iop_64HIto32, mkexpr(t5)),
8812 mkU32(1))));
8813 putDSPControl(IRExpr_ITE(mkexpr(t6),
8814 getDSPControl(),
8815 binop(Iop_Or32,
8816 getDSPControl(),
8817 binop(Iop_Shl32,
8818 mkU32(0x1),
8819 mkU8(ac + 16)))));
8820 assign(t7,
8821 IRExpr_ITE(mkexpr(t6),
8822 mkexpr(t5),
8823 IRExpr_ITE(binop(Iop_CmpEQ32,
8824 binop(Iop_And32,
8825 unop(Iop_64HIto32,
8826 mkexpr(t5)),
8827 mkU32(1)),
8828 mkU32(0x0)),
8829 mkU64(0x000000007fffffffULL),
8830 mkU64(0xffffffff80000000ULL)))
8832 putAcc(ac, mkexpr(t7));
8833 break;
8836 case 0x14: { /* MAQ_S.W.PHL */
8837 DIP("maq_s.w.phl ac%u, r%u, r%u", ac, rs, rt);
8838 vassert(!mode64);
8839 t0 = newTemp(Ity_I32);
8840 t1 = newTemp(Ity_I32);
8841 t2 = newTemp(Ity_I32);
8842 t3 = newTemp(Ity_I1);
8843 t4 = newTemp(Ity_I32);
8844 t5 = newTemp(Ity_I64);
8846 assign(t5, getAcc(ac));
8848 assign(t0, unop(Iop_16Sto32,
8849 unop(Iop_32HIto16, getIReg(rs))));
8850 assign(t1, unop(Iop_16Sto32,
8851 unop(Iop_32HIto16, getIReg(rt))));
8853 assign(t2, binop(Iop_And32,
8854 unop(Iop_1Sto32,
8855 binop(Iop_CmpEQ32,
8856 binop(Iop_And32,
8857 mkexpr(t0),
8858 mkU32(0xffff)),
8859 mkU32(0x8000))),
8860 unop(Iop_1Sto32,
8861 binop(Iop_CmpEQ32,
8862 binop(Iop_And32,
8863 mkexpr(t1),
8864 mkU32(0xffff)),
8865 mkU32(0x8000)))));
8867 assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
8869 putDSPControl(IRExpr_ITE(mkexpr(t3),
8870 getDSPControl(),
8871 binop(Iop_Or32,
8872 getDSPControl(),
8873 binop(Iop_Shl32,
8874 mkU32(0x1),
8875 mkU8(ac + 16)))));
8877 assign(t4, unop(Iop_64to32,
8878 binop(Iop_MullS32,
8879 mkexpr(t0), mkexpr(t1))));
8880 putAcc(ac, IRExpr_ITE(mkexpr(t3),
8881 binop(Iop_Add64,
8882 unop(Iop_32Sto64,
8883 binop(Iop_Shl32,
8884 mkexpr(t4),
8885 mkU8(0x1))),
8886 mkexpr(t5)),
8887 binop(Iop_Add64,
8888 mkexpr(t5),
8889 unop(Iop_32Sto64,
8890 mkU32(0x7fffffff)))));
8891 break;
8894 case 0x16: { /* MAQ_S.W.PHR */
8895 DIP("maq_s.w.phr ac%u, r%u, r%u", ac, rs, rt);
8896 vassert(!mode64);
8897 t0 = newTemp(Ity_I32);
8898 t1 = newTemp(Ity_I32);
8899 t2 = newTemp(Ity_I32);
8900 t3 = newTemp(Ity_I1);
8901 t4 = newTemp(Ity_I32);
8902 t5 = newTemp(Ity_I64);
8904 assign(t5, getAcc(ac));
8906 assign(t0, unop(Iop_16Sto32,
8907 unop(Iop_32to16, getIReg(rs))));
8908 assign(t1, unop(Iop_16Sto32,
8909 unop(Iop_32to16, getIReg(rt))));
8911 assign(t2, binop(Iop_And32,
8912 unop(Iop_1Sto32,
8913 binop(Iop_CmpEQ32,
8914 binop(Iop_And32,
8915 mkexpr(t0),
8916 mkU32(0xffff)),
8917 mkU32(0x8000))),
8918 unop(Iop_1Sto32,
8919 binop(Iop_CmpEQ32,
8920 binop(Iop_And32,
8921 mkexpr(t1),
8922 mkU32(0xffff)),
8923 mkU32(0x8000)))));
8925 assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x0)));
8927 putDSPControl(IRExpr_ITE(mkexpr(t3),
8928 getDSPControl(),
8929 binop(Iop_Or32,
8930 getDSPControl(),
8931 binop(Iop_Shl32,
8932 mkU32(0x1),
8933 mkU8(ac + 16)))));
8935 assign(t4, unop(Iop_64to32,
8936 binop(Iop_MullS32,
8937 mkexpr(t0), mkexpr(t1))));
8938 putAcc(ac, IRExpr_ITE(mkexpr(t3),
8939 binop(Iop_Add64,
8940 unop(Iop_32Sto64,
8941 binop(Iop_Shl32,
8942 mkexpr(t4),
8943 mkU8(0x1))),
8944 mkexpr(t5)),
8945 binop(Iop_Add64,
8946 mkexpr(t5),
8947 unop(Iop_32Sto64,
8948 mkU32(0x7fffffff)))));
8949 break;
8952 case 0x18: { /* DPAQX_S.W.PH */
8953 DIP("dpaqx_s.w.ph ac%u, r%u, r%u", ac, rs, rt);
8954 vassert(!mode64);
8955 t0 = newTemp(Ity_I64);
8956 t1 = newTemp(Ity_I64);
8957 t2 = newTemp(Ity_I1);
8958 t3 = newTemp(Ity_I1);
8959 t4 = newTemp(Ity_I64);
8960 t5 = newTemp(Ity_I64);
8961 t6 = newTemp(Ity_I1);
8962 t7 = newTemp(Ity_I1);
8963 t8 = newTemp(Ity_I64);
8964 t9 = newTemp(Ity_I64);
8966 assign(t0, getAcc(ac));
8968 assign(t1, binop(Iop_Shl64,
8969 binop(Iop_MullS32,
8970 unop(Iop_16Sto32,
8971 unop(Iop_32HIto16,
8972 getIReg(rs))),
8973 unop(Iop_16Sto32,
8974 unop(Iop_32to16,
8975 getIReg(rt)))),
8976 mkU8(0x1)));
8977 assign(t2, binop(Iop_CmpEQ32,
8978 unop(Iop_16Uto32,
8979 unop(Iop_32HIto16, getIReg(rs))),
8980 mkU32(0x00008000)));
8981 assign(t3, binop(Iop_CmpEQ32,
8982 unop(Iop_16Uto32,
8983 unop(Iop_32to16, getIReg(rt))),
8984 mkU32(0x00008000)));
8985 assign(t4,
8986 IRExpr_ITE(mkexpr(t2),
8987 IRExpr_ITE(mkexpr(t3),
8988 mkU64(0x000000007fffffffULL),
8989 mkexpr(t1)),
8990 mkexpr(t1)));
8992 putDSPControl(IRExpr_ITE(mkexpr(t2),
8993 IRExpr_ITE(mkexpr(t3),
8994 binop(Iop_Or32,
8995 getDSPControl(),
8996 binop(Iop_Shl32,
8997 mkU32(0x1),
8998 mkU8(ac + 16))),
8999 getDSPControl()),
9000 getDSPControl()));
9002 assign(t5, binop(Iop_Shl64,
9003 binop(Iop_MullS32,
9004 unop(Iop_16Sto32,
9005 unop(Iop_32to16,
9006 getIReg(rs))),
9007 unop(Iop_16Sto32,
9008 unop(Iop_32HIto16,
9009 getIReg(rt)))),
9010 mkU8(0x1)));
9011 assign(t6, binop(Iop_CmpEQ32,
9012 unop(Iop_16Uto32,
9013 unop(Iop_32to16, getIReg(rs))),
9014 mkU32(0x00008000)));
9015 assign(t7, binop(Iop_CmpEQ32,
9016 unop(Iop_16Uto32,
9017 unop(Iop_32HIto16, getIReg(rt))),
9018 mkU32(0x00008000)));
9019 assign(t8,
9020 IRExpr_ITE(mkexpr(t6),
9021 IRExpr_ITE(mkexpr(t7),
9022 mkU64(0x000000007fffffffULL),
9023 mkexpr(t5)),
9024 mkexpr(t5)));
9026 putDSPControl(IRExpr_ITE(mkexpr(t6),
9027 IRExpr_ITE(mkexpr(t7),
9028 binop(Iop_Or32,
9029 getDSPControl(),
9030 binop(Iop_Shl32,
9031 mkU32(0x1),
9032 mkU8(ac + 16)
9035 getDSPControl()),
9036 getDSPControl()));
9038 assign(t9, binop(Iop_Add64,
9039 binop(Iop_Add64, mkexpr(t4), mkexpr(t8)),
9040 mkexpr(t0)));
9041 putAcc(ac, mkexpr(t9));
9042 break;
9045 case 0x19: { /* DPSQX_S.W.PH */
9046 DIP("dpsqx_s.w.ph ac%u, r%u, r%u", ac, rs, rt);
9047 vassert(!mode64);
9048 t0 = newTemp(Ity_I64);
9049 t1 = newTemp(Ity_I64);
9050 t2 = newTemp(Ity_I1);
9051 t3 = newTemp(Ity_I1);
9052 t4 = newTemp(Ity_I64);
9053 t5 = newTemp(Ity_I64);
9054 t6 = newTemp(Ity_I1);
9055 t7 = newTemp(Ity_I1);
9056 t8 = newTemp(Ity_I64);
9057 t9 = newTemp(Ity_I64);
9059 assign(t0, getAcc(ac));
9061 assign(t1, binop(Iop_Shl64,
9062 binop(Iop_MullS32,
9063 unop(Iop_16Sto32,
9064 unop(Iop_32HIto16,
9065 getIReg(rs))),
9066 unop(Iop_16Sto32,
9067 unop(Iop_32to16,
9068 getIReg(rt)))),
9069 mkU8(0x1)));
9070 assign(t2, binop(Iop_CmpEQ32,
9071 unop(Iop_16Uto32,
9072 unop(Iop_32HIto16, getIReg(rs))),
9073 mkU32(0x00008000)));
9074 assign(t3, binop(Iop_CmpEQ32,
9075 unop(Iop_16Uto32,
9076 unop(Iop_32to16, getIReg(rt))),
9077 mkU32(0x00008000)));
9078 assign(t4,
9079 IRExpr_ITE(mkexpr(t2),
9080 IRExpr_ITE(mkexpr(t3),
9081 mkU64(0x000000007fffffffULL),
9082 mkexpr(t1)),
9083 mkexpr(t1)));
9085 putDSPControl(IRExpr_ITE(mkexpr(t2),
9086 IRExpr_ITE(mkexpr(t3),
9087 binop(Iop_Or32,
9088 getDSPControl(),
9089 binop(Iop_Shl32,
9090 mkU32(0x1),
9091 mkU8(ac + 16)
9094 getDSPControl()),
9095 getDSPControl()));
9097 assign(t5, binop(Iop_Shl64,
9098 binop(Iop_MullS32,
9099 unop(Iop_16Sto32,
9100 unop(Iop_32to16,
9101 getIReg(rs))),
9102 unop(Iop_16Sto32,
9103 unop(Iop_32HIto16,
9104 getIReg(rt)))),
9105 mkU8(0x1)));
9106 assign(t6, binop(Iop_CmpEQ32,
9107 unop(Iop_16Uto32,
9108 unop(Iop_32to16, getIReg(rs))),
9109 mkU32(0x00008000)));
9110 assign(t7, binop(Iop_CmpEQ32,
9111 unop(Iop_16Uto32,
9112 unop(Iop_32HIto16, getIReg(rt))),
9113 mkU32(0x00008000)));
9114 assign(t8,
9115 IRExpr_ITE(mkexpr(t6),
9116 IRExpr_ITE(mkexpr(t7),
9117 mkU64(0x000000007fffffffULL),
9118 mkexpr(t5)),
9119 mkexpr(t5)));
9121 putDSPControl(IRExpr_ITE(mkexpr(t6),
9122 IRExpr_ITE(mkexpr(t7),
9123 binop(Iop_Or32,
9124 getDSPControl(),
9125 binop(Iop_Shl32,
9126 mkU32(0x1),
9127 mkU8(ac + 16)
9130 getDSPControl()),
9131 getDSPControl()));
9133 assign(t9, binop(Iop_Sub64,
9134 mkexpr(t0),
9135 binop(Iop_Add64, mkexpr(t4), mkexpr(t8))));
9136 putAcc(ac, mkexpr(t9));
9137 break;
9140 case 0x1A: { /* DPAQX_SA.W.PH */
9141 DIP("dpaqx_sa.w.ph ac%u, r%u, r%u", ac, rs, rt);
9142 vassert(!mode64);
9143 t0 = newTemp(Ity_I64);
9144 t1 = newTemp(Ity_I64);
9145 t2 = newTemp(Ity_I1);
9146 t3 = newTemp(Ity_I1);
9147 t4 = newTemp(Ity_I64);
9148 t5 = newTemp(Ity_I64);
9149 t6 = newTemp(Ity_I1);
9150 t7 = newTemp(Ity_I1);
9151 t8 = newTemp(Ity_I64);
9152 t9 = newTemp(Ity_I64);
9153 t10 = newTemp(Ity_I32);
9155 assign(t0, getAcc(ac));
9156 /* Calculate the first cross dot product and saturate if
9157 needed. */
9158 assign(t1, unop(Iop_32Sto64,
9159 binop(Iop_Shl32,
9160 binop(Iop_Mul32,
9161 unop(Iop_16Sto32,
9162 unop(Iop_32HIto16,
9163 getIReg(rs))),
9164 unop(Iop_16Sto32,
9165 unop(Iop_32to16,
9166 getIReg(rt)))),
9167 mkU8(0x1))));
9169 /* If both input arguments are equal 0x8000, saturate
9170 intermediate product and write to DSPControl
9171 register. */
9172 assign(t2, binop(Iop_CmpEQ32,
9173 unop(Iop_16Uto32,
9174 unop(Iop_32HIto16, getIReg(rs))),
9175 mkU32(0x00008000)));
9176 assign(t3, binop(Iop_CmpEQ32,
9177 unop(Iop_16Uto32,
9178 unop(Iop_32to16, getIReg(rt))),
9179 mkU32(0x00008000)));
9181 assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
9182 binop(Iop_And32,
9183 unop(Iop_1Sto32,
9184 mkexpr(t2)),
9185 unop(Iop_1Sto32,
9186 mkexpr(t3))),
9187 mkU32(0)),
9188 mkU64(0x000000007fffffffULL),
9189 mkexpr(t1)));
9191 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
9192 binop(Iop_And32,
9193 unop(Iop_1Sto32,
9194 mkexpr(t2)),
9195 unop(Iop_1Sto32,
9196 mkexpr(t3))),
9197 mkU32(0)),
9198 binop(Iop_Or32,
9199 getDSPControl(),
9200 binop(Iop_Shl32,
9201 mkU32(0x1),
9202 mkU8(ac + 16))),
9203 getDSPControl()));
9204 /* Calculate second cross dot product and saturate if
9205 needed. */
9206 assign(t5, unop(Iop_32Sto64,
9207 binop(Iop_Shl32,
9208 binop(Iop_Mul32,
9209 unop(Iop_16Sto32,
9210 unop(Iop_32to16,
9211 getIReg(rs))),
9212 unop(Iop_16Sto32,
9213 unop(Iop_32HIto16,
9214 getIReg(rt)))),
9215 mkU8(0x1))));
9217 /* If both input arguments are equal 0x8000, saturate
9218 intermediate product and write to DSPControl
9219 register. */
9220 assign(t6, binop(Iop_CmpEQ32,
9221 unop(Iop_16Uto32,
9222 unop(Iop_32to16, getIReg(rs))),
9223 mkU32(0x00008000)));
9224 assign(t7, binop(Iop_CmpEQ32,
9225 unop(Iop_16Uto32,
9226 unop(Iop_32HIto16, getIReg(rt))),
9227 mkU32(0x00008000)));
9229 assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
9230 binop(Iop_And32,
9231 unop(Iop_1Sto32,
9232 mkexpr(t6)),
9233 unop(Iop_1Sto32,
9234 mkexpr(t7))),
9235 mkU32(0)),
9236 mkU64(0x000000007fffffffULL),
9237 mkexpr(t5)));
9239 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
9240 binop(Iop_And32,
9241 unop(Iop_1Sto32,
9242 mkexpr(t6)),
9243 unop(Iop_1Sto32,
9244 mkexpr(t7))),
9245 mkU32(0)),
9246 binop(Iop_Or32,
9247 getDSPControl(),
9248 binop(Iop_Shl32,
9249 mkU32(0x1),
9250 mkU8(ac + 16))),
9251 getDSPControl()));
9252 /* Subtract intermediate products from value in the
9253 accumulator. */
9254 assign(t9,
9255 binop(Iop_Add64,
9256 mkexpr(t0),
9257 binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
9259 putAcc(ac,
9260 IRExpr_ITE(binop(Iop_CmpEQ32,
9261 binop(Iop_And32,
9262 unop(Iop_64HIto32,
9263 mkexpr(t9)),
9264 mkU32(0x80000000)),
9265 mkU32(0x0)),
9266 IRExpr_ITE(binop(Iop_CmpNE32,
9267 unop(Iop_64HIto32,
9268 binop(Iop_Shl64,
9269 mkexpr(t9),
9270 mkU8(1))),
9271 mkU32(0x0)),
9272 mkU64(0x000000007fffffffULL),
9273 mkexpr(t9)),
9274 IRExpr_ITE(binop(Iop_CmpNE32,
9275 unop(Iop_64HIto32,
9276 binop(Iop_Shl64,
9277 mkexpr(t9),
9278 mkU8(1))),
9279 mkU32(0xffffffff)),
9280 mkU64(0xffffffff80000000ULL),
9281 mkexpr(t9))));
9282 assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
9283 unop(Iop_64to32,
9284 mkexpr(t9)),
9285 unop(Iop_64to32,
9286 getAcc(ac))),
9287 getDSPControl(),
9288 binop(Iop_Or32,
9289 getDSPControl(),
9290 binop(Iop_Shl32,
9291 mkU32(0x1),
9292 mkU8(ac + 16)))));
9293 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
9294 unop(Iop_64HIto32,
9295 mkexpr(t9)),
9296 unop(Iop_64HIto32,
9297 getAcc(ac))),
9298 mkexpr(t10),
9299 binop(Iop_Or32,
9300 getDSPControl(),
9301 binop(Iop_Shl32,
9302 mkU32(0x1),
9303 mkU8(ac + 16)))));
9304 break;
9307 case 0x1B: { /* DPSQX_SA.W.PH */
9308 DIP("dpsqx_sa.w.ph ac%u, r%u, r%u", ac, rs, rt);
9309 vassert(!mode64);
9310 t0 = newTemp(Ity_I64);
9311 t1 = newTemp(Ity_I64);
9312 t2 = newTemp(Ity_I1);
9313 t3 = newTemp(Ity_I1);
9314 t4 = newTemp(Ity_I64);
9315 t5 = newTemp(Ity_I64);
9316 t6 = newTemp(Ity_I1);
9317 t7 = newTemp(Ity_I1);
9318 t8 = newTemp(Ity_I64);
9319 t9 = newTemp(Ity_I64);
9320 t10 = newTemp(Ity_I32);
9322 assign(t0, getAcc(ac));
9323 /* Calculate the first cross dot product and saturate if
9324 needed. */
9325 assign(t1, unop(Iop_32Sto64,
9326 binop(Iop_Shl32,
9327 binop(Iop_Mul32,
9328 unop(Iop_16Sto32,
9329 unop(Iop_32HIto16,
9330 getIReg(rs))),
9331 unop(Iop_16Sto32,
9332 unop(Iop_32to16,
9333 getIReg(rt)))),
9334 mkU8(0x1))));
9336 /* If both input arguments are equal 0x8000, saturate
9337 intermediate product and write to DSPControl
9338 register. */
9339 assign(t2, binop(Iop_CmpEQ32,
9340 unop(Iop_16Uto32,
9341 unop(Iop_32HIto16, getIReg(rs))),
9342 mkU32(0x00008000)));
9343 assign(t3, binop(Iop_CmpEQ32,
9344 unop(Iop_16Uto32,
9345 unop(Iop_32to16, getIReg(rt))),
9346 mkU32(0x00008000)));
9348 assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
9349 binop(Iop_And32,
9350 unop(Iop_1Sto32,
9351 mkexpr(t2)),
9352 unop(Iop_1Sto32,
9353 mkexpr(t3))),
9354 mkU32(0)),
9355 mkU64(0x000000007fffffffULL),
9356 mkexpr(t1)));
9358 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
9359 binop(Iop_And32,
9360 unop(Iop_1Sto32,
9361 mkexpr(t2)),
9362 unop(Iop_1Sto32,
9363 mkexpr(t3))),
9364 mkU32(0)),
9365 binop(Iop_Or32,
9366 getDSPControl(),
9367 binop(Iop_Shl32,
9368 mkU32(0x1),
9369 mkU8(ac + 16))),
9370 getDSPControl()));
9371 /* Calculate second cross dot product and saturate if
9372 needed. */
9373 assign(t5, unop(Iop_32Sto64,
9374 binop(Iop_Shl32,
9375 binop(Iop_Mul32,
9376 unop(Iop_16Sto32,
9377 unop(Iop_32to16,
9378 getIReg(rs))),
9379 unop(Iop_16Sto32,
9380 unop(Iop_32HIto16,
9381 getIReg(rt)))),
9382 mkU8(0x1))));
9384 /* If both input arguments are equal 0x8000, saturate
9385 intermediate product and write to DSPControl
9386 register. */
9387 assign(t6, binop(Iop_CmpEQ32,
9388 unop(Iop_16Uto32,
9389 unop(Iop_32to16, getIReg(rs))),
9390 mkU32(0x00008000)));
9391 assign(t7, binop(Iop_CmpEQ32,
9392 unop(Iop_16Uto32,
9393 unop(Iop_32HIto16, getIReg(rt))),
9394 mkU32(0x00008000)));
9396 assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
9397 binop(Iop_And32,
9398 unop(Iop_1Sto32,
9399 mkexpr(t6)),
9400 unop(Iop_1Sto32,
9401 mkexpr(t7))),
9402 mkU32(0)),
9403 mkU64(0x000000007fffffffULL),
9404 mkexpr(t5)));
9406 putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
9407 binop(Iop_And32,
9408 unop(Iop_1Sto32,
9409 mkexpr(t6)),
9410 unop(Iop_1Sto32,
9411 mkexpr(t7))),
9412 mkU32(0)),
9413 binop(Iop_Or32,
9414 getDSPControl(),
9415 binop(Iop_Shl32,
9416 mkU32(0x1),
9417 mkU8(ac + 16))),
9418 getDSPControl()));
9419 /* Subtract intermediate products from value in the
9420 accumulator. */
9421 assign(t9,
9422 binop(Iop_Sub64,
9423 mkexpr(t0),
9424 binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
9426 putAcc(ac,
9427 IRExpr_ITE(binop(Iop_CmpEQ32,
9428 binop(Iop_And32,
9429 unop(Iop_64HIto32,
9430 mkexpr(t9)),
9431 mkU32(0x80000000)),
9432 mkU32(0x0)),
9433 IRExpr_ITE(binop(Iop_CmpNE32,
9434 unop(Iop_64HIto32,
9435 binop(Iop_Shl64,
9436 mkexpr(t9),
9437 mkU8(1))),
9438 mkU32(0x0)),
9439 mkU64(0x000000007fffffffULL),
9440 mkexpr(t9)),
9441 IRExpr_ITE(binop(Iop_CmpNE32,
9442 unop(Iop_64HIto32,
9443 binop(Iop_Shl64,
9444 mkexpr(t9),
9445 mkU8(1))),
9446 mkU32(0xffffffff)),
9447 mkU64(0xffffffff80000000ULL),
9448 mkexpr(t9))));
9449 assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
9450 unop(Iop_64to32,
9451 mkexpr(t9)),
9452 unop(Iop_64to32,
9453 getAcc(ac))),
9454 getDSPControl(),
9455 binop(Iop_Or32,
9456 getDSPControl(),
9457 binop(Iop_Shl32,
9458 mkU32(0x1),
9459 mkU8(ac + 16)))));
9460 putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
9461 unop(Iop_64HIto32,
9462 mkexpr(t9)),
9463 unop(Iop_64HIto32,
9464 getAcc(ac))),
9465 mkexpr(t10),
9466 binop(Iop_Or32,
9467 getDSPControl(),
9468 binop(Iop_Shl32,
9469 mkU32(0x1),
9470 mkU8(ac + 16)))));
9471 break;
9474 default:
9475 return -1;
9478 return 0;
9481 static UInt disDSPInstr_MIPS_WRK_Special3_APPEND( UInt cins )
9483 IRTemp t1 = 0, t2, t3;
9484 UInt rs, rt, rd, sa;
9486 rs = get_rs(cins);
9487 rt = get_rt(cins);
9488 rd = get_rd(cins);
9489 sa = get_sa(cins);
9491 switch (sa) {
9492 case 0x0: { /* APPEND */
9493 DIP("append r%u, r%u, %u", rt, rs, rd);
9494 vassert(!mode64);
9495 t1 = newTemp(Ity_I32);
9496 t2 = newTemp(Ity_I32);
9498 assign(t1, binop(Iop_Shl32, getIReg(rt), mkU8(rd)));
9500 if (31 == rd) {
9501 putIReg(rt, binop(Iop_Or32,
9502 mkexpr(t1),
9503 binop(Iop_And32,
9504 getIReg(rs),
9505 mkU32(0x7fffffff))));
9506 } else if (1 == rd) {
9507 putIReg(rt,
9508 binop(Iop_Or32,
9509 mkexpr(t1),
9510 binop(Iop_And32,
9511 getIReg(rs), mkU32(0x1))));
9512 } else {
9513 assign(t2,
9514 unop(Iop_Not32,
9515 binop(Iop_Shl32,
9516 mkU32(0xffffffff), mkU8(rd))));
9518 putIReg(rt, binop(Iop_Or32,
9519 mkexpr(t1),
9520 binop(Iop_And32,
9521 getIReg(rs), mkexpr(t2))));
9524 break;
9527 case 0x1: { /* PREPEND */
9528 DIP("prepend r%u, r%u, %u", rt, rs, rd);
9529 vassert(!mode64);
9530 t1 = newTemp(Ity_I32);
9531 t2 = newTemp(Ity_I32);
9532 t3 = newTemp(Ity_I32);
9534 if (0 != rd) {
9535 assign(t1, binop(Iop_Shr32, getIReg(rt), mkU8(rd)));
9537 if (31 == rd) {
9538 putIReg(rt, binop(Iop_Or32,
9539 mkexpr(t1),
9540 binop(Iop_Shl32,
9541 binop(Iop_And32,
9542 getIReg(rs),
9543 mkU32(0x7fffffff)),
9544 mkU8(1))));
9545 } else if (1 == rd) {
9546 putIReg(rt, binop(Iop_Or32,
9547 mkexpr(t1),
9548 binop(Iop_Shl32,
9549 binop(Iop_And32,
9550 getIReg(rs),
9551 mkU32(0x1)),
9552 mkU8(31))));
9553 } else {
9554 assign(t2, binop(Iop_Add32, mkU32(rd), mkU32(0x1)));
9556 assign(t3, unop(Iop_Not32,
9557 binop(Iop_Shl32,
9558 mkU32(0xffffffff),
9559 unop(Iop_32to8, mkexpr(t2)))));
9561 putIReg(rt, binop(Iop_Or32,
9562 mkexpr(t1),
9563 binop(Iop_Shl32,
9564 binop(Iop_And32,
9565 getIReg(rs),
9566 mkexpr(t3)),
9567 mkU8(32 - rd))));
9571 break;
9574 case 0x10: { /* BALIGN */
9575 DIP("balign r%u, r%u, %u", rt, rs, rd);
9576 vassert(!mode64);
9577 t1 = newTemp(Ity_I32);
9578 t2 = newTemp(Ity_I32);
9579 t3 = newTemp(Ity_I32);
9581 if ((2 != rd) && (0 != rd)) {
9582 assign(t1, binop(Iop_Shl32,
9583 binop(Iop_And32,
9584 mkU32(rd), mkU32(0x3)),
9585 mkU8(0x3)));
9586 assign(t2, binop(Iop_Shl32,
9587 getIReg(rt),
9588 unop(Iop_32to8, mkexpr(t1))));
9589 assign(t3, binop(Iop_Shr32,
9590 getIReg(rs),
9591 unop(Iop_32to8,
9592 binop(Iop_Shl32,
9593 binop(Iop_Sub32,
9594 mkU32(0x4),
9595 binop(Iop_And32,
9596 mkU32(rd),
9597 mkU32(0x3))),
9598 mkU8(0x3)))));
9599 putIReg(rt, binop(Iop_Or32, mkexpr(t2), mkexpr(t3)));
9602 break;
9605 default:
9606 return -1;
9609 return 0;
9612 static UInt disDSPInstr_MIPS_WRK_Special3( UInt cins )
9614 switch (get_function(cins)) {
9615 case 0x12: { /* ABSQ_S.PH */
9616 return disDSPInstr_MIPS_WRK_Special3_ABSQ_SPH(cins);
9619 case 0x38: { /* EXTR.W */
9620 return disDSPInstr_MIPS_WRK_Special3_EXTR_W(cins);
9623 case 0xA: { /* LX */
9624 return disDSPInstr_MIPS_WRK_Special3_LX(cins);
9627 case 0xC: { /* INSV */
9628 return disDSPInstr_MIPS_WRK_Special3_INSV(cins);
9631 case 0x10: { /* ADDU.QB */
9632 return disDSPInstr_MIPS_WRK_Special3_ADDU_QB(cins);
9635 case 0x11: { /* CMPU.EQ.QB */
9636 return disDSPInstr_MIPS_WRK_Special3_CMPU_EQ_QB(cins);
9639 case 0x13: { /* SHLL.QB */
9640 return disDSPInstr_MIPS_WRK_Special3_SHLL_QB(cins);
9643 case 0x18: { /* ADDUH.QB/MUL.PH */
9644 return disDSPInstr_MIPS_WRK_Special3_ADDUH_QB(cins);
9647 case 0x30: { /* DPA.W.PH */
9648 return disDSPInstr_MIPS_WRK_Special3_DPAW_PH(cins);
9651 case 0x31: { /* APPEND */
9652 return disDSPInstr_MIPS_WRK_Special3_APPEND(cins);
9655 default:
9656 return -1;
9660 UInt disDSPInstr_MIPS_WRK ( UInt cins )
9662 UInt opcode = get_opcode(cins);
9664 switch (opcode) {
9665 case 0x00: { /* Special */
9666 return disDSPInstr_MIPS_WRK_Special(cins);
9669 case 0x1C: { /* Special2 */
9670 return disDSPInstr_MIPS_WRK_Special2(cins);
9673 case 0x1F: { /* Special3 */
9674 return disDSPInstr_MIPS_WRK_Special3(cins);
9677 default:
9678 return -1;