Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cranelift/codegen/src/isa/s390x/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ impl ABIMachineSpec for S390xMachineDeps {
insts.push(Inst::AluRUImm32 {
alu_op: ALUOp::AddLogical64,
rd: into_reg,
ri: into_reg.to_reg(),
imm,
});
}
Expand Down Expand Up @@ -546,12 +547,14 @@ impl ABIMachineSpec for S390xMachineDeps {
insts.push(Inst::AluRSImm16 {
alu_op: ALUOp::Add64,
rd: writable_stack_reg(),
ri: stack_reg(),
imm,
});
} else {
insts.push(Inst::AluRSImm32 {
alu_op: ALUOp::Add64,
rd: writable_stack_reg(),
ri: stack_reg(),
imm,
});
}
Expand Down
42 changes: 26 additions & 16 deletions cranelift/codegen/src/isa/s390x/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -27,48 +27,59 @@
(AluRR
(alu_op ALUOp)
(rd WritableReg)
;; Input side of `rd`. `rd` is constrained to reuse `ri`'s
;; allocation during regalloc. Hence, we have SSA form here (ri
;; is strictly a use, rd is strictly a def) and it becomes a
;; modified-reg form when encoded.
(ri Reg)
(rm Reg))

;; An ALU operation with a register in-/out operand and
;; a memory source.
(AluRX
(alu_op ALUOp)
(rd WritableReg)
(ri Reg)
(mem MemArg))

;; An ALU operation with a register in-/out operand and a signed 16-bit
;; immediate source.
(AluRSImm16
(alu_op ALUOp)
(rd WritableReg)
(ri Reg)
(imm i16))

;; An ALU operation with a register in-/out operand and a signed 32-bit
;; immediate source.
(AluRSImm32
(alu_op ALUOp)
(rd WritableReg)
(ri Reg)
(imm i32))

;; An ALU operation with a register in-/out operand and an unsigned 32-bit
;; immediate source.
(AluRUImm32
(alu_op ALUOp)
(rd WritableReg)
(ri Reg)
(imm u32))

;; An ALU operation with a register in-/out operand and a shifted 16-bit
;; immediate source.
(AluRUImm16Shifted
(alu_op ALUOp)
(rd WritableReg)
(ri Reg)
(imm UImm16Shifted))

;; An ALU operation with a register in-/out operand and a shifted 32-bit
;; immediate source.
(AluRUImm32Shifted
(alu_op ALUOp)
(rd WritableReg)
(ri Reg)
(imm UImm32Shifted))

;; A multiply operation with two register sources and a register pair destination.
Expand Down Expand Up @@ -1999,50 +2010,50 @@
;; Helper for emitting `MInst.AluRR` instructions.
(decl alu_rr (Type ALUOp Reg Reg) Reg)
(rule (alu_rr ty op src1 src2)
(let ((dst WritableReg (copy_writable_reg ty src1))
(_ Unit (emit (MInst.AluRR op dst src2))))
(let ((dst WritableReg (temp_writable_reg ty))
(_ Unit (emit (MInst.AluRR op dst src1 src2))))
dst))

;; Helper for emitting `MInst.AluRX` instructions.
(decl alu_rx (Type ALUOp Reg MemArg) Reg)
(rule (alu_rx ty op src mem)
(let ((dst WritableReg (copy_writable_reg ty src))
(_ Unit (emit (MInst.AluRX op dst mem))))
(let ((dst WritableReg (temp_writable_reg ty))
(_ Unit (emit (MInst.AluRX op dst src mem))))
dst))

;; Helper for emitting `MInst.AluRSImm16` instructions.
(decl alu_rsimm16 (Type ALUOp Reg i16) Reg)
(rule (alu_rsimm16 ty op src imm)
(let ((dst WritableReg (copy_writable_reg ty src))
(_ Unit (emit (MInst.AluRSImm16 op dst imm))))
(let ((dst WritableReg (temp_writable_reg ty))
(_ Unit (emit (MInst.AluRSImm16 op dst src imm))))
dst))

;; Helper for emitting `MInst.AluRSImm32` instructions.
(decl alu_rsimm32 (Type ALUOp Reg i32) Reg)
(rule (alu_rsimm32 ty op src imm)
(let ((dst WritableReg (copy_writable_reg ty src))
(_ Unit (emit (MInst.AluRSImm32 op dst imm))))
(let ((dst WritableReg (temp_writable_reg ty))
(_ Unit (emit (MInst.AluRSImm32 op dst src imm))))
dst))

;; Helper for emitting `MInst.AluRUImm32` instructions.
(decl alu_ruimm32 (Type ALUOp Reg u32) Reg)
(rule (alu_ruimm32 ty op src imm)
(let ((dst WritableReg (copy_writable_reg ty src))
(_ Unit (emit (MInst.AluRUImm32 op dst imm))))
(let ((dst WritableReg (temp_writable_reg ty))
(_ Unit (emit (MInst.AluRUImm32 op dst src imm))))
dst))

;; Helper for emitting `MInst.AluRUImm16Shifted` instructions.
(decl alu_ruimm16shifted (Type ALUOp Reg UImm16Shifted) Reg)
(rule (alu_ruimm16shifted ty op src imm)
(let ((dst WritableReg (copy_writable_reg ty src))
(_ Unit (emit (MInst.AluRUImm16Shifted op dst imm))))
(let ((dst WritableReg (temp_writable_reg ty))
(_ Unit (emit (MInst.AluRUImm16Shifted op dst src imm))))
dst))

;; Helper for emitting `MInst.AluRUImm32Shifted` instructions.
(decl alu_ruimm32shifted (Type ALUOp Reg UImm32Shifted) Reg)
(rule (alu_ruimm32shifted ty op src imm)
(let ((dst WritableReg (copy_writable_reg ty src))
(_ Unit (emit (MInst.AluRUImm32Shifted op dst imm))))
(let ((dst WritableReg (temp_writable_reg ty))
(_ Unit (emit (MInst.AluRUImm32Shifted op dst src imm))))
dst))

;; Helper for emitting `MInst.SMulWide` instructions.
Expand Down Expand Up @@ -2705,8 +2716,7 @@
;; Push a `MInst.AluRUImm32Shifted` instruction to a sequence.
(decl push_alu_uimm32shifted (VecMInstBuilder ALUOp WritableReg Reg UImm32Shifted) Reg)
(rule (push_alu_uimm32shifted ib op (real_reg dst) r imm)
(if (same_reg dst r))
(let ((_ Unit (inst_builder_push ib (MInst.AluRUImm32Shifted op dst imm))))
(let ((_ Unit (inst_builder_push ib (MInst.AluRUImm32Shifted op dst r imm))))
dst))

;; Push a `MInst.ShiftRR` instruction to a sequence.
Expand Down
67 changes: 59 additions & 8 deletions cranelift/codegen/src/isa/s390x/inst/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,12 @@ impl MachInstEmit for Inst {
_ => unreachable!(),
};
if have_rr && rd.to_reg() == rn {
let inst = Inst::AluRR { alu_op, rd, rm };
let inst = Inst::AluRR {
alu_op,
rd,
ri: rn,
rm,
};
inst.emit(&[], sink, emit_info, state);
} else {
put(sink, &enc_rrf_ab(opcode, rd.to_reg(), rn, rm, 0));
Expand All @@ -1442,7 +1447,12 @@ impl MachInstEmit for Inst {
let rn = allocs.next(rn);

if rd.to_reg() == rn {
let inst = Inst::AluRSImm16 { alu_op, rd, imm };
let inst = Inst::AluRSImm16 {
alu_op,
rd,
ri: rn,
imm,
};
inst.emit(&[], sink, emit_info, state);
} else {
let opcode = match alu_op {
Expand All @@ -1453,8 +1463,10 @@ impl MachInstEmit for Inst {
put(sink, &enc_rie_d(opcode, rd.to_reg(), rn, imm as u16));
}
}
&Inst::AluRR { alu_op, rd, rm } => {
&Inst::AluRR { alu_op, rd, ri, rm } => {
let rd = allocs.next_writable(rd);
let ri = allocs.next(ri);
debug_assert_eq!(rd.to_reg(), ri);
let rm = allocs.next(rm);

let (opcode, is_rre) = match alu_op {
Expand Down Expand Up @@ -1490,9 +1502,12 @@ impl MachInstEmit for Inst {
&Inst::AluRX {
alu_op,
rd,
ri,
ref mem,
} => {
let rd = allocs.next_writable(rd);
let ri = allocs.next(ri);
debug_assert_eq!(rd.to_reg(), ri);
let mem = mem.with_allocs(&mut allocs);

let (opcode_rx, opcode_rxy) = match alu_op {
Expand Down Expand Up @@ -1530,8 +1545,15 @@ impl MachInstEmit for Inst {
rd, &mem, opcode_rx, opcode_rxy, None, true, sink, emit_info, state,
);
}
&Inst::AluRSImm16 { alu_op, rd, imm } => {
&Inst::AluRSImm16 {
alu_op,
rd,
ri,
imm,
} => {
let rd = allocs.next_writable(rd);
let ri = allocs.next(ri);
debug_assert_eq!(rd.to_reg(), ri);

let opcode = match alu_op {
ALUOp::Add32 => 0xa7a, // AHI
Expand All @@ -1542,8 +1564,15 @@ impl MachInstEmit for Inst {
};
put(sink, &enc_ri_a(opcode, rd.to_reg(), imm as u16));
}
&Inst::AluRSImm32 { alu_op, rd, imm } => {
&Inst::AluRSImm32 {
alu_op,
rd,
ri,
imm,
} => {
let rd = allocs.next_writable(rd);
let ri = allocs.next(ri);
debug_assert_eq!(rd.to_reg(), ri);

let opcode = match alu_op {
ALUOp::Add32 => 0xc29, // AFI
Expand All @@ -1554,8 +1583,15 @@ impl MachInstEmit for Inst {
};
put(sink, &enc_ril_a(opcode, rd.to_reg(), imm as u32));
}
&Inst::AluRUImm32 { alu_op, rd, imm } => {
&Inst::AluRUImm32 {
alu_op,
rd,
ri,
imm,
} => {
let rd = allocs.next_writable(rd);
let ri = allocs.next(ri);
debug_assert_eq!(rd.to_reg(), ri);

let opcode = match alu_op {
ALUOp::AddLogical32 => 0xc2b, // ALFI
Expand All @@ -1566,8 +1602,15 @@ impl MachInstEmit for Inst {
};
put(sink, &enc_ril_a(opcode, rd.to_reg(), imm));
}
&Inst::AluRUImm16Shifted { alu_op, rd, imm } => {
&Inst::AluRUImm16Shifted {
alu_op,
rd,
ri,
imm,
} => {
let rd = allocs.next_writable(rd);
let ri = allocs.next(ri);
debug_assert_eq!(rd.to_reg(), ri);

let opcode = match (alu_op, imm.shift) {
(ALUOp::And32, 0) => 0xa57, // NILL
Expand All @@ -1586,8 +1629,15 @@ impl MachInstEmit for Inst {
};
put(sink, &enc_ri_a(opcode, rd.to_reg(), imm.bits));
}
&Inst::AluRUImm32Shifted { alu_op, rd, imm } => {
&Inst::AluRUImm32Shifted {
alu_op,
rd,
ri,
imm,
} => {
let rd = allocs.next_writable(rd);
let ri = allocs.next(ri);
debug_assert_eq!(rd.to_reg(), ri);

let opcode = match (alu_op, imm.shift) {
(ALUOp::And32, 0) => 0xc0b, // NILF
Expand Down Expand Up @@ -3412,6 +3462,7 @@ impl MachInstEmit for Inst {
let inst = Inst::AluRX {
alu_op: ALUOp::Add64Ext32,
rd: rtmp,
ri: rtmp.to_reg(),
mem: MemArg::reg_plus_reg(rtmp.to_reg(), ridx, MemFlags::trusted()),
};
inst.emit(&[], sink, emit_info, state);
Expand Down
Loading