cranelift: Fix shifts and implement rotates in interpreter (#4519)
* cranelift: Fix shifts and implement rotates in interpreter * x64: Implement `rotl`/`rotr` for some small type combinations
This commit is contained in:
@@ -818,31 +818,17 @@
|
||||
|
||||
;;;; Rules for `rotl` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; `i16` and `i8`: we need to extend the shift amount, or mask the
|
||||
;; constant.
|
||||
;; `i64` and smaller: we can rely on x86's rotate-amount masking since
|
||||
;; we operate on the whole register. For const's we mask the constant.
|
||||
|
||||
(rule (lower (has_type (ty_8_or_16 ty) (rotl src amt)))
|
||||
(let ((amt_ Gpr (extend_to_gpr amt $I32 (ExtendKind.Zero))))
|
||||
(x64_rotl ty src (gpr_to_imm8_gpr amt_))))
|
||||
(rule (lower (has_type (fits_in_64 ty) (rotl src amt)))
|
||||
(x64_rotl ty src (put_masked_in_imm8_gpr amt ty)))
|
||||
|
||||
(rule (lower (has_type (ty_8_or_16 ty)
|
||||
(rule (lower (has_type (fits_in_64 ty)
|
||||
(rotl src (u64_from_iconst amt))))
|
||||
(x64_rotl ty src
|
||||
(const_to_type_masked_imm8 amt ty)))
|
||||
|
||||
;; `i64` and `i32`: we can rely on x86's rotate-amount masking since
|
||||
;; we operate on the whole register.
|
||||
|
||||
(rule (lower (has_type (ty_32_or_64 ty) (rotl src amt)))
|
||||
;; NB: Only the low bits of `amt` matter since we logically mask the
|
||||
;; shift amount to the value's bit width.
|
||||
(let ((amt_ Gpr (lo_gpr amt)))
|
||||
(x64_rotl ty src amt_)))
|
||||
|
||||
(rule (lower (has_type (ty_32_or_64 ty)
|
||||
(rotl src (u64_from_iconst amt))))
|
||||
(x64_rotl ty src
|
||||
(const_to_type_masked_imm8 amt ty)))
|
||||
|
||||
;; `i128`.
|
||||
|
||||
@@ -858,31 +844,17 @@
|
||||
|
||||
;;;; Rules for `rotr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; `i16` and `i8`: we need to extend the shift amount, or mask the
|
||||
;; constant.
|
||||
;; `i64` and smaller: we can rely on x86's rotate-amount masking since
|
||||
;; we operate on the whole register. For const's we mask the constant.
|
||||
|
||||
(rule (lower (has_type (ty_8_or_16 ty) (rotr src amt)))
|
||||
(let ((amt_ Gpr (extend_to_gpr amt $I32 (ExtendKind.Zero))))
|
||||
(x64_rotr ty src amt_)))
|
||||
(rule (lower (has_type (fits_in_64 ty) (rotr src amt)))
|
||||
(x64_rotr ty src (put_masked_in_imm8_gpr amt ty)))
|
||||
|
||||
(rule (lower (has_type (ty_8_or_16 ty)
|
||||
(rule (lower (has_type (fits_in_64 ty)
|
||||
(rotr src (u64_from_iconst amt))))
|
||||
(x64_rotr ty src
|
||||
(const_to_type_masked_imm8 amt ty)))
|
||||
|
||||
;; `i64` and `i32`: we can rely on x86's rotate-amount masking since
|
||||
;; we operate on the whole register.
|
||||
|
||||
(rule (lower (has_type (ty_32_or_64 ty) (rotr src amt)))
|
||||
;; NB: Only the low bits of `amt` matter since we logically mask the
|
||||
;; shift amount to the value's bit width.
|
||||
(let ((amt_ Gpr (lo_gpr amt)))
|
||||
(x64_rotr ty src amt_)))
|
||||
|
||||
(rule (lower (has_type (ty_32_or_64 ty)
|
||||
(rotr src (u64_from_iconst amt))))
|
||||
(x64_rotr ty src
|
||||
(const_to_type_masked_imm8 amt ty)))
|
||||
|
||||
;; `i128`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user