Browse Source

riscv64: Add instruction helpers (#6099)

* riscv64: Add helpers for `add`

* riscv64: Add helpers for `sub`

* riscv64: Add helpers for `sll`

* riscv64: Add helpers for `srl`

* riscv64: Add helpers for `sra`

* riscv64: Add helpers for `or`

* riscv64: Add helpers for `and`

* riscv64: Add helpers for `xor`

* riscv64: Add helpers for `addi`

* riscv64: Add helpers for `slli`

* riscv64: Add helpers for `srli`

* riscv64: Add helpers for `srai`

* riscv64: Add helpers for `ori`

* riscv64: Add helpers for `xori`

* riscv64: Add helpers for `andi`

* riscv64: Add helpers for `not`

* riscv64: Add helpers for `sltiu`

* riscv64: Add helpers for `seqz`

* riscv64: Add helpers for `addw`

* riscv64: Add helpers for `subw`

* riscv64: Add helpers for `sllw`

* riscv64: Add helpers for `slliw`

* riscv64: Add helpers for `srlw`

* riscv64: Add helpers for `srliw`

* riscv64: Add helpers for `sraw`

* riscv64: Add helpers for `sraiw`

* riscv64: Add helpers for `sltu`

* riscv64: Add helpers for `mul`

* riscv64: Add helpers for `mulh`

* riscv64: Add helpers for `mulhu`

* riscv64: Add helpers for `div`

* riscv64: Add helpers for `divu`

* riscv64: Add helpers for `rem`

* riscv64: Add helpers for `remu`

* riscv64: Add helpers for `mulw`

* riscv64: Add helpers for `divw`

* riscv64: Add helpers for `divuw`

* riscv64: Add helpers for `remw`

* riscv64: Add helpers for `remuw`

* riscv64: Add helpers for `neg`

* riscv64: Add helpers for `addiw`

* riscv64: Add helpers for `sext.w`

* riscv64: Add helpers for `fadd`

* riscv64: Add helpers for `fsub`

* riscv64: Add helpers for `fmul`

* riscv64: Add helpers for `fdiv`

* riscv64: Add helpers for `fsqrt`

* riscv64: Add helpers for `fmadd`

* riscv64: Add helpers for `fsgnj`

* riscv64: Add helpers for `fsgnjn`

* riscv64: Add helpers for `fsgnjx`

* riscv64: Add helpers for `fcvtds`

* riscv64: Add helpers for `fcvtsd`

* riscv64: Add helpers for `adduw`

* riscv64: Add helpers for `zext.w`

* riscv64: Add helpers for `andn`

* riscv64: Add helpers for `orn`

* riscv64: Add helpers for `clz`

* riscv64: Add helpers for `clzw`

* riscv64: Add helpers for `ctz`

* riscv64: Add helpers for `ctzw`

* riscv64: Add helpers for `cpop`

* riscv64: Add helpers for `max`

* riscv64: Add helpers for `feq`

* riscv64: Add helpers for `flt`

* riscv64: Add helpers for `fle`

* riscv64: Add helpers for `fgt`

* riscv64: Add helpers for `fge`

* riscv64: Add helpers for `sext.b`

* riscv64: Add helpers for `sext.h`

* riscv64: Add helpers for `zext.h`

* riscv64: Add helpers for `rol`

* riscv64: Add helpers for `rolw`

* riscv64: Add helpers for `ror`

* riscv64: Add helpers for `rorw`

* riscv64: Add helpers for `rev8`

* riscv64: Add helpers for `brev8`

* riscv64: Add helpers for `bseti`

* riscv64: Add helpers for `pack`

* riscv64: Add helpers for `packw`

* riscv64: Add helpers for `slli.uw`

* riscv64: Add helpers for `fabs`

* riscv64: Add helpers for `fneg`
pull/6102/head
Afonso Bordado 2 years ago
committed by GitHub
parent
commit
a002a2cc5e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 914
      cranelift/codegen/src/isa/riscv64/inst.isle
  2. 245
      cranelift/codegen/src/isa/riscv64/lower.isle

914
cranelift/codegen/src/isa/riscv64/inst.isle

File diff suppressed because it is too large

245
cranelift/codegen/src/isa/riscv64/lower.isle

@ -29,7 +29,7 @@
;; Base case, simply adding things in registers.
(rule 0 (lower (has_type (fits_in_64 ty) (iadd x y)))
(alu_add x y))
(rv_add x y))
;; Special cases for when one operand is an immediate that fits in 12 bits.
(rule 1 (lower (has_type (fits_in_64 ty) (iadd x (imm12_from_value y))))
@ -42,11 +42,11 @@
;; Needs `Zba`
(rule 3 (lower (has_type $I64 (iadd x (uextend y @ (value_type $I32)))))
(if-let $true (has_zba))
(alu_rrr (AluOPRRR.Adduw) y x))
(rv_adduw y x))
(rule 4 (lower (has_type $I64 (iadd (uextend x @ (value_type $I32)) y)))
(if-let $true (has_zba))
(alu_rrr (AluOPRRR.Adduw) x y))
(rv_adduw x y))
;; Add with const shift. We have a few of these instructions with `Zba`.
(decl pure partial match_shnadd (Imm64) AluOPRRR)
@ -88,13 +88,13 @@
;; I128 cases
(rule 7 (lower (has_type $I128 (iadd x y)))
(let ((low Reg (alu_add (value_regs_get x 0) (value_regs_get y 0)))
(let ((low Reg (rv_add (value_regs_get x 0) (value_regs_get y 0)))
;; compute carry.
(carry Reg (alu_rrr (AluOPRRR.SltU) low (value_regs_get y 0)))
(carry Reg (rv_sltu low (value_regs_get y 0)))
;;
(high_tmp Reg (alu_add (value_regs_get x 1) (value_regs_get y 1)))
(high_tmp Reg (rv_add (value_regs_get x 1) (value_regs_get y 1)))
;; add carry.
(high Reg (alu_add high_tmp carry)))
(high Reg (rv_add high_tmp carry)))
(value_regs low high)))
;;; Rules for `uadd_overflow_trap` ;;;;;;;;;;;;;
@ -109,10 +109,10 @@
;; Base case, simply subtracting things in registers.
(rule -2 (lower (has_type (fits_in_64 ty) (isub x y)))
(alu_rrr (AluOPRRR.Sub) x y))
(rv_sub x y))
(rule -1 (lower (has_type (fits_in_32 ty) (isub x y)))
(alu_rrr (AluOPRRR.Subw) x y))
(rv_subw x y))
(rule (lower (has_type $I128 (isub x y)))
(i128_sub x y))
@ -126,9 +126,9 @@
;;;; Rules for `imul` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule -2 (lower (has_type (fits_in_64 ty) (imul x y)))
(alu_rrr (AluOPRRR.Mul) x y))
(rv_mul x y))
(rule -1 (lower (has_type (fits_in_32 ty) (imul x y)))
(alu_rrr (AluOPRRR.Mulw) x y))
(rv_mulw x y))
;;;; Rules for `smulhi` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_64 ty) (smulhi x y)))
@ -152,14 +152,14 @@
;; 128bit mul formula:
;; dst_lo = x_lo * y_lo
;; dst_hi = umulhi(x_lo, y_lo) + (x_lo * y_hi) + (x_hi * y_lo)
;; dst_hi = mulhu(x_lo, y_lo) + (x_lo * y_hi) + (x_hi * y_lo)
;;
;; We can convert the above formula into the following
;; umulh dst_hi, x_lo, y_lo
;; mulhu dst_hi, x_lo, y_lo
;; madd dst_hi, x_lo, y_hi, dst_hi
;; madd dst_hi, x_hi, y_lo, dst_hi
;; madd dst_lo, x_lo, y_lo, zero
(dst_hi1 Reg (umulh x_lo y_lo))
(dst_hi1 Reg (rv_mulhu x_lo y_lo))
(dst_hi2 Reg (madd x_lo y_hi dst_hi1))
(dst_hi Reg (madd x_hi y_lo dst_hi2))
(dst_lo Reg (madd x_lo y_lo (zero_reg))))
@ -172,7 +172,7 @@
(let
((y2 Reg (ext_int_if_need $false y ty))
(_ InstOutput (gen_div_by_zero y2)))
(alu_rrr (AluOPRRR.Divuw) (ext_int_if_need $false x ty) y2)))
(rv_divuw (ext_int_if_need $false x ty) y2)))
(rule -1 (lower (has_type (fits_in_32 ty) (sdiv x y)))
(let
@ -180,18 +180,18 @@
(b Reg (ext_int_if_need $true y ty))
(_ InstOutput (gen_div_overflow a b ty))
(_ InstOutput (gen_div_by_zero b)))
(alu_rrr (AluOPRRR.Divw) a b)))
(rv_divw a b)))
(rule (lower (has_type $I64 (sdiv x y)))
(let
((_ InstOutput (gen_div_overflow x y $I64))
(_ InstOutput (gen_div_by_zero y)) )
(alu_rrr (AluOPRRR.Div) x y)))
(rv_div x y)))
(rule (lower (has_type $I64 (udiv x y)))
(let
((_ InstOutput (gen_div_by_zero y)))
(alu_rrr (AluOPRRR.DivU) x y)))
(rv_divu x y)))
;;;; Rules for `rem` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -199,46 +199,46 @@
(let
((y2 Reg (ext_int_if_need $false y ty))
(_ InstOutput (gen_div_by_zero y2)))
(alu_rrr (AluOPRRR.Remuw) (ext_int_if_need $false x ty) y2)))
(rv_remuw (ext_int_if_need $false x ty) y2)))
(rule -1 (lower (has_type (fits_in_16 ty) (srem x y)))
(let
((y2 Reg (ext_int_if_need $true y ty))
(_ InstOutput (gen_div_by_zero y2)))
(alu_rrr (AluOPRRR.Remw) (ext_int_if_need $true x ty) y2)))
(rv_remw (ext_int_if_need $true x ty) y2)))
(rule (lower (has_type $I32 (srem x y)))
(let
((y2 Reg (ext_int_if_need $true y $I32))
(_ InstOutput (gen_div_by_zero y2)))
(alu_rrr (AluOPRRR.Remw) x y2)))
(rv_remw x y2)))
(rule (lower (has_type $I32 (urem x y)))
(let
((y2 Reg (ext_int_if_need $false y $I32))
(_ InstOutput (gen_div_by_zero y2)))
(alu_rrr (AluOPRRR.Remuw) x y2)))
(rv_remuw x y2)))
(rule (lower (has_type $I64 (srem x y)))
(let
((_ InstOutput (gen_div_by_zero y)))
(alu_rrr (AluOPRRR.Rem) x y)))
(rv_rem x y)))
(rule (lower (has_type $I64 (urem x y)))
(let
((_ InstOutput (gen_div_by_zero y)))
(alu_rrr (AluOPRRR.RemU) x y)))
(rv_remu x y)))
;;;; Rules for `and` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule -1 (lower (has_type (fits_in_64 (ty_int ty)) (band x y)))
(alu_rrr (AluOPRRR.And) x y))
(rv_and x y))
;; Special cases for when one operand is an immediate that fits in 12 bits.
(rule 2 (lower (has_type (fits_in_64 (ty_int ty)) (band x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Andi) x y))
(rv_andi x y))
(rule 1 (lower (has_type (fits_in_64 (ty_int ty)) (band (imm12_from_value x) y)))
(alu_rr_imm12 (AluOPRRI.Andi) y x))
(rv_andi y x))
(rule (lower (has_type $I128 (band x y)))
(lower_b128_binary (AluOPRRR.And) x y))
@ -255,37 +255,37 @@
(rule 3 (lower (has_type (fits_in_64 (ty_int ty)) (band x (bnot y))))
(if-let $true (has_zbb))
(gen_andn x y))
(rv_andn x y))
(rule 4 (lower (has_type (fits_in_64 (ty_int ty)) (band (bnot y) x)))
(if-let $true (has_zbb))
(gen_andn x y))
(rv_andn x y))
(rule 5 (lower (has_type $I128 (band x (bnot y))))
(if-let $true (has_zbb))
(let
((low Reg (gen_andn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (gen_andn (value_regs_get x 1) (value_regs_get y 1))))
((low Reg (rv_andn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (rv_andn (value_regs_get x 1) (value_regs_get y 1))))
(value_regs low high)))
(rule 6 (lower (has_type $I128 (band (bnot y) x)))
(if-let $true (has_zbb))
(let
((low Reg (gen_andn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (gen_andn (value_regs_get x 1) (value_regs_get y 1))))
((low Reg (rv_andn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (rv_andn (value_regs_get x 1) (value_regs_get y 1))))
(value_regs low high)))
;;;; Rules for `or` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule -1 (lower (has_type (fits_in_64 (ty_int ty)) (bor x y)))
(alu_rrr (AluOPRRR.Or) x y))
(rv_or x y))
;; Special cases for when one operand is an immediate that fits in 12 bits.
(rule 2 (lower (has_type (fits_in_64 (ty_int ty)) (bor x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Ori) x y))
(rv_ori x y))
(rule 1 (lower (has_type (fits_in_64 (ty_int ty)) (bor (imm12_from_value x) y)))
(alu_rr_imm12 (AluOPRRI.Ori) y x))
(rv_ori y x))
(rule (lower (has_type $I128 (bor x y)))
(lower_b128_binary (AluOPRRR.Or) x y))
@ -302,37 +302,37 @@
(rule 3 (lower (has_type (fits_in_64 (ty_int ty)) (bor x (bnot y))))
(if-let $true (has_zbb))
(gen_orn x y))
(rv_orn x y))
(rule 4 (lower (has_type (fits_in_64 (ty_int ty)) (bor (bnot y) x)))
(if-let $true (has_zbb))
(gen_orn x y))
(rv_orn x y))
(rule 5 (lower (has_type $I128 (bor x (bnot y))))
(if-let $true (has_zbb))
(let
((low Reg (gen_orn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (gen_orn (value_regs_get x 1) (value_regs_get y 1))))
((low Reg (rv_orn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (rv_orn (value_regs_get x 1) (value_regs_get y 1))))
(value_regs low high)))
(rule 6 (lower (has_type $I128 (bor (bnot y) x)))
(if-let $true (has_zbb))
(let
((low Reg (gen_orn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (gen_orn (value_regs_get x 1) (value_regs_get y 1))))
((low Reg (rv_orn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (rv_orn (value_regs_get x 1) (value_regs_get y 1))))
(value_regs low high)))
;;;; Rules for `xor` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule -1 (lower (has_type (fits_in_64 (ty_int ty)) (bxor x y)))
(alu_rrr (AluOPRRR.Xor) x y))
(rv_xor x y))
;; Special cases for when one operand is an immediate that fits in 12 bits.
(rule 2 (lower (has_type (fits_in_64 (ty_int ty)) (bxor x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Xori) x y))
(rv_xori x y))
(rule 1 (lower (has_type (fits_in_64 (ty_int ty)) (bxor (imm12_from_value x) y)))
(alu_rr_imm12 (AluOPRRI.Xori) y x))
(rv_xori y x))
(rule (lower (has_type $I128 (bxor x y)))
(lower_b128_binary (AluOPRRR.Xor) x y))
@ -346,7 +346,7 @@
;;;; Rules for `bnot` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule -1 (lower (has_type (fits_in_64 (ty_int ty)) (bnot x)))
(alu_rr_imm12 (AluOPRRI.Xori) x (imm_from_neg_bits -1)))
(rv_xori x (imm_from_neg_bits -1)))
(rule (lower (has_type $I128 (bnot x)))
(bnot_128 x))
@ -402,35 +402,35 @@
;; The instructions below are present in RV64I and sign-extend the result to 64 bits.
(rule 1 (lower (has_type $I64 (sextend (has_type $I32 (iadd x y)))))
(alu_rrr (AluOPRRR.Addw) x y))
(rv_addw x y))
(rule 1 (lower (has_type $I64 (sextend (has_type $I32 (isub x y)))))
(alu_rrr (AluOPRRR.Subw) x y))
(rv_subw x y))
(rule 1 (lower (has_type $I64 (sextend (has_type $I32 (ishl x y)))))
(alu_rrr (AluOPRRR.Sllw) x (value_regs_get y 0)))
(rv_sllw x (value_regs_get y 0)))
(rule 1 (lower (has_type $I64 (sextend (has_type $I32 (ushr x y)))))
(alu_rrr (AluOPRRR.Srlw) x (value_regs_get y 0)))
(rv_srlw x (value_regs_get y 0)))
(rule 1 (lower (has_type $I64 (sextend (has_type $I32 (sshr x y)))))
(alu_rrr (AluOPRRR.Sraw) x (value_regs_get y 0)))
(rv_sraw x (value_regs_get y 0)))
(rule 2 (lower (has_type $I64 (sextend (has_type $I32 (iadd x (imm12_from_value y))))))
(alu_rr_imm12 (AluOPRRI.Addiw) x y))
(rv_addiw x y))
(rule 3 (lower (has_type $I64 (sextend (has_type $I32 (iadd (imm12_from_value x) y)))))
(alu_rr_imm12 (AluOPRRI.Addiw) y x))
(rv_addiw y x))
(rule 2 (lower (has_type $I64 (sextend (has_type $I32 (ishl x (imm12_from_value y))))))
(alu_rr_imm12 (AluOPRRI.Slliw) x y))
(rv_slliw x y))
(rule 2 (lower (has_type $I64 (sextend (has_type $I32 (ushr x (imm12_from_value y))))))
(alu_rr_imm12 (AluOPRRI.SrliW) x y))
(rv_srliw x y))
(rule 2 (lower (has_type $I64 (sextend (has_type $I32 (sshr x (imm12_from_value y))))))
(alu_rr_imm12 (AluOPRRI.Sraiw) x y))
(rv_sraiw x y))
;;;; Rules for `popcnt` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_64 ty) (popcnt x)))
@ -440,31 +440,31 @@
;;;; Rules for `ishl` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule 1 (lower (has_type $I8 (ishl x y)))
(alu_rrr (AluOPRRR.Sllw) x (alu_andi (value_regs_get y 0) 7))
)
(rv_sllw x (rv_andi (value_regs_get y 0) (imm12_const 7))))
(rule 2 (lower (has_type $I8 (ishl x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Slliw) x (imm12_and y 7)))
(rv_slliw x (imm12_and y 7)))
(rule 1 (lower (has_type $I16 (ishl x y)))
(alu_rrr (AluOPRRR.Sllw) x (alu_andi (value_regs_get y 0) 15))
)
(rv_sllw x (rv_andi (value_regs_get y 0) (imm12_const 15))))
(rule 2 (lower (has_type $I16 (ishl x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Slliw) x (imm12_and y 15)))
(rv_slliw x (imm12_and y 15)))
(rule 1 (lower (has_type $I32 (ishl x y)))
(alu_rrr (AluOPRRR.Sllw) x (value_regs_get y 0)))
(rv_sllw x (value_regs_get y 0)))
(rule 2 (lower (has_type $I32 (ishl x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Slliw) x y))
(rv_slliw x y))
(rule 2 (lower (has_type $I64 (ishl x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Slli) x y))
(rv_slli x y))
(rule 1 (lower (has_type $I64 (ishl x y)))
(alu_rrr (AluOPRRR.Sll) x (value_regs_get y 0)))
(rv_sll x (value_regs_get y 0)))
;; With `Zba` we have a shift that zero extends the LHS argument.
(rule 3 (lower (has_type $I64 (ishl (uextend x @ (value_type $I32)) (maybe_uextend (imm12_from_value y)))))
(if-let $true (has_zba))
(alu_rr_imm12 (AluOPRRI.SlliUw) x y))
(rv_slliuw x y))
;; I128 cases
(rule 0 (lower (has_type $I128 (ishl x y)))
@ -472,26 +472,26 @@
;;;; Rules for `ushr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule 1 (lower (has_type $I8 (ushr x y)))
(alu_rrr (AluOPRRR.Srlw) (ext_int_if_need $false x $I8) (alu_andi (value_regs_get y 0) 7))
)
(rv_srlw (ext_int_if_need $false x $I8) (rv_andi (value_regs_get y 0) (imm12_const 7))))
(rule 2 (lower (has_type $I8 (ushr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.SrliW) (ext_int_if_need $false x $I8) (imm12_and y 7)))
(rv_srliw (ext_int_if_need $false x $I8) (imm12_and y 7)))
(rule 1 (lower (has_type $I16 (ushr x y)))
(alu_rrr (AluOPRRR.Srlw) (ext_int_if_need $false x $I16) (alu_andi (value_regs_get y 0) 15))
)
(rv_srlw (ext_int_if_need $false x $I16) (rv_andi (value_regs_get y 0) (imm12_const 15))))
(rule 2 (lower (has_type $I16 (ushr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.SrliW) (ext_int_if_need $false x $I16) (imm12_and y 15)))
(rv_srliw (ext_int_if_need $false x $I16) (imm12_and y 15)))
(rule 1 (lower (has_type $I32 (ushr x y)))
(alu_rrr (AluOPRRR.Srlw) x (value_regs_get y 0)))
(rv_srlw x (value_regs_get y 0)))
(rule 2 (lower (has_type $I32 (ushr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.SrliW) x y))
(rv_srliw x y))
(rule 2 (lower (has_type $I64 (ushr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Srli) x y))
(rv_srli x y))
(rule 1 (lower (has_type $I64 (ushr x y)))
(alu_rrr (AluOPRRR.Srl) x (value_regs_get y 0)))
(rv_srl x (value_regs_get y 0)))
(rule 0 (lower (has_type $I128 (ushr x y)))
(lower_i128_ushr x y))
@ -499,25 +499,25 @@
;;;; Rules for `sshr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule 1 (lower (has_type $I8 (sshr x y)))
(alu_rrr (AluOPRRR.Sra) (ext_int_if_need $true x $I8) (alu_andi (value_regs_get y 0) 7))
)
(rv_sra (ext_int_if_need $true x $I8) (rv_andi (value_regs_get y 0) (imm12_const 7))))
(rule 2 (lower (has_type $I8 (sshr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Srai) (ext_int_if_need $true x $I8) (imm12_and y 7)))
(rv_srai (ext_int_if_need $true x $I8) (imm12_and y 7)))
(rule 1 (lower (has_type $I16 (sshr x y)))
(alu_rrr (AluOPRRR.Sra) (ext_int_if_need $true x $I16) (alu_andi (value_regs_get y 0) 15))
)
(rv_sra (ext_int_if_need $true x $I16) (rv_andi (value_regs_get y 0) (imm12_const 15))))
(rule 2 (lower (has_type $I16 (sshr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Srai) (ext_int_if_need $true x $I16) (imm12_and y 15)))
(rv_srai (ext_int_if_need $true x $I16) (imm12_and y 15)))
(rule 1 (lower (has_type $I32 (sshr x y)))
(alu_rrr (AluOPRRR.Sraw) x (value_regs_get y 0)))
(rv_sraw x (value_regs_get y 0)))
(rule 2 (lower (has_type $I32 (sshr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Sraiw) x y))
(rv_sraiw x y))
(rule 1 (lower (has_type $I64 (sshr x y)))
(alu_rrr (AluOPRRR.Sra) x (value_regs_get y 0)))
(rv_sra x (value_regs_get y 0)))
(rule 2 (lower (has_type $I64 (sshr x (imm12_from_value y))))
(alu_rr_imm12 (AluOPRRI.Srai) x y))
(rv_srai x y))
(rule 0 (lower (has_type $I128 (sshr x y)))
(lower_i128_sshr x (value_regs_get y 0)))
@ -538,32 +538,25 @@
;;;; Rules for `fabs` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule
(lower (has_type ty (fabs x)))
(gen_fabs x ty))
(rule (lower (has_type ty (fabs x)))
(rv_fabs ty x))
;;;; Rules for `fneg` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule
(lower (has_type ty (fneg x)))
(fpu_rrr (f_copy_neg_sign_op ty) ty x x))
(rule (lower (has_type ty (fneg x)))
(rv_fneg ty x))
;;;; Rules for `fcopysign` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type ty (fcopysign x y)))
(fpu_rrr (f_copysign_op ty) ty x y))
(rv_fsgnj ty x y))
;;;; Rules for `fma` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type $F32 (fma x y z)))
(fpu_rrrr (FpuOPRRRR.FmaddS) $F64 x y z))
(rule (lower (has_type $F64 (fma x y z)))
(fpu_rrrr (FpuOPRRRR.FmaddD) $F64 x y z))
(rule (lower (has_type ty (fma x y z)))
(rv_fmadd ty x y z))
;;;; Rules for `sqrt` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type $F32 (sqrt x)))
(fpu_rr (FpuOPRR.FsqrtS) $F64 x))
(rule (lower (has_type $F64 (sqrt x)))
(fpu_rr (FpuOPRR.FsqrtD) $F64 x))
(rule (lower (has_type ty (sqrt x)))
(rv_fsqrt ty x))
;;;; Rules for `AtomicRMW` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -600,7 +593,7 @@
(has_type (valid_atomic_transaction ty) (atomic_rmw flags (AtomicRmwOp.Sub) addr x)))
(let
((tmp WritableReg (temp_writable_reg ty))
(x2 Reg (alu_rrr (AluOPRRR.Sub) (zero_reg) x)))
(x2 Reg (rv_neg x)))
(gen_atomic (get_atomic_rmw_op ty (AtomicRmwOp.Add)) addr x2 (atomic_amo))))
(decl gen_atomic_rmw_loop (AtomicRmwOp Type Reg Reg) Reg)
@ -634,14 +627,14 @@
(decl gen_atomic_offset (Reg Type) Reg)
(rule 1 (gen_atomic_offset p (fits_in_16 ty))
(alu_slli (alu_andi p 3) 3))
(rv_slli (rv_andi p (imm12_const 3)) (imm12_const 3)))
(rule (gen_atomic_offset p _)
(zero_reg))
(decl gen_atomic_p (Reg Type) Reg)
(rule 1 (gen_atomic_p p (fits_in_16 ty))
(alu_andi p -4))
(rv_andi p (imm12_const -4)))
(rule (gen_atomic_p p _)
p)
@ -662,28 +655,26 @@
(gen_move2 (value_regs_get x 0) ty ty))
;;;;; Rules for `fpromote`;;;;;;;;;;;;;;;;;
(rule
(lower (has_type ty (fpromote x)))
(fpu_rr (FpuOPRR.FcvtDS) ty x))
(rule (lower (fpromote x))
(rv_fcvtds x))
(rule
(lower (has_type ty (fdemote x)))
(fpu_rr (FpuOPRR.FcvtSD) ty x))
;;;;; Rules for `fdemote`;;;;;;;;;;;;;;;;;;
(rule (lower (fdemote x))
(rv_fcvtsd x))
;;;;; Rules for `for float arithmatic`
(rule
(lower (has_type ty (fadd x y)))
(fpu_rrr (f_arithmatic_op ty (Opcode.Fadd)) ty x y))
(rule
(lower (has_type ty (fsub x y)))
(fpu_rrr (f_arithmatic_op ty (Opcode.Fsub)) ty x y))
(rule
(lower (has_type ty (fmul x y)))
(fpu_rrr (f_arithmatic_op ty (Opcode.Fmul)) ty x y))
(rule
(lower (has_type ty (fdiv x y)))
(fpu_rrr (f_arithmatic_op ty (Opcode.Fdiv)) ty x y))
;;;;; Rules for for float arithmetic
(rule (lower (has_type ty (fadd x y)))
(rv_fadd ty x y))
(rule (lower (has_type ty (fsub x y)))
(rv_fsub ty x y))
(rule (lower (has_type ty (fmul x y)))
(rv_fmul ty x y))
(rule (lower (has_type ty (fdiv x y)))
(rv_fdiv ty x y))
(rule
(lower (has_type ty (fmin x y)))
@ -710,13 +701,13 @@
;; Null references are represented by the constant value `0`.
(rule (lower (is_null v))
(seqz v))
(rv_seqz v))
;;;;; Rules for `is_invalid`;;;;;;;;;
;; Invalid references are represented by the constant value `-1`.
(rule (lower (is_invalid v))
(seqz (alu_rr_imm12 (AluOPRRI.Addi) v (imm12_const 1))))
(rv_seqz (rv_addi v (imm12_const 1))))
;;;;; Rules for `select`;;;;;;;;;
(rule

Loading…
Cancel
Save