Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20170110' into staging

TCG opcodes for extract, clz, ctz, ctpop

# gpg: Signature made Wed 11 Jan 2017 02:12:41 GMT
# gpg:                using RSA key 0xAD1270CC4DD0279B
# gpg: Good signature from "Richard Henderson <rth7680@gmail.com>"
# gpg:                 aka "Richard Henderson <rth@redhat.com>"
# gpg:                 aka "Richard Henderson <rth@twiddle.net>"
# Primary key fingerprint: 9CB1 8DDA F8E8 49AD 2AFC  16A4 AD12 70CC 4DD0 279B

* remotes/rth/tags/pull-tcg-20170110: (65 commits)
  tcg/i386: Handle ctpop opcode
  tcg/ppc: Handle ctpop opcode
  tcg: Use ctpop to generate ctz if needed
  tests: New test-bitcnt
  qemu/host-utils.h: Reduce the operation count in the fallback ctpop
  target-i386: Use ctpop helper
  target-tilegx: Use ctpop helper
  target-sparc: Use ctpop helper
  target-s390x: Avoid a loop for popcnt
  target-ppc: Use ctpop helper
  target-alpha: Use ctpop helper
  tcg: Add opcode for ctpop
  target-xtensa: Use clrsb helper
  target-tricore: Use clrsb helper
  target-arm: Use clrsb helper
  tcg: Add helpers for clrsb
  tcg/i386: Rely on undefined/undocumented behaviour of BSF/BSR
  tcg/i386: Handle ctz and clz opcodes
  tcg/i386: Allow bmi2 shiftx to have non-matching operands
  tcg/i386: Hoist common arguments in tcg_out_op
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2017-01-12 13:21:32 +00:00
82 changed files with 2593 additions and 1101 deletions
+10 -2
View File
@@ -682,6 +682,7 @@ fetch_data(struct disassemble_info *info, bfd_byte *addr)
#define PREGRP104 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 104 } }
#define PREGRP105 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 105 } }
#define PREGRP106 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 106 } }
#define PREGRP107 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 107 } }
#define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
#define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
@@ -1247,7 +1248,7 @@ static const struct dis386 dis386_twobyte[] = {
{ "ud2b", { XX } },
{ GRP8 },
{ "btcS", { Ev, Gv } },
{ "bsfS", { Gv, Ev } },
{ PREGRP107 },
{ PREGRP36 },
{ "movs{bR|x|bR|x}", { Gv, Eb } },
{ "movs{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movsww ! */
@@ -1431,7 +1432,7 @@ static const unsigned char twobyte_uses_REPZ_prefix[256] = {
/* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
/* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
/* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
/* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
/* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0, /* bf */
/* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
/* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
/* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
@@ -2800,6 +2801,13 @@ static const struct dis386 prefix_user_table[][4] = {
{ "shrxS", { Gv, Ev, Bv } },
},
/* PREGRP107 */
{
{ "bsfS", { Gv, Ev } },
{ "tzcntS", { Gv, Ev } },
{ "bsfS", { Gv, Ev } },
{ "(bad)", { XX } },
},
};
static const struct dis386 x86_64_table[][2] = {
+10
View File
@@ -1955,6 +1955,9 @@ extract_tbr (unsigned long insn,
#define POWER4 PPC_OPCODE_POWER4
#define POWER5 PPC_OPCODE_POWER5
#define POWER6 PPC_OPCODE_POWER6
/* Documentation purposes only; we don't actually check the isa for disas. */
#define POWER7 PPC_OPCODE_POWER6
#define POWER9 PPC_OPCODE_POWER6
#define CELL PPC_OPCODE_CELL
#define PPC32 PPC_OPCODE_32 | PPC_OPCODE_PPC
#define PPC64 PPC_OPCODE_64 | PPC_OPCODE_PPC
@@ -3589,6 +3592,13 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{ "lbzux", X(31,119), X_MASK, COM, { RT, RAL, RB } },
{ "popcntb", X(31,122), XRB_MASK, POWER5, { RA, RS } },
{ "popcntw", X(31,378), XRB_MASK, POWER7, { RA, RS } },
{ "popcntd", X(31,506), XRB_MASK, POWER7, { RA, RS } },
{ "cnttzw", XRC(31,538,0), XRB_MASK, POWER9, { RA, RS } },
{ "cnttzw.", XRC(31,538,1), XRB_MASK, POWER9, { RA, RS } },
{ "cnttzd", XRC(31,570,0), XRB_MASK, POWER9, { RA, RS } },
{ "cnttzd.", XRC(31,570,1), XRB_MASK, POWER9, { RA, RS } },
{ "not", XRC(31,124,0), X_MASK, COM, { RA, RS, RBS } },
{ "nor", XRC(31,124,0), X_MASK, COM, { RA, RS, RB } },
+11 -14
View File
@@ -327,7 +327,7 @@ static inline int ctpop8(uint8_t val)
#else
val = (val & 0x55) + ((val >> 1) & 0x55);
val = (val & 0x33) + ((val >> 2) & 0x33);
val = (val & 0x0f) + ((val >> 4) & 0x0f);
val = (val + (val >> 4)) & 0x0f;
return val;
#endif
@@ -344,8 +344,8 @@ static inline int ctpop16(uint16_t val)
#else
val = (val & 0x5555) + ((val >> 1) & 0x5555);
val = (val & 0x3333) + ((val >> 2) & 0x3333);
val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f);
val = (val & 0x00ff) + ((val >> 8) & 0x00ff);
val = (val + (val >> 4)) & 0x0f0f;
val = (val + (val >> 8)) & 0x00ff;
return val;
#endif
@@ -360,11 +360,10 @@ static inline int ctpop32(uint32_t val)
#if QEMU_GNUC_PREREQ(3, 4)
return __builtin_popcount(val);
#else
val = (val & 0x55555555) + ((val >> 1) & 0x55555555);
val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f);
val = (val & 0x00ff00ff) + ((val >> 8) & 0x00ff00ff);
val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
val = (val & 0x55555555) + ((val >> 1) & 0x55555555);
val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
val = (val + (val >> 4)) & 0x0f0f0f0f;
val = (val * 0x01010101) >> 24;
return val;
#endif
@@ -379,12 +378,10 @@ static inline int ctpop64(uint64_t val)
#if QEMU_GNUC_PREREQ(3, 4)
return __builtin_popcountll(val);
#else
val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL);
val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL);
val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL);
val = (val & 0x00ff00ff00ff00ffULL) + ((val >> 8) & 0x00ff00ff00ff00ffULL);
val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL);
val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL);
val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL);
val = (val + (val >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
val = (val * 0x0101010101010101ULL) >> 56;
return val;
#endif
-4
View File
@@ -3,10 +3,6 @@ DEF_HELPER_FLAGS_1(load_pcc, TCG_CALL_NO_RWG_SE, i64, env)
DEF_HELPER_FLAGS_3(check_overflow, TCG_CALL_NO_WG, void, env, i64, i64)
DEF_HELPER_FLAGS_1(ctpop, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_1(ctlz, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_1(cttz, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_2(zap, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(zapnot, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-15
View File
@@ -24,21 +24,6 @@
#include "qemu/host-utils.h"
uint64_t helper_ctpop(uint64_t arg)
{
return ctpop64(arg);
}
uint64_t helper_ctlz(uint64_t arg)
{
return clz64(arg);
}
uint64_t helper_cttz(uint64_t arg)
{
return ctz64(arg);
}
uint64_t helper_zapnot(uint64_t val, uint64_t mskb)
{
uint64_t mask;
+45 -28
View File
@@ -949,7 +949,13 @@ static void gen_ext_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
uint8_t lit, uint8_t byte_mask)
{
if (islit) {
tcg_gen_shli_i64(vc, va, (64 - lit * 8) & 0x3f);
int pos = (64 - lit * 8) & 0x3f;
int len = cto32(byte_mask) * 8;
if (pos < len) {
tcg_gen_deposit_z_i64(vc, va, pos, len - pos);
} else {
tcg_gen_movi_i64(vc, 0);
}
} else {
TCGv tmp = tcg_temp_new();
tcg_gen_shli_i64(tmp, load_gpr(ctx, rb), 3);
@@ -966,38 +972,44 @@ static void gen_ext_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
uint8_t lit, uint8_t byte_mask)
{
if (islit) {
tcg_gen_shri_i64(vc, va, (lit & 7) * 8);
int pos = (lit & 7) * 8;
int len = cto32(byte_mask) * 8;
if (pos + len >= 64) {
len = 64 - pos;
}
tcg_gen_extract_i64(vc, va, pos, len);
} else {
TCGv tmp = tcg_temp_new();
tcg_gen_andi_i64(tmp, load_gpr(ctx, rb), 7);
tcg_gen_shli_i64(tmp, tmp, 3);
tcg_gen_shr_i64(vc, va, tmp);
tcg_temp_free(tmp);
gen_zapnoti(vc, vc, byte_mask);
}
gen_zapnoti(vc, vc, byte_mask);
}
/* INSWH, INSLH, INSQH */
static void gen_ins_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
uint8_t lit, uint8_t byte_mask)
{
TCGv tmp = tcg_temp_new();
/* The instruction description has us left-shift the byte mask and extract
bits <15:8> and apply that zap at the end. This is equivalent to simply
performing the zap first and shifting afterward. */
gen_zapnoti(tmp, va, byte_mask);
if (islit) {
lit &= 7;
if (unlikely(lit == 0)) {
tcg_gen_movi_i64(vc, 0);
int pos = 64 - (lit & 7) * 8;
int len = cto32(byte_mask) * 8;
if (pos < len) {
tcg_gen_extract_i64(vc, va, pos, len - pos);
} else {
tcg_gen_shri_i64(vc, tmp, 64 - lit * 8);
tcg_gen_movi_i64(vc, 0);
}
} else {
TCGv tmp = tcg_temp_new();
TCGv shift = tcg_temp_new();
/* The instruction description has us left-shift the byte mask
and extract bits <15:8> and apply that zap at the end. This
is equivalent to simply performing the zap first and shifting
afterward. */
gen_zapnoti(tmp, va, byte_mask);
/* If (B & 7) == 0, we need to shift by 64 and leave a zero. Do this
portably by splitting the shift into two parts: shift_count-1 and 1.
Arrange for the -1 by using ones-complement instead of
@@ -1010,32 +1022,37 @@ static void gen_ins_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
tcg_gen_shr_i64(vc, tmp, shift);
tcg_gen_shri_i64(vc, vc, 1);
tcg_temp_free(shift);
tcg_temp_free(tmp);
}
tcg_temp_free(tmp);
}
/* INSBL, INSWL, INSLL, INSQL */
static void gen_ins_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
uint8_t lit, uint8_t byte_mask)
{
TCGv tmp = tcg_temp_new();
/* The instruction description has us left-shift the byte mask
the same number of byte slots as the data and apply the zap
at the end. This is equivalent to simply performing the zap
first and shifting afterward. */
gen_zapnoti(tmp, va, byte_mask);
if (islit) {
tcg_gen_shli_i64(vc, tmp, (lit & 7) * 8);
int pos = (lit & 7) * 8;
int len = cto32(byte_mask) * 8;
if (pos + len > 64) {
len = 64 - pos;
}
tcg_gen_deposit_z_i64(vc, va, pos, len);
} else {
TCGv tmp = tcg_temp_new();
TCGv shift = tcg_temp_new();
/* The instruction description has us left-shift the byte mask
and extract bits <15:8> and apply that zap at the end. This
is equivalent to simply performing the zap first and shifting
afterward. */
gen_zapnoti(tmp, va, byte_mask);
tcg_gen_andi_i64(shift, load_gpr(ctx, rb), 7);
tcg_gen_shli_i64(shift, shift, 3);
tcg_gen_shl_i64(vc, tmp, shift);
tcg_temp_free(shift);
tcg_temp_free(tmp);
}
tcg_temp_free(tmp);
}
/* MSKWH, MSKLH, MSKQH */
@@ -2524,7 +2541,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
REQUIRE_TB_FLAG(TB_FLAGS_AMASK_CIX);
REQUIRE_REG_31(ra);
REQUIRE_NO_LIT;
gen_helper_ctpop(vc, vb);
tcg_gen_ctpop_i64(vc, vb);
break;
case 0x31:
/* PERR */
@@ -2538,14 +2555,14 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
REQUIRE_TB_FLAG(TB_FLAGS_AMASK_CIX);
REQUIRE_REG_31(ra);
REQUIRE_NO_LIT;
gen_helper_ctlz(vc, vb);
tcg_gen_clzi_i64(vc, vb, 64);
break;
case 0x33:
/* CTTZ */
REQUIRE_TB_FLAG(TB_FLAGS_AMASK_CIX);
REQUIRE_REG_31(ra);
REQUIRE_NO_LIT;
gen_helper_cttz(vc, vb);
tcg_gen_ctzi_i64(vc, vb, 64);
break;
case 0x34:
/* UNPKBW */
-20
View File
@@ -54,26 +54,6 @@ int64_t HELPER(sdiv64)(int64_t num, int64_t den)
return num / den;
}
uint64_t HELPER(clz64)(uint64_t x)
{
return clz64(x);
}
uint64_t HELPER(cls64)(uint64_t x)
{
return clrsb64(x);
}
uint32_t HELPER(cls32)(uint32_t x)
{
return clrsb32(x);
}
uint32_t HELPER(clz32)(uint32_t x)
{
return clz32(x);
}
uint64_t HELPER(rbit64)(uint64_t x)
{
return revbit64(x);
-4
View File
@@ -18,10 +18,6 @@
*/
DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
DEF_HELPER_FLAGS_1(clz64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_1(cls64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_1(cls32, TCG_CALL_NO_RWG_SE, i32, i32)
DEF_HELPER_FLAGS_1(clz32, TCG_CALL_NO_RWG_SE, i32, i32)
DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr)
-5
View File
@@ -5725,11 +5725,6 @@ uint32_t HELPER(uxtb16)(uint32_t x)
return res;
}
uint32_t HELPER(clz)(uint32_t x)
{
return clz32(x);
}
int32_t HELPER(sdiv)(int32_t num, int32_t den)
{
if (den == 0)
-1
View File
@@ -1,4 +1,3 @@
DEF_HELPER_FLAGS_1(clz, TCG_CALL_NO_RWG_SE, i32, i32)
DEF_HELPER_FLAGS_1(sxtb16, TCG_CALL_NO_RWG_SE, i32, i32)
DEF_HELPER_FLAGS_1(uxtb16, TCG_CALL_NO_RWG_SE, i32, i32)
+39 -62
View File
@@ -3216,67 +3216,44 @@ static void disas_bitfield(DisasContext *s, uint32_t insn)
low 32-bits anyway. */
tcg_tmp = read_cpu_reg(s, rn, 1);
/* Recognize the common aliases. */
if (opc == 0) { /* SBFM */
if (ri == 0) {
if (si == 7) { /* SXTB */
tcg_gen_ext8s_i64(tcg_rd, tcg_tmp);
goto done;
} else if (si == 15) { /* SXTH */
tcg_gen_ext16s_i64(tcg_rd, tcg_tmp);
goto done;
} else if (si == 31) { /* SXTW */
tcg_gen_ext32s_i64(tcg_rd, tcg_tmp);
goto done;
}
}
if (si == 63 || (si == 31 && ri <= si)) { /* ASR */
if (si == 31) {
tcg_gen_ext32s_i64(tcg_tmp, tcg_tmp);
}
tcg_gen_sari_i64(tcg_rd, tcg_tmp, ri);
goto done;
}
} else if (opc == 2) { /* UBFM */
if (ri == 0) { /* UXTB, UXTH, plus non-canonical AND */
tcg_gen_andi_i64(tcg_rd, tcg_tmp, bitmask64(si + 1));
return;
}
if (si == 63 || (si == 31 && ri <= si)) { /* LSR */
if (si == 31) {
tcg_gen_ext32u_i64(tcg_tmp, tcg_tmp);
}
tcg_gen_shri_i64(tcg_rd, tcg_tmp, ri);
return;
}
if (si + 1 == ri && si != bitsize - 1) { /* LSL */
int shift = bitsize - 1 - si;
tcg_gen_shli_i64(tcg_rd, tcg_tmp, shift);
goto done;
}
}
if (opc != 1) { /* SBFM or UBFM */
tcg_gen_movi_i64(tcg_rd, 0);
}
/* do the bit move operation */
if (si >= ri) {
/* Recognize simple(r) extractions. */
if (si <= ri) {
/* Wd<s-r:0> = Wn<s:r> */
tcg_gen_shri_i64(tcg_tmp, tcg_tmp, ri);
pos = 0;
len = (si - ri) + 1;
if (opc == 0) { /* SBFM: ASR, SBFX, SXTB, SXTH, SXTW */
tcg_gen_sextract_i64(tcg_rd, tcg_tmp, ri, len);
goto done;
} else if (opc == 2) { /* UBFM: UBFX, LSR, UXTB, UXTH */
tcg_gen_extract_i64(tcg_rd, tcg_tmp, ri, len);
return;
}
/* opc == 1, BXFIL fall through to deposit */
tcg_gen_extract_i64(tcg_tmp, tcg_tmp, ri, len);
pos = 0;
} else {
/* Wd<32+s-r,32-r> = Wn<s:0> */
pos = bitsize - ri;
/* Handle the ri > si case with a deposit
* Wd<32+s-r,32-r> = Wn<s:0>
*/
len = si + 1;
pos = (bitsize - ri) & (bitsize - 1);
}
tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
if (opc == 0 && len < ri) {
/* SBFM: sign extend the destination field from len to fill
the balance of the word. Let the deposit below insert all
of those sign bits. */
tcg_gen_sextract_i64(tcg_tmp, tcg_tmp, 0, len);
len = ri;
}
if (opc == 0) { /* SBFM - sign extend the destination field */
tcg_gen_shli_i64(tcg_rd, tcg_rd, 64 - (pos + len));
tcg_gen_sari_i64(tcg_rd, tcg_rd, 64 - (pos + len));
if (opc == 1) { /* BFM, BXFIL */
tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
} else {
/* SBFM or UBFM: We start with zero, and we haven't modified
any bits outside bitsize, therefore the zero-extension
below is unneeded. */
tcg_gen_deposit_z_i64(tcg_rd, tcg_tmp, pos, len);
return;
}
done:
@@ -3977,11 +3954,11 @@ static void handle_clz(DisasContext *s, unsigned int sf,
tcg_rn = cpu_reg(s, rn);
if (sf) {
gen_helper_clz64(tcg_rd, tcg_rn);
tcg_gen_clzi_i64(tcg_rd, tcg_rn, 64);
} else {
TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
tcg_gen_extrl_i64_i32(tcg_tmp32, tcg_rn);
gen_helper_clz(tcg_tmp32, tcg_tmp32);
tcg_gen_clzi_i32(tcg_tmp32, tcg_tmp32, 32);
tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
tcg_temp_free_i32(tcg_tmp32);
}
@@ -3995,11 +3972,11 @@ static void handle_cls(DisasContext *s, unsigned int sf,
tcg_rn = cpu_reg(s, rn);
if (sf) {
gen_helper_cls64(tcg_rd, tcg_rn);
tcg_gen_clrsb_i64(tcg_rd, tcg_rn);
} else {
TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
tcg_gen_extrl_i64_i32(tcg_tmp32, tcg_rn);
gen_helper_cls32(tcg_tmp32, tcg_tmp32);
tcg_gen_clrsb_i32(tcg_tmp32, tcg_tmp32);
tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
tcg_temp_free_i32(tcg_tmp32);
}
@@ -7614,9 +7591,9 @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u,
switch (opcode) {
case 0x4: /* CLS, CLZ */
if (u) {
gen_helper_clz64(tcg_rd, tcg_rn);
tcg_gen_clzi_i64(tcg_rd, tcg_rn, 64);
} else {
gen_helper_cls64(tcg_rd, tcg_rn);
tcg_gen_clrsb_i64(tcg_rd, tcg_rn);
}
break;
case 0x5: /* NOT */
@@ -10284,9 +10261,9 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
goto do_cmop;
case 0x4: /* CLS */
if (u) {
gen_helper_clz32(tcg_res, tcg_op);
tcg_gen_clzi_i32(tcg_res, tcg_op, 32);
} else {
gen_helper_cls32(tcg_res, tcg_op);
tcg_gen_clrsb_i32(tcg_res, tcg_op);
}
break;
case 0x7: /* SQABS, SQNEG */
+11 -32
View File
@@ -288,29 +288,6 @@ static void gen_revsh(TCGv_i32 var)
tcg_gen_ext16s_i32(var, var);
}
/* Unsigned bitfield extract. */
static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
{
if (shift)
tcg_gen_shri_i32(var, var, shift);
tcg_gen_andi_i32(var, var, mask);
}
/* Signed bitfield extract. */
static void gen_sbfx(TCGv_i32 var, int shift, int width)
{
uint32_t signbit;
if (shift)
tcg_gen_sari_i32(var, var, shift);
if (shift + width < 32) {
signbit = 1u << (width - 1);
tcg_gen_andi_i32(var, var, (1u << width) - 1);
tcg_gen_xori_i32(var, var, signbit);
tcg_gen_subi_i32(var, var, signbit);
}
}
/* Return (b << 32) + a. Mark inputs as dead */
static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
{
@@ -7060,7 +7037,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
switch (size) {
case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
case 2: gen_helper_clz(tmp, tmp); break;
case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
default: abort();
}
break;
@@ -8242,7 +8219,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
ARCH(5);
rd = (insn >> 12) & 0xf;
tmp = load_reg(s, rm);
gen_helper_clz(tmp, tmp);
tcg_gen_clzi_i32(tmp, tmp, 32);
store_reg(s, rd, tmp);
} else {
goto illegal_op;
@@ -9178,9 +9155,9 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
goto illegal_op;
if (i < 32) {
if (op1 & 0x20) {
gen_ubfx(tmp, shift, (1u << i) - 1);
tcg_gen_extract_i32(tmp, tmp, shift, i);
} else {
gen_sbfx(tmp, shift, i);
tcg_gen_sextract_i32(tmp, tmp, shift, i);
}
}
store_reg(s, rd, tmp);
@@ -10015,7 +9992,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
tcg_temp_free_i32(tmp2);
break;
case 0x18: /* clz */
gen_helper_clz(tmp, tmp);
tcg_gen_clzi_i32(tmp, tmp, 32);
break;
case 0x20:
case 0x21:
@@ -10497,15 +10474,17 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
imm++;
if (shift + imm > 32)
goto illegal_op;
if (imm < 32)
gen_sbfx(tmp, shift, imm);
if (imm < 32) {
tcg_gen_sextract_i32(tmp, tmp, shift, imm);
}
break;
case 6: /* Unsigned bitfield extract. */
imm++;
if (shift + imm > 32)
goto illegal_op;
if (imm < 32)
gen_ubfx(tmp, shift, (1u << imm) - 1);
if (imm < 32) {
tcg_gen_extract_i32(tmp, tmp, shift, imm);
}
break;
case 3: /* Bitfield insert/clear. */
if (imm < shift)
-1
View File
@@ -7,7 +7,6 @@ DEF_HELPER_1(rfn, void, env)
DEF_HELPER_3(movl_sreg_reg, void, env, i32, i32)
DEF_HELPER_3(movl_reg_sreg, void, env, i32, i32)
DEF_HELPER_FLAGS_1(lz, TCG_CALL_NO_SE, i32, i32)
DEF_HELPER_FLAGS_4(btst, TCG_CALL_NO_SE, i32, env, i32, i32, i32)
DEF_HELPER_FLAGS_4(evaluate_flags_muls, TCG_CALL_NO_SE, i32, env, i32, i32, i32)
-5
View File
@@ -230,11 +230,6 @@ void helper_rfn(CPUCRISState *env)
env->pregs[PR_CCS] |= M_FLAG_V32;
}
uint32_t helper_lz(uint32_t t0)
{
return clz32(t0);
}
uint32_t helper_btst(CPUCRISState *env, uint32_t t0, uint32_t t1, uint32_t ccs)
{
/* FIXME: clean this up. */
+1 -1
View File
@@ -767,7 +767,7 @@ static void cris_alu_op_exec(DisasContext *dc, int op,
t_gen_subx_carry(dc, dst);
break;
case CC_OP_LZ:
gen_helper_lz(dst, b);
tcg_gen_clzi_tl(dst, b, TARGET_LONG_BITS);
break;
case CC_OP_MULS:
tcg_gen_muls2_tl(dst, cpu_PR[PR_MOF], a, b);
+3
View File
@@ -105,6 +105,8 @@ target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1,
return src1;
case CC_OP_CLR:
return CC_Z | CC_P;
case CC_OP_POPCNT:
return src1 ? 0 : CC_Z;
case CC_OP_MULB:
return compute_all_mulb(dst, src1);
@@ -232,6 +234,7 @@ target_ulong helper_cc_compute_c(target_ulong dst, target_ulong src1,
case CC_OP_LOGICL:
case CC_OP_LOGICQ:
case CC_OP_CLR:
case CC_OP_POPCNT:
return 0;
case CC_OP_EFLAGS:
+1
View File
@@ -777,6 +777,7 @@ typedef enum {
CC_OP_ADCOX, /* CC_DST = C, CC_SRC2 = O, CC_SRC = rest. */
CC_OP_CLR, /* Z set, all other flags clear. */
CC_OP_POPCNT, /* Z via CC_SRC, all other flags clear. */
CC_OP_NB,
} CCOp;
-2
View File
@@ -202,8 +202,6 @@ DEF_HELPER_FLAGS_3(xsetbv, TCG_CALL_NO_WG, void, env, i32, i64)
DEF_HELPER_FLAGS_2(rdpkru, TCG_CALL_NO_WG, i64, env, i32)
DEF_HELPER_FLAGS_3(wrpkru, TCG_CALL_NO_WG, void, env, i32, i64)
DEF_HELPER_FLAGS_1(clz, TCG_CALL_NO_RWG_SE, tl, tl)
DEF_HELPER_FLAGS_1(ctz, TCG_CALL_NO_RWG_SE, tl, tl)
DEF_HELPER_FLAGS_2(pdep, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(pext, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-11
View File
@@ -417,17 +417,6 @@ void helper_idivq_EAX(CPUX86State *env, target_ulong t0)
# define clztl clz64
#endif
/* bit operations */
target_ulong helper_ctz(target_ulong t0)
{
return ctztl(t0);
}
target_ulong helper_clz(target_ulong t0)
{
return clztl(t0);
}
target_ulong helper_pdep(target_ulong src, target_ulong mask)
{
target_ulong dest = 0;
-26
View File
@@ -2157,32 +2157,6 @@ target_ulong helper_crc32(uint32_t crc1, target_ulong msg, uint32_t len)
return crc;
}
#define POPMASK(i) ((target_ulong) -1 / ((1LL << (1 << i)) + 1))
#define POPCOUNT(n, i) ((n & POPMASK(i)) + ((n >> (1 << i)) & POPMASK(i)))
target_ulong helper_popcnt(CPUX86State *env, target_ulong n, uint32_t type)
{
CC_SRC = n ? 0 : CC_Z;
n = POPCOUNT(n, 0);
n = POPCOUNT(n, 1);
n = POPCOUNT(n, 2);
n = POPCOUNT(n, 3);
if (type == 1) {
return n & 0xff;
}
n = POPCOUNT(n, 4);
#ifndef TARGET_X86_64
return n;
#else
if (type == 2) {
return n & 0xff;
}
return POPCOUNT(n, 5);
#endif
}
void glue(helper_pclmulqdq, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
uint32_t ctrl)
{

Some files were not shown because too many files have changed in this diff Show More