1 ;; Machine Description for TI MSP43* processors
2 ;; Copyright (C) 2013-2025 Free Software Foundation, Inc.
3 ;; Contributed by Red Hat.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 (define_predicate "msp430_volatile_memory_operand"
22 (and (match_code "mem")
23 (match_test ("memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0), MEM_ADDR_SPACE (op))")))
26 ; TRUE if neither op nor op0 are a post_inc. We cannot use post_inc for the
27 ; dst operand so this must be used for any predicates which might allow a mem.
28 ; Since we check both op and op0, this will be FALSE for both "(post_inc)" and
30 (define_predicate "msp430_nonpostinc_operand"
31 (not (ior (match_code "post_inc")
32 (and (ior (match_operand 0 "msp430_volatile_memory_operand")
34 (match_code "post_inc" "0")))))
36 ; TRUE for any valid general operand. We do this because
37 ; general_operand refuses to match volatile memory refs.
38 (define_predicate "msp430_general_operand"
39 (ior (match_operand 0 "general_operand")
40 (match_operand 0 "msp430_volatile_memory_operand"))
43 ; Likewise for nonimmediate_operand.
44 (define_predicate "msp430_nonimmediate_operand"
45 (ior (match_operand 0 "nonimmediate_operand")
46 (match_operand 0 "msp430_volatile_memory_operand"))
49 ; Similar to msp430_nonimmediate_operand but disallow post_inc operands
50 (define_predicate "msp430_general_dst_operand"
51 (and (match_operand 0 "msp430_nonpostinc_operand")
52 (match_operand 0 "msp430_nonimmediate_operand")))
54 ; Similar to msp430_general_dst_operand but disallow volatile memory references
55 ; Note that msp430_nonpostinc_operand will allow a volatile mem but nonimmediate
56 ; will not, so overall this predicate will behave as expected.
57 ; The heuristic for deciding if we can allow volatile memory appears to be:
58 ; "If the number of references to the variable in the source code matches
59 ; the number of references to the variable in the assembly template, we can
60 ; safely allow a volatile memory reference".
61 ; - paraphrasing DJ Delorie here:
62 ; https://gcc.gnu.org/ml/gcc-patches/2014-05/msg00870.html
63 ; When applied to instruction patterns, this means that we can only allow
64 ; volatile memory when the output assembler template contains only one
65 ; instruction which references that volatile address.
66 (define_predicate "msp430_general_dst_nonv_operand"
67 (and (match_operand 0 "msp430_nonpostinc_operand")
68 (match_operand 0 "nonimmediate_operand")))
70 (define_predicate "ubyte_operand"
71 (and (match_code "const_int")
72 (match_test "IN_RANGE (INTVAL (op), 0, 255)")))
74 ; TRUE for comparisons we support.
75 (define_predicate "msp430_cmp_operator"
76 (match_code "eq,ne,lt,ltu,ge,geu"))
78 ; TRUE for comparisons we need to reverse.
79 (define_predicate "msp430_reversible_cmp_operator"
80 (match_code "gt,gtu,le,leu"))
82 ; TRUE for constants the constant generator can produce
83 (define_predicate "msp430_constgen_operator"
84 (and (match_code "const_int")
85 (match_test (" INTVAL (op) == 0
90 || INTVAL (op) == -1 "))))
92 ; TRUE for constants the constant generator can produce
93 (define_predicate "msp430_inv_constgen_operator"
94 (and (match_code "const_int")
95 (match_test (" INTVAL (op) == ~0
100 || INTVAL (op) == ~(-1) "))))
102 ; See above note on post_inc
103 (define_predicate "msp430_nonsubreg_dst_operand"
104 (and (match_operand 0 "msp430_nonpostinc_operand")
105 (match_code "reg,mem")))
107 (define_predicate "msp430_nonsubreg_or_imm_operand"
108 (ior (match_code "reg,mem")
109 (match_operand 0 "immediate_operand")))
111 (define_predicate "msp430_nonsubregnonpostinc_or_imm_operand"
112 (and (match_operand 0 "msp430_nonpostinc_operand")
113 (ior (match_code "reg,mem")
114 (match_operand 0 "immediate_operand"))))
116 (define_predicate "const_1_to_8_operand"
117 (and (match_code "const_int")
118 (match_test (" INTVAL (op) >= 1
119 && INTVAL (op) <= 8 "))))
121 (define_predicate "const_0_to_15_operand"
122 (and (match_code "const_int")
123 (match_test (" INTVAL (op) >= 0
124 && INTVAL (op) <= 15 "))))
126 (define_predicate "const_1_to_19_operand"
127 (and (match_code "const_int")
128 (match_test (" INTVAL (op) >= 1
129 && INTVAL (op) <= 19 "))))
131 (define_predicate "msp430_symbol_operand"
132 (match_code "symbol_ref")
135 ; Used in length attribute tests - if a source operand is a reg,
136 ; (mem (post_inc)), or (mem (reg)) then it is cheap compared to other operand
138 (define_predicate "msp430_cheap_operand"
139 (ior (match_code "reg")
140 (and (match_code "mem")
141 (ior (match_code "reg" "0")
142 (match_code "post_inc" "0")))))
144 ; Used for insn attributes only. For insn patterns themselves, use constraints.
145 (define_predicate "msp430_high_memory_operand"
146 (match_test "msp430x_insn_required (op)"))