From c08a013b53c92c61190a57221e4b1ede21db99ad Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Thu, 20 Jan 2022 16:59:18 +0100 Subject: [PATCH] s390x: Codegen fixes and preparation for ISLE migration In preparing the back-end to move to ISLE, I detected a number of codegen bugs in the existing code, which are fixed here: - Fix internal compiler error with uload16/icmp corner case. - Fix broken Cls lowering. - Correctly mask shift count for i8/i16 shifts. In addition, I made several changes to operand encodings in various MInst patterns. These should not have any functional effect, but will make the ISLE migration easier: - Encode floating-point constants as u32/u64 in MInst patterns. - Encode shift amounts as u8 and Reg in ShiftOp pattern. - Use MemArg in LoadMultiple64 and StoreMultiple64 patterns. --- cranelift/codegen/src/isa/s390x/abi.rs | 6 +- cranelift/codegen/src/isa/s390x/inst/emit.rs | 52 ++-- .../codegen/src/isa/s390x/inst/emit_tests.rs | 294 +++++++++--------- cranelift/codegen/src/isa/s390x/inst/mod.rs | 84 +++-- cranelift/codegen/src/isa/s390x/lower.rs | 77 +++-- .../filetests/filetests/isa/s390x/bitops.clif | 8 +- .../filetests/filetests/isa/s390x/icmp.clif | 26 ++ .../filetests/isa/s390x/shift-rotate.clif | 14 +- 8 files changed, 300 insertions(+), 261 deletions(-) diff --git a/cranelift/codegen/src/isa/s390x/abi.rs b/cranelift/codegen/src/isa/s390x/abi.rs index 5dd7dd55c688..1ab9a1f0016e 100644 --- a/cranelift/codegen/src/isa/s390x/abi.rs +++ b/cranelift/codegen/src/isa/s390x/abi.rs @@ -501,8 +501,7 @@ impl ABIMachineSpec for S390xMachineDeps { insts.push(Inst::StoreMultiple64 { rt: gpr(first_clobbered_gpr as u8), rt2: gpr(15), - addr_reg: stack_reg(), - addr_off: SImm20::maybe_from_i64(offset).unwrap(), + mem: MemArg::reg_plus_off(stack_reg(), offset, MemFlags::trusted()), }); } if flags.unwind_info() { @@ -606,8 +605,7 @@ impl ABIMachineSpec for S390xMachineDeps { insts.push(Inst::LoadMultiple64 { rt: writable_gpr(first_clobbered_gpr as u8), rt2: writable_gpr(15), - addr_reg: stack_reg(), - addr_off: SImm20::maybe_from_i64(offset).unwrap(), + mem: MemArg::reg_plus_off(stack_reg(), offset, MemFlags::trusted()), }); } diff --git a/cranelift/codegen/src/isa/s390x/inst/emit.rs b/cranelift/codegen/src/isa/s390x/inst/emit.rs index 1d7134d7f3eb..f02b1f2e51ce 100644 --- a/cranelift/codegen/src/isa/s390x/inst/emit.rs +++ b/cranelift/codegen/src/isa/s390x/inst/emit.rs @@ -1188,13 +1188,9 @@ impl MachInstEmit for Inst { ShiftOp::AShR32 => 0xebdc, // SRAK (SRA ?) ShiftOp::AShR64 => 0xeb0a, // SRAG }; - let shift_reg = match shift_reg { - Some(reg) => reg, - None => zero_reg(), - }; put( sink, - &enc_rsy(opcode, rd.to_reg(), rn, shift_reg, shift_imm.bits()), + &enc_rsy(opcode, rd.to_reg(), rn, shift_reg, shift_imm.into()), ); } @@ -1574,25 +1570,35 @@ impl MachInstEmit for Inst { } } - &Inst::LoadMultiple64 { - rt, - rt2, - addr_reg, - addr_off, - } => { + &Inst::LoadMultiple64 { rt, rt2, ref mem } => { let opcode = 0xeb04; // LMG let rt = rt.to_reg(); let rt2 = rt2.to_reg(); - put(sink, &enc_rsy(opcode, rt, rt2, addr_reg, addr_off.bits())); + mem_rs_emit( + rt, + rt2, + &mem, + None, + Some(opcode), + true, + sink, + emit_info, + state, + ); } - &Inst::StoreMultiple64 { - rt, - rt2, - addr_reg, - addr_off, - } => { + &Inst::StoreMultiple64 { rt, rt2, ref mem } => { let opcode = 0xeb24; // STMG - put(sink, &enc_rsy(opcode, rt, rt2, addr_reg, addr_off.bits())); + mem_rs_emit( + rt, + rt2, + &mem, + None, + Some(opcode), + true, + sink, + emit_info, + state, + ); } &Inst::LoadAddr { rd, ref mem } => { @@ -1741,7 +1747,7 @@ impl MachInstEmit for Inst { let opcode = 0xa75; // BRAS let reg = writable_spilltmp_reg().to_reg(); put(sink, &enc_ri_b(opcode, reg, 8)); - sink.put4(const_data.to_bits().swap_bytes()); + sink.put4(const_data.swap_bytes()); let inst = Inst::FpuLoad32 { rd, mem: MemArg::reg(reg, MemFlags::trusted()), @@ -1752,7 +1758,7 @@ impl MachInstEmit for Inst { let opcode = 0xa75; // BRAS let reg = writable_spilltmp_reg().to_reg(); put(sink, &enc_ri_b(opcode, reg, 12)); - sink.put8(const_data.to_bits().swap_bytes()); + sink.put8(const_data.swap_bytes()); let inst = Inst::FpuLoad64 { rd, mem: MemArg::reg(reg, MemFlags::trusted()), @@ -2009,8 +2015,8 @@ impl MachInstEmit for Inst { shift_op: ShiftOp::LShL64, rd: rtmp2, rn: ridx, - shift_imm: SImm20::maybe_from_i64(2).unwrap(), - shift_reg: None, + shift_imm: 2, + shift_reg: zero_reg(), }; inst.emit(sink, emit_info, state); diff --git a/cranelift/codegen/src/isa/s390x/inst/emit_tests.rs b/cranelift/codegen/src/isa/s390x/inst/emit_tests.rs index 9d60355fd199..5a3affcbbbc8 100644 --- a/cranelift/codegen/src/isa/s390x/inst/emit_tests.rs +++ b/cranelift/codegen/src/isa/s390x/inst/emit_tests.rs @@ -1,4 +1,4 @@ -use crate::ir::MemFlags; +use crate::ir::{MemFlags, TrapCode}; use crate::isa::s390x::inst::*; use crate::isa::s390x::settings as s390x_settings; use crate::settings; @@ -2062,352 +2062,352 @@ fn test_s390x_binemit() { shift_op: ShiftOp::RotL32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: None, + shift_imm: 0, + shift_reg: zero_reg(), }, - "EB450000801D", - "rll %r4, %r5, -524288", + "EB450000001D", + "rll %r4, %r5, 0", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::RotL32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: None, + shift_imm: 63, + shift_reg: zero_reg(), }, - "EB450FFF7F1D", - "rll %r4, %r5, 524287", + "EB45003F001D", + "rll %r4, %r5, 63", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::RotL32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 0, + shift_reg: gpr(6), }, - "EB456000801D", - "rll %r4, %r5, -524288(%r6)", + "EB456000001D", + "rll %r4, %r5, 0(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::RotL32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 63, + shift_reg: gpr(6), }, - "EB456FFF7F1D", - "rll %r4, %r5, 524287(%r6)", + "EB45603F001D", + "rll %r4, %r5, 63(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::RotL64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: None, + shift_imm: 0, + shift_reg: zero_reg(), }, - "EB450000801C", - "rllg %r4, %r5, -524288", + "EB450000001C", + "rllg %r4, %r5, 0", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::RotL64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: None, + shift_imm: 63, + shift_reg: zero_reg(), }, - "EB450FFF7F1C", - "rllg %r4, %r5, 524287", + "EB45003F001C", + "rllg %r4, %r5, 63", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::RotL64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 0, + shift_reg: gpr(6), }, - "EB456000801C", - "rllg %r4, %r5, -524288(%r6)", + "EB456000001C", + "rllg %r4, %r5, 0(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::RotL64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 63, + shift_reg: gpr(6), }, - "EB456FFF7F1C", - "rllg %r4, %r5, 524287(%r6)", + "EB45603F001C", + "rllg %r4, %r5, 63(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShL32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: None, + shift_imm: 0, + shift_reg: zero_reg(), }, - "EB45000080DF", - "sllk %r4, %r5, -524288", + "EB45000000DF", + "sllk %r4, %r5, 0", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShL32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: None, + shift_imm: 63, + shift_reg: zero_reg(), }, - "EB450FFF7FDF", - "sllk %r4, %r5, 524287", + "EB45003F00DF", + "sllk %r4, %r5, 63", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShL32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 0, + shift_reg: gpr(6), }, - "EB45600080DF", - "sllk %r4, %r5, -524288(%r6)", + "EB45600000DF", + "sllk %r4, %r5, 0(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShL32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 63, + shift_reg: gpr(6), }, - "EB456FFF7FDF", - "sllk %r4, %r5, 524287(%r6)", + "EB45603F00DF", + "sllk %r4, %r5, 63(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShL64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: None, + shift_imm: 0, + shift_reg: zero_reg(), }, - "EB450000800D", - "sllg %r4, %r5, -524288", + "EB450000000D", + "sllg %r4, %r5, 0", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShL64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: None, + shift_imm: 63, + shift_reg: zero_reg(), }, - "EB450FFF7F0D", - "sllg %r4, %r5, 524287", + "EB45003F000D", + "sllg %r4, %r5, 63", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShL64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 0, + shift_reg: gpr(6), }, - "EB456000800D", - "sllg %r4, %r5, -524288(%r6)", + "EB456000000D", + "sllg %r4, %r5, 0(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShL64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 63, + shift_reg: gpr(6), }, - "EB456FFF7F0D", - "sllg %r4, %r5, 524287(%r6)", + "EB45603F000D", + "sllg %r4, %r5, 63(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShR32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: None, + shift_imm: 0, + shift_reg: zero_reg(), }, - "EB45000080DE", - "srlk %r4, %r5, -524288", + "EB45000000DE", + "srlk %r4, %r5, 0", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShR32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: None, + shift_imm: 63, + shift_reg: zero_reg(), }, - "EB450FFF7FDE", - "srlk %r4, %r5, 524287", + "EB45003F00DE", + "srlk %r4, %r5, 63", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShR32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 0, + shift_reg: gpr(6), }, - "EB45600080DE", - "srlk %r4, %r5, -524288(%r6)", + "EB45600000DE", + "srlk %r4, %r5, 0(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShR32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 63, + shift_reg: gpr(6), }, - "EB456FFF7FDE", - "srlk %r4, %r5, 524287(%r6)", + "EB45603F00DE", + "srlk %r4, %r5, 63(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShR64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: None, + shift_imm: 0, + shift_reg: zero_reg(), }, - "EB450000800C", - "srlg %r4, %r5, -524288", + "EB450000000C", + "srlg %r4, %r5, 0", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShR64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: None, + shift_imm: 63, + shift_reg: zero_reg(), }, - "EB450FFF7F0C", - "srlg %r4, %r5, 524287", + "EB45003F000C", + "srlg %r4, %r5, 63", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShR64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 0, + shift_reg: gpr(6), }, - "EB456000800C", - "srlg %r4, %r5, -524288(%r6)", + "EB456000000C", + "srlg %r4, %r5, 0(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::LShR64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 63, + shift_reg: gpr(6), }, - "EB456FFF7F0C", - "srlg %r4, %r5, 524287(%r6)", + "EB45603F000C", + "srlg %r4, %r5, 63(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::AShR32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: None, + shift_imm: 0, + shift_reg: zero_reg(), }, - "EB45000080DC", - "srak %r4, %r5, -524288", + "EB45000000DC", + "srak %r4, %r5, 0", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::AShR32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: None, + shift_imm: 63, + shift_reg: zero_reg(), }, - "EB450FFF7FDC", - "srak %r4, %r5, 524287", + "EB45003F00DC", + "srak %r4, %r5, 63", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::AShR32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 0, + shift_reg: gpr(6), }, - "EB45600080DC", - "srak %r4, %r5, -524288(%r6)", + "EB45600000DC", + "srak %r4, %r5, 0(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::AShR32, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 63, + shift_reg: gpr(6), }, - "EB456FFF7FDC", - "srak %r4, %r5, 524287(%r6)", + "EB45603F00DC", + "srak %r4, %r5, 63(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::AShR64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: None, + shift_imm: 0, + shift_reg: zero_reg(), }, - "EB450000800A", - "srag %r4, %r5, -524288", + "EB450000000A", + "srag %r4, %r5, 0", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::AShR64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: None, + shift_imm: 63, + shift_reg: zero_reg(), }, - "EB450FFF7F0A", - "srag %r4, %r5, 524287", + "EB45003F000A", + "srag %r4, %r5, 63", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::AShR64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(-524288).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 0, + shift_reg: gpr(6), }, - "EB456000800A", - "srag %r4, %r5, -524288(%r6)", + "EB456000000A", + "srag %r4, %r5, 0(%r6)", )); insns.push(( Inst::ShiftRR { shift_op: ShiftOp::AShR64, rd: writable_gpr(4), rn: gpr(5), - shift_imm: SImm20::maybe_from_i64(524287).unwrap(), - shift_reg: Some(gpr(6)), + shift_imm: 63, + shift_reg: gpr(6), }, - "EB456FFF7F0A", - "srag %r4, %r5, 524287(%r6)", + "EB45603F000A", + "srag %r4, %r5, 63(%r6)", )); insns.push(( @@ -5718,8 +5718,12 @@ fn test_s390x_binemit() { Inst::LoadMultiple64 { rt: writable_gpr(8), rt2: writable_gpr(12), - addr_reg: gpr(15), - addr_off: SImm20::maybe_from_i64(-524288).unwrap(), + mem: MemArg::BXD20 { + base: gpr(15), + index: zero_reg(), + disp: SImm20::maybe_from_i64(-524288).unwrap(), + flags: MemFlags::trusted(), + }, }, "EB8CF0008004", "lmg %r8, %r12, -524288(%r15)", @@ -5728,8 +5732,12 @@ fn test_s390x_binemit() { Inst::LoadMultiple64 { rt: writable_gpr(8), rt2: writable_gpr(12), - addr_reg: gpr(15), - addr_off: SImm20::maybe_from_i64(524287).unwrap(), + mem: MemArg::BXD20 { + base: gpr(15), + index: zero_reg(), + disp: SImm20::maybe_from_i64(524287).unwrap(), + flags: MemFlags::trusted(), + }, }, "EB8CFFFF7F04", "lmg %r8, %r12, 524287(%r15)", @@ -5739,8 +5747,12 @@ fn test_s390x_binemit() { Inst::StoreMultiple64 { rt: gpr(8), rt2: gpr(12), - addr_reg: gpr(15), - addr_off: SImm20::maybe_from_i64(-524288).unwrap(), + mem: MemArg::BXD20 { + base: gpr(15), + index: zero_reg(), + disp: SImm20::maybe_from_i64(-524288).unwrap(), + flags: MemFlags::trusted(), + }, }, "EB8CF0008024", "stmg %r8, %r12, -524288(%r15)", @@ -5749,8 +5761,12 @@ fn test_s390x_binemit() { Inst::StoreMultiple64 { rt: gpr(8), rt2: gpr(12), - addr_reg: gpr(15), - addr_off: SImm20::maybe_from_i64(524287).unwrap(), + mem: MemArg::BXD20 { + base: gpr(15), + index: zero_reg(), + disp: SImm20::maybe_from_i64(524287).unwrap(), + flags: MemFlags::trusted(), + }, }, "EB8CFFFF7F24", "stmg %r8, %r12, 524287(%r15)", @@ -7964,7 +7980,7 @@ fn test_s390x_binemit() { insns.push(( Inst::LoadFpuConst32 { rd: writable_fpr(8), - const_data: 1.0, + const_data: 1.0_f32.to_bits(), }, "A71500043F80000078801000", "bras %r1, 8 ; data.f32 1 ; le %f8, 0(%r1)", @@ -7972,7 +7988,7 @@ fn test_s390x_binemit() { insns.push(( Inst::LoadFpuConst64 { rd: writable_fpr(8), - const_data: 1.0, + const_data: 1.0_f64.to_bits(), }, "A71500063FF000000000000068801000", "bras %r1, 12 ; data.f64 1 ; ld %f8, 0(%r1)", diff --git a/cranelift/codegen/src/isa/s390x/inst/mod.rs b/cranelift/codegen/src/isa/s390x/inst/mod.rs index b48b4fb2a7a6..4ee366482af8 100644 --- a/cranelift/codegen/src/isa/s390x/inst/mod.rs +++ b/cranelift/codegen/src/isa/s390x/inst/mod.rs @@ -371,8 +371,8 @@ pub enum Inst { shift_op: ShiftOp, rd: Writable, rn: Reg, - shift_imm: SImm20, - shift_reg: Option, + shift_imm: u8, + shift_reg: Reg, }, /// An unary operation with a register source and a register destination. @@ -604,15 +604,13 @@ pub enum Inst { LoadMultiple64 { rt: Writable, rt2: Writable, - addr_reg: Reg, - addr_off: SImm20, + mem: MemArg, }, /// A store-multiple instruction. StoreMultiple64 { rt: Reg, rt2: Reg, - addr_reg: Reg, - addr_off: SImm20, + mem: MemArg, }, /// A 32-bit move instruction. @@ -820,12 +818,12 @@ pub enum Inst { LoadFpuConst32 { rd: Writable, - const_data: f32, + const_data: u32, }, LoadFpuConst64 { rd: Writable, - const_data: f64, + const_data: u64, }, /// Conversion: FP -> integer. @@ -1206,7 +1204,7 @@ impl Inst { // TODO: use LZER to load 0.0 Inst::LoadFpuConst32 { rd, - const_data: value, + const_data: value.to_bits(), } } @@ -1215,7 +1213,7 @@ impl Inst { // TODO: use LZDR to load 0.0 Inst::LoadFpuConst64 { rd, - const_data: value, + const_data: value.to_bits(), } } @@ -1334,8 +1332,8 @@ fn s390x_get_regs(inst: &Inst, collector: &mut RegUsageCollector) { } => { collector.add_def(rd); collector.add_use(rn); - if let Some(reg) = shift_reg { - collector.add_use(reg); + if shift_reg != zero_reg() { + collector.add_use(shift_reg); } } &Inst::UnaryRR { rd, rn, .. } => { @@ -1422,24 +1420,24 @@ fn s390x_get_regs(inst: &Inst, collector: &mut RegUsageCollector) { memarg_regs(mem, collector); } &Inst::LoadMultiple64 { - rt, rt2, addr_reg, .. + rt, rt2, ref mem, .. } => { let first_regnum = rt.to_reg().get_hw_encoding(); let last_regnum = rt2.to_reg().get_hw_encoding(); for regnum in first_regnum..last_regnum + 1 { collector.add_def(writable_gpr(regnum)); } - collector.add_use(addr_reg); + memarg_regs(mem, collector); } &Inst::StoreMultiple64 { - rt, rt2, addr_reg, .. + rt, rt2, ref mem, .. } => { let first_regnum = rt.get_hw_encoding(); let last_regnum = rt2.get_hw_encoding(); for regnum in first_regnum..last_regnum + 1 { collector.add_use(gpr(regnum)); } - collector.add_use(addr_reg); + memarg_regs(mem, collector); } &Inst::Mov64 { rd, rm } => { collector.add_def(rd); @@ -1734,8 +1732,8 @@ fn s390x_map_regs(inst: &mut Inst, mapper: &RUM) { } => { map_def(mapper, rd); map_use(mapper, rn); - if let Some(reg) = shift_reg { - map_use(mapper, reg); + if *shift_reg != zero_reg() { + map_use(mapper, shift_reg); } } &mut Inst::UnaryRR { @@ -2825,7 +2823,7 @@ impl Inst { rd, rn, shift_imm, - ref shift_reg, + shift_reg, } => { let op = match shift_op { ShiftOp::RotL32 => "rll", @@ -2839,10 +2837,10 @@ impl Inst { }; let rd = rd.to_reg().show_rru(mb_rru); let rn = rn.show_rru(mb_rru); - let shift_imm = shift_imm.show_rru(mb_rru); - let shift_reg = match shift_reg { - Some(reg) => format!("({})", reg.show_rru(mb_rru)), - None => "".to_string(), + let shift_reg = if shift_reg != zero_reg() { + format!("({})", shift_reg.show_rru(mb_rru)) + } else { + "".to_string() }; format!("{} {}, {}, {}{}", op, rd, rn, shift_imm, shift_reg) } @@ -3188,29 +3186,21 @@ impl Inst { let mem = mem.show_rru(mb_rru); format!("{}{} {}, {}, 0", mem_str, op, rd, mem) } - &Inst::LoadMultiple64 { - rt, - rt2, - addr_reg, - addr_off, - } => { + &Inst::LoadMultiple64 { rt, rt2, ref mem } => { + let (mem_str, mem) = + mem_finalize_for_show(mem, mb_rru, state, false, true, false, false); let rt = rt.show_rru(mb_rru); let rt2 = rt2.show_rru(mb_rru); - let addr_reg = addr_reg.show_rru(mb_rru); - let addr_off = addr_off.show_rru(mb_rru); - format!("lmg {}, {}, {}({})", rt, rt2, addr_off, addr_reg) - } - &Inst::StoreMultiple64 { - rt, - rt2, - addr_reg, - addr_off, - } => { + let mem = mem.show_rru(mb_rru); + format!("{}lmg {}, {}, {}", mem_str, rt, rt2, mem) + } + &Inst::StoreMultiple64 { rt, rt2, ref mem } => { + let (mem_str, mem) = + mem_finalize_for_show(mem, mb_rru, state, false, true, false, false); let rt = rt.show_rru(mb_rru); let rt2 = rt2.show_rru(mb_rru); - let addr_reg = addr_reg.show_rru(mb_rru); - let addr_off = addr_off.show_rru(mb_rru); - format!("stmg {}, {}, {}({})", rt, rt2, addr_off, addr_reg) + let mem = mem.show_rru(mb_rru); + format!("{}stmg {}, {}, {}", mem_str, rt, rt2, mem) } &Inst::Mov64 { rd, rm } => { let rd = rd.to_reg().show_rru(mb_rru); @@ -3398,7 +3388,10 @@ impl Inst { let tmp = writable_spilltmp_reg().to_reg().show_rru(mb_rru); format!( "bras {}, 8 ; data.f32 {} ; le {}, 0({})", - tmp, const_data, rd, tmp + tmp, + f32::from_bits(const_data), + rd, + tmp ) } &Inst::LoadFpuConst64 { rd, const_data } => { @@ -3406,7 +3399,10 @@ impl Inst { let tmp = writable_spilltmp_reg().to_reg().show_rru(mb_rru); format!( "bras {}, 12 ; data.f64 {} ; ld {}, 0({})", - tmp, const_data, rd, tmp + tmp, + f64::from_bits(const_data), + rd, + tmp ) } &Inst::FpuToInt { op, rd, rn } => { diff --git a/cranelift/codegen/src/isa/s390x/lower.rs b/cranelift/codegen/src/isa/s390x/lower.rs index b7a13368715d..f4aa7c805d7c 100644 --- a/cranelift/codegen/src/isa/s390x/lower.rs +++ b/cranelift/codegen/src/isa/s390x/lower.rs @@ -600,8 +600,8 @@ fn lower_bitcast>( shift_op: ShiftOp::LShL64, rd: tmp, rn, - shift_imm: SImm20::maybe_from_i64(32).unwrap(), - shift_reg: None, + shift_imm: 32, + shift_reg: zero_reg(), }); ctx.emit(Inst::MovToFpr { rd, @@ -615,8 +615,8 @@ fn lower_bitcast>( shift_op: ShiftOp::LShR64, rd, rn: tmp.to_reg(), - shift_imm: SImm20::maybe_from_i64(32).unwrap(), - shift_reg: None, + shift_imm: 32, + shift_reg: zero_reg(), }); } _ => unreachable!("invalid bitcast from {:?} to {:?}", input_ty, output_ty), @@ -720,7 +720,7 @@ fn lower_icmp_to_flags>( } _ => { let reg_ty = choose_32_64(ty, types::I32, types::I64); - let rm = extend_memory_to_reg(ctx, mem, ty, reg_ty, false); + let rm = extend_memory_to_reg(ctx, mem, types::I16, reg_ty, false); return ctx.emit(Inst::CmpRR { op, rn, rm }); } } @@ -1109,8 +1109,8 @@ fn lower_insn_to_regs>( shift_op, rd, rn: rd.to_reg(), - shift_imm: SImm20::maybe_from_i64(32).unwrap(), - shift_reg: None, + shift_imm: 32, + shift_reg: zero_reg(), }); } types::I16 | types::I8 => { @@ -1141,8 +1141,8 @@ fn lower_insn_to_regs>( shift_op, rd, rn: rd.to_reg(), - shift_imm: SImm20::maybe_from_i64(shift_amt).unwrap(), - shift_reg: None, + shift_imm: shift_amt, + shift_reg: zero_reg(), }); } _ => { @@ -1330,9 +1330,8 @@ fn lower_insn_to_regs>( let rd = get_output_reg(ctx, outputs[0]).only_reg().unwrap(); let rn = put_input_in_reg(ctx, inputs[0], narrow_mode); if let Some(imm) = input_matches_const(ctx, inputs[1]) { - let imm = imm & if size < 64 { 31 } else { 63 }; - let shift_imm = SImm20::maybe_from_i64(imm as i64).unwrap(); - let shift_reg = None; + let shift_imm = (imm & (size as u64 - 1)) as u8; + let shift_reg = zero_reg(); ctx.emit(Inst::ShiftRR { shift_op, rd, @@ -1342,18 +1341,18 @@ fn lower_insn_to_regs>( }); } else { let rm = put_input_in_reg(ctx, inputs[1], NarrowValueMode::None); - let shift_imm = SImm20::zero(); + let shift_imm = 0; let shift_reg = if size < 64 { let tmp = ctx.alloc_tmp(types::I64).only_reg().unwrap(); ctx.emit(Inst::gen_move(tmp, rm, types::I64)); ctx.emit(Inst::AluRUImm16Shifted { alu_op: ALUOp::And64, rd: tmp, - imm: UImm16Shifted::maybe_from_u64(31).unwrap(), + imm: UImm16Shifted::maybe_from_u64(size as u64 - 1).unwrap(), }); - Some(tmp.to_reg()) + tmp.to_reg() } else { - Some(rm) + rm }; ctx.emit(Inst::ShiftRR { shift_op, @@ -1422,8 +1421,8 @@ fn lower_insn_to_regs>( shift_op, rd, rn, - shift_imm: SImm20::maybe_from_i64(shiftcount as i64).unwrap(), - shift_reg: None, + shift_imm: shiftcount as u8, + shift_reg: zero_reg(), }); } else { let rm = put_input_in_reg(ctx, inputs[1], NarrowValueMode::None); @@ -1446,8 +1445,8 @@ fn lower_insn_to_regs>( shift_op, rd, rn, - shift_imm: SImm20::zero(), - shift_reg: Some(rm), + shift_imm: 0, + shift_reg: rm, }); } } else { @@ -1466,8 +1465,8 @@ fn lower_insn_to_regs>( shift_op: ShiftOp::LShL32, rd: tmp1, rn, - shift_imm: SImm20::maybe_from_i64(lshl_count as i64).unwrap(), - shift_reg: None, + shift_imm: lshl_count as u8, + shift_reg: zero_reg(), }); let tmp2 = ctx.alloc_tmp(types::I32).only_reg().unwrap(); @@ -1475,8 +1474,8 @@ fn lower_insn_to_regs>( shift_op: ShiftOp::LShR32, rd: tmp2, rn, - shift_imm: SImm20::maybe_from_i64(lshr_count as i64).unwrap(), - shift_reg: None, + shift_imm: lshr_count as u8, + shift_reg: zero_reg(), }); ctx.emit(Inst::AluRRR { @@ -1514,16 +1513,16 @@ fn lower_insn_to_regs>( shift_op: ShiftOp::LShL32, rd: lshl, rn, - shift_imm: SImm20::zero(), - shift_reg: Some(lshl.to_reg()), + shift_imm: 0, + shift_reg: lshl.to_reg(), }); ctx.emit(Inst::ShiftRR { shift_op: ShiftOp::LShR32, rd: lshr, rn, - shift_imm: SImm20::zero(), - shift_reg: Some(lshr.to_reg()), + shift_imm: 0, + shift_reg: lshr.to_reg(), }); ctx.emit(Inst::AluRRR { @@ -1708,15 +1707,15 @@ fn lower_insn_to_regs>( shift_op: shl_op, rd, rn, - shift_imm: SImm20::maybe_from_i64(count.into()).unwrap(), - shift_reg: None, + shift_imm: count, + shift_reg: zero_reg(), }); ctx.emit(Inst::ShiftRR { shift_op: shr_op, rd, rn: rd.to_reg(), - shift_imm: SImm20::maybe_from_i64(count.into()).unwrap(), - shift_reg: None, + shift_imm: count, + shift_reg: zero_reg(), }); } else { // Case 2: 8-or-more-bit to N-bit extension: just sign-extend. A @@ -1825,8 +1824,8 @@ fn lower_insn_to_regs>( shift_op: ShiftOp::AShR64, rd: tmp, rn, - shift_imm: SImm20::maybe_from_i64(63).unwrap(), - shift_reg: None, + shift_imm: 63, + shift_reg: zero_reg(), }); ctx.emit(Inst::AluRRR { alu_op: ALUOp::Xor64, @@ -1835,7 +1834,7 @@ fn lower_insn_to_regs>( rm: rn, }); - ctx.emit(Inst::Flogr { rn }); + ctx.emit(Inst::Flogr { rn: tmp.to_reg() }); ctx.emit(Inst::gen_move(rd, gpr(0), ty)); if ty_bits_size < 64 { @@ -1937,8 +1936,8 @@ fn lower_insn_to_regs>( shift_op: choose_32_64(ty, ShiftOp::LShL32, ShiftOp::LShL64), rd: tmp, rn: rd.to_reg(), - shift_imm: SImm20::maybe_from_i64(shift.into()).unwrap(), - shift_reg: None, + shift_imm: shift, + shift_reg: zero_reg(), }); ctx.emit(Inst::AluRR { alu_op: choose_32_64(ty, ALUOp::Add32, ALUOp::Add64), @@ -1951,8 +1950,8 @@ fn lower_insn_to_regs>( shift_op: choose_32_64(ty, ShiftOp::LShR32, ShiftOp::LShR64), rd, rn: rd.to_reg(), - shift_imm: SImm20::maybe_from_i64(shift.into()).unwrap(), - shift_reg: None, + shift_imm: shift, + shift_reg: zero_reg(), }); } } diff --git a/cranelift/filetests/filetests/isa/s390x/bitops.clif b/cranelift/filetests/filetests/isa/s390x/bitops.clif index 3cab149939b3..a6bb3308d0a7 100644 --- a/cranelift/filetests/filetests/isa/s390x/bitops.clif +++ b/cranelift/filetests/filetests/isa/s390x/bitops.clif @@ -93,7 +93,7 @@ block0(v0: i64): } ; check: srag %r3, %r2, 63 -; nextln: xgr %r3, %r2 +; nextln: xgrk %r2, %r3, %r2 ; nextln: flogr %r0, %r2 ; nextln: lgr %r2, %r0 ; nextln: br %r14 @@ -106,7 +106,7 @@ block0(v0: i32): ; check: lgfr %r2, %r2 ; nextln: srag %r3, %r2, 63 -; nextln: xgr %r3, %r2 +; nextln: xgrk %r2, %r3, %r2 ; nextln: flogr %r0, %r2 ; nextln: lr %r2, %r0 ; nextln: ahi %r2, -32 @@ -120,7 +120,7 @@ block0(v0: i16): ; check: lghr %r2, %r2 ; nextln: srag %r3, %r2, 63 -; nextln: xgr %r3, %r2 +; nextln: xgrk %r2, %r3, %r2 ; nextln: flogr %r0, %r2 ; nextln: lr %r2, %r0 ; nextln: ahi %r2, -48 @@ -134,7 +134,7 @@ block0(v0: i8): ; check: lgbr %r2, %r2 ; nextln: srag %r3, %r2, 63 -; nextln: xgr %r3, %r2 +; nextln: xgrk %r2, %r3, %r2 ; nextln: flogr %r0, %r2 ; nextln: lr %r2, %r0 ; nextln: ahi %r2, -56 diff --git a/cranelift/filetests/filetests/isa/s390x/icmp.clif b/cranelift/filetests/filetests/isa/s390x/icmp.clif index ef792f34cfd4..50c2120ac798 100644 --- a/cranelift/filetests/filetests/isa/s390x/icmp.clif +++ b/cranelift/filetests/filetests/isa/s390x/icmp.clif @@ -418,6 +418,19 @@ block0(v0: i64): ; nextln: lochil %r2, 1 ; nextln: br %r14 +function %icmp_ult_i64_mem_ext16(i64, i64) -> b1 { +block0(v0: i64, v1: i64): + v2 = uload16.i64 v1 + v3 = icmp.i64 ult v0, v2 + return v3 +} + +; check: llgh %r3, 0(%r3) +; check: clgr %r2, %r3 +; nextln: lhi %r2, 0 +; nextln: lochil %r2, 1 +; nextln: br %r14 + function %icmp_ult_i64_sym_ext16(i64) -> b1 { gv0 = symbol colocated %sym block0(v0: i64): @@ -493,6 +506,19 @@ block0(v0: i32): ; nextln: lochil %r2, 1 ; nextln: br %r14 +function %icmp_ult_i32_mem_ext16(i32, i64) -> b1 { +block0(v0: i32, v1: i64): + v2 = uload16.i32 v1 + v3 = icmp.i32 ult v0, v2 + return v3 +} + +; check: llh %r3, 0(%r3) +; check: clr %r2, %r3 +; nextln: lhi %r2, 0 +; nextln: lochil %r2, 1 +; nextln: br %r14 + function %icmp_ult_i32_sym_ext16(i32) -> b1 { gv0 = symbol colocated %sym block0(v0: i32): diff --git a/cranelift/filetests/filetests/isa/s390x/shift-rotate.clif b/cranelift/filetests/filetests/isa/s390x/shift-rotate.clif index bb42cfcad56f..9c682fe77842 100644 --- a/cranelift/filetests/filetests/isa/s390x/shift-rotate.clif +++ b/cranelift/filetests/filetests/isa/s390x/shift-rotate.clif @@ -251,10 +251,8 @@ block0(v0: i16, v1: i16): return v2 } -; FIXME: check shift count ? - ; check: llhr %r2, %r2 -; nextln: nill %r3, 31 +; nextln: nill %r3, 15 ; nextln: srlk %r2, %r2, 0(%r3) ; nextln: br %r14 @@ -276,7 +274,7 @@ block0(v0: i8, v1: i8): } ; check: llcr %r2, %r2 -; nextln: nill %r3, 31 +; nextln: nill %r3, 7 ; nextln: srlk %r2, %r2, 0(%r3) ; nextln: br %r14 @@ -339,7 +337,7 @@ block0(v0: i16, v1: i16): return v2 } -; check: nill %r3, 31 +; check: nill %r3, 15 ; nextln: sllk %r2, %r2, 0(%r3) ; nextln: br %r14 @@ -359,7 +357,7 @@ block0(v0: i8, v1: i8): return v2 } -; check: nill %r3, 31 +; check: nill %r3, 7 ; nextln: sllk %r2, %r2, 0(%r3) ; nextln: br %r14 @@ -422,7 +420,7 @@ block0(v0: i16, v1: i16): } ; check: lhr %r2, %r2 -; nextln: nill %r3, 31 +; nextln: nill %r3, 15 ; nextln: srak %r2, %r2, 0(%r3) ; nextln: br %r14 @@ -444,7 +442,7 @@ block0(v0: i8, v1: i8): } ; check: lbr %r2, %r2 -; nextln: nill %r3, 31 +; nextln: nill %r3, 7 ; nextln: srak %r2, %r2, 0(%r3) ; nextln: br %r14