Commit 0f2d17c1 authored by Peter Maydell's avatar Peter Maydell
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 204febd1 993508e4
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
@@ -362,9 +362,8 @@ static inline int ctpop32(uint32_t 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 + (val >> 4)) & 0x0f0f0f0f;
    val = (val * 0x01010101) >> 24;

    return val;
#endif
@@ -381,10 +380,8 @@ static inline int ctpop64(uint64_t 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 + (val >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
    val = (val * 0x0101010101010101ULL) >> 56;

    return val;
#endif
+0 −4
Original line number Diff line number Diff line
@@ -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)

+0 −15
Original line number Diff line number Diff line
@@ -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;
Loading