Author: sewardj
Date: Thu Jun 26 12:39:05 2014
New Revision: 2891
Log:
arm64: implement: rbit 16b,8b, rev16 16b,8b
Modified:
trunk/priv/guest_arm64_toIR.c
trunk/priv/host_arm64_defs.c
trunk/priv/host_arm64_defs.h
trunk/priv/host_arm64_isel.c
trunk/priv/ir_defs.c
trunk/pub/libvex_ir.h
Modified: trunk/priv/guest_arm64_toIR.c
==============================================================================
--- trunk/priv/guest_arm64_toIR.c (original)
+++ trunk/priv/guest_arm64_toIR.c Thu Jun 26 12:39:05 2014
@@ -5657,6 +5657,16 @@
}
+/* |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)
{
@@ -7464,6 +7474,17 @@
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 -------- */
@@ -7489,12 +7510,24 @@
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
Modified: trunk/priv/host_arm64_defs.c
==============================================================================
--- trunk/priv/host_arm64_defs.c (original)
+++ trunk/priv/host_arm64_defs.c Thu Jun 26 12:39:05 2014
@@ -947,6 +947,8 @@
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");
}
}
@@ -5387,6 +5389,10 @@
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);
@@ -5439,6 +5445,12 @@
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;
}
Modified: trunk/priv/host_arm64_defs.h
==============================================================================
--- trunk/priv/host_arm64_defs.h (original)
+++ trunk/priv/host_arm64_defs.h Thu Jun 26 12:39:05 2014
@@ -360,6 +360,8 @@
ARM64vecu_CLS32x4, ARM64vecu_CLS16x8, ARM64vecu_CLS8x16,
ARM64vecu_CLZ32x4, ARM64vecu_CLZ16x8, ARM64vecu_CLZ8x16,
ARM64vecu_CNT8x16,
+ ARM64vecu_RBIT,
+ ARM64vecu_REV1616B,
ARM64vecu_INVALID
}
ARM64VecUnaryOp;
Modified: trunk/priv/host_arm64_isel.c
==============================================================================
--- trunk/priv/host_arm64_isel.c (original)
+++ trunk/priv/host_arm64_isel.c Thu Jun 26 12:39:05 2014
@@ -4417,6 +4417,8 @@
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);
@@ -4438,6 +4440,8 @@
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));
Modified: trunk/priv/ir_defs.c
==============================================================================
--- trunk/priv/ir_defs.c (original)
+++ trunk/priv/ir_defs.c Thu Jun 26 12:39:05 2014
@@ -976,6 +976,7 @@
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;
@@ -2912,6 +2913,7 @@
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:
Modified: trunk/pub/libvex_ir.h
==============================================================================
--- trunk/pub/libvex_ir.h (original)
+++ trunk/pub/libvex_ir.h Thu Jun 26 12:39:05 2014
@@ -1598,6 +1598,7 @@
Iop_Reverse8sIn16_x8,
Iop_Reverse8sIn32_x4, Iop_Reverse16sIn32_x4,
Iop_Reverse8sIn64_x2, Iop_Reverse16sIn64_x2, Iop_Reverse32sIn64_x2,
+ Iop_Reverse1sIn8_x16, /* Reverse bits in each byte lane. */
/* PERMUTING -- copy src bytes to dst,
as indexed by control vector bytes:
|