diff --git a/cranelift/codegen/meta/src/isa/x86/recipes.rs b/cranelift/codegen/meta/src/isa/x86/recipes.rs index 50ac9fca7f..d126580804 100644 --- a/cranelift/codegen/meta/src/isa/x86/recipes.rs +++ b/cranelift/codegen/meta/src/isa/x86/recipes.rs @@ -399,6 +399,7 @@ pub fn define<'shared>( let f_unary_ieee32 = formats.by_name("UnaryIeee32"); let f_unary_ieee64 = formats.by_name("UnaryIeee64"); let f_unary_imm = formats.by_name("UnaryImm"); + let f_unary_imm128 = formats.by_name("UnaryImm128"); // Predicates shorthands. let use_sse41 = settings.predicate_by_name("use_sse41"); @@ -2382,6 +2383,19 @@ pub fn define<'shared>( ), ); + recipes.add_template_recipe( + EncodingRecipeBuilder::new("vconst", f_unary_imm128, 5) + .operands_out(vec![fpr]) + .clobbers_flags(false) + .emit( + r#" + {{PUT_OP}}(bits, rex2(0, out_reg0), sink); + modrm_riprel(out_reg0, sink); + const_disp4(imm, func, sink); + "#, + ), + ); + recipes.add_template_recipe( EncodingRecipeBuilder::new("jt_base", f_branch_table_base, 5) .operands_out(vec![gpr]) diff --git a/cranelift/codegen/src/isa/x86/binemit.rs b/cranelift/codegen/src/isa/x86/binemit.rs index 8aa51c07b6..afe2c2611f 100644 --- a/cranelift/codegen/src/isa/x86/binemit.rs +++ b/cranelift/codegen/src/isa/x86/binemit.rs @@ -4,7 +4,7 @@ use super::enc_tables::{needs_offset, needs_sib_byte}; use super::registers::RU; use crate::binemit::{bad_encoding, CodeSink, Reloc}; use crate::ir::condcodes::{CondCode, FloatCC, IntCC}; -use crate::ir::{Ebb, Function, Inst, InstructionData, JumpTable, Opcode, TrapCode}; +use crate::ir::{Constant, Ebb, Function, Inst, InstructionData, JumpTable, Opcode, TrapCode}; use crate::isa::{RegUnit, StackBase, StackBaseMask, StackRef, TargetIsa}; use crate::regalloc::RegDiversions; @@ -341,3 +341,11 @@ fn jt_disp4(jt: JumpTable, func: &Function, sink: &mut CS sink.put4(delta); sink.reloc_jt(Reloc::X86PCRelRodata4, jt); } + +/// Emit a four-byte displacement to `constant` +fn const_disp4(constant: Constant, func: &Function, sink: &mut CS) { + let offset = func.dfg.constants.get_offset(constant); + let delta = offset.wrapping_sub(sink.offset() + 4); + sink.put4(delta); + sink.reloc_constant(Reloc::X86PCRelRodata4, offset); +}