Skip to content

Commit

Permalink
s390x: Improved TrapIf implementation (#6079)
Browse files Browse the repository at this point in the history
Following up on the discussion in
#6011
this adds an improved implementation of TrapIf for s390x
using a single conditional branch instruction.

If the trap conditions is true, we branch into the middle of
the branch instruction - those middle two bytes are zero,
which matches the encoding of the trap instruction.

In addition, show the trap code for Trap and TrapIf
instructions in assembler output.
  • Loading branch information
uweigand authored Mar 23, 2023
1 parent a6925c2 commit 6f66abd
Show file tree
Hide file tree
Showing 64 changed files with 357 additions and 451 deletions.
19 changes: 13 additions & 6 deletions cranelift/codegen/src/isa/s390x/inst/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,7 @@ fn enc_ril_b(opcode: u16, r1: Reg, ri2: u32) -> [u8; 6] {
let opcode1 = ((opcode >> 4) & 0xff) as u8;
let opcode2 = (opcode & 0xf) as u8;
let r1 = machreg_to_gpr(r1) & 0x0f;
let ri2 = ri2 >> 1;

enc[0] = opcode1;
enc[1] = r1 << 4 | opcode2;
Expand All @@ -700,6 +701,7 @@ fn enc_ril_c(opcode: u16, m1: u8, ri2: u32) -> [u8; 6] {
let opcode1 = ((opcode >> 4) & 0xff) as u8;
let opcode2 = (opcode & 0xf) as u8;
let m1 = m1 & 0x0f;
let ri2 = ri2 >> 1;

enc[0] = opcode1;
enc[1] = m1 << 4 | opcode2;
Expand Down Expand Up @@ -3590,14 +3592,19 @@ impl Inst {
put_with_trap(sink, &enc_e(0x0000), trap_code);
}
&Inst::TrapIf { cond, trap_code } => {
// Branch over trap if condition is false.
let opcode = 0xa74; // BCR
put(sink, &enc_ri_c(opcode, cond.invert().bits(), 4 + 2));
// Now emit the actual trap.
if let Some(s) = state.take_stack_map() {
sink.add_stack_map(StackMapExtent::UpcomingBytes(2), s);
sink.add_stack_map(StackMapExtent::UpcomingBytes(6), s);
}
put_with_trap(sink, &enc_e(0x0000), trap_code);
// We implement a TrapIf as a conditional branch into the middle
// of the branch (BRCL) instruction itself - those middle two bytes
// are zero, which matches the trap instruction itself.
let opcode = 0xc04; // BCRL
let enc = &enc_ril_c(opcode, cond.bits(), 2);
debug_assert!(enc.len() == 6 && enc[2] == 0 && enc[3] == 0);
// The trap must be placed on the last byte of the embedded trap
// instruction, so we need to emit the encoding in two parts.
put_with_trap(sink, &enc[0..4], trap_code);
put(sink, &enc[4..6]);
}
&Inst::JTSequence { ridx, ref targets } => {
let ridx = allocs.next(ridx);
Expand Down
8 changes: 4 additions & 4 deletions cranelift/codegen/src/isa/s390x/inst/emit_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7027,22 +7027,22 @@ fn test_s390x_binemit() {
"br %r14",
));

insns.push((Inst::Debugtrap, "0001", "debugtrap"));
insns.push((Inst::Debugtrap, "0001", ".word 0x0001 # debugtrap"));

insns.push((
Inst::Trap {
trap_code: TrapCode::StackOverflow,
},
"0000",
"trap",
".word 0x0000 # trap=stk_ovf",
));
insns.push((
Inst::TrapIf {
cond: Cond::from_mask(1),
trap_code: TrapCode::StackOverflow,
},
"A7E400030000",
"jno 6 ; trap",
"C01400000001",
"jgo .+2 # trap=stk_ovf",
));

insns.push((
Expand Down
12 changes: 7 additions & 5 deletions cranelift/codegen/src/isa/s390x/inst/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3185,11 +3185,13 @@ impl Inst {
let cond = cond.pretty_print_default();
format!("jg{} {}", cond, target)
}
&Inst::Debugtrap => "debugtrap".to_string(),
&Inst::Trap { .. } => "trap".to_string(),
&Inst::TrapIf { cond, .. } => {
let cond = cond.invert().pretty_print_default();
format!("j{} 6 ; trap", cond)
&Inst::Debugtrap => ".word 0x0001 # debugtrap".to_string(),
&Inst::Trap { trap_code } => {
format!(".word 0x0000 # trap={}", trap_code)
}
&Inst::TrapIf { cond, trap_code } => {
let cond = cond.pretty_print_default();
format!("jg{} .+2 # trap={}", cond, trap_code)
}
&Inst::JTSequence { ridx, ref targets } => {
let ridx = pretty_print_reg(ridx, allocs);
Expand Down
2 changes: 1 addition & 1 deletion cranelift/filetests/filetests/isa/s390x/call.clif
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ block0:
; block0:
; lghi %r2, 0
; brasl %r14, %g
; trap
; .word 0x0000 # trap=user0
;
; Disassembled:
; block0: ; offset 0x0
Expand Down
Loading

0 comments on commit 6f66abd

Please sign in to comment.