}
+/* |fullWidth| is a full V128 width result. Depending on bitQ,
+ zero out the upper half. */
+static IRExpr* math_MAYBE_ZERO_HI64 ( UInt bitQ, IRTemp fullWidth )
+{
+ if (bitQ == 1) return mkexpr(fullWidth);
+ if (bitQ == 0) return unop(Iop_ZeroHI64ofV128, mkexpr(fullWidth));
+ vassert(0);
+}
+
+
static
Bool dis_AdvSIMD_EXT(/*MB_OUT*/DisResult* dres, UInt insn)
{
UInt dd = INSN(4,0);
vassert(size < 4);
+ if (bitU == 0 && size == X00 && opcode == BITS5(0,0,0,0,1)) {
+ /* -------- 0,00,00001: REV16 16b_16b, 8b_8b -------- */
+ IRTemp res = newTemp(Ity_V128);
+ assign(res, unop(Iop_Reverse8sIn16_x8, getQReg128(nn)));
+ putQReg128(dd, math_MAYBE_ZERO_HI64(bitQ, res));
+ const HChar* arr = nameArr_Q_SZ(bitQ, 0);
+ DIP("%s %s.%s, %s.%s\n", "rev16",
+ nameQReg128(dd), arr, nameQReg128(nn), arr);
+ return True;
+ }
+
if (opcode == BITS5(0,0,1,0,0)) {
/* -------- 0,xx,00100: CLS std6_std6 -------- */
/* -------- 1,xx,00100: CLZ std6_std6 -------- */
assign(res, unop(bitU == 0 ? Iop_Cnt8x16 : Iop_NotV128, getQReg128(nn)));
putQReg128(dd, bitQ == 0 ? unop(Iop_ZeroHI64ofV128, mkexpr(res))
: mkexpr(res));
- const HChar* arr = nameArr_Q_SZ(bitQ, size);
+ const HChar* arr = nameArr_Q_SZ(bitQ, 0);
DIP("%s %s.%s, %s.%s\n", bitU == 0 ? "cnt" : "not",
nameQReg128(dd), arr, nameQReg128(nn), arr);
return True;
}
+ if (bitU == 1 && size == X01 && opcode == BITS5(0,0,1,0,1)) {
+ /* -------- 1,01,00101 RBIT 16b_16b, 8b_8b -------- */
+ IRTemp res = newTemp(Ity_V128);
+ assign(res, unop(Iop_Reverse1sIn8_x16, getQReg128(nn)));
+ putQReg128(dd, bitQ == 0 ? unop(Iop_ZeroHI64ofV128, mkexpr(res))
+ : mkexpr(res));
+ const HChar* arr = nameArr_Q_SZ(bitQ, 0);
+ DIP("%s %s.%s, %s.%s\n", "rbit",
+ nameQReg128(dd), arr, nameQReg128(nn), arr);
+ return True;
+ }
+
if (opcode == BITS5(0,1,0,0,0)) {
/* -------- 0,xx,01000: CMGT std7_std7_#0 -------- */ // >s 0
/* -------- 1,xx,01000: CMGE std7_std7_#0 -------- */ // >=s 0
case ARM64vecu_CLZ16x8: *nm = "clz "; *ar = "8h"; return;
case ARM64vecu_CLZ8x16: *nm = "clz "; *ar = "16b"; return;
case ARM64vecu_CNT8x16: *nm = "cnt "; *ar = "16b"; return;
+ case ARM64vecu_RBIT: *nm = "rbit "; *ar = "16b"; return;
+ case ARM64vecu_REV1616B: *nm = "rev16"; *ar = "16b"; return;
default: vpanic("showARM64VecUnaryOp");
}
}
011 01110 00 1 00000 010010 n d CLZ Vd.16b, Vn.16b
010 01110 00 1 00000 010110 n d CNT Vd.16b, Vn.16b
+
+ 011 01110 01 1 00000 010110 n d RBIT Vd.16b, Vn.16b
+
+ 010 01110 00 1 00000 000110 n d REV16 Vd.16b, Vn.16b
*/
UInt vD = qregNo(i->ARM64in.VUnaryV.dst);
UInt vN = qregNo(i->ARM64in.VUnaryV.arg);
case ARM64vecu_CNT8x16:
*p++ = X_3_8_5_6_5_5(X010, X01110001, X00000, X010110, vN, vD);
break;
+ case ARM64vecu_RBIT:
+ *p++ = X_3_8_5_6_5_5(X011, X01110011, X00000, X010110, vN, vD);
+ break;
+ case ARM64vecu_REV1616B:
+ *p++ = X_3_8_5_6_5_5(X010, X01110001, X00000, X000110, vN, vD);
+ break;
default:
goto bad;
}
case Iop_Cls32x4: case Iop_Cls16x8: case Iop_Cls8x16:
case Iop_Clz32x4: case Iop_Clz16x8: case Iop_Clz8x16:
case Iop_Cnt8x16:
+ case Iop_Reverse1sIn8_x16:
+ case Iop_Reverse8sIn16_x8:
{
HReg res = newVRegV(env);
HReg arg = iselV128Expr(env, e->Iex.Unop.arg);
case Iop_Clz16x8: op = ARM64vecu_CLZ16x8; break;
case Iop_Clz8x16: op = ARM64vecu_CLZ8x16; break;
case Iop_Cnt8x16: op = ARM64vecu_CNT8x16; break;
+ case Iop_Reverse1sIn8_x16: op = ARM64vecu_RBIT; break;
+ case Iop_Reverse8sIn16_x8: op = ARM64vecu_REV1616B; break;
default: vassert(0);
}
addInstr(env, ARM64Instr_VUnaryV(op, res, arg));
case Iop_Reverse8sIn64_x2: vex_printf("Reverse8sIn64_x2"); return;
case Iop_Reverse16sIn64_x2: vex_printf("Reverse16sIn64_x2"); return;
case Iop_Reverse32sIn64_x2: vex_printf("Reverse32sIn64_x2"); return;
+ case Iop_Reverse1sIn8_x16: vex_printf("Reverse1sIn8_x16"); return;
case Iop_F32ToFixed32Ux4_RZ: vex_printf("F32ToFixed32Ux4_RZ"); return;
case Iop_F32ToFixed32Sx4_RZ: vex_printf("F32ToFixed32Sx4_RZ"); return;
case Iop_Reverse32sIn64_x2:
case Iop_Reverse8sIn32_x4: case Iop_Reverse16sIn32_x4:
case Iop_Reverse8sIn16_x8:
+ case Iop_Reverse1sIn8_x16:
case Iop_Neg64Fx2: case Iop_Neg32Fx4:
case Iop_Abs8x16: case Iop_Abs16x8: case Iop_Abs32x4: case Iop_Abs64x2:
case Iop_CipherSV128: