annotate gcc/config/or1k/or1k.md @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 ;; Machine description for OpenRISC
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 ;; Copyright (C) 2018-2020 Free Software Foundation, Inc.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 ;; Contributed by Stafford Horne
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 ;; This file is part of GCC.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 ;; GCC is free software; you can redistribute it and/or modify it
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 ;; under the terms of the GNU General Public License as published
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 ;; by the Free Software Foundation; either version 3, or (at your
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 ;; option) any later version.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 ;; License for more details.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 ;; You should have received a copy of the GNU General Public License
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 ;; along with GCC; see the file COPYING3. If not see
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 ;; <http://www.gnu.org/licenses/>.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 ;; OpenRISC specific constraints, predicates and attributes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 (include "constraints.md")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 (include "predicates.md")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 ;; Register numbers
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 (define_constants
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 [(SP_REGNUM 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 (HFP_REGNUM 2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 (LR_REGNUM 9)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 (TLS_REGNUM 10)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 (RV_REGNUM 11)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 (PE_TMP_REGNUM 13)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 (AP_REGNUM 32)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 (SFP_REGNUM 33)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 (SR_F_REGNUM 34)]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 (define_c_enum "unspec" [
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 UNSPEC_SET_GOT
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 UNSPEC_GOT
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 UNSPEC_GOTOFF
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 UNSPEC_TPOFF
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 UNSPEC_GOTTPOFF
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 UNSPEC_TLSGD
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 UNSPEC_MSYNC
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 ])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 (define_c_enum "unspecv" [
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 UNSPECV_SET_GOT
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 UNSPECV_LL
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 UNSPECV_SC
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 ])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 ;; Instruction scheduler
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 ; Most instructions are 4 bytes long.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 (define_attr "length" "" (const_int 4))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 (define_attr "type"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 "alu,st,ld,control,multi,fpu"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 (const_string "alu"))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 (define_attr "insn_support" "class1,sext,sfimm,shftimm,ror,rori" (const_string "class1"))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 (define_attr "enabled" ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 (cond [(eq_attr "insn_support" "class1") (const_int 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 (and (eq_attr "insn_support" "sext")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 (ne (symbol_ref "TARGET_SEXT") (const_int 0))) (const_int 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 (and (eq_attr "insn_support" "sfimm")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 (ne (symbol_ref "TARGET_SFIMM") (const_int 0))) (const_int 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 (and (eq_attr "insn_support" "shftimm")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 (ne (symbol_ref "TARGET_SHFTIMM") (const_int 0))) (const_int 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 (and (eq_attr "insn_support" "ror")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 (ne (symbol_ref "TARGET_ROR") (const_int 0))) (const_int 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 (and (eq_attr "insn_support" "rori")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 (ne (symbol_ref "TARGET_RORI") (const_int 0))) (const_int 1)]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 (const_int 0)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 ;; Describe a user's asm statement.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 (define_asm_attributes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 [(set_attr "type" "multi")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 (define_automaton "or1k")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 (define_cpu_unit "cpu" "or1k")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 (define_insn_reservation "alu" 1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 (eq_attr "type" "alu")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 "cpu")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 (define_insn_reservation "st" 1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 (eq_attr "type" "st")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 "cpu")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 (define_insn_reservation "ld" 3
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 (eq_attr "type" "st")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 "cpu")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 (define_insn_reservation "control" 1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 (eq_attr "type" "control")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 "cpu")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 (define_insn_reservation "fpu" 2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 (eq_attr "type" "fpu")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 "cpu")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 ; Define delay slots for any branch
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 (define_delay (eq_attr "type" "control")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 [(eq_attr "type" "alu,st,ld") (nil) (nil)])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 ;; nop instruction
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 (define_insn "nop"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 [(const_int 0)]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 "l.nop")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 ;; Arithmetic instructions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 (define_insn "addsi3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 [(set (match_operand:SI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 (plus:SI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 (match_operand:SI 1 "register_operand" "%r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 (match_operand:SI 2 "reg_or_s16_operand" " r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 l.add\t%0, %1, %2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 l.addi\t%0, %1, %2")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 (define_insn "mulsi3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 [(set (match_operand:SI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 (mult:SI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 (match_operand:SI 1 "register_operand" "%r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 (match_operand:SI 2 "reg_or_s16_operand" " r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 "!TARGET_SOFT_MUL"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 l.mul\t%0, %1, %2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 l.muli\t%0, %1, %2")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 (define_insn "divsi3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 [(set (match_operand:SI 0 "register_operand" "=r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 (div:SI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 (match_operand:SI 1 "register_operand" "r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 (match_operand:SI 2 "register_operand" "r")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 "!TARGET_SOFT_DIV"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 "l.div\t%0, %1, %2")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 (define_insn "udivsi3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 [(set (match_operand:SI 0 "register_operand" "=r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 (udiv:SI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 (match_operand:SI 1 "register_operand" "r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 (match_operand:SI 2 "register_operand" "r")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 "!TARGET_SOFT_DIV"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 "l.divu\t%0, %1, %2")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 (define_insn "subsi3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 [(set (match_operand:SI 0 "register_operand" "=r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 (minus:SI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 (match_operand:SI 1 "reg_or_0_operand" "rO")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 (match_operand:SI 2 "register_operand" "r")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 "l.sub\t%0, %r1, %2")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 ;; Floating Point Arithmetic instructions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 ;; Mode iterator for single/double float
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 (define_mode_iterator F [(SF "TARGET_HARD_FLOAT")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 (DF "TARGET_DOUBLE_FLOAT")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 (define_mode_attr f [(SF "s") (DF "d")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 (define_mode_attr fr [(SF "r") (DF "d")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 (define_mode_attr fi [(SF "si") (DF "di")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 (define_mode_attr FI [(SF "SI") (DF "DI")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 ;; Basic arithmetic instructions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 (define_code_iterator FOP [plus minus mult div])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 (define_code_attr fop [(plus "add") (minus "sub") (mult "mul") (div "div")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 (define_insn "<fop><F:mode>3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 [(set (match_operand:F 0 "register_operand" "=<fr>")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 (FOP:F (match_operand:F 1 "register_operand" "<fr>")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 (match_operand:F 2 "register_operand" "<fr>")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 "TARGET_HARD_FLOAT"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 "lf.<fop>.<f>\t%d0, %d1, %d2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 [(set_attr "type" "fpu")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 ;; Basic float<->int conversion
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 (define_insn "float<fi><F:mode>2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 [(set (match_operand:F 0 "register_operand" "=<fr>")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 (float:F
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 (match_operand:<FI> 1 "register_operand" "<fr>")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 "TARGET_HARD_FLOAT"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 "lf.itof.<f>\t%d0, %d1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 [(set_attr "type" "fpu")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 (define_insn "fix_trunc<F:mode><fi>2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 [(set (match_operand:<FI> 0 "register_operand" "=<fr>")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 (fix:<FI>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 (match_operand:F 1 "register_operand" "<fr>")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 "TARGET_HARD_FLOAT"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 "lf.ftoi.<f>\t%d0, %d1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 [(set_attr "type" "fpu")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 ;; Logical operators
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 (define_code_iterator SHIFT [ashift ashiftrt lshiftrt])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 (define_code_attr shift_op [(ashift "ashl") (ashiftrt "ashr")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 (lshiftrt "lshr")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 (define_code_attr shift_asm [(ashift "sll") (ashiftrt "sra")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 (lshiftrt "srl")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 (define_insn "<shift_op>si3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 [(set (match_operand:SI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 (SHIFT:SI (match_operand:SI 1 "register_operand" "r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 (match_operand:SI 2 "reg_or_u6_operand" "r,n")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 l.<shift_asm>\t%0, %1, %2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 l.<shift_asm>i\t%0, %1, %2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 [(set_attr "insn_support" "*,shftimm")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 (define_insn "rotrsi3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 [(set (match_operand:SI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 (match_operand:SI 2 "ror_reg_or_u6_operand" "r,n")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 "TARGET_ROR || TARGET_RORI"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 l.ror\t%0, %1, %2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 l.rori\t%0, %1, %2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 [(set_attr "insn_support" "ror,rori")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 (define_insn "andsi3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 [(set (match_operand:SI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 (and:SI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 (match_operand:SI 1 "register_operand" "%r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 (match_operand:SI 2 "reg_or_u16_operand" " r,K")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 l.and\t%0, %1, %2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 l.andi\t%0, %1, %2")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 (define_insn "xorsi3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 [(set (match_operand:SI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 (xor:SI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 (match_operand:SI 1 "register_operand" "%r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 (match_operand:SI 2 "reg_or_s16_operand" " r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 l.xor\t%0, %1, %2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 l.xori\t%0, %1, %2")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 (define_insn "iorsi3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 [(set (match_operand:SI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 (ior:SI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 (match_operand:SI 1 "register_operand" "%r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 (match_operand:SI 2 "reg_or_u16_operand" " r,K")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 l.or\t%0, %1, %2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 l.ori\t%0, %1, %2")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 (define_expand "one_cmplsi2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 [(set (match_operand:SI 0 "register_operand" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 (xor:SI (match_operand:SI 1 "register_operand" "") (const_int -1)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 ;; Move instructions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 (define_mode_iterator I [QI HI SI])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 (define_mode_iterator I12 [QI HI])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 (define_mode_attr ldst [(QI "b") (HI "h") (SI "w")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 (define_mode_attr zext_andi [(QI "0xff") (HI "0xffff")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 (define_expand "mov<I:mode>"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 [(set (match_operand:I 0 "nonimmediate_operand" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 (match_operand:I 1 "general_operand" ""))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 or1k_expand_move (<MODE>mode, operands[0], operands[1]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 ;; 8-bit, 16-bit and 32-bit moves
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 (define_insn "*mov<I:mode>_internal"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 [(set (match_operand:I 0 "nonimmediate_operand" "=r,r,r,r, m,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 (match_operand:I 1 "input_operand" " r,M,K,I,rO,m"))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 "register_operand (operands[0], <I:MODE>mode)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 || reg_or_0_operand (operands[1], <I:MODE>mode)"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 l.or\t%0, %1, %1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301 l.movhi\t%0, hi(%1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 l.ori\t%0, r0, %1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 l.xori\t%0, r0, %1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 l.s<I:ldst>\t%0, %r1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 l.l<I:ldst>z\t%0, %1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 [(set_attr "type" "alu,alu,alu,alu,st,ld")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 ;; Hi/Low moves for constant and symbol loading
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 (define_insn "movsi_high"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 [(set (match_operand:SI 0 "register_operand" "=r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 (high:SI (match_operand:SI 1 "high_operand" "")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 "l.movhi\t%0, %h1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 [(set_attr "type" "alu")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 (define_insn "*movsi_lo_sum_iori"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 [(set (match_operand:SI 0 "register_operand" "=r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 (match_operand:SI 2 "losum_ior_operand" "")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 "l.ori\t%0, %1, %L2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 [(set_attr "type" "alu")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 (define_insn "*movsi_lo_sum_addi"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 [(set (match_operand:SI 0 "register_operand" "=r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 (match_operand:SI 2 "losum_add_operand" "")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 "l.addi\t%0, %1, %L2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 [(set_attr "type" "alu")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 ;; 64-bit moves
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 ;; ??? The clobber that emit_move_multi_word emits is arguably incorrect.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 ;; Consider gcc.c-torture/execute/20030222-1.c, where a reg-reg DImode
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 ;; move gets register allocated to a no-op move. At which point the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 ;; we actively clobber the input.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 (define_expand "movdi"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 (match_operand:DI 1 "general_operand" ""))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 if (MEM_P (operands[0]) && !const0_operand(operands[1], DImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 operands[1] = force_reg (DImode, operands[1]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 (define_insn_and_split "*movdi"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,o,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 (match_operand:DI 1 "general_operand" " r,o,rO,n"))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 "register_operand (operands[0], DImode)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352 || reg_or_0_operand (operands[1], DImode)"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 "#"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355 [(const_int 0)]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 rtx l0 = operand_subword (operands[0], 0, 0, DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 rtx l1 = operand_subword (operands[1], 0, 0, DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 rtx h0 = operand_subword (operands[0], 1, 0, DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 rtx h1 = operand_subword (operands[1], 1, 0, DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 if (reload_completed && reg_overlap_mentioned_p (l0, h1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 gcc_assert (!reg_overlap_mentioned_p (h0, l1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 emit_move_insn (h0, h1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 emit_move_insn (l0, l1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 emit_move_insn (l0, l1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 emit_move_insn (h0, h1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 ;; Sign Extending
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 ;; Zero extension can always be done with AND or an extending load.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 (define_insn "zero_extend<mode>si2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 [(set (match_operand:SI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 (zero_extend:SI (match_operand:I12 1 "reg_or_mem_operand" "r,m")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 l.andi\t%0, %1, <zext_andi>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 l.l<ldst>z\t%0, %1")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 ;; Sign extension in registers is an optional extension, but the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 ;; extending load is always available. If SEXT is not available,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 ;; force the middle-end to do the expansion to shifts.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 (define_insn "extend<mode>si2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 [(set (match_operand:SI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 (sign_extend:SI (match_operand:I12 1 "reg_or_mem_operand" "r,m")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397 "TARGET_SEXT"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 l.ext<ldst>s\t%0, %1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 l.l<ldst>s\t%0, %1")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402 (define_insn "*extend<mode>si2_mem"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 [(set (match_operand:SI 0 "register_operand" "=r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404 (sign_extend:SI (match_operand:I12 1 "memory_operand" "m")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 "l.l<ldst>s\t%0, %1")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 ;; Compare instructions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412 ;; OpenRISC supports these integer comparisons:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 ;;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 ;; l.sfeq[i] - equality, r r or r i
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 ;; l.sfne[i] - not equal, r r or r i
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 ;; l.sflt{s,u}[i] - less than, signed or unsigned, r r or r i
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 ;; l.sfle{s,u}[i] - less than or equal, signed or unsigned, r r or r i
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 ;; l.sfgt{s,u}[i] - greater than, signed or unsigned, r r or r i
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 ;; l.sfge{s,u}[i] - greater than or equal, signed or unsigned, r r or r i
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 ;;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 ;; EQ,NE,LT,LTU,LE,LEU,GT,GTU,GE,GEU
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 ;; We iterate through all of these
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 ;;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 (define_code_iterator intcmpcc [ne eq lt ltu gt gtu ge le geu leu])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 (define_code_attr insn [(ne "ne") (eq "eq") (lt "lts") (ltu "ltu")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427 (gt "gts") (gtu "gtu") (ge "ges") (le "les")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 (geu "geu") (leu "leu")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 (define_insn "*sf_insn"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431 [(set (reg:BI SR_F_REGNUM)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 (intcmpcc:BI (match_operand:SI 0 "reg_or_0_operand" "rO,rO")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 (match_operand:SI 1 "reg_or_s16_operand" "r,I")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 l.sf<insn>\t%r0, %1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 l.sf<insn>i\t%r0, %1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 [(set_attr "insn_support" "*,sfimm")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 ;; Support FP comparisons too
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442 ;; The OpenRISC FPU supports these comparisons:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443 ;;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 ;; lf.sfeq.{d,s} - equality, r r, double or single precision
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 ;; lf.sfge.{d,s} - greater than or equal, r r, double or single precision
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 ;; lf.sfgt.{d,s} - greater than, r r, double or single precision
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 ;; lf.sfle.{d,s} - less than or equal, r r, double or single precision
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 ;; lf.sflt.{d,s} - less than, r r, double or single precision
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 ;; lf.sfne.{d,s} - not equal, r r, double or single precision
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450 ;;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451 ;; Double precision is only supported on some hardware. Only register/register
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 ;; comparisons are supported. All comparisons are signed.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 (define_code_iterator fpcmpcc [ne eq lt gt ge le uneq unle unlt ungt unge
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 unordered])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 (define_code_attr fpcmpinsn [(ne "ne") (eq "eq") (lt "lt") (gt "gt") (ge "ge")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457 (le "le") (uneq "ueq") (unle "ule") (unlt "ult")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458 (ungt "ugt") (unge "uge") (unordered "un")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 (define_insn "*sf_fp_insn"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462 [(set (reg:BI SR_F_REGNUM)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 (fpcmpcc:BI (match_operand:F 0 "register_operand" "<fr>")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464 (match_operand:F 1 "register_operand" "<fr>")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465 "TARGET_HARD_FLOAT"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 "lf.sf<fpcmpinsn>.<f>\t%d0, %d1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467 [(set_attr "type" "fpu")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 ;; Conditional Store instructions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 (define_expand "cstoresi4"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475 [(set (match_operand:SI 0 "register_operand" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476 (if_then_else:SI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 (match_operator 1 "comparison_operator"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478 [(match_operand:SI 2 "reg_or_0_operand" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479 (match_operand:SI 3 "reg_or_s16_operand" "")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 (match_dup 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 (const_int 0)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 or1k_expand_compare (operands + 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485 PUT_MODE (operands[1], SImode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 emit_insn (gen_rtx_SET (operands[0], operands[1]));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 ;; Support FP cstores too
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 (define_expand "cstore<F:mode>4"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 [(set (match_operand:SI 0 "register_operand" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 (if_then_else:F
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 (match_operator 1 "fp_comparison_operator"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 [(match_operand:F 2 "register_operand" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 (match_operand:F 3 "register_operand" "")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 (match_dup 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498 (const_int 0)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499 "TARGET_HARD_FLOAT"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501 or1k_expand_compare (operands + 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 PUT_MODE (operands[1], SImode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503 emit_insn (gen_rtx_SET (operands[0], operands[1]));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507 ;; Being able to "copy" SR_F to a general register is helpful for
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508 ;; the atomic insns, wherein the usual usage is to test the success
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509 ;; of the compare-and-swap. Representing the operation in this way,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510 ;; rather than exposing the cmov immediately, allows the optimizers
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 ;; to propagate the use of SR_F directly into a branch.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 (define_expand "sne_sr_f"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 [(set (match_operand:SI 0 "register_operand" "=r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515 (ne:SI (reg:BI SR_F_REGNUM) (const_int 0)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516 "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 (define_insn_and_split "*scc"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 [(set (match_operand:SI 0 "register_operand" "=r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 (match_operator:SI 1 "equality_comparison_operator"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 [(reg:BI SR_F_REGNUM) (const_int 0)]))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523 "#"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 "reload_completed"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525 [(set (match_dup 0) (const_int 1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526 (set (match_dup 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 (if_then_else:SI (match_dup 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 (match_dup 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529 (const_int 0)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532 (define_expand "mov<I:mode>cc"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533 [(set (match_operand:I 0 "register_operand" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534 (if_then_else:I (match_operand 1 "comparison_operator" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535 (match_operand:I 2 "reg_or_0_operand" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536 (match_operand:I 3 "reg_or_0_operand" "")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 rtx xops[3] = { operands[1], XEXP (operands[1], 0), XEXP (operands[1], 1) };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540 or1k_expand_compare (xops);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541 operands[1] = xops[0];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 (define_insn_and_split "*cmov<I:mode>"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545 [(set (match_operand:I 0 "register_operand" "=r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546 (if_then_else:I
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547 (match_operator 3 "equality_comparison_operator"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548 [(reg:BI SR_F_REGNUM) (const_int 0)])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 (match_operand:I 1 "reg_or_0_operand" "rO")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550 (match_operand:I 2 "reg_or_0_operand" "rO")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 return (GET_CODE (operands[3]) == NE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 ? "l.cmov\t%0, %r1, %r2"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 : "l.cmov\t%0, %r2, %r1");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557 "!TARGET_CMOV"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558 [(const_int 0)]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560 rtx x;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561 rtx label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563 /* Generated a *cbranch pattern. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564 if (rtx_equal_p (operands[0], operands[2]))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 PUT_CODE (operands[3], (GET_CODE (operands[3]) == NE) ? EQ : NE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 x = gen_rtx_IF_THEN_ELSE (VOIDmode, operands[3], label, pc_rtx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569 emit_move_insn (operands[0], operands[1]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573 x = gen_rtx_IF_THEN_ELSE (VOIDmode, operands[3], label, pc_rtx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 emit_move_insn (operands[0], operands[1]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576 emit_move_insn (operands[0], operands[2]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579 emit_label (XEXP (label, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584 ;; Branch instructions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587 (define_expand "cbranchsi4"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588 [(set (pc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589 (if_then_else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590 (match_operator 0 "comparison_operator"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591 [(match_operand:SI 1 "reg_or_0_operand" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592 (match_operand:SI 2 "reg_or_s16_operand" "")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593 (label_ref (match_operand 3 "" ""))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594 (pc)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597 or1k_expand_compare (operands);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600 ;; Support FP branching
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602 (define_expand "cbranch<F:mode>4"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603 [(set (pc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604 (if_then_else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 (match_operator 0 "fp_comparison_operator"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606 [(match_operand:F 1 "register_operand" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607 (match_operand:F 2 "register_operand" "")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608 (label_ref (match_operand 3 "" ""))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609 (pc)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610 "TARGET_HARD_FLOAT"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612 or1k_expand_compare (operands);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615 (define_insn "*cbranch"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616 [(set (pc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617 (if_then_else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 (match_operator 1 "equality_comparison_operator"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619 [(reg:BI SR_F_REGNUM) (const_int 0)])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620 (label_ref (match_operand 0 "" ""))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621 (pc)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624 return (GET_CODE (operands[1]) == NE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625 ? "l.bf\t%0%#"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 : "l.bnf\t%0%#");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628 [(set_attr "type" "control")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631 ;; Jump instructions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634 (define_insn "jump"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635 [(set (pc) (label_ref (match_operand 0 "" "")))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 "l.j\t%0%#"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638 [(set_attr "type" "control")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640 (define_insn "indirect_jump"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643 "l.jr\t%0%#"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644 [(set_attr "type" "control")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647 ;; Prologue & Epilogue
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650 (define_expand "prologue"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651 [(const_int 1)]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654 or1k_expand_prologue ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658 ;; Expand epilogue as RTL
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659 (define_expand "epilogue"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660 [(return)]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663 or1k_expand_epilogue ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664 emit_jump_insn (gen_simple_return ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668 (define_expand "sibcall_epilogue"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669 [(return)]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672 or1k_expand_epilogue ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673 /* Placing a USE of LR here, rather than as a REG_USE on the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674 sibcall itself, means that LR is not unnecessarily live
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675 within the function itself, which would force creation of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676 a stack frame. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677 emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, LR_REGNUM)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681 (define_expand "simple_return"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682 [(parallel [(simple_return) (use (match_dup 0))])]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 operands[0] = gen_rtx_REG (Pmode, LR_REGNUM);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688 (define_insn "*simple_return"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 [(simple_return)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690 (use (match_operand:SI 0 "register_operand" "r"))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692 "l.jr\t%0%#"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693 [(set_attr "type" "control")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695 (define_expand "eh_return"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696 [(use (match_operand 0 "general_operand"))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699 or1k_expand_eh_return (operands[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703 ;; This is a placeholder, during RA, in order to create the PIC regiter.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704 ;; We do this so that we don't unconditionally mark the LR register as
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705 ;; clobbered. It is replaced during prologue generation with the proper
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706 ;; set_got pattern below. This works because the set_got_tmp insn is the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707 ;; first insn in the stream and that it isn't moved during RA.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708 (define_insn "set_got_tmp"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709 [(set (match_operand:SI 0 "register_operand" "=t")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710 (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_GOT))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716 ;; The insn to initialize the GOT.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717 (define_insn "set_got"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718 [(set (match_operand:SI 0 "register_operand" "=t")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720 (clobber (reg:SI LR_REGNUM))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
722 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
723 return ("l.jal\t8\;"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
724 " l.movhi\t%0, gotpchi(_GLOBAL_OFFSET_TABLE_-4)\;"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
725 "l.ori\t%0, %0, gotpclo(_GLOBAL_OFFSET_TABLE_+0)\;"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
726 "l.add\t%0, %0, r9");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
727 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
728 [(set_attr "length" "16")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
729 (set_attr "type" "multi")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
730
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
731 ;; Block memory operations from being scheduled across frame (de)allocation.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
732 (define_insn "frame_addsi3"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
733 [(set (match_operand:SI 0 "register_operand" "=r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
734 (plus:SI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
735 (match_operand:SI 1 "register_operand" "%r,r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
736 (match_operand:SI 2 "reg_or_s16_operand" " r,I")))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
737 (clobber (mem:BLK (scratch)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
738 "reload_completed"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
739 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
740 l.add\t%0, %1, %2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
741 l.addi\t%0, %1, %2")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
742
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
743 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
744 ;; Atomic Operations
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
745 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
746
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
747 ;; Note that MULT stands in for the non-existant NAND rtx_code.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
748 (define_code_iterator FETCHOP [plus minus ior xor and mult])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
749
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
750 (define_code_attr fetchop_name
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
751 [(plus "add")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
752 (minus "sub")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
753 (ior "or")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
754 (xor "xor")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
755 (and "and")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
756 (mult "nand")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
757
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
758 (define_code_attr fetchop_pred
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
759 [(plus "reg_or_s16_operand")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
760 (minus "register_operand")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
761 (ior "reg_or_u16_operand")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
762 (xor "reg_or_s16_operand")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
763 (and "reg_or_u16_operand")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
764 (mult "reg_or_u16_operand")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
765
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
766 (define_expand "mem_thread_fence"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
767 [(match_operand:SI 0 "const_int_operand" "")] ;; model
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
768 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
769 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
770 memmodel model = memmodel_base (INTVAL (operands[0]));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
771 if (model != MEMMODEL_RELAXED)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
772 emit_insn (gen_msync ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
773 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
774 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
775
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
776 (define_expand "msync"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
777 [(set (match_dup 0) (unspec:BLK [(match_dup 0)] UNSPEC_MSYNC))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
778 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
779 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
780 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
781 MEM_VOLATILE_P (operands[0]) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
782 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
783
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
784 (define_insn "*msync"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
785 [(set (match_operand:BLK 0 "" "")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
786 (unspec:BLK [(match_dup 0)] UNSPEC_MSYNC))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
787 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
788 "l.msync")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
789
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
790 (define_insn "load_locked_si"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
791 [(set (match_operand:SI 0 "register_operand" "=r")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
792 (unspec_volatile:SI
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
793 [(match_operand:SI 1 "memory_operand" "m")] UNSPECV_LL))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
794 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
795 "l.lwa\t%0,%1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
796 [(set_attr "type" "ld")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
797
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
798 (define_insn "store_conditional_si"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
799 [(set (reg:BI SR_F_REGNUM)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
800 (unspec_volatile:BI [(const_int 0)] UNSPECV_SC))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
801 (set (match_operand:SI 0 "memory_operand" "=m")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
802 (match_operand:SI 1 "reg_or_0_operand" "rO"))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
803 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
804 "l.swa\t%0,%r1"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
805 [(set_attr "type" "st")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
806
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
807 (define_expand "atomic_compare_and_swapsi"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
808 [(match_operand:SI 0 "register_operand") ;; bool output
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
809 (match_operand:SI 1 "register_operand") ;; val output
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
810 (match_operand:SI 2 "memory_operand") ;; memory
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
811 (match_operand:SI 3 "reg_or_s16_operand") ;; expected
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
812 (match_operand:SI 4 "reg_or_0_operand") ;; desired
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
813 (match_operand:SI 5 "const_int_operand") ;; is_weak
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
814 (match_operand:SI 6 "const_int_operand") ;; mod_s
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
815 (match_operand:SI 7 "const_int_operand")] ;; mod_f
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
816 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
817 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
818 or1k_expand_atomic_compare_and_swap (operands);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
819 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
820 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
821
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
822 (define_expand "atomic_compare_and_swap<mode>"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
823 [(match_operand:SI 0 "register_operand") ;; bool output
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
824 (match_operand:I12 1 "register_operand") ;; val output
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
825 (match_operand:I12 2 "memory_operand") ;; memory
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
826 (match_operand:I12 3 "register_operand") ;; expected
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
827 (match_operand:I12 4 "reg_or_0_operand") ;; desired
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
828 (match_operand:SI 5 "const_int_operand") ;; is_weak
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
829 (match_operand:SI 6 "const_int_operand") ;; mod_s
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
830 (match_operand:SI 7 "const_int_operand")] ;; mod_f
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
831 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
832 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
833 or1k_expand_atomic_compare_and_swap_qihi (operands);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
834 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
835 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
836
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
837 (define_expand "atomic_exchangesi"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
838 [(match_operand:SI 0 "register_operand") ;; output
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
839 (match_operand:SI 1 "memory_operand") ;; memory
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
840 (match_operand:SI 2 "reg_or_0_operand") ;; input
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
841 (match_operand:SI 3 "const_int_operand")] ;; model
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
842 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
843 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
844 or1k_expand_atomic_exchange (operands);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
845 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
846 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
847
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
848 (define_expand "atomic_exchange<mode>"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
849 [(match_operand:I12 0 "register_operand") ;; output
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
850 (match_operand:I12 1 "memory_operand") ;; memory
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
851 (match_operand:I12 2 "reg_or_0_operand") ;; input
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
852 (match_operand:SI 3 "const_int_operand")] ;; model
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
853 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
854 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
855 or1k_expand_atomic_exchange_qihi (operands);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
856 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
857 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
858
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
859 (define_expand "atomic_<fetchop_name>si"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
860 [(match_operand:SI 0 "memory_operand") ;; memory
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
861 (FETCHOP:SI (match_dup 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
862 (match_operand:SI 1 "<fetchop_pred>")) ;; operand
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
863 (match_operand:SI 2 "const_int_operand")] ;; model
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
864 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
865 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
866 or1k_expand_atomic_op (<CODE>, operands[0], operands[1], NULL, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
867 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
868 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
869
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
870 (define_expand "atomic_<fetchop_name><mode>"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
871 [(match_operand:I12 0 "memory_operand") ;; memory
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
872 (FETCHOP:I12 (match_dup 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
873 (match_operand:I12 1 "register_operand")) ;; operand
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
874 (match_operand:SI 2 "const_int_operand")] ;; model
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
875 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
876 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
877 or1k_expand_atomic_op_qihi (<CODE>, operands[0], operands[1], NULL, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
878 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
879 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
880
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
881 (define_expand "atomic_fetch_<fetchop_name>si"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
882 [(match_operand:SI 0 "register_operand" "") ;; output
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
883 (match_operand:SI 1 "memory_operand" "") ;; memory
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
884 (FETCHOP:SI (match_dup 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
885 (match_operand:SI 2 "<fetchop_pred>" "")) ;; operand
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
886 (match_operand:SI 3 "const_int_operand" "")] ;; model
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
887 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
888 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
889 or1k_expand_atomic_op (<CODE>, operands[1], operands[2], operands[0], NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
890 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
891 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
892
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
893 (define_expand "atomic_fetch_<fetchop_name><mode>"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
894 [(match_operand:I12 0 "register_operand" "") ;; output
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
895 (match_operand:I12 1 "memory_operand" "") ;; memory
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
896 (FETCHOP:I12 (match_dup 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
897 (match_operand:I12 2 "<fetchop_pred>" "")) ;; operand
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
898 (match_operand:SI 3 "const_int_operand" "")] ;; model
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
899 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
900 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
901 or1k_expand_atomic_op_qihi (<CODE>, operands[1], operands[2],
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
902 operands[0], NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
903 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
904 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
905
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
906 (define_expand "atomic_<fetchop_name>_fetchsi"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
907 [(match_operand:SI 0 "register_operand" "") ;; output
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
908 (match_operand:SI 1 "memory_operand" "") ;; memory
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
909 (FETCHOP:SI (match_dup 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
910 (match_operand:SI 2 "<fetchop_pred>" "")) ;; operand
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
911 (match_operand:SI 3 "const_int_operand" "")] ;; model
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
912 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
913 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
914 or1k_expand_atomic_op (<CODE>, operands[1], operands[2], NULL, operands[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
915 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
916 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
917
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
918 (define_expand "atomic_<fetchop_name>_fetch<mode>"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
919 [(match_operand:I12 0 "register_operand" "") ;; output
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
920 (match_operand:I12 1 "memory_operand" "") ;; memory
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
921 (FETCHOP:I12 (match_dup 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
922 (match_operand:I12 2 "<fetchop_pred>" "")) ;; operand
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
923 (match_operand:SI 3 "const_int_operand" "")] ;; model
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
924 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
925 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
926 or1k_expand_atomic_op_qihi (<CODE>, operands[1], operands[2],
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
927 NULL, operands[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
928 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
929 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
930
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
931 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
932 ;; Call Instructions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
933 ;; -------------------------------------------------------------------------
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
934
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
935 ;; Leave these to last, as the modeless operand for call_value
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
936 ;; interferes with normal patterns.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
937
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
938 (define_expand "call"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
939 [(call (match_operand 0) (match_operand 1))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
940 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
941 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
942 or1k_expand_call (NULL, operands[0], operands[1], false);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
943 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
944 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
945
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
946 (define_expand "sibcall"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
947 [(call (match_operand 0) (match_operand 1))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
948 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
949 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
950 or1k_expand_call (NULL, operands[0], operands[1], true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
951 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
952 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
953
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
954 (define_expand "call_value"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
955 [(set (match_operand 0) (call (match_operand 1) (match_operand 2)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
956 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
957 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
958 or1k_expand_call (operands[0], operands[1], operands[2], false);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
959 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
960 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
961
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
962 (define_expand "sibcall_value"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
963 [(set (match_operand 0) (call (match_operand 1) (match_operand 2)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
964 ""
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
965 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
966 or1k_expand_call (operands[0], operands[1], operands[2], true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
967 DONE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
968 })
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
969
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
970 (define_insn "*call"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
971 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "r,s"))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
972 (match_operand 1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
973 (clobber (reg:SI LR_REGNUM))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
974 "!SIBLING_CALL_P (insn)"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
975 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
976 l.jalr\t%0%#
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
977 l.jal\t%P0%#"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
978 [(set_attr "type" "control")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
979
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
980 (define_insn "*sibcall"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
981 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "c,s"))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
982 (match_operand 1))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
983 "SIBLING_CALL_P (insn)"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
984 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
985 l.jr\t%0%#
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
986 l.j\t%P0%#"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
987 [(set_attr "type" "control")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
988
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
989 (define_insn "*call_value"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
990 [(set (match_operand 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
991 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "r,s"))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
992 (match_operand 2)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
993 (clobber (reg:SI LR_REGNUM))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
994 "!SIBLING_CALL_P (insn)"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
995 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
996 l.jalr\t%1%#
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
997 l.jal\t%P1%#"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
998 [(set_attr "type" "control")])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
999
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1000 (define_insn "*sibcall_value"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1001 [(set (match_operand 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1002 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "c,s"))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1003 (match_operand 2)))]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1004 "SIBLING_CALL_P (insn)"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1005 "@
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1006 l.jr\t%1%#
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1007 l.j\t%P1%#"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1008 [(set_attr "type" "control")])