Merge pull request #3502 from cfallin/ifcmp-sp
Add back the `ifcmp_sp` CLIF opcode.
This commit is contained in:
@@ -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`");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
31
cranelift/filetests/filetests/isa/x64/ifcmp-sp.clif
Normal file
31
cranelift/filetests/filetests/isa/x64/ifcmp-sp.clif
Normal 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
|
||||
|
||||
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user