;; Constraint definitions for LoongArch. ;; Copyright (C) 2021-2022 Free Software Foundation, Inc. ;; Contributed by Loongson Ltd. ;; ;; This file is part of GCC. ;; ;; GCC is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3, or (at your option) ;; any later version. ;; ;; GCC is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with GCC; see the file COPYING3. If not see ;; http://www.gnu.org/licenses/.

;; Register constraints

;; “a” <-----unused ;; “b” “A constant call not local address.” ;; “c” “A constant call local address.” ;; “d” <-----unused ;; “e” JIRL_REGS ;; “f” FP_REGS ;; “g” <-----unused ;; “h” <-----unused ;; “i” “Matches a general integer constant.” (Global non-architectural) ;; “j” SIBCALL_REGS ;; “k” “A memory operand whose address is formed by a base register and ;; (optionally scaled) index register.” ;; “l” “A signed 16-bit constant.” ;; “m” “A memory operand whose address is formed by a base register and offset ;; that is suitable for use in instructions with the same addressing mode ;; as @code{st.w} and @code{ld.w}.” ;; “n” “Matches a non-symbolic integer constant.” (Global non-architectural) ;; “o” “Matches an offsettable memory reference.” (Global non-architectural) ;; “p” “Matches a general address.” (Global non-architectural) ;; “q” CSR_REGS ;; “r” GENERAL_REGS (Global non-architectural) ;; “s” “Matches a symbolic integer constant.” (Global non-architectural) ;; “t” <-----unused ;; “u” “A signed 52bit constant and low 32-bit is zero (for logic instructions)” ;; “v” “A signed 64-bit constant and low 44-bit is zero (for logic instructions).” ;; “w” “Matches any valid memory.” ;; “x” <-----unused ;; “y” <-----unused ;; “z” FCC_REGS ;; “A” <-----unused ;; “B” <-----unused ;; “C” <-----unused ;; “D” <-----unused ;; “E” “Matches a floating-point constant.” (Global non-architectural) ;; “F” “Matches a floating-point constant.” (Global non-architectural) ;; “G” “Floating-point zero.” ;; “H” <-----unused ;; “I” “A signed 12-bit constant (for arithmetic instructions).” ;; “J” “Integer zero.” ;; “K” “An unsigned 12-bit constant (for logic instructions).” ;; “L” <-----unused ;; “M” <-----unused ;; “N” <-----unused ;; “O” <-----unused ;; “P” <-----unused ;; “Q” <-----unused ;; “R” <-----unused ;; “S” <-----unused ;; “T” <-----unused ;; “U” <-----unused ;; “V” “Matches a non-offsettable memory reference.” (Global non-architectural) ;; “W” <-----unused ;; “X” “Matches anything.” (Global non-architectural) ;; “Y” - ;; “Yd” ;; “A constant @code{move_operand} that can be safely loaded using ;; @code{la}.” ;; “Yx” ;; “Z” - ;; “ZC” ;; “A memory operand whose address is formed by a base register and offset ;; that is suitable for use in instructions with the same addressing mode ;; as @code{ll.w} and @code{sc.w}.” ;; “ZB” ;; “An address that is held in a general-purpose register. ;; The offset is zero” ;; “ZD” ;; “An address operand whose address is formed by a base register ;; and offset that is suitable for use in instructions with the same ;; addressing mode as @code{preld}.” ;; “<” “Matches a pre-dec or post-dec operand.” (Global non-architectural) ;; “>” “Matches a pre-inc or post-inc operand.” (Global non-architectural)

(define_constraint “b” “@internal A constant call no local address.” (match_operand 0 “is_const_call_no_local_symbol”))

(define_constraint “c” “@internal A constant call local address.” (match_operand 0 “is_const_call_local_symbol”))

(define_register_constraint “e” “JIRL_REGS” “@internal”)

(define_register_constraint “f” “TARGET_HARD_FLOAT ? FP_REGS : NO_REGS” “A floating-point register (if available).”)

(define_register_constraint “j” “SIBCALL_REGS” “@internal”)

(define_memory_constraint “k” “A memory operand whose address is formed by a base register and (optionally scaled) index register.” (and (match_code “mem”) (match_test “loongarch_base_index_address_p (XEXP (op, 0), mode)”)))

(define_constraint “l” “A signed 16-bit constant.” (and (match_code “const_int”) (match_test “IMM16_OPERAND (ival)”)))

(define_memory_constraint “m” “A memory operand whose address is formed by a base register and offset that is suitable for use in instructions with the same addressing mode as @code{st.w} and @code{ld.w}.” (and (match_code “mem”) (match_test “loongarch_12bit_offset_address_p (XEXP (op, 0), mode)”)))

(define_register_constraint “q” “CSR_REGS” “A general-purpose register except for $r0 and $r1 for lcsr.”)

(define_constraint “u” “A signed 52bit constant and low 32-bit is zero (for logic instructions).” (and (match_code “const_int”) (match_test “LU32I_OPERAND (ival)”)))

(define_constraint “v” “A signed 64-bit constant and low 44-bit is zero (for logic instructions).” (and (match_code “const_int”) (match_test “LU52I_OPERAND (ival)”)))

(define_register_constraint “z” “FCC_REGS” “A floating-point condition code register.”)

;; Floating-point constraints

(define_constraint “G” “Floating-point zero.” (and (match_code “const_double”) (match_test “op == CONST0_RTX (mode)”)))

;; Integer constraints

(define_constraint “I” “A signed 12-bit constant (for arithmetic instructions).” (and (match_code “const_int”) (match_test “IMM12_OPERAND (ival)”)))

(define_constraint “J” “Integer zero.” (and (match_code “const_int”) (match_test “ival == 0”)))

(define_constraint “K” “An unsigned 12-bit constant (for logic instructions).” (and (match_code “const_int”) (match_test “IMM12_OPERAND_UNSIGNED (ival)”)))

(define_constraint “Yd” “@internal A constant @code{move_operand} that can be safely loaded using @code{la}.” (and (match_operand 0 “move_operand”) (match_test “CONSTANT_P (op)”)))

(define_constraint “Yx” “@internal” (match_operand 0 “low_bitmask_operand”))

(define_memory_constraint “ZC” “A memory operand whose address is formed by a base register and offset that is suitable for use in instructions with the same addressing mode as @code{ll.w} and @code{sc.w}.” (and (match_code “mem”) (match_test “loongarch_14bit_shifted_offset_address_p (XEXP (op, 0), mode)”)))

(define_memory_constraint “ZB” “@internal An address that is held in a general-purpose register. The offset is zero” (and (match_code “mem”) (match_test “REG_P (XEXP (op, 0))”)))

(define_address_constraint “ZD” “An address operand whose address is formed by a base register and offset that is suitable for use in instructions with the same addressing mode as @code{preld}.” (match_test “loongarch_12bit_offset_address_p (op, mode)”))