endbr64 has no operand but comes with a ModR/M byte. Handle it in the
same way as *fence instructions.

Signed-off-by: Yao Zi <zi...@disroot.org>
---
 i386-asm.c   | 12 +++++++++---
 x86_64-asm.h |  3 +++
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/i386-asm.c b/i386-asm.c
index 33783d5f..a3e16fb8 100644
--- a/i386-asm.c
+++ b/i386-asm.c
@@ -1002,15 +1002,21 @@ again:
     modrm_index = -1;
     modreg_index = -1;
     if (pa->instr_type & OPC_MODRM) {
+#ifdef TCC_TARGET_X86_64
        if (!nb_ops) {
            /* A modrm opcode without operands is a special case (e.g. mfence).
-              It has a group and acts as if there's an register operand 0
-              (ax).  */
+              It has a group and acts as if there's an register operand */
            i = 0;
            ops[i].type = OP_REG;
-           ops[i].reg = 0;
+           if (pa->sym == TOK_ASM_endbr64)
+             ops[i].reg = 2; // dx
+           else if (pa->sym >= TOK_ASM_lfence && pa->sym <= TOK_ASM_sfence)
+             ops[i].reg = 0; // ax
+           else
+             tcc_error("bad MODR/M opcode without operands");
            goto modrm_found;
        }
+#endif
         /* first look for an ea operand */
         for(i = 0;i < nb_ops; i++) {
             if (op_type[i] & OP_EA)
diff --git a/x86_64-asm.h b/x86_64-asm.h
index e4655a7a..883232ea 100644
--- a/x86_64-asm.h
+++ b/x86_64-asm.h
@@ -538,6 +538,9 @@ ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, 
OPT_EA | OPT_REG32 ))
     DEF_ASM_OP0L(mfence, 0x0fae, 6, OPC_MODRM)
     DEF_ASM_OP0L(sfence, 0x0fae, 7, OPC_MODRM)
     DEF_ASM_OP1(clflush, 0x0fae, 7, OPC_MODRM, OPT_EA)
+
+    /* Control-Flow Enforcement */
+    DEF_ASM_OP0L(endbr64, 0xf30f1e, 7, OPC_MODRM)
 #undef ALT
 #undef DEF_ASM_OP0
 #undef DEF_ASM_OP0L
-- 
2.46.0


_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to