Add uadd_overflow_trap (#5123)
Add a new instruction uadd_overflow_trap, which is a fused version of iadd_ifcout and trapif. Adding this instruction removes a dependency on the iflags type, and would allow us to move closer to removing it entirely. The instruction is defined for the i32 and i64 types only, and is currently only used in the legalization of heap_addr.
This commit is contained in:
@@ -2022,6 +2022,13 @@
|
||||
(_ Unit (emit (MInst.AluRRR op dst src1 src2))))
|
||||
dst))
|
||||
|
||||
;; Helper for emitting `MInst.AluRRR` instructions as flag producers.
|
||||
(decl alu_rrr_with_flags_paired (Type ALUOp Reg Reg) ProducesFlags)
|
||||
(rule (alu_rrr_with_flags_paired ty op src1 src2)
|
||||
(let ((dst WritableReg (temp_writable_reg ty)))
|
||||
(ProducesFlags.ProducesFlagsReturnsResultWithConsumer
|
||||
(MInst.AluRRR op dst src1 src2) dst)))
|
||||
|
||||
;; Helper for emitting `MInst.AluRRSImm16` instructions.
|
||||
(decl alu_rrsimm16 (Type ALUOp Reg i16) Reg)
|
||||
(rule (alu_rrsimm16 ty op src imm)
|
||||
@@ -2036,6 +2043,13 @@
|
||||
(_ Unit (emit (MInst.AluRR op dst src1 src2))))
|
||||
dst))
|
||||
|
||||
;; Helper for emitting `MInst.AluRR` instructions as flag producers.
|
||||
(decl alu_rr_with_flags_paired (Type ALUOp Reg Reg) ProducesFlags)
|
||||
(rule (alu_rr_with_flags_paired ty op src1 src2)
|
||||
(let ((dst WritableReg (temp_writable_reg ty)))
|
||||
(ProducesFlags.ProducesFlagsReturnsResultWithConsumer
|
||||
(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)
|
||||
@@ -2043,6 +2057,13 @@
|
||||
(_ Unit (emit (MInst.AluRX op dst src mem))))
|
||||
dst))
|
||||
|
||||
;; Helper for emitting `MInst.AluRX` instructions as flags producers.
|
||||
(decl alu_rx_with_flags_paired (Type ALUOp Reg MemArg) ProducesFlags)
|
||||
(rule (alu_rx_with_flags_paired ty op src mem)
|
||||
(let ((dst WritableReg (temp_writable_reg ty)))
|
||||
(ProducesFlags.ProducesFlagsReturnsResultWithConsumer
|
||||
(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)
|
||||
@@ -2064,6 +2085,13 @@
|
||||
(_ Unit (emit (MInst.AluRUImm32 op dst src imm))))
|
||||
dst))
|
||||
|
||||
;; Helper for emitting `MInst.AluRUImm32` instructions as flag producers.
|
||||
(decl alu_ruimm32_with_flags_paired (Type ALUOp Reg u32) ProducesFlags)
|
||||
(rule (alu_ruimm32_with_flags_paired ty op src imm)
|
||||
(let ((dst WritableReg (temp_writable_reg ty)))
|
||||
(ProducesFlags.ProducesFlagsReturnsResultWithConsumer
|
||||
(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)
|
||||
@@ -3877,18 +3905,38 @@
|
||||
(decl add_logical_reg (Type Reg Reg) Reg)
|
||||
(rule (add_logical_reg ty x y) (alu_rrr ty (aluop_add_logical ty) x y))
|
||||
|
||||
(decl add_logical_reg_with_flags_paired (Type Reg Reg) ProducesFlags)
|
||||
(rule (add_logical_reg_with_flags_paired ty x y)
|
||||
(alu_rrr_with_flags_paired ty (aluop_add_logical ty) x y))
|
||||
|
||||
(decl add_logical_reg_zext32 (Type Reg Reg) Reg)
|
||||
(rule (add_logical_reg_zext32 ty x y) (alu_rr ty (aluop_add_logical_zext32 ty) x y))
|
||||
|
||||
(decl add_logical_reg_zext32_with_flags_paired (Type Reg Reg) ProducesFlags)
|
||||
(rule (add_logical_reg_zext32_with_flags_paired ty x y)
|
||||
(alu_rr_with_flags_paired ty (aluop_add_logical_zext32 ty) x y))
|
||||
|
||||
(decl add_logical_zimm32 (Type Reg u32) Reg)
|
||||
(rule (add_logical_zimm32 ty x y) (alu_ruimm32 ty (aluop_add_logical ty) x y))
|
||||
|
||||
(decl add_logical_zimm32_with_flags_paired (Type Reg u32) ProducesFlags)
|
||||
(rule (add_logical_zimm32_with_flags_paired ty x y)
|
||||
(alu_ruimm32_with_flags_paired ty (aluop_add_logical ty) x y))
|
||||
|
||||
(decl add_logical_mem (Type Reg MemArg) Reg)
|
||||
(rule (add_logical_mem ty x y) (alu_rx ty (aluop_add_logical ty) x y))
|
||||
|
||||
(decl add_logical_mem_with_flags_paired (Type Reg MemArg) ProducesFlags)
|
||||
(rule (add_logical_mem_with_flags_paired ty x y)
|
||||
(alu_rx_with_flags_paired ty (aluop_add_logical ty) x y))
|
||||
|
||||
(decl add_logical_mem_zext32 (Type Reg MemArg) Reg)
|
||||
(rule (add_logical_mem_zext32 ty x y) (alu_rx ty (aluop_add_logical_zext32 ty) x y))
|
||||
|
||||
(decl add_logical_mem_zext32_with_flags_paired (Type Reg MemArg) ProducesFlags)
|
||||
(rule (add_logical_mem_zext32_with_flags_paired ty x y)
|
||||
(alu_rx_with_flags_paired ty (aluop_add_logical_zext32 ty) x y))
|
||||
|
||||
|
||||
;; Helpers for generating `sub` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
@@ -3870,6 +3870,60 @@
|
||||
(trap_if_bool (bool (flags_to_producesflags flags) (mask_as_cond 3))
|
||||
trap_code)))
|
||||
|
||||
;;;; Rules for `uadd_overflow_trap` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule 0 (lower (has_type (fits_in_64 ty) (uadd_overflow_trap x y tc)))
|
||||
(with_flags
|
||||
(add_logical_reg_with_flags_paired ty x y)
|
||||
(trap_if_impl (mask_as_cond 3) tc)))
|
||||
|
||||
;; Add a register an a zero-extended register.
|
||||
(rule 4 (lower (has_type (fits_in_64 ty)
|
||||
(uadd_overflow_trap x (zext32_value y) tc)))
|
||||
(with_flags
|
||||
(add_logical_reg_zext32_with_flags_paired ty x y)
|
||||
(trap_if_impl (mask_as_cond 3) tc)))
|
||||
(rule 8 (lower (has_type (fits_in_64 ty)
|
||||
(uadd_overflow_trap (zext32_value x) y tc)))
|
||||
(with_flags
|
||||
(add_logical_reg_zext32_with_flags_paired ty y x)
|
||||
(trap_if_impl (mask_as_cond 3) tc)))
|
||||
|
||||
;; Add a register and an immediate
|
||||
(rule 3 (lower (has_type (fits_in_64 ty)
|
||||
(uadd_overflow_trap x (u32_from_value y) tc)))
|
||||
(with_flags
|
||||
(add_logical_zimm32_with_flags_paired ty x y)
|
||||
(trap_if_impl (mask_as_cond 3) tc)))
|
||||
(rule 7 (lower (has_type (fits_in_64 ty)
|
||||
(uadd_overflow_trap (u32_from_value x) y tc)))
|
||||
(with_flags
|
||||
(add_logical_zimm32_with_flags_paired ty y x)
|
||||
(trap_if_impl (mask_as_cond 3) tc)))
|
||||
|
||||
;; Add a register and memory (32/64-bit types).
|
||||
(rule 2 (lower (has_type (fits_in_64 ty)
|
||||
(uadd_overflow_trap x (sinkable_load_32_64 y) tc)))
|
||||
(with_flags
|
||||
(add_logical_mem_with_flags_paired ty x (sink_load y))
|
||||
(trap_if_impl (mask_as_cond 3) tc)))
|
||||
(rule 6 (lower (has_type (fits_in_64 ty)
|
||||
(uadd_overflow_trap (sinkable_load_32_64 x) y tc)))
|
||||
(with_flags
|
||||
(add_logical_mem_with_flags_paired ty y (sink_load x))
|
||||
(trap_if_impl (mask_as_cond 3) tc)))
|
||||
|
||||
;; Add a register and zero-extended memory.
|
||||
(rule 1 (lower (has_type (fits_in_64 ty)
|
||||
(uadd_overflow_trap x (sinkable_uload32 y) tc)))
|
||||
(with_flags
|
||||
(add_logical_mem_zext32_with_flags_paired ty x (sink_uload32 y))
|
||||
(trap_if_impl (mask_as_cond 3) tc)))
|
||||
(rule 5 (lower (has_type (fits_in_64 ty)
|
||||
(uadd_overflow_trap (sinkable_uload32 x) y tc)))
|
||||
(with_flags
|
||||
(add_logical_mem_zext32_with_flags_paired ty y (sink_uload32 x))
|
||||
(trap_if_impl (mask_as_cond 3) tc)))
|
||||
|
||||
;;;; Rules for `return` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
@@ -240,6 +240,7 @@ impl LowerBackend for S390xBackend {
|
||||
| Opcode::IaddCout
|
||||
| Opcode::IaddCarry
|
||||
| Opcode::IaddIfcarry
|
||||
| Opcode::UaddOverflowTrap
|
||||
| Opcode::IsubBin
|
||||
| Opcode::IsubIfbin
|
||||
| Opcode::IsubBout
|
||||
|
||||
Reference in New Issue
Block a user