qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RISU RFC PATCH v1 4/7] risugen_x86: add module


From: Richard Henderson
Subject: Re: [Qemu-devel] [RISU RFC PATCH v1 4/7] risugen_x86: add module
Date: Thu, 27 Jun 2019 12:29:12 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.0

On 6/19/19 7:04 AM, Jan Bobek wrote:
> +    --x86_64     : generate 64-bit (rather than 32-bit) x86 code.

Better is to use

        .mode   x86.64
vs
        .mode   x86.32

or some such, like we do for aarch64.

> +sub write_mov_reg_imm($$)
> +{
> +    my ($reg, $imm) = @_;
> +
> +    my %insn = (opcode => {value => 0xB8 | ($reg & 0x7), len => 1},
> +                imm => {value => $imm, len => $is_x86_64 ? 8 : 4});
> +
> +    $insn{rex}{w} = 1 if $is_x86_64;
> +    $insn{rex}{b} = 1 if $reg >= 8;
> +
> +    write_insn(%insn);
> +}

There are 3 different insns that x86_64 can use for different ranges of
immediates; you are always using the full 10 byte version.

Using 0xb8 without REX.W may be used for any unsigned 32-bit value.
Using 0xc7 with REX.W may be used for any signed 32-bit value.
Using 0xb8 with REX.W of course allows any 64-bit value.

It's not terribly important, but the code size does get large.

> +sub rand_insn_modrm($$)
> +{
> +    my ($opts, $insn) = @_;
> +    my $modrm;
> +
> +    while (1) {
> +        $modrm = rand_fill({mod => {bitlen => 2},
> +                            reg => {bitlen => 3},
> +                            rm => {bitlen => 3}},
> +                           $opts);
> +
> +        if ($modrm->{mod} != MOD_DIRECT) {
> +            # Displacement only; we cannot use this since we
> +            # don't know absolute address of the memblock.
> +            next if $modrm->{mod} == MOD_INDIRECT && $modrm->{rm} == REG_EBP;
...
> +sub rand_insn_rex($$)
> +{
> +    my ($opts, $insn) = @_;
> +
> +    $opts->{w} = 0 unless defined $opts->{w};
> +    $opts->{x} = 0 unless defined $opts->{x} || defined $insn->{sib};
> +
> +    my $rex = rand_fill({w => {bitlen => 1},
> +                         r => {bitlen => 1},
> +                         b => {bitlen => 1},
> +                         x => {bitlen => 1}},
> +                        $opts);

I don't think it's a good idea to generate reg/rm/sib.index separate from
rex.r/b/x.  In particular, all of your tests vs EBP and ESP are not quite
right, since the final insn may be referencing R12 or R13.

What is your plan for handling the unary insns for which modrm.r is opcode and
not a register?  This doesn't seem to allow for those.  How about insns for
which modrm.mod must be 3 (register) or must be != 3 (memory/address)?  Is this
simply going to fall into "testing of illegal encodings"?


r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]