diff --git a/cranelift/codegen/src/isa/x64/inst.isle b/cranelift/codegen/src/isa/x64/inst.isle index 9b4262bed78e..78f4aa23872c 100644 --- a/cranelift/codegen/src/isa/x64/inst.isle +++ b/cranelift/codegen/src/isa/x64/inst.isle @@ -1553,17 +1553,38 @@ (type Gpr (primitive Gpr)) (type WritableGpr (primitive WritableGpr)) (type OptionWritableGpr (primitive OptionWritableGpr)) -(type GprMem extern (enum)) -(type GprMemImm extern (enum)) +(type GprMem extern + (enum + (Reg (reg Reg)) + (Mem (addr SyntheticAmode)))) +(type GprMemImm extern + (enum + (Reg (reg Reg)) + (Mem (addr SyntheticAmode)) + (Imm (simm32 u32)))) (type Imm8Gpr extern (enum)) (type Xmm (primitive Xmm)) (type WritableXmm (primitive WritableXmm)) (type OptionWritableXmm (primitive OptionWritableXmm)) -(type XmmMem extern (enum)) -(type XmmMemAligned extern (enum)) -(type XmmMemImm extern (enum)) -(type XmmMemAlignedImm extern (enum)) +(type XmmMem extern + (enum + (Reg (reg Reg)) + (Mem (addr SyntheticAmode)))) +(type XmmMemAligned extern + (enum + (Reg (reg Reg)) + (Mem (addr SyntheticAmode)))) +(type XmmMemImm extern + (enum + (Reg (reg Reg)) + (Mem (addr SyntheticAmode)) + (Imm (simm32 u32)))) +(type XmmMemAlignedImm extern + (enum + (Reg (reg Reg)) + (Mem (addr SyntheticAmode)) + (Imm (simm32 u32)))) ;; Convert an `Imm8Reg` into an `Imm8Gpr`. (decl imm8_reg_to_imm8_gpr (Imm8Reg) Imm8Gpr) diff --git a/cranelift/codegen/src/isa/x64/inst/args.rs b/cranelift/codegen/src/isa/x64/inst/args.rs index 53ad25ae4b48..0d74280db0b6 100644 --- a/cranelift/codegen/src/isa/x64/inst/args.rs +++ b/cranelift/codegen/src/isa/x64/inst/args.rs @@ -128,31 +128,34 @@ macro_rules! newtype_of_reg { } $( - /// A newtype wrapper around `RegMem` for general-purpose registers. + /// A newtype wrapper around `RegMem`; these variants should match + /// the `RegMem` variants exactly. #[derive(Clone, Debug)] - pub struct $newtype_reg_mem(RegMem); + #[expect(missing_docs, reason = "see `RegMem`")] + pub enum $newtype_reg_mem { + Reg { reg: Reg }, + Mem { addr: SyntheticAmode }, + } impl From<$newtype_reg_mem> for RegMem { fn from(rm: $newtype_reg_mem) -> Self { - rm.0 - } - } - impl<'a> From<&'a $newtype_reg_mem> for &'a RegMem { - fn from(rm: &'a $newtype_reg_mem) -> &'a RegMem { - &rm.0 + match rm { + $newtype_reg_mem::Reg { reg } => RegMem::Reg { reg }, + $newtype_reg_mem::Mem { addr } => RegMem::Mem { addr }, + } } } impl From<$newtype_reg> for $newtype_reg_mem { fn from(r: $newtype_reg) -> Self { - $newtype_reg_mem(RegMem::reg(r.into())) + $newtype_reg_mem::Reg { reg: r.into() } } } impl $newtype_reg_mem { - /// Construct a `RegMem` newtype from the given `RegMem`, or return - /// `None` if the `RegMem` is not a valid instance of this `RegMem` - /// newtype. + /// Construct a `RegMem` newtype from the given `RegMem`, or + /// return `None` if the `RegMem` is not a valid instance of + /// this `RegMem` newtype. pub fn new(rm: RegMem) -> Option { match rm { RegMem::Mem { addr } => { @@ -163,7 +166,7 @@ macro_rules! newtype_of_reg { } )? if _allow { - Some(Self(RegMem::Mem { addr })) + Some(Self::Mem { addr }) } else { None } @@ -185,7 +188,7 @@ macro_rules! newtype_of_reg { ); } )? - Self(RegMem::Mem { addr }) + Self::Mem { addr } } RegMem::Reg { reg } => $newtype_reg::unwrap_new(reg).into(), } @@ -193,40 +196,51 @@ macro_rules! newtype_of_reg { /// Convert this newtype into its underlying `RegMem`. pub fn to_reg_mem(self) -> RegMem { - self.0 + self.into() } #[allow(dead_code)] // Used by some newtypes and not others. pub(crate) fn get_operands(&mut self, collector: &mut impl OperandVisitor) { - self.0.get_operands(collector); + match self { + Self::Reg { reg } => collector.reg_use(reg), + Self::Mem { addr } => addr.get_operands(collector), + } } } impl PrettyPrint for $newtype_reg_mem { fn pretty_print(&self, size: u8) -> String { - self.0.pretty_print(size) + match self { + Self::Reg { reg } => pretty_print_reg(*reg, size), + Self::Mem { addr } => addr.pretty_print(size), + } } } )* $( - /// A newtype wrapper around `RegMemImm`. + /// A newtype wrapper imitating `RegMemImm`; these variants should + /// match the `RegMemImm` variants exactly. #[derive(Clone, Debug)] - pub struct $newtype_reg_mem_imm(RegMemImm); + #[expect(missing_docs, reason = "see `RegMemImm`")] + pub enum $newtype_reg_mem_imm { + Reg { reg: Reg }, + Mem { addr: SyntheticAmode }, + Imm { simm32: u32 }, + } impl From<$newtype_reg_mem_imm> for RegMemImm { fn from(rmi: $newtype_reg_mem_imm) -> RegMemImm { - rmi.0 - } - } - impl<'a> From<&'a $newtype_reg_mem_imm> for &'a RegMemImm { - fn from(rmi: &'a $newtype_reg_mem_imm) -> &'a RegMemImm { - &rmi.0 + match rmi { + $newtype_reg_mem_imm::Reg { reg } => RegMemImm::Reg { reg }, + $newtype_reg_mem_imm::Mem { addr } => RegMemImm::Mem { addr }, + $newtype_reg_mem_imm::Imm { simm32 } => RegMemImm::Imm { simm32 }, + } } } impl From<$newtype_reg> for $newtype_reg_mem_imm { fn from(r: $newtype_reg) -> Self { - $newtype_reg_mem_imm(RegMemImm::reg(r.into())) + $newtype_reg_mem_imm::Reg { reg: r.into() } } } @@ -236,7 +250,7 @@ macro_rules! newtype_of_reg { /// newtype. pub fn new(rmi: RegMemImm) -> Option { match rmi { - RegMemImm::Imm { .. } => Some(Self(rmi)), + RegMemImm::Imm { simm32 } => Some(Self::Imm { simm32 }), RegMemImm::Mem { addr } => { let mut _allow = true; $( @@ -245,7 +259,7 @@ macro_rules! newtype_of_reg { } )? if _allow { - Some(Self(RegMemImm::Mem { addr })) + Some(Self::Mem { addr }) } else { None } @@ -258,7 +272,7 @@ macro_rules! newtype_of_reg { /// messages in case of failure. pub fn unwrap_new(rmi: RegMemImm) -> Self { match rmi { - RegMemImm::Imm { .. } => Self(rmi), + RegMemImm::Imm { simm32 } => Self::Imm { simm32 }, RegMemImm::Mem { addr } => { $( if $aligned_imm && !addr.aligned() { @@ -269,7 +283,7 @@ macro_rules! newtype_of_reg { ); } )? - Self(RegMemImm::Mem { addr }) + Self::Mem { addr } } RegMemImm::Reg { reg } => $newtype_reg::unwrap_new(reg).into(), @@ -279,18 +293,26 @@ macro_rules! newtype_of_reg { /// Convert this newtype into its underlying `RegMemImm`. #[allow(dead_code)] // Used by some newtypes and not others. pub fn to_reg_mem_imm(self) -> RegMemImm { - self.0 + self.into() } #[allow(dead_code)] // Used by some newtypes and not others. pub(crate) fn get_operands(&mut self, collector: &mut impl OperandVisitor) { - self.0.get_operands(collector); + match self { + Self::Reg { reg } => collector.reg_use(reg), + Self::Mem { addr } => addr.get_operands(collector), + Self::Imm { .. } => {} + } } } impl PrettyPrint for $newtype_reg_mem_imm { fn pretty_print(&self, size: u8) -> String { - self.0.pretty_print(size) + match self { + Self::Reg { reg } => pretty_print_reg(*reg, size), + Self::Mem { addr } => addr.pretty_print(size), + Self::Imm { simm32 } => format!("${}", *simm32 as i32), + } } } )* @@ -679,15 +701,6 @@ impl RegMemImm { debug_assert_eq!(reg.class(), expected_reg_class); } } - - /// Add the regs mentioned by `self` to `collector`. - pub(crate) fn get_operands(&mut self, collector: &mut impl OperandVisitor) { - match self { - Self::Reg { reg } => collector.reg_use(reg), - Self::Mem { addr } => addr.get_operands(collector), - Self::Imm { .. } => {} - } - } } impl From for RegMemImm { diff --git a/cranelift/codegen/src/isa/x64/pcc.rs b/cranelift/codegen/src/isa/x64/pcc.rs index 3088b7e80950..e71de6a98207 100644 --- a/cranelift/codegen/src/isa/x64/pcc.rs +++ b/cranelift/codegen/src/isa/x64/pcc.rs @@ -3,8 +3,11 @@ use crate::ir::pcc::*; use crate::ir::types::*; use crate::isa::x64::args::AvxOpcode; +use crate::isa::x64::args::{ + GprMem, GprMemImm, XmmMem, XmmMemAligned, XmmMemAlignedImm, XmmMemImm, +}; use crate::isa::x64::inst::args::{ - Amode, Gpr, Imm8Reg, RegMem, RegMemImm, ShiftKind, SseOpcode, SyntheticAmode, ToWritableReg, CC, + Amode, Gpr, Imm8Reg, RegMem, ShiftKind, SseOpcode, SyntheticAmode, ToWritableReg, CC, }; use crate::isa::x64::inst::Inst; use crate::machinst::pcc::*; @@ -67,14 +70,14 @@ pub(crate) fn check( ref src2, dst, .. - } => match <&RegMem>::from(src2) { - RegMem::Mem { addr } => { + } => match src2 { + GprMem::Mem { addr } => { let loaded = check_load(ctx, None, addr, vcode, size.to_type(), 64)?; check_output(ctx, vcode, dst.to_writable_reg(), &[], |_vcode| { clamp_range(ctx, 64, size.to_bits().into(), loaded) }) } - RegMem::Reg { .. } => undefined_result(ctx, vcode, dst, 64, size.to_bits().into()), + GprMem::Reg { .. } => undefined_result(ctx, vcode, dst, 64, size.to_bits().into()), }, Inst::UnaryRmR { @@ -85,14 +88,14 @@ pub(crate) fn check( } | Inst::UnaryRmRImmVex { size, ref src, dst, .. - } => match <&RegMem>::from(src) { - RegMem::Mem { addr } => { + } => match src { + GprMem::Mem { addr } => { check_load(ctx, None, addr, vcode, size.to_type(), 64)?; check_output(ctx, vcode, dst.to_writable_reg(), &[], |_vcode| { clamp_range(ctx, 64, size.to_bits().into(), None) }) } - RegMem::Reg { .. } => undefined_result(ctx, vcode, dst, 64, size.to_bits().into()), + GprMem::Reg { .. } => undefined_result(ctx, vcode, dst, 64, size.to_bits().into()), }, Inst::Div { @@ -102,11 +105,11 @@ pub(crate) fn check( dst_remainder, .. } => { - match <&RegMem>::from(divisor) { - RegMem::Mem { addr } => { + match divisor { + GprMem::Mem { addr } => { check_load(ctx, None, addr, vcode, size.to_type(), 64)?; } - RegMem::Reg { .. } => {} + GprMem::Reg { .. } => {} } undefined_result(ctx, vcode, dst_quotient, 64, 64)?; undefined_result(ctx, vcode, dst_remainder, 64, 64)?; @@ -115,11 +118,11 @@ pub(crate) fn check( Inst::Div8 { dst, ref divisor, .. } => { - match <&RegMem>::from(divisor) { - RegMem::Mem { addr } => { + match divisor { + GprMem::Mem { addr } => { check_load(ctx, None, addr, vcode, I8, 64)?; } - RegMem::Reg { .. } => {} + GprMem::Reg { .. } => {} } // 64-bit result width because result may be negative // hence high bits set. @@ -140,22 +143,22 @@ pub(crate) fn check( ref src2, .. } => { - match <&RegMem>::from(src2) { - RegMem::Mem { addr } => { + match src2 { + GprMem::Mem { addr } => { check_load(ctx, None, addr, vcode, size.to_type(), 64)?; } - RegMem::Reg { .. } => {} + GprMem::Reg { .. } => {} } undefined_result(ctx, vcode, dst_lo, 64, size.to_bits().into())?; undefined_result(ctx, vcode, dst_hi, 64, size.to_bits().into())?; Ok(()) } Inst::Mul8 { dst, ref src2, .. } => { - match <&RegMem>::from(src2) { - RegMem::Mem { addr } => { + match src2 { + GprMem::Mem { addr } => { check_load(ctx, None, addr, vcode, I8, 64)?; } - RegMem::Reg { .. } => {} + GprMem::Reg { .. } => {} } undefined_result(ctx, vcode, dst, 64, 16)?; Ok(()) @@ -166,11 +169,11 @@ pub(crate) fn check( ref src2, .. } => { - match <&RegMem>::from(src2) { - RegMem::Mem { addr } => { + match src2 { + GprMem::Mem { addr } => { check_load(ctx, None, addr, vcode, size.to_type(), 64)?; } - RegMem::Reg { .. } => {} + GprMem::Reg { .. } => {} } undefined_result(ctx, vcode, dst, 64, size.to_bits().into())?; Ok(()) @@ -181,11 +184,11 @@ pub(crate) fn check( ref src1, .. } => { - match <&RegMem>::from(src1) { - RegMem::Mem { addr } => { + match src1 { + GprMem::Mem { addr } => { check_load(ctx, None, addr, vcode, size.to_type(), 64)?; } - RegMem::Reg { .. } => {} + GprMem::Reg { .. } => {} } undefined_result(ctx, vcode, dst, 64, size.to_bits().into())?; Ok(()) @@ -224,13 +227,13 @@ pub(crate) fn check( } => { let from_bytes: u16 = ext_mode.src_size().into(); let to_bytes: u16 = ext_mode.dst_size().into(); - match <&RegMem>::from(src) { - RegMem::Reg { reg } => { + match src { + GprMem::Reg { reg } => { check_unop(ctx, vcode, 64, dst.to_writable_reg(), *reg, |src| { clamp_range(ctx, 64, from_bytes * 8, Some(src.clone())) }) } - RegMem::Mem { addr } => { + GprMem::Mem { addr } => { let loaded = check_load( ctx, Some(dst.to_writable_reg()), @@ -275,11 +278,11 @@ pub(crate) fn check( ref src, dst, } => { - match <&RegMem>::from(src) { - RegMem::Mem { addr } => { + match src { + GprMem::Mem { addr } => { check_load(ctx, None, addr, vcode, ext_mode.src_type(), 64)?; } - RegMem::Reg { .. } => {} + GprMem::Reg { .. } => {} } undefined_result(ctx, vcode, dst, 64, 64) } @@ -315,8 +318,8 @@ pub(crate) fn check( } Inst::XmmRmiReg { dst, ref src2, .. } => { - match <&RegMemImm>::from(src2) { - RegMemImm::Mem { addr } => { + match src2 { + XmmMemAlignedImm::Mem { addr } => { check_load(ctx, None, addr, vcode, I8X16, 128)?; } _ => {} @@ -329,8 +332,8 @@ pub(crate) fn check( src1, ref src2, .. - } => match <&RegMemImm>::from(src2) { - RegMemImm::Mem { + } => match src2 { + GprMemImm::Mem { addr: SyntheticAmode::ConstantOffset(k), } => { match vcode.constants.get(*k) { @@ -344,20 +347,20 @@ pub(crate) fn check( } Ok(()) } - RegMemImm::Mem { addr } => { + GprMemImm::Mem { addr } => { if let Some(rhs) = check_load(ctx, None, addr, vcode, size.to_type(), 64)? { let lhs = get_fact_or_default(vcode, src1.to_reg(), 64); state.cmp_flags = Some((lhs, rhs)); } Ok(()) } - RegMemImm::Reg { reg } => { + GprMemImm::Reg { reg } => { let rhs = get_fact_or_default(vcode, *reg, 64); let lhs = get_fact_or_default(vcode, src1.to_reg(), 64); state.cmp_flags = Some((lhs, rhs)); Ok(()) } - RegMemImm::Imm { simm32 } => { + GprMemImm::Imm { simm32 } => { let lhs = get_fact_or_default(vcode, src1.to_reg(), 64); let rhs = Fact::constant(64, (*simm32 as i32) as i64 as u64); state.cmp_flags = Some((lhs, rhs)); @@ -376,12 +379,12 @@ pub(crate) fn check( alternative, cc, .. - } => match <&RegMem>::from(consequent) { - RegMem::Mem { addr } => { + } => match consequent { + GprMem::Mem { addr } => { check_load(ctx, None, addr, vcode, size.to_type(), 64)?; Ok(()) } - RegMem::Reg { reg } if (cc == CC::NB || cc == CC::NBE) && cmp_flags.is_some() => { + GprMem::Reg { reg } if (cc == CC::NB || cc == CC::NBE) && cmp_flags.is_some() => { let (cmp_lhs, cmp_rhs) = cmp_flags.unwrap(); trace!("lhs = {:?} rhs = {:?}", cmp_lhs, cmp_rhs); let reg = *reg; @@ -411,12 +414,12 @@ pub(crate) fn check( Inst::XmmCmove { dst, .. } => ensure_no_fact(vcode, dst.to_writable_reg().to_reg()), - Inst::Push64 { ref src } => match <&RegMemImm>::from(src) { - RegMemImm::Mem { addr } => { + Inst::Push64 { ref src } => match src { + GprMemImm::Mem { addr } => { check_load(ctx, None, addr, vcode, I64, 64)?; Ok(()) } - RegMemImm::Reg { .. } | RegMemImm::Imm { .. } => Ok(()), + GprMemImm::Reg { .. } | GprMemImm::Imm { .. } => Ok(()), }, Inst::Pop64 { dst } => undefined_result(ctx, vcode, dst, 64, 64), @@ -431,11 +434,11 @@ pub(crate) fn check( | Inst::XmmUnaryRmRImm { dst, src: ref src2, .. } => { - match <&RegMem>::from(src2) { - RegMem::Mem { addr } => { + match src2 { + XmmMemAligned::Mem { addr } => { check_load(ctx, None, addr, vcode, I8X16, 128)?; } - RegMem::Reg { .. } => {} + XmmMemAligned::Reg { .. } => {} } ensure_no_fact(vcode, dst.to_writable_reg().to_reg()) } @@ -446,11 +449,11 @@ pub(crate) fn check( op: SseOpcode::Movss, .. } => { - match <&RegMem>::from(src) { - RegMem::Mem { addr } => { + match src { + XmmMem::Mem { addr } => { check_load(ctx, None, addr, vcode, F32, 32)?; } - RegMem::Reg { .. } => {} + XmmMem::Reg { .. } => {} } ensure_no_fact(vcode, dst.to_writable_reg().to_reg()) } @@ -460,11 +463,11 @@ pub(crate) fn check( op: SseOpcode::Movsd, .. } => { - match <&RegMem>::from(src) { - RegMem::Mem { addr } => { + match src { + XmmMem::Mem { addr } => { check_load(ctx, None, addr, vcode, F64, 64)?; } - RegMem::Reg { .. } => {} + XmmMem::Reg { .. } => {} } ensure_no_fact(vcode, dst.to_writable_reg().to_reg()) } @@ -488,11 +491,11 @@ pub(crate) fn check( src3: ref src2, .. } => { - match <&RegMem>::from(src2) { - RegMem::Mem { addr } => { + match src2 { + XmmMem::Mem { addr } => { check_load(ctx, None, addr, vcode, I8X16, 128)?; } - RegMem::Reg { .. } => {} + XmmMem::Reg { .. } => {} } ensure_no_fact(vcode, dst.to_writable_reg().to_reg()) } @@ -533,31 +536,31 @@ pub(crate) fn check( _ => (I8X16, 128), }; - match <&RegMem>::from(src2) { - RegMem::Mem { addr } => { + match src2 { + XmmMem::Mem { addr } => { check_load(ctx, None, addr, vcode, ty, size)?; } - RegMem::Reg { .. } => {} + XmmMem::Reg { .. } => {} } ensure_no_fact(vcode, dst.to_writable_reg().to_reg()) } Inst::XmmRmiRVex { dst, ref src2, .. } => { - match <&RegMemImm>::from(src2) { - RegMemImm::Mem { addr } => { + match src2 { + XmmMemImm::Mem { addr } => { check_load(ctx, None, addr, vcode, I8X16, 128)?; } - RegMemImm::Reg { .. } | RegMemImm::Imm { .. } => {} + XmmMemImm::Reg { .. } | XmmMemImm::Imm { .. } => {} } ensure_no_fact(vcode, dst.to_writable_reg().to_reg()) } Inst::XmmVexPinsr { dst, ref src2, .. } => { - match <&RegMem>::from(src2) { - RegMem::Mem { addr } => { + match src2 { + GprMem::Mem { addr } => { check_load(ctx, None, addr, vcode, I64, 64)?; } - RegMem::Reg { .. } => {} + GprMem::Reg { .. } => {} } ensure_no_fact(vcode, dst.to_writable_reg().to_reg()) } @@ -569,11 +572,11 @@ pub(crate) fn check( Inst::XmmToGprImmVex { dst, .. } => ensure_no_fact(vcode, dst.to_writable_reg().to_reg()), Inst::GprToXmmVex { dst, ref src, .. } | Inst::GprToXmm { dst, ref src, .. } => { - match <&RegMem>::from(src) { - RegMem::Mem { addr } => { + match src { + GprMem::Mem { addr } => { check_load(ctx, None, addr, vcode, I64, 64)?; } - RegMem::Reg { .. } => {} + GprMem::Reg { .. } => {} } ensure_no_fact(vcode, dst.to_writable_reg().to_reg()) } @@ -609,11 +612,11 @@ pub(crate) fn check( Inst::CvtIntToFloat { dst, ref src2, .. } | Inst::CvtIntToFloatVex { dst, ref src2, .. } => { - match <&RegMem>::from(src2) { - RegMem::Mem { addr } => { + match src2 { + GprMem::Mem { addr } => { check_load(ctx, None, addr, vcode, I64, 64)?; } - RegMem::Reg { .. } => {} + GprMem::Reg { .. } => {} } ensure_no_fact(vcode, dst.to_writable_reg().to_reg()) } @@ -661,11 +664,11 @@ pub(crate) fn check( Inst::XmmCmpRmR { ref src1, ref src2, .. } => { - match <&RegMem>::from(src2) { - RegMem::Mem { addr } => { + match src2 { + XmmMemAligned::Mem { addr } => { check_load(ctx, None, addr, vcode, I8X16, 128)?; } - RegMem::Reg { .. } => {} + XmmMemAligned::Reg { .. } => {} } ensure_no_fact(vcode, src1.to_reg()) } @@ -677,7 +680,7 @@ pub(crate) fn check( op, .. } if op.has_scalar_src2() => { - match <&RegMem>::from(src2) { + match src2 { RegMem::Mem { addr } => { check_load( ctx, @@ -694,7 +697,7 @@ pub(crate) fn check( } Inst::XmmRmRImm { dst, ref src2, .. } => { - match <&RegMem>::from(src2) { + match src2 { RegMem::Mem { addr } => { check_load(ctx, None, addr, vcode, I8X16, 128)?; } @@ -706,11 +709,11 @@ pub(crate) fn check( Inst::XmmCmpRmRVex { ref src1, ref src2, .. } => { - match <&RegMem>::from(src2) { - RegMem::Mem { addr } => { + match src2 { + XmmMem::Mem { addr } => { check_load(ctx, None, addr, vcode, F32, 32)?; } - RegMem::Reg { .. } => {} + XmmMem::Reg { .. } => {} } ensure_no_fact(vcode, src1.to_reg()) } @@ -731,7 +734,7 @@ pub(crate) fn check( Inst::ReturnCallUnknown { .. } => Ok(()), - Inst::CallUnknown { ref info } => match <&RegMem>::from(&info.dest) { + Inst::CallUnknown { ref info } => match &info.dest { RegMem::Mem { addr } => { check_load(ctx, None, addr, vcode, I64, 64)?; Ok(()) @@ -740,7 +743,7 @@ pub(crate) fn check( }, Inst::JmpUnknown { target: ref dest, .. - } => match <&RegMem>::from(dest) { + } => match dest { RegMem::Mem { addr } => { check_load(ctx, None, addr, vcode, I64, 64)?; Ok(())