diff --git a/i386-asm.c b/i386-asm.c index 33783d5f5..470b20e7d 100644 --- a/i386-asm.c +++ b/i386-asm.c @@ -1002,15 +1002,21 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) 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 0 */ 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 e4655a7a6..883232eaf 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