xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/msp430/predicates.md (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1;;  Machine Description for TI MSP43* processors
2;;  Copyright (C) 2013-2020 Free Software Foundation, Inc.
3;;  Contributed by Red Hat.
4
5;; This file is part of GCC.
6
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)
10;; any later version.
11
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.
16
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/>.
20
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))")))
24)
25
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
29; "(mem (post_inc))"
30(define_predicate "msp430_nonpostinc_operand"
31  (not (ior (match_code "post_inc")
32	    (and (ior (match_operand 0 "msp430_volatile_memory_operand")
33		      (match_code "mem"))
34		 (match_code "post_inc" "0")))))
35
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"))
41)
42
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"))
47)
48
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")))
53
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")))
69
70(define_predicate "ubyte_operand"
71  (and (match_code "const_int")
72       (match_test "IN_RANGE (INTVAL (op), 0, 255)")))
73
74; TRUE for comparisons we support.
75(define_predicate "msp430_cmp_operator"
76  (match_code "eq,ne,lt,ltu,ge,geu"))
77
78; TRUE for comparisons we need to reverse.
79(define_predicate "msp430_reversible_cmp_operator"
80  (match_code "gt,gtu,le,leu"))
81
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
86		     || INTVAL (op) == 1
87		     || INTVAL (op) == 2
88		     || INTVAL (op) == 4
89		     || INTVAL (op) == 8
90		     || INTVAL (op) == -1 "))))
91
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
96		     || INTVAL (op) == ~1
97		     || INTVAL (op) == ~2
98		     || INTVAL (op) == ~4
99		     || INTVAL (op) == ~8
100		     || INTVAL (op) == ~(-1) "))))
101
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")))
106
107(define_predicate "msp430_nonsubreg_or_imm_operand"
108  (ior (match_code "reg,mem")
109       (match_operand 0 "immediate_operand")))
110
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"))))
115
116; TRUE for constants which are bit positions for zero_extract
117(define_predicate "msp430_bitpos"
118  (and (match_code "const_int")
119       (match_test ("   INTVAL (op) >= 0
120		     && INTVAL (op) <= 15 "))))
121
122(define_predicate "msp430_symbol_operand"
123  (match_code "symbol_ref")
124)
125