annotate gcc/config/cr16/cr16.md @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ;; GCC machine description for CR16.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 ;; Copyright (C) 2012-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 ;; Contributed by KPIT Cummins Infosystems Limited.
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 ;; This file is part of GCC.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 ;; GCC is free software; you can redistribute it and/or modify it
kono
parents:
diff changeset
8 ;; under the terms of the GNU General Public License as published by
kono
parents:
diff changeset
9 ;; the Free Software Foundation; either version 3, or (at your option)
kono
parents:
diff changeset
10 ;; any later version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
kono
parents:
diff changeset
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
kono
parents:
diff changeset
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
kono
parents:
diff changeset
15 ;; License for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 ;; You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
18 ;; along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
19 ;; <http://www.gnu.org/licenses/>.
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 ;; Register numbers
kono
parents:
diff changeset
22 (define_constants
kono
parents:
diff changeset
23 [(SP_REGNUM 15); Stack pointer
kono
parents:
diff changeset
24 (RA_REGNUM 14); Return address
kono
parents:
diff changeset
25 ]
kono
parents:
diff changeset
26 )
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 ;; Predicates & Constraints
kono
parents:
diff changeset
29 (include "predicates.md")
kono
parents:
diff changeset
30 (include "constraints.md")
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 ;; UNSPEC usage
kono
parents:
diff changeset
33 (define_constants
kono
parents:
diff changeset
34 [(UNSPEC_PIC_ADDR 0)
kono
parents:
diff changeset
35 (UNSPEC_PIC_LOAD_ADDR 1)
kono
parents:
diff changeset
36 (UNSPEC_LIBRARY_OFFSET 2)
kono
parents:
diff changeset
37 (UNSPEC_SH_LIB_PUSH_R12 3)
kono
parents:
diff changeset
38 (UNSPEC_SH_LIB_POP_R12 4)
kono
parents:
diff changeset
39 (UNSPEC_RETURN_ADDR 5)
kono
parents:
diff changeset
40 ]
kono
parents:
diff changeset
41 )
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 ;; Attributes
kono
parents:
diff changeset
44 (define_attr "length" "" (const_int 2))
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 (define_asm_attributes
kono
parents:
diff changeset
47 [(set_attr "length" "2")]
kono
parents:
diff changeset
48 )
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 ;; Mode Macro Definitions
kono
parents:
diff changeset
51 (define_mode_iterator CR16IM [QI HI SI])
kono
parents:
diff changeset
52 (define_mode_iterator LONG [SI SF])
kono
parents:
diff changeset
53 (define_mode_iterator ALLMTD [QI HI SI SF DI DF])
kono
parents:
diff changeset
54 (define_mode_iterator DOUBLE [DI DF])
kono
parents:
diff changeset
55 (define_mode_iterator SHORT [QI HI])
kono
parents:
diff changeset
56 (define_mode_attr tIsa [(QI "b") (HI "w") (SI "d") (SF "d")])
kono
parents:
diff changeset
57 (define_mode_attr lImmArith [(QI "4") (HI "4") (SI "6") (SF "6")])
kono
parents:
diff changeset
58 (define_mode_attr lImmArithD [(QI "4") (HI "4") (SI "6") (SF "6") (DI "12") (DF "12")])
kono
parents:
diff changeset
59 (define_mode_attr iF [(QI "i") (HI "i") (SI "i") (SF "F")])
kono
parents:
diff changeset
60 (define_mode_attr iFD [(DI "i") (DF "F")])
kono
parents:
diff changeset
61 (define_mode_attr LL [(QI "L") (HI "L")])
kono
parents:
diff changeset
62 (define_mode_attr shImmBits [(QI "3") (HI "4") (SI "5")])
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 ; In QI mode we push 2 bytes instead of 1 byte.
kono
parents:
diff changeset
65 (define_mode_attr pushCnstr [(QI "X") (HI "<") (SI "<") (SF "<") (DI "<") (DF "<")])
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 ; tpush will be used to generate the 'number of registers to push' in the
kono
parents:
diff changeset
68 ; push instruction.
kono
parents:
diff changeset
69 (define_mode_attr tpush [(QI "1") (HI "1") (SI "2") (SF "2") (DI "4") (DF "4")])
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 ;; Code Macro Definitions
kono
parents:
diff changeset
72 (define_code_attr sIsa [(sign_extend "") (zero_extend "u")])
kono
parents:
diff changeset
73 (define_code_attr sPat [(sign_extend "s") (zero_extend "u")])
kono
parents:
diff changeset
74 (define_code_attr szPat [(sign_extend "") (zero_extend "zero_")])
kono
parents:
diff changeset
75 (define_code_attr szIsa [(sign_extend "x") (zero_extend "z")])
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 (define_code_iterator sz_xtnd [ sign_extend zero_extend])
kono
parents:
diff changeset
78 (define_code_iterator any_cond [eq ne gt gtu lt ltu ge geu le leu])
kono
parents:
diff changeset
79 (define_code_iterator plusminus [plus minus])
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
kono
parents:
diff changeset
82 (define_code_attr plusminus_flag [(plus "PLUS") (minus "MINUS")])
kono
parents:
diff changeset
83 (define_code_attr comm [(plus "%") (minus "")])
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 (define_code_iterator any_logic [and ior xor])
kono
parents:
diff changeset
86 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
kono
parents:
diff changeset
87 (define_code_attr any_logic_insn [(and "and") (ior "ior") (xor "xor")])
kono
parents:
diff changeset
88 (define_code_attr any_logic_flag [(and "AND") (ior "IOR") (xor "XOR")])
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 (define_mode_iterator QH [QI HI])
kono
parents:
diff changeset
91 (define_mode_attr qh [(QI "qi") (HI "hi")])
kono
parents:
diff changeset
92 (define_mode_attr QHsz [(QI "2,2,2") (HI "2,2,4")])
kono
parents:
diff changeset
93 (define_mode_attr QHsuffix [(QI "b") (HI "w")])
kono
parents:
diff changeset
94
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 ;; Function Prologue and Epilogue
kono
parents:
diff changeset
97 (define_expand "prologue"
kono
parents:
diff changeset
98 [(const_int 0)]
kono
parents:
diff changeset
99 ""
kono
parents:
diff changeset
100 {
kono
parents:
diff changeset
101 cr16_expand_prologue ();
kono
parents:
diff changeset
102 DONE;
kono
parents:
diff changeset
103 }
kono
parents:
diff changeset
104 )
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 (define_insn "push_for_prologue"
kono
parents:
diff changeset
107 [(set (reg:SI SP_REGNUM)
kono
parents:
diff changeset
108 (minus:SI (reg:SI SP_REGNUM)
kono
parents:
diff changeset
109 (match_operand:SI 0 "immediate_operand" "i")))]
kono
parents:
diff changeset
110 "reload_completed"
kono
parents:
diff changeset
111 {
kono
parents:
diff changeset
112 return cr16_prepare_push_pop_string (0);
kono
parents:
diff changeset
113 }
kono
parents:
diff changeset
114 [(set_attr "length" "4")]
kono
parents:
diff changeset
115 )
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 (define_expand "epilogue"
kono
parents:
diff changeset
118 [(return)]
kono
parents:
diff changeset
119 ""
kono
parents:
diff changeset
120 {
kono
parents:
diff changeset
121 cr16_expand_epilogue ();
kono
parents:
diff changeset
122 DONE;
kono
parents:
diff changeset
123 }
kono
parents:
diff changeset
124 )
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 (define_insn "pop_and_popret_return"
kono
parents:
diff changeset
127 [(set (reg:SI SP_REGNUM)
kono
parents:
diff changeset
128 (plus:SI (reg:SI SP_REGNUM)
kono
parents:
diff changeset
129 (match_operand:SI 0 "immediate_operand" "i")))
kono
parents:
diff changeset
130 (use (reg:SI RA_REGNUM))
kono
parents:
diff changeset
131 (return)]
kono
parents:
diff changeset
132 "reload_completed"
kono
parents:
diff changeset
133 {
kono
parents:
diff changeset
134 return cr16_prepare_push_pop_string (1);
kono
parents:
diff changeset
135 }
kono
parents:
diff changeset
136 [(set_attr "length" "4")]
kono
parents:
diff changeset
137 )
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139 (define_insn "popret_RA_return"
kono
parents:
diff changeset
140 [(use (reg:SI RA_REGNUM))
kono
parents:
diff changeset
141 (return)]
kono
parents:
diff changeset
142 "reload_completed"
kono
parents:
diff changeset
143 "popret\tra"
kono
parents:
diff changeset
144 [(set_attr "length" "2")]
kono
parents:
diff changeset
145 )
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 ;; Arithmetic Instruction Patterns
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 ;; Addition-Subtraction "adddi3/subdi3" insns.
kono
parents:
diff changeset
150 (define_insn "<plusminus_insn>di3"
kono
parents:
diff changeset
151 [(set (match_operand:DI 0 "register_operand" "=r")
kono
parents:
diff changeset
152 (plusminus:DI (match_operand:DI 1 "register_operand" "<comm>0")
kono
parents:
diff changeset
153 (match_operand:DI 2 "register_operand" "r")))]
kono
parents:
diff changeset
154 ""
kono
parents:
diff changeset
155 {
kono
parents:
diff changeset
156 return cr16_emit_add_sub_di (operands, <plusminus_flag>);
kono
parents:
diff changeset
157 })
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 (define_insn "addsi3"
kono
parents:
diff changeset
160 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
kono
parents:
diff changeset
161 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0")
kono
parents:
diff changeset
162 (match_operand:SI 2 "reg_si_int_operand" "r,M,N,O,i")))]
kono
parents:
diff changeset
163 ""
kono
parents:
diff changeset
164 "addd\t%2, %0"
kono
parents:
diff changeset
165 [(set_attr "length" "2,2,4,4,6")]
kono
parents:
diff changeset
166 )
kono
parents:
diff changeset
167
kono
parents:
diff changeset
168 ;; Addition-Subtraction "addhi3/subhi3" insns.
kono
parents:
diff changeset
169 (define_insn "<plusminus_insn>hi3"
kono
parents:
diff changeset
170 [(set (match_operand:HI 0 "register_operand" "=c,c,c")
kono
parents:
diff changeset
171 (plusminus:HI (match_operand:HI 1 "register_operand" "<comm>0,0,0")
kono
parents:
diff changeset
172 (match_operand:HI 2 "reg_hi_int_operand" "c,M,N")))]
kono
parents:
diff changeset
173 ""
kono
parents:
diff changeset
174 "<plusminus_insn>w\t%2, %0"
kono
parents:
diff changeset
175 [(set_attr "length" "2,2,4")]
kono
parents:
diff changeset
176 )
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 ;; Addition-Subtraction "addqi3/subqi3" insns.
kono
parents:
diff changeset
179 (define_insn "<plusminus_insn>qi3"
kono
parents:
diff changeset
180 [(set (match_operand:QI 0 "register_operand" "=c,c")
kono
parents:
diff changeset
181 (plusminus:QI (match_operand:QI 1 "register_operand" "<comm>0,0")
kono
parents:
diff changeset
182 (match_operand:QI 2 "reg_qi_int_operand" "c,M")))]
kono
parents:
diff changeset
183 ""
kono
parents:
diff changeset
184 "<plusminus_insn>b\t%2, %0"
kono
parents:
diff changeset
185 [(set_attr "length" "2,2")]
kono
parents:
diff changeset
186 )
kono
parents:
diff changeset
187
kono
parents:
diff changeset
188 ;; Subtract Instruction
kono
parents:
diff changeset
189 (define_insn "subsi3"
kono
parents:
diff changeset
190 [(set (match_operand:SI 0 "register_operand" "=r,r")
kono
parents:
diff changeset
191 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
kono
parents:
diff changeset
192 (match_operand:SI 2 "reg_si_int_operand" "r,i")))]
kono
parents:
diff changeset
193 ""
kono
parents:
diff changeset
194 "subd\t%2, %0"
kono
parents:
diff changeset
195 [(set_attr "length" "4,6")]
kono
parents:
diff changeset
196 )
kono
parents:
diff changeset
197
kono
parents:
diff changeset
198 ;; Multiply and Accumulate Instructions "smachisi3/umachisi3"
kono
parents:
diff changeset
199 (define_insn "<sPat>maddhisi4"
kono
parents:
diff changeset
200 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
201 (plus:SI
kono
parents:
diff changeset
202 (mult:SI (sz_xtnd:SI (match_operand:HI 1 "register_operand" "r"))
kono
parents:
diff changeset
203 (sz_xtnd:SI (match_operand:HI 2 "register_operand" "r")))
kono
parents:
diff changeset
204 (match_operand:SI 3 "register_operand" "0")))]
kono
parents:
diff changeset
205 "TARGET_MAC"
kono
parents:
diff changeset
206 "mac<sPat>w\t%1, %2, %0"
kono
parents:
diff changeset
207 [(set_attr "length" "2")]
kono
parents:
diff changeset
208 )
kono
parents:
diff changeset
209
kono
parents:
diff changeset
210 ;; Multiply Instructions
kono
parents:
diff changeset
211 (define_insn "mulhi3"
kono
parents:
diff changeset
212 [(set (match_operand:HI 0 "register_operand" "=c,c,c")
kono
parents:
diff changeset
213 (mult:HI (match_operand:HI 1 "register_operand" "%0,0,0")
kono
parents:
diff changeset
214 (match_operand:HI 2 "reg_or_int_operand" "c,M,N")))]
kono
parents:
diff changeset
215 ""
kono
parents:
diff changeset
216 "mulw\t%2, %0"
kono
parents:
diff changeset
217 [(set_attr "length" "2,2,4")]
kono
parents:
diff changeset
218 )
kono
parents:
diff changeset
219
kono
parents:
diff changeset
220 (define_insn "mulqihi3"
kono
parents:
diff changeset
221 [(set (match_operand:HI 0 "register_operand" "=c")
kono
parents:
diff changeset
222 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
kono
parents:
diff changeset
223 (sign_extend:HI (match_operand:QI 2 "register_operand" "c"))))]
kono
parents:
diff changeset
224 ""
kono
parents:
diff changeset
225 "mulsb\t%2, %0"
kono
parents:
diff changeset
226 [(set_attr "length" "2")]
kono
parents:
diff changeset
227 )
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 ;; Bit Set/Clear Instructions
kono
parents:
diff changeset
230 (define_expand "insv"
kono
parents:
diff changeset
231 [(set (zero_extract (match_operand 0 "memory_operand" "")
kono
parents:
diff changeset
232 (match_operand 1 "immediate_operand" "")
kono
parents:
diff changeset
233 (match_operand 2 "immediate_operand" ""))
kono
parents:
diff changeset
234 (match_operand 3 "immediate_operand" ""))]
kono
parents:
diff changeset
235 "TARGET_BIT_OPS"
kono
parents:
diff changeset
236 {
kono
parents:
diff changeset
237 if (INTVAL (operands[1]) != 1)
kono
parents:
diff changeset
238 FAIL;
kono
parents:
diff changeset
239 if (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 15)
kono
parents:
diff changeset
240 FAIL;
kono
parents:
diff changeset
241 if (INTVAL (operands[3]) == 1)
kono
parents:
diff changeset
242 {
kono
parents:
diff changeset
243 if (GET_MODE (operands[0]) == QImode)
kono
parents:
diff changeset
244 {
kono
parents:
diff changeset
245 emit_insn (gen_set_bitqi (operands[0], operands[2]));
kono
parents:
diff changeset
246 DONE;
kono
parents:
diff changeset
247 }
kono
parents:
diff changeset
248 else if (GET_MODE (operands[0]) == HImode)
kono
parents:
diff changeset
249 {
kono
parents:
diff changeset
250 emit_insn (gen_set_bithi (operands[0], operands[2]));
kono
parents:
diff changeset
251 DONE;
kono
parents:
diff changeset
252 }
kono
parents:
diff changeset
253 }
kono
parents:
diff changeset
254 if (INTVAL (operands[3]) == 0)
kono
parents:
diff changeset
255 {
kono
parents:
diff changeset
256 if (GET_MODE (operands[0]) == QImode)
kono
parents:
diff changeset
257 {
kono
parents:
diff changeset
258 emit_insn (gen_clr_bitqi (operands[0], operands[2]));
kono
parents:
diff changeset
259 DONE;
kono
parents:
diff changeset
260 }
kono
parents:
diff changeset
261 else if (GET_MODE (operands[0]) == HImode)
kono
parents:
diff changeset
262 {
kono
parents:
diff changeset
263 emit_insn (gen_clr_bithi (operands[0], operands[2]));
kono
parents:
diff changeset
264 DONE;
kono
parents:
diff changeset
265 }
kono
parents:
diff changeset
266 }
kono
parents:
diff changeset
267 }
kono
parents:
diff changeset
268 )
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 (define_insn "set_bit<mode>"
kono
parents:
diff changeset
271 [(set (zero_extract:SHORT (match_operand:SHORT 0 "memory_operand" "+m")
kono
parents:
diff changeset
272 (const_int 1)
kono
parents:
diff changeset
273 (match_operand 1 "immediate_operand" "i"))
kono
parents:
diff changeset
274 (const_int 1))]
kono
parents:
diff changeset
275 "TARGET_BIT_OPS"
kono
parents:
diff changeset
276 "sbit<tIsa>\t%1,%0"
kono
parents:
diff changeset
277 [(set_attr "length" "2")]
kono
parents:
diff changeset
278 )
kono
parents:
diff changeset
279
kono
parents:
diff changeset
280 (define_insn "clr_bit<mode>"
kono
parents:
diff changeset
281 [(set (zero_extract:SHORT (match_operand:SHORT 0 "memory_operand" "+m")
kono
parents:
diff changeset
282 (const_int 1)
kono
parents:
diff changeset
283 (match_operand 1 "immediate_operand" "i"))
kono
parents:
diff changeset
284 (const_int 0))]
kono
parents:
diff changeset
285 "TARGET_BIT_OPS"
kono
parents:
diff changeset
286 "cbit<tIsa>\t%1,%0"
kono
parents:
diff changeset
287 [(set_attr "length" "2")]
kono
parents:
diff changeset
288 )
kono
parents:
diff changeset
289
kono
parents:
diff changeset
290 (define_insn "set_bit<mode>_mem"
kono
parents:
diff changeset
291 [(set (match_operand:SHORT 0 "bit_operand" "=m")
kono
parents:
diff changeset
292 (ior:SHORT (match_dup 0)
kono
parents:
diff changeset
293 (match_operand:SHORT 1 "one_bit_operand" "i"))
kono
parents:
diff changeset
294 )]
kono
parents:
diff changeset
295 "TARGET_BIT_OPS"
kono
parents:
diff changeset
296 "sbit<tIsa>\t$%s1,%0"
kono
parents:
diff changeset
297 [(set_attr "length" "2")]
kono
parents:
diff changeset
298 )
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 (define_insn "clear_bit<mode>_mem"
kono
parents:
diff changeset
301 [(set (match_operand:SHORT 0 "bit_operand" "=m")
kono
parents:
diff changeset
302 (and:SHORT (match_dup 0)
kono
parents:
diff changeset
303 (match_operand:SHORT 1 "rev_one_bit_operand" "i"))
kono
parents:
diff changeset
304 )]
kono
parents:
diff changeset
305 "TARGET_BIT_OPS"
kono
parents:
diff changeset
306 "cbit<tIsa>\t$%r1,%0"
kono
parents:
diff changeset
307 [(set_attr "length" "2")]
kono
parents:
diff changeset
308 )
kono
parents:
diff changeset
309
kono
parents:
diff changeset
310 ;; Logical Instructions - and/ior/xor "anddi3/iordi3/xordi3"
kono
parents:
diff changeset
311 (define_insn "<any_logic_insn>di3"
kono
parents:
diff changeset
312 [(set (match_operand:DI 0 "register_operand" "=r")
kono
parents:
diff changeset
313 (any_logic:DI (match_operand:DI 1 "register_operand" "%0")
kono
parents:
diff changeset
314 (match_operand:DI 2 "register_operand" "r")))]
kono
parents:
diff changeset
315 ""
kono
parents:
diff changeset
316 {
kono
parents:
diff changeset
317 return cr16_emit_logical_di (operands, <any_logic_flag>);
kono
parents:
diff changeset
318 })
kono
parents:
diff changeset
319
kono
parents:
diff changeset
320 ; Logical and/ior/xor "andsi3/iorsi3/xorsi3"
kono
parents:
diff changeset
321 (define_insn "<any_logic_insn>si3"
kono
parents:
diff changeset
322 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
kono
parents:
diff changeset
323 (any_logic:SI (match_operand:SI 1 "register_operand" "%0,0,0,0")
kono
parents:
diff changeset
324 (match_operand:SI 2 "reg_si_int_operand" "r,M,N,i")))]
kono
parents:
diff changeset
325 ""
kono
parents:
diff changeset
326 "<logic>d\t%2, %0"
kono
parents:
diff changeset
327 [(set_attr "length" "2,2,4,6")]
kono
parents:
diff changeset
328 )
kono
parents:
diff changeset
329
kono
parents:
diff changeset
330 ; Logical and/ior/xor in HImode "andhi3/iorhi3/xorhi3"
kono
parents:
diff changeset
331 ; Logical and/ior/xor in QImode "andqi3/iorqi3/xorqi3"
kono
parents:
diff changeset
332 (define_insn "<any_logic_insn><qh>3"
kono
parents:
diff changeset
333 [(set (match_operand:QH 0 "register_operand" "=c,c,c")
kono
parents:
diff changeset
334 (any_logic:QH (match_operand:QH 1 "register_operand" "%0,0,0")
kono
parents:
diff changeset
335 (match_operand:QH 2 "reg_hi_int_operand" "c,M,N")))]
kono
parents:
diff changeset
336 ""
kono
parents:
diff changeset
337 "<logic><QHsuffix>\t%2, %0"
kono
parents:
diff changeset
338 [(set_attr "length" "<QHsz>")]
kono
parents:
diff changeset
339 )
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 ;; Sign and Zero Extend Instructions
kono
parents:
diff changeset
342 (define_insn "<szPat>extendhisi2"
kono
parents:
diff changeset
343 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
344 (sz_xtnd:SI (match_operand:HI 1 "register_operand" "r")))]
kono
parents:
diff changeset
345 ""
kono
parents:
diff changeset
346 "mov<szIsa>w\t%1, %0"
kono
parents:
diff changeset
347 [(set_attr "length" "4")]
kono
parents:
diff changeset
348 )
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 (define_insn "<szPat>extendqihi2"
kono
parents:
diff changeset
351 [(set (match_operand:HI 0 "register_operand" "=r")
kono
parents:
diff changeset
352 (sz_xtnd:HI (match_operand:QI 1 "register_operand" "r")))]
kono
parents:
diff changeset
353 ""
kono
parents:
diff changeset
354 "mov<szIsa>b\t%1, %0"
kono
parents:
diff changeset
355 [(set_attr "length" "4")]
kono
parents:
diff changeset
356 )
kono
parents:
diff changeset
357
kono
parents:
diff changeset
358 ;; One's Complement
kono
parents:
diff changeset
359 (define_insn "one_cmpldi2"
kono
parents:
diff changeset
360 [(set (match_operand:DI 0 "register_operand" "=r")
kono
parents:
diff changeset
361 (not:DI (match_operand:DI 1 "register_operand" "0")))]
kono
parents:
diff changeset
362 ""
kono
parents:
diff changeset
363 {
kono
parents:
diff changeset
364 rtx xoperand ;
kono
parents:
diff changeset
365 int reg0 = REGNO (operands[0]);
kono
parents:
diff changeset
366
kono
parents:
diff changeset
367 xoperand = gen_rtx_REG (SImode, reg0 + 2);
kono
parents:
diff changeset
368 output_asm_insn ("xord\t$-1, %0", operands);
kono
parents:
diff changeset
369 output_asm_insn ("xord\t$-1, %0", &xoperand);
kono
parents:
diff changeset
370 return "" ;
kono
parents:
diff changeset
371 }
kono
parents:
diff changeset
372 [(set_attr "length" "12")]
kono
parents:
diff changeset
373 )
kono
parents:
diff changeset
374
kono
parents:
diff changeset
375 (define_insn "one_cmpl<mode>2"
kono
parents:
diff changeset
376 [(set (match_operand:CR16IM 0 "register_operand" "=r")
kono
parents:
diff changeset
377 (not:CR16IM (match_operand:CR16IM 1 "register_operand" "0")))]
kono
parents:
diff changeset
378 ""
kono
parents:
diff changeset
379 "xor<tIsa>\t$-1, %0"
kono
parents:
diff changeset
380 [(set_attr "length" "2")]
kono
parents:
diff changeset
381 )
kono
parents:
diff changeset
382
kono
parents:
diff changeset
383 ;; Arithmetic Left and Right Shift Instructions
kono
parents:
diff changeset
384 (define_insn "ashlqi3"
kono
parents:
diff changeset
385 [(set (match_operand:QI 0 "register_operand" "=c,c")
kono
parents:
diff changeset
386 (ashift:QI (match_operand:QI 1 "register_operand" "0,0")
kono
parents:
diff changeset
387 (match_operand:QI 2 "nonmemory_operand" "c,I")))]
kono
parents:
diff changeset
388 ""
kono
parents:
diff changeset
389 "ashub\t%2, %0"
kono
parents:
diff changeset
390 [(set_attr "length" "2,2")]
kono
parents:
diff changeset
391 )
kono
parents:
diff changeset
392
kono
parents:
diff changeset
393 (define_insn "ashlhi3"
kono
parents:
diff changeset
394 [(set (match_operand:HI 0 "register_operand" "=c,c")
kono
parents:
diff changeset
395 (ashift:HI (match_operand:HI 1 "register_operand" "0,0")
kono
parents:
diff changeset
396 (match_operand:QI 2 "nonmemory_operand" "c,J")))]
kono
parents:
diff changeset
397 ""
kono
parents:
diff changeset
398 "ashuw\t%2, %0"
kono
parents:
diff changeset
399 [(set_attr "length" "2,2")]
kono
parents:
diff changeset
400 )
kono
parents:
diff changeset
401
kono
parents:
diff changeset
402 (define_insn "ashlsi3"
kono
parents:
diff changeset
403 [(set (match_operand:SI 0 "register_operand" "=r,r")
kono
parents:
diff changeset
404 (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
kono
parents:
diff changeset
405 (match_operand:QI 2 "nonmemory_operand" "r,K")))]
kono
parents:
diff changeset
406 ""
kono
parents:
diff changeset
407 "ashud\t%2, %0"
kono
parents:
diff changeset
408 [(set_attr "length" "2,2")]
kono
parents:
diff changeset
409 )
kono
parents:
diff changeset
410
kono
parents:
diff changeset
411 (define_expand "ashr<mode>3"
kono
parents:
diff changeset
412 [(set (match_operand:CR16IM 0 "register_operand" "")
kono
parents:
diff changeset
413 (ashiftrt:CR16IM (match_operand:CR16IM 1 "register_operand" "")
kono
parents:
diff changeset
414 (match_operand:QI 2 "nonmemory_operand" "")))]
kono
parents:
diff changeset
415 ""
kono
parents:
diff changeset
416 {
kono
parents:
diff changeset
417 if (GET_CODE (operands[2]) == CONST_INT)
kono
parents:
diff changeset
418 {
kono
parents:
diff changeset
419 /* If the constant is not in range, try placing it in a reg */
kono
parents:
diff changeset
420 if (!UNSIGNED_INT_FITS_N_BITS(INTVAL (operands[2]),<shImmBits>))
kono
parents:
diff changeset
421 operands[2] = copy_to_mode_reg(QImode, operands[2]);
kono
parents:
diff changeset
422 }
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 if (GET_CODE (operands[2]) != CONST_INT)
kono
parents:
diff changeset
425 operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
kono
parents:
diff changeset
426 }
kono
parents:
diff changeset
427 )
kono
parents:
diff changeset
428
kono
parents:
diff changeset
429 (define_insn "ashrqi3_imm_insn"
kono
parents:
diff changeset
430 [(set (match_operand:QI 0 "register_operand" "=c")
kono
parents:
diff changeset
431 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
kono
parents:
diff changeset
432 (match_operand:QI 2 "shift_qi_imm_operand" "i")))]
kono
parents:
diff changeset
433 ""
kono
parents:
diff changeset
434 "ashub\t$%n2, %0"
kono
parents:
diff changeset
435 [(set_attr "length" "2")]
kono
parents:
diff changeset
436 )
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 (define_insn "ashrhi3_imm_insn"
kono
parents:
diff changeset
439 [(set (match_operand:HI 0 "register_operand" "=c")
kono
parents:
diff changeset
440 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
kono
parents:
diff changeset
441 (match_operand:QI 2 "shift_hi_imm_operand" "i")))]
kono
parents:
diff changeset
442 ""
kono
parents:
diff changeset
443 "ashuw\t$%n2, %0"
kono
parents:
diff changeset
444 [(set_attr "length" "2")]
kono
parents:
diff changeset
445 )
kono
parents:
diff changeset
446
kono
parents:
diff changeset
447 (define_insn "ashrsi3_imm_insn"
kono
parents:
diff changeset
448 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
449 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
kono
parents:
diff changeset
450 (match_operand:QI 2 "shift_si_imm_operand" "i")))]
kono
parents:
diff changeset
451 ""
kono
parents:
diff changeset
452 "ashud\t$%n2, %0"
kono
parents:
diff changeset
453 [(set_attr "length" "2")]
kono
parents:
diff changeset
454 )
kono
parents:
diff changeset
455
kono
parents:
diff changeset
456 (define_insn "ashrqi3_neg_insn"
kono
parents:
diff changeset
457 [(set (match_operand:QI 0 "register_operand" "=c")
kono
parents:
diff changeset
458 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
kono
parents:
diff changeset
459 (neg:QI (match_operand:QI 2 "register_operand" "c"))))]
kono
parents:
diff changeset
460 ""
kono
parents:
diff changeset
461 "ashub\t%2,%0"
kono
parents:
diff changeset
462 [(set_attr "length" "2")]
kono
parents:
diff changeset
463 )
kono
parents:
diff changeset
464
kono
parents:
diff changeset
465 (define_insn "ashrhi3_neg_insn"
kono
parents:
diff changeset
466 [(set (match_operand:HI 0 "register_operand" "=c")
kono
parents:
diff changeset
467 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
kono
parents:
diff changeset
468 (neg:QI (match_operand:QI 2 "register_operand" "c"))))]
kono
parents:
diff changeset
469 ""
kono
parents:
diff changeset
470 "ashuw\t%2,%0"
kono
parents:
diff changeset
471 [(set_attr "length" "2")]
kono
parents:
diff changeset
472 )
kono
parents:
diff changeset
473
kono
parents:
diff changeset
474 (define_insn "ashrdi3_neg_insn"
kono
parents:
diff changeset
475 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
476 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
kono
parents:
diff changeset
477 (neg:QI (match_operand:QI 2 "register_operand" "r"))))]
kono
parents:
diff changeset
478 ""
kono
parents:
diff changeset
479 "ashud\t%2,%0"
kono
parents:
diff changeset
480 [(set_attr "length" "2")]
kono
parents:
diff changeset
481 )
kono
parents:
diff changeset
482
kono
parents:
diff changeset
483 (define_expand "lshr<mode>3"
kono
parents:
diff changeset
484 [(set (match_operand:CR16IM 0 "register_operand" "")
kono
parents:
diff changeset
485 (lshiftrt:CR16IM (match_operand:CR16IM 1 "register_operand" "")
kono
parents:
diff changeset
486 (match_operand:QI 2 "reg_or_int_operand" "")))]
kono
parents:
diff changeset
487 ""
kono
parents:
diff changeset
488 {
kono
parents:
diff changeset
489 if (GET_CODE (operands[2]) == CONST_INT)
kono
parents:
diff changeset
490 {
kono
parents:
diff changeset
491 /* If the constant is not in range, try placing it in a reg */
kono
parents:
diff changeset
492 if (!UNSIGNED_INT_FITS_N_BITS(INTVAL (operands[2]),<shImmBits>))
kono
parents:
diff changeset
493 operands[2] = copy_to_mode_reg(QImode, operands[2]);
kono
parents:
diff changeset
494 }
kono
parents:
diff changeset
495
kono
parents:
diff changeset
496 if (GET_CODE (operands[2]) != CONST_INT)
kono
parents:
diff changeset
497 operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
kono
parents:
diff changeset
498 }
kono
parents:
diff changeset
499 )
kono
parents:
diff changeset
500
kono
parents:
diff changeset
501 (define_insn "lshrqi3_imm_insn"
kono
parents:
diff changeset
502 [(set (match_operand:QI 0 "register_operand" "=c")
kono
parents:
diff changeset
503 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
kono
parents:
diff changeset
504 (match_operand:QI 2 "shift_qi_operand" "Q")))]
kono
parents:
diff changeset
505 ""
kono
parents:
diff changeset
506 "lshb\t$%n2, %0"
kono
parents:
diff changeset
507 [(set_attr "length" "2")]
kono
parents:
diff changeset
508 )
kono
parents:
diff changeset
509
kono
parents:
diff changeset
510 (define_insn "lshrhi3_imm_insn"
kono
parents:
diff changeset
511 [(set (match_operand:HI 0 "register_operand" "=c")
kono
parents:
diff changeset
512 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
kono
parents:
diff changeset
513 (match_operand:QI 2 "shift_hi_operand" "R")))]
kono
parents:
diff changeset
514 ""
kono
parents:
diff changeset
515 "lshw\t$%n2, %0"
kono
parents:
diff changeset
516 [(set_attr "length" "2")]
kono
parents:
diff changeset
517 )
kono
parents:
diff changeset
518
kono
parents:
diff changeset
519 (define_insn "lshrsi3_imm_insn"
kono
parents:
diff changeset
520 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
521 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
kono
parents:
diff changeset
522 (match_operand:QI 2 "shift_si_operand" "S")))]
kono
parents:
diff changeset
523 ""
kono
parents:
diff changeset
524 "lshd\t$%n2, %0"
kono
parents:
diff changeset
525 [(set_attr "length" "2")]
kono
parents:
diff changeset
526 )
kono
parents:
diff changeset
527
kono
parents:
diff changeset
528 (define_insn "lshrqi3_neg_insn"
kono
parents:
diff changeset
529 [(set (match_operand:QI 0 "register_operand" "=c")
kono
parents:
diff changeset
530 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
kono
parents:
diff changeset
531 (neg:QI (match_operand:QI 2 "register_operand" "c"))))]
kono
parents:
diff changeset
532 ""
kono
parents:
diff changeset
533 "lshb\t%2,%0"
kono
parents:
diff changeset
534 [(set_attr "length" "2")]
kono
parents:
diff changeset
535 )
kono
parents:
diff changeset
536
kono
parents:
diff changeset
537 (define_insn "lshrhi3_neg_insn"
kono
parents:
diff changeset
538 [(set (match_operand:HI 0 "register_operand" "=c")
kono
parents:
diff changeset
539 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
kono
parents:
diff changeset
540 (neg:QI (match_operand:QI 2 "register_operand" "c"))))]
kono
parents:
diff changeset
541 ""
kono
parents:
diff changeset
542 "lshw\t%2,%0"
kono
parents:
diff changeset
543 [(set_attr "length" "2")]
kono
parents:
diff changeset
544 )
kono
parents:
diff changeset
545
kono
parents:
diff changeset
546 (define_insn "lshrsi3_neg_insn"
kono
parents:
diff changeset
547 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
548 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
kono
parents:
diff changeset
549 (neg:QI (match_operand:QI 2 "register_operand" "r"))))]
kono
parents:
diff changeset
550 ""
kono
parents:
diff changeset
551 "lshd\t%2,%0"
kono
parents:
diff changeset
552 [(set_attr "length" "2")]
kono
parents:
diff changeset
553 )
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 ;; Move Instructions
kono
parents:
diff changeset
556
kono
parents:
diff changeset
557 ;; Move any non-immediate operand 0 to a general operand 1.
kono
parents:
diff changeset
558 ;; This applies only before starting the reload process
kono
parents:
diff changeset
559 ;; Operand 0 is not a register operand of type mode MODE
kono
parents:
diff changeset
560 ;; If Operand 0 is a push operand of type mode MODE
kono
parents:
diff changeset
561 ;; then, if Operand 1 is a non-SP register
kono
parents:
diff changeset
562 ;; then, Operand 1 = copy_to_mode_reg (<MODE>mode, Operand 1)
kono
parents:
diff changeset
563 ;; endif
kono
parents:
diff changeset
564 ;; else
kono
parents:
diff changeset
565 ;; if Operand 1 is either register or 4-bit immediate constant
kono
parents:
diff changeset
566 ;; then, Operand 1 = copy_to_mode_reg (<MODE>mode, Operand 1)
kono
parents:
diff changeset
567 ;; endif
kono
parents:
diff changeset
568 ;; endif
kono
parents:
diff changeset
569 ;;
kono
parents:
diff changeset
570 ;; What does copy_to_mode_reg (mode, rtx val) do?
kono
parents:
diff changeset
571 ;; Copy the value into new temp reg and return the reg where the
kono
parents:
diff changeset
572 ;; mode of the new reg is always mode MODE when value is constant
kono
parents:
diff changeset
573 ;;
kono
parents:
diff changeset
574 ;; Why should copy_to_mode_reg be called?
kono
parents:
diff changeset
575 ;; All sorts of move are nor supported by CR16. Therefore,
kono
parents:
diff changeset
576 ;; when unsupported move is encountered, the additional instructions
kono
parents:
diff changeset
577 ;; will be introduced for the purpose.
kono
parents:
diff changeset
578 ;;
kono
parents:
diff changeset
579 ;; A new move insn is inserted for Op 1 when one of the following
kono
parents:
diff changeset
580 ;; conditions is met.
kono
parents:
diff changeset
581 ;; Case 1: Op 0 is push_operand
kono
parents:
diff changeset
582 ;; Op 1 is SP register
kono
parents:
diff changeset
583 ;;
kono
parents:
diff changeset
584 ;; Case 2: Op 0 is not push_operand
kono
parents:
diff changeset
585 ;; Op 1 is neither register nor unsigned 4-bit immediate
kono
parents:
diff changeset
586
kono
parents:
diff changeset
587 (define_expand "mov<mode>"
kono
parents:
diff changeset
588 [(set (match_operand:ALLMTD 0 "nonimmediate_operand" "")
kono
parents:
diff changeset
589 (match_operand:ALLMTD 1 "general_operand" ""))]
kono
parents:
diff changeset
590 ""
kono
parents:
diff changeset
591 {
kono
parents:
diff changeset
592 if (!(reload_in_progress || reload_completed))
kono
parents:
diff changeset
593 {
kono
parents:
diff changeset
594 /* Only if Op0 is a register operand. */
kono
parents:
diff changeset
595 if (!register_operand (operands[0], <MODE>mode))
kono
parents:
diff changeset
596 {
kono
parents:
diff changeset
597 if (push_operand (operands[0], <MODE>mode))
kono
parents:
diff changeset
598 {
kono
parents:
diff changeset
599 /* Use copy_to_mode_reg only if the register needs
kono
parents:
diff changeset
600 to be pushed is SP as CR16 does not support pushing SP. */
kono
parents:
diff changeset
601 if (!nosp_reg_operand (operands[1], <MODE>mode))
kono
parents:
diff changeset
602 operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]);
kono
parents:
diff changeset
603 }
kono
parents:
diff changeset
604 else
kono
parents:
diff changeset
605 {
kono
parents:
diff changeset
606 /* Use copy_to_mode_reg if op1 is not register operand
kono
parents:
diff changeset
607 subject to conditions inside. */
kono
parents:
diff changeset
608 if (!register_operand (operands[1], <MODE>mode))
kono
parents:
diff changeset
609 {
kono
parents:
diff changeset
610 /* CR16 does not support moving immediate to SI or SF
kono
parents:
diff changeset
611 type memory. */
kono
parents:
diff changeset
612 if (<MODE>mode == SImode || <MODE>mode == SFmode ||
kono
parents:
diff changeset
613 <MODE>mode == DImode || <MODE>mode == DFmode)
kono
parents:
diff changeset
614 operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]);
kono
parents:
diff changeset
615 else
kono
parents:
diff changeset
616 /* moving imm4 is supported by CR16 instruction. */
kono
parents:
diff changeset
617 if (!u4bits_operand (operands[1], <MODE>mode))
kono
parents:
diff changeset
618 operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]);
kono
parents:
diff changeset
619 }
kono
parents:
diff changeset
620 }
kono
parents:
diff changeset
621 }
kono
parents:
diff changeset
622
kono
parents:
diff changeset
623 /* If operand-1 is a symbol, convert it into a BRO or GOT Format. */
kono
parents:
diff changeset
624 if (flag_pic && ! legitimate_pic_operand_p (operands[1]))
kono
parents:
diff changeset
625 {
kono
parents:
diff changeset
626 operands[1] = legitimize_pic_address (operands[1], <MODE>mode, 0);
kono
parents:
diff changeset
627 }
kono
parents:
diff changeset
628 }
kono
parents:
diff changeset
629 }
kono
parents:
diff changeset
630 )
kono
parents:
diff changeset
631
kono
parents:
diff changeset
632 ; ALLMT : QI,HI,SI,SF
kono
parents:
diff changeset
633 ; pushCnstr : Push constraints
kono
parents:
diff changeset
634 ; QI : X
kono
parents:
diff changeset
635 ; HI,SI,SF,DI,DF : <
kono
parents:
diff changeset
636 ; b : All non-sp registers
kono
parents:
diff changeset
637 ; tpush : Push count
kono
parents:
diff changeset
638 ; QI,HI : 1
kono
parents:
diff changeset
639 ; SI,SF : 2
kono
parents:
diff changeset
640 ; DI,DF : 4
kono
parents:
diff changeset
641 (define_insn "push<mode>_internal"
kono
parents:
diff changeset
642 [(set (match_operand:ALLMTD 0 "push_operand" "=<pushCnstr>")
kono
parents:
diff changeset
643 (match_operand:ALLMTD 1 "nosp_reg_operand" "b"))]
kono
parents:
diff changeset
644 ""
kono
parents:
diff changeset
645 "push\t$<tpush>,%p1"
kono
parents:
diff changeset
646 [(set_attr "length" "2")]
kono
parents:
diff changeset
647 )
kono
parents:
diff changeset
648
kono
parents:
diff changeset
649 ; (DI, DF) move
kono
parents:
diff changeset
650 (define_insn "*mov<mode>_double"
kono
parents:
diff changeset
651 [(set (match_operand:DOUBLE 0 "nonimmediate_operand" "=r, r, r, m")
kono
parents:
diff changeset
652 (match_operand:DOUBLE 1 "general_operand" "r, <iFD>, m, r"))]
kono
parents:
diff changeset
653 "register_operand (operands[0], DImode)
kono
parents:
diff changeset
654 || register_operand (operands[0], DFmode)
kono
parents:
diff changeset
655 || register_operand (operands[1], DImode)
kono
parents:
diff changeset
656 || register_operand (operands[1], DFmode)"
kono
parents:
diff changeset
657 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
658 if (which_alternative == 0) {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
659 rtx xoperands[2];
111
kono
parents:
diff changeset
660 int reg0 = REGNO (operands[0]);
kono
parents:
diff changeset
661 int reg1 = REGNO (operands[1]);
kono
parents:
diff changeset
662
kono
parents:
diff changeset
663 xoperands[0] = gen_rtx_REG (SImode, reg0 + 2);
kono
parents:
diff changeset
664 xoperands[1] = gen_rtx_REG (SImode, reg1 + 2);
kono
parents:
diff changeset
665 if ((reg1 + 2) != reg0)
kono
parents:
diff changeset
666 {
kono
parents:
diff changeset
667 output_asm_insn ("movd\t%1, %0", operands);
kono
parents:
diff changeset
668 output_asm_insn ("movd\t%1, %0", xoperands);
kono
parents:
diff changeset
669 }
kono
parents:
diff changeset
670 else
kono
parents:
diff changeset
671 {
kono
parents:
diff changeset
672 output_asm_insn ("movd\t%1, %0", xoperands);
kono
parents:
diff changeset
673 output_asm_insn ("movd\t%1, %0", operands);
kono
parents:
diff changeset
674 }}
kono
parents:
diff changeset
675
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
676 else if (which_alternative == 1) {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
677 rtx lo_operands[2];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
678 rtx hi_operands[2];
111
kono
parents:
diff changeset
679
kono
parents:
diff changeset
680 lo_operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
kono
parents:
diff changeset
681 hi_operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
kono
parents:
diff changeset
682 lo_operands[1] = simplify_gen_subreg (SImode, operands[1],
kono
parents:
diff changeset
683 VOIDmode == GET_MODE (operands[1])
kono
parents:
diff changeset
684 ? DImode : GET_MODE (operands[1]), 0);
kono
parents:
diff changeset
685 hi_operands[1] = simplify_gen_subreg (SImode, operands[1],
kono
parents:
diff changeset
686 VOIDmode == GET_MODE (operands[1])
kono
parents:
diff changeset
687 ? DImode : GET_MODE (operands[1]), 4);
kono
parents:
diff changeset
688 output_asm_insn ("movd\t%1, %0", lo_operands);
kono
parents:
diff changeset
689 output_asm_insn ("movd\t%1, %0", hi_operands);}
kono
parents:
diff changeset
690
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
691 else if (which_alternative == 2) {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
692 rtx xoperands[2];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
693 int reg0 = REGNO (operands[0]), reg1 = -2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
694 rtx addr;
111
kono
parents:
diff changeset
695
kono
parents:
diff changeset
696 if (MEM_P (operands[1]))
kono
parents:
diff changeset
697 addr = XEXP (operands[1], 0);
kono
parents:
diff changeset
698 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
699 addr = NULL_RTX;
111
kono
parents:
diff changeset
700 switch (GET_CODE (addr))
kono
parents:
diff changeset
701 {
kono
parents:
diff changeset
702 case REG:
kono
parents:
diff changeset
703 case SUBREG:
kono
parents:
diff changeset
704 reg1 = REGNO (addr);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
705 break;
111
kono
parents:
diff changeset
706 case PLUS:
kono
parents:
diff changeset
707 switch (GET_CODE (XEXP (addr, 0))) {
kono
parents:
diff changeset
708 case REG:
kono
parents:
diff changeset
709 case SUBREG:
kono
parents:
diff changeset
710 reg1 = REGNO (XEXP (addr, 0));
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
711 break;
111
kono
parents:
diff changeset
712 case PLUS:
kono
parents:
diff changeset
713 reg1 = REGNO (XEXP (XEXP (addr, 0), 0));
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
714 break;
111
kono
parents:
diff changeset
715 default:
kono
parents:
diff changeset
716 inform (DECL_SOURCE_LOCATION (cfun->decl), "unexpected expression; addr:");
kono
parents:
diff changeset
717 debug_rtx (addr);
kono
parents:
diff changeset
718 inform (DECL_SOURCE_LOCATION (cfun->decl), "operands[1]:");
kono
parents:
diff changeset
719 debug_rtx (operands[1]);
kono
parents:
diff changeset
720 inform (DECL_SOURCE_LOCATION (cfun->decl), "generated code might now work\n");
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
721 break;}
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
722 break;
111
kono
parents:
diff changeset
723 default:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
724 break;
111
kono
parents:
diff changeset
725 }
kono
parents:
diff changeset
726
kono
parents:
diff changeset
727 xoperands[0] = gen_rtx_REG (SImode, reg0 + 2);
kono
parents:
diff changeset
728 xoperands[1] = offset_address (operands[1], GEN_INT (4), 2);
kono
parents:
diff changeset
729 gcc_assert ((reg0 + 1) != reg1);
kono
parents:
diff changeset
730 if (reg0 != reg1 && (reg1 + 1) != reg0)
kono
parents:
diff changeset
731 {
kono
parents:
diff changeset
732 output_asm_insn ("loadd\t%1, %0", operands);
kono
parents:
diff changeset
733 output_asm_insn ("loadd\t%1, %0", xoperands);
kono
parents:
diff changeset
734 }
kono
parents:
diff changeset
735 else
kono
parents:
diff changeset
736 {
kono
parents:
diff changeset
737 output_asm_insn ("loadd\t%1, %0", xoperands);
kono
parents:
diff changeset
738 output_asm_insn ("loadd\t%1, %0", operands);
kono
parents:
diff changeset
739 }}
kono
parents:
diff changeset
740 else
kono
parents:
diff changeset
741 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
742 rtx xoperands[2];
111
kono
parents:
diff changeset
743 xoperands[0] = offset_address (operands[0], GEN_INT (4), 2);
kono
parents:
diff changeset
744 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
kono
parents:
diff changeset
745 output_asm_insn ("stord\t%1, %0", operands);
kono
parents:
diff changeset
746 output_asm_insn ("stord\t%1, %0", xoperands);
kono
parents:
diff changeset
747 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
748 return "";
111
kono
parents:
diff changeset
749 }
kono
parents:
diff changeset
750 [(set_attr "length" "4, <lImmArithD>, <lImmArithD>, <lImmArithD>")]
kono
parents:
diff changeset
751 )
kono
parents:
diff changeset
752
kono
parents:
diff changeset
753 ; All long (SI, SF) register move, load and store operations
kono
parents:
diff changeset
754 ; The print_operand will take care of printing the register pair
kono
parents:
diff changeset
755 ; when mode is SI/SF and register is in SHORT_REGS
kono
parents:
diff changeset
756 (define_insn "*mov<mode>_long"
kono
parents:
diff changeset
757 [(set (match_operand:LONG 0 "nonimmediate_operand" "=r, r, r, m")
kono
parents:
diff changeset
758 (match_operand:LONG 1 "general_operand" "r, <iF>, m, r"))]
kono
parents:
diff changeset
759 "register_operand (operands[0], <MODE>mode)
kono
parents:
diff changeset
760 || register_operand (operands[1], <MODE>mode)"
kono
parents:
diff changeset
761 "@
kono
parents:
diff changeset
762 mov<tIsa>\t%1, %0
kono
parents:
diff changeset
763 mov<tIsa>\t%1, %0
kono
parents:
diff changeset
764 load<tIsa>\t%1, %0
kono
parents:
diff changeset
765 stor<tIsa>\t%1, %0"
kono
parents:
diff changeset
766 [(set_attr "length" "2,<lImmArith>,<lImmArith>,<lImmArith>")]
kono
parents:
diff changeset
767 )
kono
parents:
diff changeset
768
kono
parents:
diff changeset
769 ;; All short (QI, HI) register move, load and store operations
kono
parents:
diff changeset
770 (define_insn "*mov<mode>_short"
kono
parents:
diff changeset
771 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r, r, r, m, m")
kono
parents:
diff changeset
772 (match_operand:SHORT 1 "general_operand" "r, <iF>, m, r, <LL>"))]
kono
parents:
diff changeset
773 "(register_operand (operands[0], <MODE>mode))
kono
parents:
diff changeset
774 || (store_operand (operands[0], <MODE>mode)
kono
parents:
diff changeset
775 && (register_operand (operands[1], <MODE>mode)
kono
parents:
diff changeset
776 || u4bits_operand (operands[1], <MODE>mode)))"
kono
parents:
diff changeset
777 "@
kono
parents:
diff changeset
778 mov<tIsa>\t%1, %0
kono
parents:
diff changeset
779 mov<tIsa>\t%1, %0
kono
parents:
diff changeset
780 load<tIsa>\t%1, %0
kono
parents:
diff changeset
781 stor<tIsa>\t%1, %0
kono
parents:
diff changeset
782 stor<tIsa>\t%1, %0"
kono
parents:
diff changeset
783 [(set_attr "length" "2,<lImmArith>,<lImmArith>,<lImmArith>,<lImmArith>")]
kono
parents:
diff changeset
784 )
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 ;; Compare Instructions
kono
parents:
diff changeset
787 ; Instruction generated compares the operands in reverse order
kono
parents:
diff changeset
788 ; Therefore, while printing the asm, the reverse of the
kono
parents:
diff changeset
789 ; compare condition shall be printed.
kono
parents:
diff changeset
790 (define_insn "cbranch<mode>4"
kono
parents:
diff changeset
791 [(set (pc)
kono
parents:
diff changeset
792 (if_then_else (match_operator 0 "ordered_comparison_operator"
kono
parents:
diff changeset
793 [(match_operand:CR16IM 1 "register_operand" "r,r")
kono
parents:
diff changeset
794 (match_operand:CR16IM 2 "nonmemory_operand" "r,n")])
kono
parents:
diff changeset
795 (label_ref (match_operand 3 "" ""))
kono
parents:
diff changeset
796 (pc)))
kono
parents:
diff changeset
797 (clobber (cc0))]
kono
parents:
diff changeset
798 ""
kono
parents:
diff changeset
799 "cmp<tIsa>\t%2, %1\;b%d0\t%l3"
kono
parents:
diff changeset
800 [(set_attr "length" "6,6")]
kono
parents:
diff changeset
801 )
kono
parents:
diff changeset
802
kono
parents:
diff changeset
803 (define_expand "cmp<mode>"
kono
parents:
diff changeset
804 [(parallel [(set (cc0)
kono
parents:
diff changeset
805 (compare (match_operand:CR16IM 0 "register_operand" "")
kono
parents:
diff changeset
806 (match_operand:CR16IM 1 "nonmemory_operand" "")))
kono
parents:
diff changeset
807 (clobber (match_scratch:HI 2 "=r"))] ) ]
kono
parents:
diff changeset
808 ""
kono
parents:
diff changeset
809 "")
kono
parents:
diff changeset
810
kono
parents:
diff changeset
811 ;; Scond Instructions
kono
parents:
diff changeset
812 (define_expand "cstore<mode>4"
kono
parents:
diff changeset
813 [(set (cc0)
kono
parents:
diff changeset
814 (compare (match_operand:CR16IM 2 "register_operand" "")
kono
parents:
diff changeset
815 (match_operand:CR16IM 3 "nonmemory_operand" "")))
kono
parents:
diff changeset
816 (set (match_operand:HI 0 "register_operand")
kono
parents:
diff changeset
817 (match_operator:HI 1 "ordered_comparison_operator"
kono
parents:
diff changeset
818 [(cc0) (const_int 0)]))]
kono
parents:
diff changeset
819 ""
kono
parents:
diff changeset
820 ""
kono
parents:
diff changeset
821 )
kono
parents:
diff changeset
822
kono
parents:
diff changeset
823 (define_insn "*cmp<mode>_insn"
kono
parents:
diff changeset
824 [(set (cc0)
kono
parents:
diff changeset
825 (compare (match_operand:CR16IM 0 "register_operand" "r,r")
kono
parents:
diff changeset
826 (match_operand:CR16IM 1 "nonmemory_operand" "r,n")))]
kono
parents:
diff changeset
827 ""
kono
parents:
diff changeset
828 "cmp<tIsa>\t%1, %0"
kono
parents:
diff changeset
829 [(set_attr "length" "2,4")]
kono
parents:
diff changeset
830 )
kono
parents:
diff changeset
831
kono
parents:
diff changeset
832 (define_insn "sCOND_internal"
kono
parents:
diff changeset
833 [(set (match_operand:HI 0 "register_operand" "=r")
kono
parents:
diff changeset
834 (match_operator:HI 1 "ordered_comparison_operator"
kono
parents:
diff changeset
835 [(cc0) (const_int 0)]))]
kono
parents:
diff changeset
836 ""
kono
parents:
diff changeset
837 "s%d1\t%0"
kono
parents:
diff changeset
838 [(set_attr "length" "2")]
kono
parents:
diff changeset
839 )
kono
parents:
diff changeset
840
kono
parents:
diff changeset
841 ;; Jumps and Branches
kono
parents:
diff changeset
842 (define_insn "indirect_jump_return"
kono
parents:
diff changeset
843 [(set (pc)
kono
parents:
diff changeset
844 (reg:SI RA_REGNUM))
kono
parents:
diff changeset
845 (return)]
kono
parents:
diff changeset
846 "reload_completed"
kono
parents:
diff changeset
847 "jump\t (ra)"
kono
parents:
diff changeset
848 [(set_attr "length" "2")]
kono
parents:
diff changeset
849 )
kono
parents:
diff changeset
850
kono
parents:
diff changeset
851 (define_insn "jump_return"
kono
parents:
diff changeset
852 [(unspec:SI [(const_int 0)] UNSPEC_RETURN_ADDR)
kono
parents:
diff changeset
853 (return)]
kono
parents:
diff changeset
854 "reload_completed"
kono
parents:
diff changeset
855 "jump\t(ra)"
kono
parents:
diff changeset
856 [(set_attr "length" "2")]
kono
parents:
diff changeset
857 )
kono
parents:
diff changeset
858
kono
parents:
diff changeset
859 (define_insn "indirect_jump"
kono
parents:
diff changeset
860 [(set (pc)
kono
parents:
diff changeset
861 (match_operand:SI 0 "reg_or_sym_operand" "r,i"))]
kono
parents:
diff changeset
862 ""
kono
parents:
diff changeset
863 "@
kono
parents:
diff changeset
864 jump\t%0
kono
parents:
diff changeset
865 br\t%a0"
kono
parents:
diff changeset
866 [(set_attr "length" "2,6")]
kono
parents:
diff changeset
867 )
kono
parents:
diff changeset
868
kono
parents:
diff changeset
869 (define_insn "interrupt_return"
kono
parents:
diff changeset
870 [(unspec_volatile [(const_int 0)] 0)
kono
parents:
diff changeset
871 (return)]
kono
parents:
diff changeset
872 ""
kono
parents:
diff changeset
873 {
kono
parents:
diff changeset
874 return cr16_prepare_push_pop_string (1);
kono
parents:
diff changeset
875 }
kono
parents:
diff changeset
876 [(set_attr "length" "14")]
kono
parents:
diff changeset
877 )
kono
parents:
diff changeset
878
kono
parents:
diff changeset
879 (define_insn "jump_to_imm"
kono
parents:
diff changeset
880 [(set (pc)
kono
parents:
diff changeset
881 (match_operand 0 "jump_imm_operand" "i"))]
kono
parents:
diff changeset
882 ""
kono
parents:
diff changeset
883 "br\t%c0"
kono
parents:
diff changeset
884 [(set_attr "length" "6")]
kono
parents:
diff changeset
885 )
kono
parents:
diff changeset
886
kono
parents:
diff changeset
887 (define_insn "jump"
kono
parents:
diff changeset
888 [(set (pc)
kono
parents:
diff changeset
889 (label_ref (match_operand 0 "" "")))]
kono
parents:
diff changeset
890 ""
kono
parents:
diff changeset
891 "br\t%l0"
kono
parents:
diff changeset
892 [(set_attr "length" "6")]
kono
parents:
diff changeset
893 )
kono
parents:
diff changeset
894
kono
parents:
diff changeset
895 ;; Table Jump
kono
parents:
diff changeset
896 (define_insn "tablejump"
kono
parents:
diff changeset
897 [(set (pc)
kono
parents:
diff changeset
898 (match_operand:SI 0 "register_operand" "r"))
kono
parents:
diff changeset
899 (use (label_ref:SI (match_operand 1 "" "")))]
kono
parents:
diff changeset
900 "!flag_pic"
kono
parents:
diff changeset
901 "jump\t%0"
kono
parents:
diff changeset
902 [(set_attr "length" "2")]
kono
parents:
diff changeset
903 )
kono
parents:
diff changeset
904
kono
parents:
diff changeset
905 ;; Call Instructions
kono
parents:
diff changeset
906 (define_expand "call"
kono
parents:
diff changeset
907 [(call (match_operand:QI 0 "memory_operand" "")
kono
parents:
diff changeset
908 (match_operand 1 "" ""))]
kono
parents:
diff changeset
909 ""
kono
parents:
diff changeset
910 {
kono
parents:
diff changeset
911 if (flag_pic && ! legitimate_pic_operand_p (operands[0]))
kono
parents:
diff changeset
912 {
kono
parents:
diff changeset
913 operands[0] = gen_const_mem (QImode,
kono
parents:
diff changeset
914 legitimize_pic_address (XEXP (operands[0], 0), Pmode, 0));
kono
parents:
diff changeset
915 emit_call_insn (gen_cr16_call (operands[0], operands[1]));
kono
parents:
diff changeset
916 }
kono
parents:
diff changeset
917 else
kono
parents:
diff changeset
918 emit_call_insn (gen_cr16_call (operands[0], operands[1]));
kono
parents:
diff changeset
919 DONE;
kono
parents:
diff changeset
920 }
kono
parents:
diff changeset
921 )
kono
parents:
diff changeset
922
kono
parents:
diff changeset
923 (define_expand "cr16_call"
kono
parents:
diff changeset
924 [(parallel
kono
parents:
diff changeset
925 [(call (match_operand:QI 0 "memory_operand" "")
kono
parents:
diff changeset
926 (match_operand 1 "" ""))
kono
parents:
diff changeset
927 (clobber (reg:SI RA_REGNUM))])]
kono
parents:
diff changeset
928 ""
kono
parents:
diff changeset
929 ""
kono
parents:
diff changeset
930 )
kono
parents:
diff changeset
931
kono
parents:
diff changeset
932 (define_insn "cr16_call_insn_branch_pic"
kono
parents:
diff changeset
933 [(call (mem:QI (match_operand:SI 0 "call_imm_operand" "i"))
kono
parents:
diff changeset
934 (match_operand 1 "" ""))
kono
parents:
diff changeset
935 (clobber (match_operand:SI 2 "register_operand" "+r"))]
kono
parents:
diff changeset
936 "flag_pic == FAR_PIC"
kono
parents:
diff changeset
937 {
kono
parents:
diff changeset
938 if (GET_CODE (operands[0]) != CONST_INT)
kono
parents:
diff changeset
939 return "loadd\t%g0, %2 \n\tjal %2";
kono
parents:
diff changeset
940 else
kono
parents:
diff changeset
941 return "jal %2";
kono
parents:
diff changeset
942 }
kono
parents:
diff changeset
943 [(set_attr "length" "8")]
kono
parents:
diff changeset
944 )
kono
parents:
diff changeset
945
kono
parents:
diff changeset
946 (define_insn "cr16_call_insn_branch"
kono
parents:
diff changeset
947 [(call (mem:QI (match_operand:SI 0 "call_imm_operand" "i"))
kono
parents:
diff changeset
948 (match_operand 1 "" ""))
kono
parents:
diff changeset
949 (clobber (match_operand:SI 2 "register_operand" "+r"))]
kono
parents:
diff changeset
950 "flag_pic == 0 || flag_pic == NEAR_PIC"
kono
parents:
diff changeset
951 {
kono
parents:
diff changeset
952 /* Print the immediate address for bal
kono
parents:
diff changeset
953 'b' is used instead of 'a' to avoid compiler calling
kono
parents:
diff changeset
954 the GO_IF_LEGITIMATE_ADDRESS which cannot
kono
parents:
diff changeset
955 perform checks on const_int code addresses as it
kono
parents:
diff changeset
956 assumes all const_int are data addresses.
kono
parents:
diff changeset
957 */
kono
parents:
diff changeset
958 if (GET_CODE (operands[0]) != CONST_INT)
kono
parents:
diff changeset
959 return "bal (ra), %a0";
kono
parents:
diff changeset
960 else
kono
parents:
diff changeset
961 operands[4] = GEN_INT ((INTVAL (operands[0]))>>1);
kono
parents:
diff changeset
962 return "movd\t%g4,\t(r1,r0)\n\tjal\t(r1,r0)";
kono
parents:
diff changeset
963 }
kono
parents:
diff changeset
964 [(set_attr "length" "6")]
kono
parents:
diff changeset
965 )
kono
parents:
diff changeset
966
kono
parents:
diff changeset
967 (define_insn "cr16_call_insn_jump"
kono
parents:
diff changeset
968 [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
kono
parents:
diff changeset
969 (match_operand 1 "" ""))
kono
parents:
diff changeset
970 (clobber (match_operand:SI 2 "register_operand" "+r"))]
kono
parents:
diff changeset
971 ""
kono
parents:
diff changeset
972 "jal\t%0"
kono
parents:
diff changeset
973 [(set_attr "length" "2")]
kono
parents:
diff changeset
974 )
kono
parents:
diff changeset
975
kono
parents:
diff changeset
976 ;; Call Value Instructions
kono
parents:
diff changeset
977
kono
parents:
diff changeset
978 (define_expand "call_value"
kono
parents:
diff changeset
979 [(set (match_operand 0 "general_operand" "")
kono
parents:
diff changeset
980 (call (match_operand:QI 1 "memory_operand" "")
kono
parents:
diff changeset
981 (match_operand 2 "" "")))]
kono
parents:
diff changeset
982 ""
kono
parents:
diff changeset
983 {
kono
parents:
diff changeset
984 if (flag_pic && !legitimate_pic_operand_p (operands[1]))
kono
parents:
diff changeset
985 {
kono
parents:
diff changeset
986 operands[1] = gen_const_mem (QImode,
kono
parents:
diff changeset
987 legitimize_pic_address (XEXP (operands[1], 0), Pmode, 0));
kono
parents:
diff changeset
988 emit_call_insn (gen_cr16_call_value (operands[0], operands[1], operands[2]));
kono
parents:
diff changeset
989 }
kono
parents:
diff changeset
990 else
kono
parents:
diff changeset
991 emit_call_insn (gen_cr16_call_value (operands[0], operands[1], operands[2]));
kono
parents:
diff changeset
992 DONE;
kono
parents:
diff changeset
993 }
kono
parents:
diff changeset
994 )
kono
parents:
diff changeset
995
kono
parents:
diff changeset
996 (define_expand "cr16_call_value"
kono
parents:
diff changeset
997 [(parallel
kono
parents:
diff changeset
998 [(set (match_operand 0 "general_operand" "")
kono
parents:
diff changeset
999 (call (match_operand 1 "memory_operand" "")
kono
parents:
diff changeset
1000 (match_operand 2 "" "")))
kono
parents:
diff changeset
1001 (clobber (reg:SI RA_REGNUM))])]
kono
parents:
diff changeset
1002 ""
kono
parents:
diff changeset
1003 ""
kono
parents:
diff changeset
1004 )
kono
parents:
diff changeset
1005
kono
parents:
diff changeset
1006 (define_insn "cr16_call_value_insn_branch_pic"
kono
parents:
diff changeset
1007 [(set (match_operand 0 "" "=g")
kono
parents:
diff changeset
1008 (call (mem:QI (match_operand:SI 1 "call_imm_operand" "i"))
kono
parents:
diff changeset
1009 (match_operand 2 "" "")))
kono
parents:
diff changeset
1010 (clobber (match_operand:SI 3 "register_operand" "+r"))]
kono
parents:
diff changeset
1011 "flag_pic == FAR_PIC"
kono
parents:
diff changeset
1012 {
kono
parents:
diff changeset
1013 if (GET_CODE (operands[1]) != CONST_INT)
kono
parents:
diff changeset
1014 return "loadd\t%g1, %3 \n\tjal %3";
kono
parents:
diff changeset
1015 else
kono
parents:
diff changeset
1016 return "jal %3";
kono
parents:
diff changeset
1017 }
kono
parents:
diff changeset
1018 [(set_attr "length" "8")]
kono
parents:
diff changeset
1019 )
kono
parents:
diff changeset
1020
kono
parents:
diff changeset
1021 (define_insn "cr16_call_value_insn_branch"
kono
parents:
diff changeset
1022 [(set (match_operand 0 "" "=g")
kono
parents:
diff changeset
1023 (call (mem:QI (match_operand:SI 1 "call_imm_operand" "i"))
kono
parents:
diff changeset
1024 (match_operand 2 "" "")))
kono
parents:
diff changeset
1025 (clobber (match_operand:SI 3 "register_operand" "+r"))]
kono
parents:
diff changeset
1026 "flag_pic == 0 || flag_pic == NEAR_PIC"
kono
parents:
diff changeset
1027 {
kono
parents:
diff changeset
1028 /* Print the immediate address for bal
kono
parents:
diff changeset
1029 'b' is used instead of 'a' to avoid compiler calling
kono
parents:
diff changeset
1030 the GO_IF_LEGITIMATE_ADDRESS which cannot
kono
parents:
diff changeset
1031 perform checks on const_int code addresses as it
kono
parents:
diff changeset
1032 assumes all const_int are data addresses.
kono
parents:
diff changeset
1033 */
kono
parents:
diff changeset
1034 if (GET_CODE (operands[1]) != CONST_INT)
kono
parents:
diff changeset
1035 return "bal (ra), %a1";
kono
parents:
diff changeset
1036 else
kono
parents:
diff changeset
1037 {
kono
parents:
diff changeset
1038 operands[4] = GEN_INT ((INTVAL (operands[1]))>>1);
kono
parents:
diff changeset
1039 return "movd\t%g4,\t(r1,r0)\n\tjal\t(r1,r0)";
kono
parents:
diff changeset
1040 }
kono
parents:
diff changeset
1041 }
kono
parents:
diff changeset
1042 [(set_attr "length" "6")]
kono
parents:
diff changeset
1043 )
kono
parents:
diff changeset
1044
kono
parents:
diff changeset
1045
kono
parents:
diff changeset
1046 (define_insn "cr16_call_value_insn_jump"
kono
parents:
diff changeset
1047 [(set (match_operand 0 "" "=g")
kono
parents:
diff changeset
1048 (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
kono
parents:
diff changeset
1049 (match_operand 2 "" "")))
kono
parents:
diff changeset
1050 (clobber (match_operand:SI 3 "register_operand" "+r"))]
kono
parents:
diff changeset
1051 ""
kono
parents:
diff changeset
1052 "jal\t%1"
kono
parents:
diff changeset
1053 [(set_attr "length" "2")]
kono
parents:
diff changeset
1054 )
kono
parents:
diff changeset
1055
kono
parents:
diff changeset
1056
kono
parents:
diff changeset
1057 ;; Nop
kono
parents:
diff changeset
1058 (define_insn "nop"
kono
parents:
diff changeset
1059 [(const_int 0)]
kono
parents:
diff changeset
1060 ""
kono
parents:
diff changeset
1061 "nop\t"
kono
parents:
diff changeset
1062 )
kono
parents:
diff changeset
1063
kono
parents:
diff changeset
1064 ;; PIC
kono
parents:
diff changeset
1065 /* When generating pic, we need to load the symbol offset into a register.
kono
parents:
diff changeset
1066 So that the optimizer does not confuse this with a normal symbol load
kono
parents:
diff changeset
1067 we use an unspec. The offset will be loaded from a constant pool entry,
kono
parents:
diff changeset
1068 since that is the only type of relocation we can use. */
kono
parents:
diff changeset
1069
kono
parents:
diff changeset
1070 (define_insn "unspec_bro_addr"
kono
parents:
diff changeset
1071 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
1072 (unspec:SI [(match_operand 1 "" "")] UNSPEC_PIC_ADDR))]
kono
parents:
diff changeset
1073 ""
kono
parents:
diff changeset
1074 "movd \t%f1, %0"
kono
parents:
diff changeset
1075 [(set_attr "length" "4")]
kono
parents:
diff changeset
1076 )
kono
parents:
diff changeset
1077
kono
parents:
diff changeset
1078 (define_insn "unspec_got_addr"
kono
parents:
diff changeset
1079 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
1080 (unspec:SI [(match_operand 1 "" "")] UNSPEC_PIC_LOAD_ADDR))]
kono
parents:
diff changeset
1081 ""
kono
parents:
diff changeset
1082 "loadd \t%g1, %0"
kono
parents:
diff changeset
1083 [(set_attr "length" "6")]
kono
parents:
diff changeset
1084 )