[AArch64] Port SIMD narrowing to ISLE (#4478)

* [AArch64] Port SIMD narrowing to ISLE

Fvdemote, snarrow, unarrow and uunarrow.

Also refactor the aarch64 instructions descriptions to parameterize
on ScalarSize instead of using different opcodes.

The zero_value pure constructor has been introduced and used by the
integer narrow operations and it replaces, and extends, the compare
zero patterns.

Copright (c) 2022, Arm Limited.

* use short 'if' patterns
This commit is contained in:
Sam Parker
2022-07-25 20:40:36 +01:00
committed by GitHub
parent dd40bf075a
commit c5ddb4b803
15 changed files with 1340 additions and 337 deletions

View File

@@ -47,6 +47,48 @@
(vec_rrr (VecALUOp.Fcmgt) (put_in_reg y) (put_in_reg x)
(vector_size ty)) (put_in_reg y) (put_in_reg x))))
;;;; Rules for `snarrow` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (ty_dyn128_int ty) (snarrow x y)))
(if-let _ (zero_value y))
(sqxtn x (lane_size ty)))
(rule (lower (has_type (ty_dyn64_int ty) (snarrow x y)))
(let ((dst Reg (mov_vec_elem x y 1 0 (VectorSize.Size64x2))))
(sqxtn dst (lane_size ty))))
(rule (lower (has_type (ty_dyn128_int ty) (snarrow x y)))
(let ((low_half Reg (sqxtn x (lane_size ty)))
(result Reg (sqxtn2 low_half y (lane_size ty))))
result))
;;;; Rules for `unarrow` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (ty_dyn128_int ty) (unarrow x y)))
(if-let _ (zero_value y))
(sqxtun x (lane_size ty)))
(rule (lower (has_type (ty_dyn64_int ty) (unarrow x y)))
(let ((dst Reg (mov_vec_elem x y 1 0 (VectorSize.Size64x2))))
(sqxtun dst (lane_size ty))))
(rule (lower (has_type (ty_dyn128_int ty) (unarrow x y)))
(let ((low_half Reg (sqxtun x (lane_size ty)))
(result Reg (sqxtun2 low_half y (lane_size ty))))
result))
;;;; Rules for `uunarrow` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (ty_dyn128_int ty) (uunarrow x y)))
(if-let _ (zero_value y))
(uqxtn x (lane_size ty)))
(rule (lower (has_type (ty_dyn64_int ty) (uunarrow x y)))
(let ((dst Reg (mov_vec_elem x y 1 0 (VectorSize.Size64x2))))
(uqxtn dst (lane_size ty))))
(rule (lower (has_type (ty_dyn128_int ty) (uunarrow x y)))
(let ((low_half Reg (uqxtn x (lane_size ty)))
(result Reg (uqxtn2 low_half y (lane_size ty))))
result))
;;; Rules for `dynamic_stack_addr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (dynamic_stack_addr stack_slot))
(let ((dst WritableReg (temp_writable_reg $I64))