;; aarch64 instruction selection and CLIF-to-MachInst lowering. ;; The main lowering constructor term: takes a clif `Inst` and returns the ;; register(s) within which the lowered instruction's result values live. (decl lower (Inst) ValueRegs) ;;;; Rules for `iconst` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (rule (lower (has_type ty (iconst (u64_from_imm64 n)))) (value_reg (imm ty n))) ;;;; Rules for `bconst` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (rule (lower (has_type ty (bconst $false))) (value_reg (imm ty 0))) (rule (lower (has_type ty (bconst $true))) (value_reg (imm ty 1))) ;;;; Rules for `null` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (rule (lower (has_type ty (null))) (value_reg (imm ty 0))) ;;;; Rules for `iadd` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; `i64` and smaller ;; Base case, simply adding things in registers. (rule (lower (has_type (fits_in_64 ty) (iadd x y))) (value_reg (alu_rrr (iadd_op ty) (put_in_reg x) (put_in_reg y)))) ;; Special cases for when one operand is an immediate that fits in 12 bits. (rule (lower (has_type (fits_in_64 ty) (iadd x (imm12_from_value y)))) (value_reg (alu_rr_imm12 (iadd_op ty) (put_in_reg x) y))) (rule (lower (has_type (fits_in_64 ty) (iadd (imm12_from_value x) y))) (value_reg (alu_rr_imm12 (iadd_op ty) (put_in_reg y) x))) ;; Same as the previous special cases, except we can switch the addition to a ;; subtraction if the negated immediate fits in 12 bits. (rule (lower (has_type (fits_in_64 ty) (iadd x (imm12_from_negated_value y)))) (value_reg (alu_rr_imm12 (isub_op ty) (put_in_reg x) y))) (rule (lower (has_type (fits_in_64 ty) (iadd (imm12_from_negated_value x) y))) (value_reg (alu_rr_imm12 (isub_op ty) (put_in_reg y) x))) ;; Special cases for when we're adding an extended register where the extending ;; operation can get folded into the add itself. (rule (lower (has_type (fits_in_64 ty) (iadd x (extended_value_from_value y)))) (value_reg (alu_rr_extend_reg (iadd_op ty) (put_in_reg x) y))) (rule (lower (has_type (fits_in_64 ty) (iadd (extended_value_from_value x) y))) (value_reg (alu_rr_extend_reg (iadd_op ty) (put_in_reg y) x))) ;; Special cases for when we're adding the shift of a different ;; register by a constant amount and the shift can get folded into the add. (rule (lower (has_type (fits_in_64 ty) (iadd x (def_inst (ishl y (def_inst (iconst (lshl_from_imm64