aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--i386-asm.c9
-rw-r--r--tests/asmtest.S7
-rw-r--r--x86_64-asm.h6
3 files changed, 22 insertions, 0 deletions
diff --git a/i386-asm.c b/i386-asm.c
index 2ffa53b..a036e49 100644
--- a/i386-asm.c
+++ b/i386-asm.c
@@ -893,6 +893,15 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
pc = 0;
if (pa->instr_type & OPC_MODRM) {
+ 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). */
+ i = 0;
+ ops[i].type = OP_REG;
+ ops[i].reg = 0;
+ goto modrm_found;
+ }
/* first look for an ea operand */
for(i = 0;i < nb_ops; i++) {
if (op_type[i] & OP_EA)
diff --git a/tests/asmtest.S b/tests/asmtest.S
index 79419b9..bf51c44 100644
--- a/tests/asmtest.S
+++ b/tests/asmtest.S
@@ -607,6 +607,13 @@ int $0x10
rdmsr
rdpmc
ud2
+#ifdef __x86_64__
+ syscall
+ sysret
+ lfence
+ mfence
+ sfence
+#endif
emms
movd %edx, %mm3
diff --git a/x86_64-asm.h b/x86_64-asm.h
index cf67e69..a40b697 100644
--- a/x86_64-asm.h
+++ b/x86_64-asm.h
@@ -88,6 +88,9 @@ ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA
DEF_ASM_OP0(rdtsc, 0x0f31)
DEF_ASM_OP0(rdmsr, 0x0f32)
DEF_ASM_OP0(rdpmc, 0x0f33)
+
+ DEF_ASM_OP0(syscall, 0x0f05)
+ DEF_ASM_OP0(sysret, 0x0f07)
DEF_ASM_OP0(ud2, 0x0f0b)
/* NOTE: we took the same order as gas opcode definition order */
@@ -482,6 +485,9 @@ ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP0L(lfence, 0x0fae, 5, OPC_MODRM)
+ DEF_ASM_OP0L(mfence, 0x0fae, 6, OPC_MODRM)
+ DEF_ASM_OP0L(sfence, 0x0fae, 7, OPC_MODRM)
#undef ALT
#undef DEF_ASM_OP0
#undef DEF_ASM_OP0L