Add back the ifcmp_sp CLIF opcode.

This opcode was removed as part of the old-backend cleanup in #3446.
While this opcode will definitely go away eventually, it is
unfortunately still used today in Lucet (as we just discovered while
working to upgrade Lucet's pinned Cranelift version). Lucet is
deprecated and slated to eventually be completely sunset in favor of
Wasmtime; but until that happens, we need to keep this opcode.
This commit is contained in:
Chris Fallin
2021-11-01 13:34:31 -07:00
parent 9e7760bd83
commit 5e96a447f0
6 changed files with 70 additions and 2 deletions

View File

@@ -1797,6 +1797,21 @@ pub(crate) fn define(
.operands_out(vec![a]),
);
ig.push(
Inst::new(
"ifcmp_sp",
r#"
Compare ``addr`` with the stack pointer and set the CPU flags.
This is like `ifcmp` where ``addr`` is the LHS operand and the stack
pointer is the RHS.
"#,
&formats.unary,
)
.operands_in(vec![addr])
.operands_out(vec![flags]),
);
let x = &Operand::new("x", TxN).with_doc("Vector to split");
let lo = &Operand::new("lo", &TxN.half_vector()).with_doc("Low-numbered lanes of `x`");
let hi = &Operand::new("hi", &TxN.half_vector()).with_doc("High-numbered lanes of `x`");

View File

@@ -3744,7 +3744,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
});
}
Opcode::ConstAddr | Opcode::Vconcat | Opcode::Vsplit => {
Opcode::ConstAddr | Opcode::Vconcat | Opcode::Vsplit | Opcode::IfcmpSp => {
return Err(CodegenError::Unsupported(format!(
"Unimplemented lowering: {}",
op

View File

@@ -2888,6 +2888,10 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
Opcode::Isplit | Opcode::Iconcat => unimplemented!("Wide integer ops not implemented."),
Opcode::IfcmpSp => {
panic!("Unused opcode should not be encountered.");
}
Opcode::Ifcmp
| Opcode::Ffcmp
| Opcode::Trapff

View File

@@ -6860,7 +6860,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
panic!("table_addr should have been removed by legalization!");
}
Opcode::Copy => {
Opcode::IfcmpSp | Opcode::Copy => {
panic!("Unused opcode should not be encountered.");
}
@@ -7075,6 +7075,23 @@ impl LowerBackend for X64Backend {
let cond_code = emit_cmp(ctx, ifcmp, cond_code);
let cc = CC::from_intcc(cond_code);
ctx.emit(Inst::jmp_cond(cc, taken, not_taken));
} else if let Some(ifcmp_sp) = matches_input(ctx, flag_input, Opcode::IfcmpSp) {
let operand = put_input_in_reg(
ctx,
InsnInput {
insn: ifcmp_sp,
input: 0,
},
);
let ty = ctx.input_ty(ifcmp_sp, 0);
ctx.emit(Inst::cmp_rmi_r(
OperandSize::from_ty(ty),
RegMemImm::reg(regs::rsp()),
operand,
));
let cond_code = ctx.data(branches[0]).cond_code().unwrap();
let cc = CC::from_intcc(cond_code);
ctx.emit(Inst::jmp_cond(cc, taken, not_taken));
} else {
// Should be disallowed by flags checks in verifier.
unimplemented!("Brif with non-ifcmp input");

View File

@@ -0,0 +1,31 @@
test compile
target x86_64
function %f(i64) -> i32 {
block0(v0: i64):
v1 = ifcmp_sp v0
brif ugt v1, block1
jump block2
block1:
v2 = iconst.i32 0
return v2
block2:
v3 = iconst.i32 1
return v3
}
; check: pushq %rbp
; nextln: movq %rsp, %rbp
; nextln: cmpq %rsp, %rdi
; nextln: jnbe label1; j label2
; check: xorl %eax, %eax
; nextln: movq %rbp, %rsp
; nextln: popq %rbp
; nextln: ret
; check: movl $$1, %eax
; nextln: movq %rbp, %rsp
; nextln: popq %rbp
; nextln: ret

View File

@@ -448,6 +448,7 @@ where
assign(Value::or(mask_a, mask_b)?)
}
Opcode::Copy => assign(arg(0)?),
Opcode::IfcmpSp => unimplemented!("IfcmpSp"),
Opcode::Icmp => assign(icmp(
ctrl_ty,
inst.cond_code().unwrap(),