cranelift: add a new resumable_trapnz instruction;
This is useful to have to allow resumable_trap to happen in loop headers, for instance. This is the correct way to implement interrupt checks in Spidermonkey, which are effectively resumable traps. Previous implementation was using traps, which is wrong, since traps semantically can't be resumed after.
This commit is contained in:
@@ -214,6 +214,7 @@ pub fn simple_legalize(func: &mut ir::Function, cfg: &mut ControlFlowGraph, isa:
|
||||
| ir::Opcode::TableAddr
|
||||
| ir::Opcode::Trapnz
|
||||
| ir::Opcode::Trapz
|
||||
| ir::Opcode::ResumableTrapnz
|
||||
| ir::Opcode::BandImm
|
||||
| ir::Opcode::BorImm
|
||||
| ir::Opcode::BxorImm
|
||||
@@ -261,15 +262,15 @@ fn expand_cond_trap(
|
||||
) {
|
||||
// Parse the instruction.
|
||||
let trapz;
|
||||
let (arg, code) = match func.dfg[inst] {
|
||||
let (arg, code, opcode) = match func.dfg[inst] {
|
||||
ir::InstructionData::CondTrap { opcode, arg, code } => {
|
||||
// We want to branch *over* an unconditional trap.
|
||||
trapz = match opcode {
|
||||
ir::Opcode::Trapz => true,
|
||||
ir::Opcode::Trapnz => false,
|
||||
ir::Opcode::Trapnz | ir::Opcode::ResumableTrapnz => false,
|
||||
_ => panic!("Expected cond trap: {}", func.dfg.display_inst(inst, None)),
|
||||
};
|
||||
(arg, code)
|
||||
(arg, code, opcode)
|
||||
}
|
||||
_ => panic!("Expected cond trap: {}", func.dfg.display_inst(inst, None)),
|
||||
};
|
||||
@@ -307,7 +308,17 @@ fn expand_cond_trap(
|
||||
|
||||
// Insert the new label and the unconditional trap terminator.
|
||||
pos.insert_block(new_block_trap);
|
||||
pos.ins().trap(code);
|
||||
|
||||
match opcode {
|
||||
ir::Opcode::Trapz | ir::Opcode::Trapnz => {
|
||||
pos.ins().trap(code);
|
||||
}
|
||||
ir::Opcode::ResumableTrapnz => {
|
||||
pos.ins().resumable_trap(code);
|
||||
pos.ins().jump(new_block_resume, &[]);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
// Insert the new label and resume the execution when the trap fails.
|
||||
pos.insert_block(new_block_resume);
|
||||
|
||||
Reference in New Issue
Block a user