aarch64: Migrate {s,u}{div,rem} to ISLE (#3572)
* aarch64: Migrate {s,u}{div,rem} to ISLE
This commit migrates four different instructions at once to ISLE:
* `sdiv`
* `udiv`
* `srem`
* `urem`
These all share similar codegen and center around the `div` instruction
to use internally. The main feature of these was to model the manual
traps since the `div` instruction doesn't trap on overflow, instead
requiring manual checks to adhere to the semantics of the instruction
itself.
While I was here I went ahead and implemented an optimization for these
instructions when the right-hand-side is a constant with a known value.
For `udiv`, `srem`, and `urem` if the right-hand-side is a nonzero
constant then the checks for traps can be skipped entirely. For `sdiv`
if the constant is not 0 and not -1 then additionally all checks can be
elided. Finally if the right-hand-side of `sdiv` is -1 the zero-check is
elided, but it still needs a check for `i64::MIN` on the left-hand-side
and currently there's a TODO where `-1` is still checked too.
* Rebasing and review conflicts
This commit is contained in:
@@ -190,6 +190,10 @@
|
||||
(decl u64_from_imm64 (u64) Imm64)
|
||||
(extern extractor infallible u64_from_imm64 u64_from_imm64)
|
||||
|
||||
;; Extract a `u64` from an `Imm64` which is not zero.
|
||||
(decl nonzero_u64_from_imm64 (u64) Imm64)
|
||||
(extern extractor nonzero_u64_from_imm64 nonzero_u64_from_imm64)
|
||||
|
||||
;; Extract a `u64` from an `Ieee32`.
|
||||
(decl u64_from_ieee32 (u64) Ieee32)
|
||||
(extern extractor infallible u64_from_ieee32 u64_from_ieee32)
|
||||
@@ -278,3 +282,10 @@
|
||||
(_z Unit (emit consumer_inst_2)))
|
||||
(value_regs consumer_result_1 consumer_result_2)))
|
||||
|
||||
;;;; Helpers for Working with TrapCode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(decl trap_code_division_by_zero () TrapCode)
|
||||
(extern constructor trap_code_division_by_zero trap_code_division_by_zero)
|
||||
|
||||
(decl trap_code_integer_overflow () TrapCode)
|
||||
(extern constructor trap_code_integer_overflow trap_code_integer_overflow)
|
||||
|
||||
Reference in New Issue
Block a user