qemu-devel
[Top][All Lists]
Advanced

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

Re: [PATCH v1 4/4] x86-disas: add x86-mini disassembler implementation


From: Michael Clark
Subject: Re: [PATCH v1 4/4] x86-disas: add x86-mini disassembler implementation
Date: Mon, 27 Jan 2025 12:22:04 +1300
User-agent: Mozilla Thunderbird

On 1/24/25 13:10, Michael Clark wrote:
+static x86_opc_prefix x86_table_make_prefix(const x86_opc_data *d,
+    const x86_opr_data *o, const x86_ord_data *p)
+{
+    x86_opc_prefix tp;
+    memset(&tp, 0, sizeof(tp));
+
+    /* extract prefix and synthesize width prefixes */
+    switch (x86_enc_type(d->enc)) {
+    case x86_enc_t_lex:
+    case x86_enc_t_vex:
+    case x86_enc_t_evex:
+        switch (d->enc & x86_enc_w_mask) {
+        case x86_enc_w_wig:
+        case x86_enc_w_wn:
+        case x86_enc_w_wb:
+        case x86_enc_w_w0: break;
+        case x86_enc_w_w1: tp.pfx = x86_enc_p_rexw; break;
+        case x86_enc_w_wx: tp.pfx_w = x86_enc_p_rexw; /* fallthrough */
+        case x86_enc_w_ww: tp.pfx_o = x86_enc_p_66; break;
+        }
+        break;
+     }
+
+    /* find register or memory operand mapping to modrm.rm field
+     * so that we can add mod=0b11 or mod!=0b11 to modrm mask */
+    tp.modfun = x86_enc_func(d->enc) == x86_enc_f_modrm_n;
+    for (size_t i = 0; i < array_size(o->opr) && o->opr[i]; i++) {
+        uint isreg = x86_opr_type_val(o->opr[i]) >= x86_opr_reg;
+        uint ismem = x86_opr_has_mem(o->opr[i]);
+        uint ismrm = x86_ord_type_val(p->ord[i]) == x86_ord_mrm;
+        if (ismrm) {
+            if (isreg && !ismem) {
+                tp.modreg = 1; /* mod == 0b11 */
+                break;
+            } else if (!isreg && ismem) {
+                tp.modmem = 1; /* mod != 0b11 */
+                break;
+            }
+        }
+    }

I am already relatively strictly following QEMU conventions for
single-line and multi-line comments. I don't remember seeing a
checkpatch.pl report for the above multi-line comment. I wonder
if the constraint is restricted to top-level comments? I left
this as-is due to symmetry with the other comments in this block
as they are single-line and it looks better. this is very pedantic.

so am curious about a determination on the commenting convention.

I have a disagreement about unbraced 'if' in switch because IMHO
the QEMU rules make combinatorial logic sparse and hard to read.
I also typically put the first brace of functions on their own
line so there is space between function signature and first line.
those are the two main rules I break. my coding-style has lots of
switch statements because I rely on switch constant analysis and
jump table conversion because it tends to translate to fast code.
also I linearize them explicitly because not all compilers detect
a constant stride for index canonicalization in switch constants.
that is where the bulk of the checkpatch.pl warnings show up.

+    /* explict second opcode byte has mod == 0b11 */
+    if (d->opm[1] == 0xff && (d->opc[1] & 0xc0) == 0xc0 &&
+        !tp.modreg && !tp.modmem)
+    {
+        tp.modreg = 1;
+    }
+
+    return tp;
+}

fyi I have made a x86-mini-v2 branch with the changes I
mentioned in an email yesterday but it is still in flux:

https://github.com/michaeljclark/qemu/commits/x86-mini-v2

I still don't expect this code to be merged any-time-soon.
maybe in the future if QEMU gains the ability to run TCG
full-system under hypervisor with accelerated page tables.
I'm also considering digging out the most recent QEMU or tcc
TCG that is fully MIT-licensed as a starting point for IR.

the patch set may eventually become compelling if there is
a complete TCG supporting all AVX-512 vector ops. maybe this
is already there but I am not reading the GPL code in QEMU.
I am unsure about that code because a lot of code is by-file
licensed. it is questionable when the provenance originates
inside QEMU as opposed to MIT-licensed or dual-licensed code
(like FreeType) that is clearly of external origin. as a
modern embedded TCG would be quite useful in Rui's chibicc
or the MIT-licensed version of tcc:

- https://github.com/rui314/chibicc
- https://github.com/absop/Tinycc/blob/master/RELICENSING

and I am confessing about a snippet of code. this may look
familiar. there is one enum and two functions that were
derived from TCG X86 but they are unused. so I should add
Fabrice's original TCG MIT-license header or remove them.

I am pretty sure I checked the provenance for the version
of TCG that I used but I need to add an explicit reference
or delete these definitions. they can't really be written
a different way because they are more like reference data
and invariant logic based on X86 ISA constraints:

+/*
+ * test conditions
+ */
+
+enum
+{
+    /* non-signed */
+    x86_never  = (0 | 0 | 0 | 0),
+    x86_always = (0 | 0 | 0 | 1),
+    x86_eq     = (8 | 0 | 0 | 0),
+    x86_ne     = (8 | 0 | 0 | 1),
+    /* signed */
+    x86_lt     = (0 | 0 | 2 | 0),
+    x86_ge     = (0 | 0 | 2 | 1),
+    x86_le     = (8 | 0 | 2 | 0),
+    x86_gt     = (8 | 0 | 2 | 1),
+    /* unsigned */
+    x86_ltu    = (0 | 4 | 0 | 0),
+    x86_geu    = (0 | 4 | 0 | 1),
+    x86_leu    = (8 | 4 | 0 | 0),
+    x86_gtu    = (8 | 4 | 0 | 1),
+};

+/*
+ * invert condition
+ */
+
+static inline uint x86_invert_cond(uint c) {
+    return c ^ 1;
+}
+
+/*
+ * swap condition operands
+ */
+
+static inline uint x86_swap_cond(uint c) {
+    return c & 6 ? c ^ 9 : c;
+}




reply via email to

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