diff --git a/librz/analysis/arch/x86/common.c b/librz/analysis/arch/x86/common.c
index c9234dde10f..a33052c63ad 100644
--- a/librz/analysis/arch/x86/common.c
+++ b/librz/analysis/arch/x86/common.c
@@ -1249,6 +1249,7 @@ RzILOpPure *x86_il_get_floating_operand_bits(X86Op op, int analysis_bits, ut64 p
 		} else {
 			RZ_LOG_ERROR("x86: RzIL: Invalid register passed as a floating point operand: %d\n", op.reg);
 		}
+		break;
 	case X86_OP_MEM:
 		switch (op.size) {
 			/* ~Duff's~ DMaroo's device */
@@ -1258,6 +1259,7 @@ RzILOpPure *x86_il_get_floating_operand_bits(X86Op op, int analysis_bits, ut64 p
 		default:
 			RZ_LOG_ERROR("x86: RzIL: Invalid memory operand width for a floating point operand: %d\n", op.size);
 		}
+		break;
 	case X86_OP_INVALID:
 	case X86_OP_IMM:
 #if CS_API_MAJOR <= 3
diff --git a/librz/analysis/arch/x86/il_fp_ops.inc b/librz/analysis/arch/x86/il_fp_ops.inc
index 1276afb4090..9e7afcbab12 100644
--- a/librz/analysis/arch/x86/il_fp_ops.inc
+++ b/librz/analysis/arch/x86/il_fp_ops.inc
@@ -207,3 +207,28 @@ IL_LIFTER(fldlg2) {
 IL_LIFTER(fldln2) {
 	return SEQ2(INIT_RMODE("rmode"), fpu_stack_push_val(math_const_to_float(FPU_LN2)));
 }
+
+/**
+ * FXCH
+ * Exchange the contents of FPU stack register with ST(0)
+ */
+IL_LIFTER(fxch) {
+	X86Reg reg;
+
+	if (ins->structure->op_count == 0) {
+		/* Use ST1 as the default reg in case no operand is provided. */
+		reg = X86_REG_ST1;
+	} else {
+		reg = ins->structure->operands[0].reg;
+	}
+
+	/* TODO: The IL generated from the following code is too verbose because of
+	many rounding checks, there are ways to remove this sort of rounding checks,
+	but it doesn't matter for now so I'm not bothering with it. */
+	return SEQ4(
+		SETL("tmp", x86_il_get_st_reg(X86_REG_ST0)),
+		x86_il_set_st_reg(X86_REG_ST0, x86_il_get_st_reg(reg)),
+		x86_il_set_st_reg(reg, VARL("tmp")),
+		x86_il_set_fpu_flag(X86_FPU_C1, IL_FALSE)
+	);
+}
diff --git a/librz/analysis/arch/x86/x86_il.c b/librz/analysis/arch/x86/x86_il.c
index 42517dbb9c0..ed8eb297b22 100644
--- a/librz/analysis/arch/x86/x86_il.c
+++ b/librz/analysis/arch/x86/x86_il.c
@@ -259,7 +259,8 @@ x86_il_ins x86_ins[X86_INS_ENDING] = {
 	[X86_INS_FLDL2E] = x86_il_fldl2e,
 	[X86_INS_FLDPI] = x86_il_fldpi,
 	[X86_INS_FLDLG2] = x86_il_fldlg2,
-	[X86_INS_FLDLN2] = x86_il_fldln2
+	[X86_INS_FLDLN2] = x86_il_fldln2,
+	[X86_INS_FXCH] = x86_il_fxch,
 };
 
 void label_int(RzILVM *vm, RzILOpEffect *op);