lkml.org 
[lkml]   [2012]   [Apr]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[RFC PATCH -tip 01/16] x86: Split default64 flag from force64 flag
    From
    Date
    Since current x86 instruction decoder treats default 64 bit
    instructions as same as force 64 bit one, eventually the
    decoder says the operand size is always 8 on those
    instructions.
    However, in real, when thoes have an operand-size prefix,
    its operand size should be 2.
    So this fixes that to split default64 from force64.

    Signed-off-by: Masami Hiramatsu <masami.hiramatsu@gmail.com>
    ---
    arch/x86/include/asm/inat.h | 18 ++++++++++++------
    arch/x86/include/asm/insn.h | 2 ++
    arch/x86/lib/insn.c | 2 ++
    arch/x86/tools/gen-insn-attr-x86.awk | 7 +++++--
    4 files changed, 21 insertions(+), 8 deletions(-)

    diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
    index 74a2e31..55e438b 100644
    --- a/arch/x86/include/asm/inat.h
    +++ b/arch/x86/include/asm/inat.h
    @@ -83,12 +83,13 @@
    /* Flags */
    #define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS)
    #define INAT_MODRM (1 << (INAT_FLAG_OFFS))
    -#define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 1))
    -#define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 2))
    -#define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 3))
    -#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4))
    -#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))
    -#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))
    +#define INAT_DEFAULT64 (1 << (INAT_FLAG_OFFS + 1))
    +#define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 2))
    +#define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 3))
    +#define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 4))
    +#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 5))
    +#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 6))
    +#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 7))
    /* Attribute making macros for attribute tables */
    #define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS)
    #define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS)
    @@ -194,6 +195,11 @@ static inline int inat_is_force64(insn_attr_t attr)
    return attr & INAT_FORCE64;
    }

    +static inline int inat_is_default64(insn_attr_t attr)
    +{
    + return attr & INAT_DEFAULT64;
    +}
    +
    static inline int inat_has_second_immediate(insn_attr_t attr)
    {
    return attr & INAT_SCNDIMM;
    diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h
    index 48eb30a..34aecec 100644
    --- a/arch/x86/include/asm/insn.h
    +++ b/arch/x86/include/asm/insn.h
    @@ -83,6 +83,8 @@ struct insn {
    #define X86_REX_X(rex) ((rex) & 2)
    #define X86_REX_B(rex) ((rex) & 1)

    +#define X86_OPCODE_GPR(opcode) ((opcode) & 0x07)
    +
    /* VEX bit flags */
    #define X86_VEX_W(vex) ((vex) & 0x80) /* VEX3 Byte2 */
    #define X86_VEX_R(vex) ((vex) & 0x80) /* VEX2/3 Byte1 */
    diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
    index 25feb1a..e34829a 100644
    --- a/arch/x86/lib/insn.c
    +++ b/arch/x86/lib/insn.c
    @@ -257,6 +257,8 @@ void insn_get_modrm(struct insn *insn)

    if (insn->x86_64 && inat_is_force64(insn->attr))
    insn->opnd_bytes = 8;
    + if (insn->x86_64 && inat_is_default64(insn->attr) && insn->opnd_bytes == 4)
    + insn->opnd_bytes = 8;
    modrm->got = 1;

    err_out:
    diff --git a/arch/x86/tools/gen-insn-attr-x86.awk b/arch/x86/tools/gen-insn-attr-x86.awk
    index 5f6a5b6..76d8889 100644
    --- a/arch/x86/tools/gen-insn-attr-x86.awk
    +++ b/arch/x86/tools/gen-insn-attr-x86.awk
    @@ -62,7 +62,8 @@ BEGIN {
    imm_flag["Lx"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"

    modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])"
    - force64_expr = "\\([df]64\\)"
    + force64_expr = "\\(f64\\)"
    + def64_expr = "\\(d64\\)"
    rex_expr = "^REX(\\.[XRWB]+)*"
    fpu_expr = "^ESC" # TODO

    @@ -303,9 +304,11 @@ function convert_operands(count,opnd, i,j,imm,mod)
    }
    flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")")
    }
    - # check force(or default) 64bit
    + # check force or default 64bit
    if (match(ext, force64_expr))
    flags = add_flags(flags, "INAT_FORCE64")
    + if (match(ext, def64_expr))
    + flags = add_flags(flags, "INAT_DEFAULT64")

    # check REX prefix
    if (match(opcode, rex_expr))


    \
     
     \ /
      Last update: 2012-04-01 18:05    [W:2.287 / U:0.244 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site