]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/bfin/bfin.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / bfin / bfin.md
1 ;;- Machine description for Blackfin for GNU compiler
2 ;; Copyright (C) 2005-2024 Free Software Foundation, Inc.
3 ;; Contributed by Analog Devices.
4
5 ;; This file is part of GCC.
6
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
11
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 ;; License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 ; operand punctuation marks:
22 ;
23 ; X -- integer value printed as log2
24 ; Y -- integer value printed as log2(~value) - for bitclear
25 ; h -- print half word register, low part
26 ; d -- print half word register, high part
27 ; D -- print operand as dregs pairs
28 ; w -- print operand as accumulator register word (a0w, a1w)
29 ; H -- high part of double mode operand
30 ; T -- byte register representation Oct. 02 2001
31
32 ; constant operand classes
33 ;
34 ; J 2**N 5bit imm scaled
35 ; Ks7 -64 .. 63 signed 7bit imm
36 ; Ku5 0..31 unsigned 5bit imm
37 ; Ks4 -8 .. 7 signed 4bit imm
38 ; Ks3 -4 .. 3 signed 3bit imm
39 ; Ku3 0 .. 7 unsigned 3bit imm
40 ; Pn 0, 1, 2 constants 0, 1 or 2, corresponding to n
41 ;
42 ; register operands
43 ; d (r0..r7)
44 ; a (p0..p5,fp,sp)
45 ; e (a0, a1)
46 ; b (i0..i3)
47 ; f (m0..m3)
48 ; v (b0..b3)
49 ; c (i0..i3,m0..m3) CIRCREGS
50 ; C (CC) CCREGS
51 ; t (lt0,lt1)
52 ; k (lc0,lc1)
53 ; u (lb0,lb1)
54 ;
55
56 ;; Define constants for hard registers.
57
58 (define_constants
59 [(REG_R0 0)
60 (REG_R1 1)
61 (REG_R2 2)
62 (REG_R3 3)
63 (REG_R4 4)
64 (REG_R5 5)
65 (REG_R6 6)
66 (REG_R7 7)
67
68 (REG_P0 8)
69 (REG_P1 9)
70 (REG_P2 10)
71 (REG_P3 11)
72 (REG_P4 12)
73 (REG_P5 13)
74 (REG_P6 14)
75 (REG_P7 15)
76
77 (REG_SP 14)
78 (REG_FP 15)
79
80 (REG_I0 16)
81 (REG_I1 17)
82 (REG_I2 18)
83 (REG_I3 19)
84
85 (REG_B0 20)
86 (REG_B1 21)
87 (REG_B2 22)
88 (REG_B3 23)
89
90 (REG_L0 24)
91 (REG_L1 25)
92 (REG_L2 26)
93 (REG_L3 27)
94
95 (REG_M0 28)
96 (REG_M1 29)
97 (REG_M2 30)
98 (REG_M3 31)
99
100 (REG_A0 32)
101 (REG_A1 33)
102
103 (REG_CC 34)
104 (REG_RETS 35)
105 (REG_RETI 36)
106 (REG_RETX 37)
107 (REG_RETN 38)
108 (REG_RETE 39)
109
110 (REG_ASTAT 40)
111 (REG_SEQSTAT 41)
112 (REG_USP 42)
113
114 (REG_ARGP 43)
115
116 (REG_LT0 44)
117 (REG_LT1 45)
118 (REG_LC0 46)
119 (REG_LC1 47)
120 (REG_LB0 48)
121 (REG_LB1 49)])
122
123 ;; Constants used in UNSPECs and UNSPEC_VOLATILEs.
124
125 (define_constants
126 [(UNSPEC_CBRANCH_TAKEN 0)
127 (UNSPEC_CBRANCH_NOPS 1)
128 (UNSPEC_RETURN 2)
129 (UNSPEC_MOVE_PIC 3)
130 (UNSPEC_LIBRARY_OFFSET 4)
131 (UNSPEC_PUSH_MULTIPLE 5)
132 ;; Multiply or MAC with extra CONST_INT operand specifying the macflag
133 (UNSPEC_MUL_WITH_FLAG 6)
134 (UNSPEC_MAC_WITH_FLAG 7)
135 (UNSPEC_MOVE_FDPIC 8)
136 (UNSPEC_FUNCDESC_GOT17M4 9)
137 (UNSPEC_LSETUP_END 10)
138 ;; Distinguish a 32-bit version of an insn from a 16-bit version.
139 (UNSPEC_32BIT 11)
140 (UNSPEC_NOP 12)
141 (UNSPEC_ATOMIC 13)])
142
143 (define_constants
144 [(UNSPEC_VOLATILE_CSYNC 1)
145 (UNSPEC_VOLATILE_SSYNC 2)
146 (UNSPEC_VOLATILE_LOAD_FUNCDESC 3)
147 (UNSPEC_VOLATILE_STORE_EH_HANDLER 4)
148 (UNSPEC_VOLATILE_DUMMY 5)
149 (UNSPEC_VOLATILE_STALL 6)])
150
151 (define_constants
152 [(MACFLAG_NONE 0)
153 (MACFLAG_T 1)
154 (MACFLAG_FU 2)
155 (MACFLAG_TFU 3)
156 (MACFLAG_IS 4)
157 (MACFLAG_IU 5)
158 (MACFLAG_W32 6)
159 (MACFLAG_M 7)
160 (MACFLAG_IS_M 8)
161 (MACFLAG_S2RND 9)
162 (MACFLAG_ISS2 10)
163 (MACFLAG_IH 11)])
164
165 (define_attr "type"
166 "move,movcc,mvi,mcld,mcst,dsp32,dsp32shiftimm,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy,stall"
167 (const_string "misc"))
168
169 (define_attr "addrtype" "32bit,preg,spreg,ireg"
170 (cond [(and (eq_attr "type" "mcld")
171 (and (match_operand 0 "dp_register_operand" "")
172 (match_operand 1 "mem_p_address_operand" "")))
173 (const_string "preg")
174 (and (eq_attr "type" "mcld")
175 (and (match_operand 0 "dp_register_operand" "")
176 (match_operand 1 "mem_spfp_address_operand" "")))
177 (const_string "spreg")
178 (and (eq_attr "type" "mcld")
179 (and (match_operand 0 "dp_register_operand" "")
180 (match_operand 1 "mem_i_address_operand" "")))
181 (const_string "ireg")
182 (and (eq_attr "type" "mcst")
183 (and (match_operand 1 "dp_register_operand" "")
184 (match_operand 0 "mem_p_address_operand" "")))
185 (const_string "preg")
186 (and (eq_attr "type" "mcst")
187 (and (match_operand 1 "dp_register_operand" "")
188 (match_operand 0 "mem_spfp_address_operand" "")))
189 (const_string "spreg")
190 (and (eq_attr "type" "mcst")
191 (and (match_operand 1 "dp_register_operand" "")
192 (match_operand 0 "mem_i_address_operand" "")))
193 (const_string "ireg")]
194 (const_string "32bit")))
195
196 (define_attr "storereg" "preg,other"
197 (cond [(and (eq_attr "type" "mcst")
198 (match_operand 1 "p_register_operand" ""))
199 (const_string "preg")]
200 (const_string "other")))
201
202 ;; Scheduling definitions
203
204 (define_automaton "bfin")
205
206 (define_cpu_unit "slot0" "bfin")
207 (define_cpu_unit "slot1" "bfin")
208 (define_cpu_unit "slot2" "bfin")
209
210 ;; Three units used to enforce parallel issue restrictions:
211 ;; only one of the 16-bit slots can use a P register in an address,
212 ;; and only one them can be a store.
213 (define_cpu_unit "store" "bfin")
214 (define_cpu_unit "pregs" "bfin")
215
216 ;; A dummy unit used to delay scheduling of loads after a conditional
217 ;; branch.
218 (define_cpu_unit "load" "bfin")
219
220 ;; A logical unit used to work around anomaly 05000074.
221 (define_cpu_unit "anomaly_05000074" "bfin")
222
223 (define_reservation "core" "slot0+slot1+slot2")
224
225 (define_insn_reservation "alu" 1
226 (eq_attr "type" "move,movcc,mvi,alu0,shft,brcc,br,call,misc,sync,compare")
227 "core")
228
229 (define_insn_reservation "imul" 3
230 (eq_attr "type" "mult")
231 "core*3")
232
233 (define_insn_reservation "dsp32" 1
234 (eq_attr "type" "dsp32")
235 "slot0")
236
237 (define_insn_reservation "dsp32shiftimm" 1
238 (and (eq_attr "type" "dsp32shiftimm")
239 (not (match_test "ENABLE_WA_05000074")))
240 "slot0")
241
242 (define_insn_reservation "dsp32shiftimm_anomaly_05000074" 1
243 (and (eq_attr "type" "dsp32shiftimm")
244 (match_test "ENABLE_WA_05000074"))
245 "slot0+anomaly_05000074")
246
247 (define_insn_reservation "load32" 1
248 (and (not (eq_attr "seq_insns" "multi"))
249 (and (eq_attr "type" "mcld") (eq_attr "addrtype" "32bit")))
250 "core+load")
251
252 (define_insn_reservation "loadp" 1
253 (and (not (eq_attr "seq_insns" "multi"))
254 (and (eq_attr "type" "mcld") (eq_attr "addrtype" "preg")))
255 "slot1+pregs+load")
256
257 (define_insn_reservation "loadsp" 1
258 (and (not (eq_attr "seq_insns" "multi"))
259 (and (eq_attr "type" "mcld") (eq_attr "addrtype" "spreg")))
260 "slot1+pregs")
261
262 (define_insn_reservation "loadi" 1
263 (and (not (eq_attr "seq_insns" "multi"))
264 (and (eq_attr "type" "mcld") (eq_attr "addrtype" "ireg")))
265 "(slot1|slot2)+load")
266
267 (define_insn_reservation "store32" 1
268 (and (not (eq_attr "seq_insns" "multi"))
269 (and (eq_attr "type" "mcst") (eq_attr "addrtype" "32bit")))
270 "core")
271
272 (define_insn_reservation "storep" 1
273 (and (and (not (eq_attr "seq_insns" "multi"))
274 (and (eq_attr "type" "mcst")
275 (ior (eq_attr "addrtype" "preg")
276 (eq_attr "addrtype" "spreg"))))
277 (ior (not (match_test "ENABLE_WA_05000074"))
278 (eq_attr "storereg" "other")))
279 "slot1+pregs+store")
280
281 (define_insn_reservation "storep_anomaly_05000074" 1
282 (and (and (not (eq_attr "seq_insns" "multi"))
283 (and (eq_attr "type" "mcst")
284 (ior (eq_attr "addrtype" "preg")
285 (eq_attr "addrtype" "spreg"))))
286 (and (match_test "ENABLE_WA_05000074")
287 (eq_attr "storereg" "preg")))
288 "slot1+anomaly_05000074+pregs+store")
289
290 (define_insn_reservation "storei" 1
291 (and (and (not (eq_attr "seq_insns" "multi"))
292 (and (eq_attr "type" "mcst") (eq_attr "addrtype" "ireg")))
293 (ior (not (match_test "ENABLE_WA_05000074"))
294 (eq_attr "storereg" "other")))
295 "(slot1|slot2)+store")
296
297 (define_insn_reservation "storei_anomaly_05000074" 1
298 (and (and (not (eq_attr "seq_insns" "multi"))
299 (and (eq_attr "type" "mcst") (eq_attr "addrtype" "ireg")))
300 (and (match_test "ENABLE_WA_05000074")
301 (eq_attr "storereg" "preg")))
302 "((slot1+anomaly_05000074)|slot2)+store")
303
304 (define_insn_reservation "multi" 2
305 (eq_attr "seq_insns" "multi")
306 "core")
307
308 (define_insn_reservation "load_stall1" 1
309 (and (eq_attr "type" "stall")
310 (match_operand 0 "const1_operand" ""))
311 "core+load*2")
312
313 (define_insn_reservation "load_stall3" 1
314 (and (eq_attr "type" "stall")
315 (match_operand 0 "const3_operand" ""))
316 "core+load*4")
317
318 (absence_set "slot0" "slot1,slot2")
319 (absence_set "slot1" "slot2")
320
321 ;; Make sure genautomata knows about the maximum latency that can be produced
322 ;; by the adjust_cost function.
323 (define_insn_reservation "dummy" 5
324 (eq_attr "type" "dummy")
325 "core")
326 \f
327 ;; Operand and operator predicates
328
329 (include "predicates.md")
330 (include "constraints.md")
331 \f
332 ;;; FRIO branches have been optimized for code density
333 ;;; this comes at a slight cost of complexity when
334 ;;; a compiler needs to generate branches in the general
335 ;;; case. In order to generate the correct branching
336 ;;; mechanisms the compiler needs keep track of instruction
337 ;;; lengths. The follow table describes how to count instructions
338 ;;; for the FRIO architecture.
339 ;;;
340 ;;; unconditional br are 12-bit imm pcrelative branches *2
341 ;;; conditional br are 10-bit imm pcrelative branches *2
342 ;;; brcc 10-bit:
343 ;;; 1024 10-bit imm *2 is 2048 (-1024..1022)
344 ;;; br 12-bit :
345 ;;; 4096 12-bit imm *2 is 8192 (-4096..4094)
346 ;;; NOTE : For brcc we generate instructions such as
347 ;;; if cc jmp; jump.[sl] offset
348 ;;; offset of jump.[sl] is from the jump instruction but
349 ;;; gcc calculates length from the if cc jmp instruction
350 ;;; furthermore gcc takes the end address of the branch instruction
351 ;;; as (pc) for a forward branch
352 ;;; hence our range is (-4094, 4092) instead of (-4096, 4094) for a br
353 ;;;
354 ;;; The way the (pc) rtx works in these calculations is somewhat odd;
355 ;;; for backward branches it's the address of the current instruction,
356 ;;; for forward branches it's the previously known address of the following
357 ;;; instruction - we have to take this into account by reducing the range
358 ;;; for a forward branch.
359
360 ;; Lengths for type "mvi" insns are always defined by the instructions
361 ;; themselves.
362 (define_attr "length" ""
363 (cond [(eq_attr "type" "mcld")
364 (if_then_else (match_operand 1 "effective_address_32bit_p" "")
365 (const_int 4) (const_int 2))
366
367 (eq_attr "type" "mcst")
368 (if_then_else (match_operand 0 "effective_address_32bit_p" "")
369 (const_int 4) (const_int 2))
370
371 (eq_attr "type" "move") (const_int 2)
372
373 (eq_attr "type" "dsp32") (const_int 4)
374 (eq_attr "type" "dsp32shiftimm") (const_int 4)
375 (eq_attr "type" "call") (const_int 4)
376
377 (eq_attr "type" "br")
378 (if_then_else (and
379 (le (minus (match_dup 0) (pc)) (const_int 4092))
380 (ge (minus (match_dup 0) (pc)) (const_int -4096)))
381 (const_int 2)
382 (const_int 4))
383
384 (eq_attr "type" "brcc")
385 (cond [(and
386 (le (minus (match_dup 3) (pc)) (const_int 1020))
387 (ge (minus (match_dup 3) (pc)) (const_int -1024)))
388 (const_int 2)
389 (and
390 (le (minus (match_dup 3) (pc)) (const_int 4092))
391 (ge (minus (match_dup 3) (pc)) (const_int -4094)))
392 (const_int 4)]
393 (const_int 6))
394 ]
395
396 (const_int 2)))
397
398 ;; Classify the insns into those that are one instruction and those that
399 ;; are more than one in sequence.
400 (define_attr "seq_insns" "single,multi"
401 (const_string "single"))
402
403 ;; Describe a user's asm statement.
404 (define_asm_attributes
405 [(set_attr "type" "misc")
406 (set_attr "seq_insns" "multi")
407 (set_attr "length" "4")])
408
409 ;; Conditional moves
410
411 (define_mode_iterator CCMOV [QI HI SI])
412
413 (define_expand "mov<mode>cc"
414 [(set (match_operand:CCMOV 0 "register_operand" "")
415 (if_then_else:CCMOV (match_operand 1 "comparison_operator" "")
416 (match_operand:CCMOV 2 "register_operand" "")
417 (match_operand:CCMOV 3 "register_operand" "")))]
418 ""
419 {
420 operands[1] = bfin_gen_compare (operands[1], <MODE>mode);
421 })
422
423 (define_insn "*mov<mode>cc_insn1"
424 [(set (match_operand:CCMOV 0 "register_operand" "=da,da,da")
425 (if_then_else:CCMOV
426 (eq:BI (match_operand:BI 3 "register_operand" "C,C,C")
427 (const_int 0))
428 (match_operand:CCMOV 1 "register_operand" "da,0,da")
429 (match_operand:CCMOV 2 "register_operand" "0,da,da")))]
430 ""
431 "@
432 if !cc %0 = %1;
433 if cc %0 = %2;
434 if !cc %0 = %1; if cc %0 = %2;"
435 [(set_attr "length" "2,2,4")
436 (set_attr "type" "movcc")
437 (set_attr "seq_insns" "*,*,multi")])
438
439 (define_insn "*mov<mode>cc_insn2"
440 [(set (match_operand:CCMOV 0 "register_operand" "=da,da,da")
441 (if_then_else:CCMOV
442 (ne:BI (match_operand:BI 3 "register_operand" "C,C,C")
443 (const_int 0))
444 (match_operand:CCMOV 1 "register_operand" "0,da,da")
445 (match_operand:CCMOV 2 "register_operand" "da,0,da")))]
446 ""
447 "@
448 if !cc %0 = %2;
449 if cc %0 = %1;
450 if cc %0 = %1; if !cc %0 = %2;"
451 [(set_attr "length" "2,2,4")
452 (set_attr "type" "movcc")
453 (set_attr "seq_insns" "*,*,multi")])
454
455 ;; Insns to load HIGH and LO_SUM
456
457 (define_insn "movsi_high"
458 [(set (match_operand:SI 0 "register_operand" "=x")
459 (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
460 "reload_completed"
461 "%d0 = %d1;"
462 [(set_attr "type" "mvi")
463 (set_attr "length" "4")])
464
465 (define_insn "movstricthi_high"
466 [(set (match_operand:SI 0 "register_operand" "+x")
467 (ior:SI (and:SI (match_dup 0) (const_int 65535))
468 (match_operand:SI 1 "immediate_operand" "i")))]
469 "reload_completed"
470 "%d0 = %d1;"
471 [(set_attr "type" "mvi")
472 (set_attr "length" "4")])
473
474 (define_insn "movsi_low"
475 [(set (match_operand:SI 0 "register_operand" "=x")
476 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
477 (match_operand:SI 2 "immediate_operand" "i")))]
478 "reload_completed"
479 "%h0 = %h2;"
480 [(set_attr "type" "mvi")
481 (set_attr "length" "4")])
482
483 (define_insn "movsi_high_pic"
484 [(set (match_operand:SI 0 "register_operand" "=x")
485 (high:SI (unspec:SI [(match_operand:SI 1 "" "")]
486 UNSPEC_MOVE_PIC)))]
487 ""
488 "%d0 = %1@GOT_LOW;"
489 [(set_attr "type" "mvi")
490 (set_attr "length" "4")])
491
492 (define_insn "movsi_low_pic"
493 [(set (match_operand:SI 0 "register_operand" "=x")
494 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
495 (unspec:SI [(match_operand:SI 2 "" "")]
496 UNSPEC_MOVE_PIC)))]
497 ""
498 "%h0 = %h2@GOT_HIGH;"
499 [(set_attr "type" "mvi")
500 (set_attr "length" "4")])
501
502 ;;; Move instructions
503
504 (define_insn_and_split "movdi_insn"
505 [(set (match_operand:DI 0 "nonimmediate_operand" "=x,mx,r")
506 (match_operand:DI 1 "general_operand" "iFx,r,mx"))]
507 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
508 "#"
509 "reload_completed"
510 [(set (match_dup 2) (match_dup 3))
511 (set (match_dup 4) (match_dup 5))]
512 {
513 rtx lo_half[2], hi_half[2];
514 split_di (operands, 2, lo_half, hi_half);
515
516 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
517 {
518 operands[2] = hi_half[0];
519 operands[3] = hi_half[1];
520 operands[4] = lo_half[0];
521 operands[5] = lo_half[1];
522 }
523 else
524 {
525 operands[2] = lo_half[0];
526 operands[3] = lo_half[1];
527 operands[4] = hi_half[0];
528 operands[5] = hi_half[1];
529 }
530 })
531
532 (define_insn "movbi"
533 [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,md,C,d,C,P1")
534 (match_operand:BI 1 "general_operand" "x,xKs3,md,d,d,C,P0,P1"))]
535
536 ""
537 "@
538 %0 = %1;
539 %0 = %1 (X);
540 %0 = B %1 (Z)%!
541 B %0 = %1;
542 CC = %1;
543 %0 = CC;
544 CC = R0 < R0;
545 CC = R0 == R0;"
546 [(set_attr "type" "move,mvi,mcld,mcst,compare,compare,compare,compare")
547 (set_attr "length" "2,2,*,*,2,2,2,2")
548 (set_attr "seq_insns" "*,*,*,*,*,*,*,*")])
549
550 (define_insn "movpdi"
551 [(set (match_operand:PDI 0 "nonimmediate_operand" "=e,<,e")
552 (match_operand:PDI 1 "general_operand" " e,e,>"))]
553 ""
554 "@
555 %0 = %1;
556 %0 = %x1; %0 = %w1;
557 %w0 = %1; %x0 = %1;"
558 [(set_attr "type" "move,mcst,mcld")
559 (set_attr "length" "4,*,*")
560 (set_attr "seq_insns" "*,multi,multi")])
561
562 (define_insn "load_accumulator"
563 [(set (match_operand:PDI 0 "register_operand" "=e")
564 (sign_extend:PDI (match_operand:SI 1 "register_operand" "d")))]
565 ""
566 "%0 = %1;"
567 [(set_attr "type" "move")])
568
569 (define_insn_and_split "load_accumulator_pair"
570 [(set (match_operand:V2PDI 0 "register_operand" "=e")
571 (sign_extend:V2PDI (vec_concat:V2SI
572 (match_operand:SI 1 "register_operand" "d")
573 (match_operand:SI 2 "register_operand" "d"))))]
574 ""
575 "#"
576 "reload_completed"
577 [(set (match_dup 3) (sign_extend:PDI (match_dup 1)))
578 (set (match_dup 4) (sign_extend:PDI (match_dup 2)))]
579 {
580 operands[3] = gen_rtx_REG (PDImode, REGNO (operands[0]));
581 operands[4] = gen_rtx_REG (PDImode, REGNO (operands[0]) + 1);
582 })
583
584 (define_insn "*pushsi_insn"
585 [(set (mem:SI (pre_dec:SI (reg:SI REG_SP)))
586 (match_operand:SI 0 "register_operand" "xy"))]
587 ""
588 "[--SP] = %0;"
589 [(set_attr "type" "mcst")
590 (set_attr "addrtype" "32bit")
591 (set_attr "length" "2")])
592
593 (define_insn "*popsi_insn"
594 [(set (match_operand:SI 0 "register_operand" "=d,xy")
595 (mem:SI (post_inc:SI (reg:SI REG_SP))))]
596 ""
597 "%0 = [SP++]%!"
598 [(set_attr "type" "mcld")
599 (set_attr "addrtype" "preg,32bit")
600 (set_attr "length" "2")])
601
602 ;; The first alternative is used to make reload choose a limited register
603 ;; class when faced with a movsi_insn that had its input operand replaced
604 ;; with a PLUS. We generally require fewer secondary reloads this way.
605
606 (define_insn "*movsi_insn"
607 [(set (match_operand:SI 0 "nonimmediate_operand" "=da,x,da,y,da,x,x,x,da,mr")
608 (match_operand:SI 1 "general_operand" "da,x,y,da,xKs7,xKsh,xKuh,ix,mr,da"))]
609 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
610 "@
611 %0 = %1;
612 %0 = %1;
613 %0 = %1;
614 %0 = %1;
615 %0 = %1 (X);
616 %0 = %1 (X);
617 %0 = %1 (Z);
618 #
619 %0 = %1%!
620 %0 = %1%!"
621 [(set_attr "type" "move,move,move,move,mvi,mvi,mvi,*,mcld,mcst")
622 (set_attr "length" "2,2,2,2,2,4,4,*,*,*")])
623
624 (define_insn "*movsi_insn32"
625 [(set (match_operand:SI 0 "register_operand" "=d,d")
626 (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "d,P0")] UNSPEC_32BIT))]
627 ""
628 "@
629 %0 = ROT %1 BY 0%!
630 %0 = %0 -|- %0%!"
631 [(set_attr "type" "dsp32shiftimm,dsp32")])
632
633 (define_split
634 [(set (match_operand:SI 0 "d_register_operand" "")
635 (const_int 0))]
636 "splitting_for_sched && !optimize_size"
637 [(set (match_dup 0) (unspec:SI [(const_int 0)] UNSPEC_32BIT))])
638
639 (define_split
640 [(set (match_operand:SI 0 "d_register_operand" "")
641 (match_operand:SI 1 "d_register_operand" ""))]
642 "splitting_for_sched && !optimize_size"
643 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_32BIT))])
644
645 (define_insn_and_split "*movv2hi_insn"
646 [(set (match_operand:V2HI 0 "nonimmediate_operand" "=da,da,d,dm")
647 (match_operand:V2HI 1 "general_operand" "i,di,md,d"))]
648
649 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
650 "@
651 #
652 %0 = %1;
653 %0 = %1%!
654 %0 = %1%!"
655 "reload_completed && GET_CODE (operands[1]) == CONST_VECTOR"
656 [(set (match_dup 0) (high:SI (match_dup 2)))
657 (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 3)))]
658 {
659 HOST_WIDE_INT intval = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
660 intval |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
661
662 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
663 operands[2] = operands[3] = GEN_INT (trunc_int_for_mode (intval, SImode));
664 }
665 [(set_attr "type" "move,move,mcld,mcst")
666 (set_attr "length" "2,2,*,*")])
667
668 (define_insn "*movhi_insn"
669 [(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr")
670 (match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
671 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
672 {
673 static const char *templates[] = {
674 "%0 = %1;",
675 "%0 = %1 (X);",
676 "%0 = %1 (X);",
677 "%0 = W %1 (X)%!",
678 "W %0 = %1%!",
679 "%h0 = W %1%!",
680 "W %0 = %h1%!"
681 };
682 int alt = which_alternative;
683 rtx mem = (MEM_P (operands[0]) ? operands[0]
684 : MEM_P (operands[1]) ? operands[1] : NULL_RTX);
685 if (mem && bfin_dsp_memref_p (mem))
686 alt += 2;
687 return templates[alt];
688 }
689 [(set_attr "type" "move,mvi,mvi,mcld,mcst")
690 (set_attr "length" "2,2,4,*,*")])
691
692 (define_insn "*movqi_insn"
693 [(set (match_operand:QI 0 "nonimmediate_operand" "=x,da,x,d,mr")
694 (match_operand:QI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
695 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
696 "@
697 %0 = %1;
698 %0 = %1 (X);
699 %0 = %1 (X);
700 %0 = B %1 (X)%!
701 B %0 = %1%!"
702 [(set_attr "type" "move,mvi,mvi,mcld,mcst")
703 (set_attr "length" "2,2,4,*,*")])
704
705 (define_insn "*movsf_insn"
706 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,da,mr")
707 (match_operand:SF 1 "general_operand" "x,Fx,mr,da"))]
708 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
709 "@
710 %0 = %1;
711 #
712 %0 = %1%!
713 %0 = %1%!"
714 [(set_attr "type" "move,*,mcld,mcst")])
715
716 (define_insn_and_split "movdf_insn"
717 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,mx,r")
718 (match_operand:DF 1 "general_operand" "iFx,r,mx"))]
719 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
720 "#"
721 "reload_completed"
722 [(set (match_dup 2) (match_dup 3))
723 (set (match_dup 4) (match_dup 5))]
724 {
725 rtx lo_half[2], hi_half[2];
726 split_di (operands, 2, lo_half, hi_half);
727
728 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
729 {
730 operands[2] = hi_half[0];
731 operands[3] = hi_half[1];
732 operands[4] = lo_half[0];
733 operands[5] = lo_half[1];
734 }
735 else
736 {
737 operands[2] = lo_half[0];
738 operands[3] = lo_half[1];
739 operands[4] = hi_half[0];
740 operands[5] = hi_half[1];
741 }
742 })
743
744 ;; Storing halfwords.
745 (define_insn "*movsi_insv"
746 [(set (zero_extract:SI (match_operand 0 "register_operand" "+d,x")
747 (const_int 16)
748 (const_int 16))
749 (match_operand:SI 1 "nonmemory_operand" "d,n"))]
750 ""
751 "@
752 %d0 = %h1 << 0%!
753 %d0 = %1;"
754 [(set_attr "type" "dsp32shiftimm,mvi")
755 (set_attr "length" "*,4")])
756
757 (define_expand "insv"
758 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
759 (match_operand:SI 1 "immediate_operand" "")
760 (match_operand:SI 2 "immediate_operand" ""))
761 (match_operand:SI 3 "nonmemory_operand" ""))]
762 ""
763 {
764 if (INTVAL (operands[1]) != 16 || INTVAL (operands[2]) != 16)
765 FAIL;
766
767 /* From mips.md: insert_bit_field doesn't verify that our source
768 matches the predicate, so check it again here. */
769 if (! register_operand (operands[0], VOIDmode))
770 FAIL;
771 })
772
773 ;; This is the main "hook" for PIC code. When generating
774 ;; PIC, movsi is responsible for determining when the source address
775 ;; needs PIC relocation and appropriately calling legitimize_pic_address
776 ;; to perform the actual relocation.
777
778 (define_expand "movsi"
779 [(set (match_operand:SI 0 "nonimmediate_operand" "")
780 (match_operand:SI 1 "general_operand" ""))]
781 ""
782 {
783 if (expand_move (operands, SImode))
784 DONE;
785 })
786
787 (define_expand "movv2hi"
788 [(set (match_operand:V2HI 0 "nonimmediate_operand" "")
789 (match_operand:V2HI 1 "general_operand" ""))]
790 ""
791 "expand_move (operands, V2HImode);")
792
793 (define_expand "movdi"
794 [(set (match_operand:DI 0 "nonimmediate_operand" "")
795 (match_operand:DI 1 "general_operand" ""))]
796 ""
797 "expand_move (operands, DImode);")
798
799 (define_expand "movsf"
800 [(set (match_operand:SF 0 "nonimmediate_operand" "")
801 (match_operand:SF 1 "general_operand" ""))]
802 ""
803 "expand_move (operands, SFmode);")
804
805 (define_expand "movdf"
806 [(set (match_operand:DF 0 "nonimmediate_operand" "")
807 (match_operand:DF 1 "general_operand" ""))]
808 ""
809 "expand_move (operands, DFmode);")
810
811 (define_expand "movhi"
812 [(set (match_operand:HI 0 "nonimmediate_operand" "")
813 (match_operand:HI 1 "general_operand" ""))]
814 ""
815 "expand_move (operands, HImode);")
816
817 (define_expand "movqi"
818 [(set (match_operand:QI 0 "nonimmediate_operand" "")
819 (match_operand:QI 1 "general_operand" ""))]
820 ""
821 " expand_move (operands, QImode); ")
822
823 ;; Some define_splits to break up SI/SFmode loads of immediate constants.
824
825 (define_split
826 [(set (match_operand:SI 0 "register_operand" "")
827 (match_operand:SI 1 "symbolic_or_const_operand" ""))]
828 "reload_completed
829 /* Always split symbolic operands; split integer constants that are
830 too large for a single instruction. */
831 && (GET_CODE (operands[1]) != CONST_INT
832 || (INTVAL (operands[1]) < -32768
833 || INTVAL (operands[1]) >= 65536
834 || (INTVAL (operands[1]) >= 32768 && PREG_P (operands[0]))))"
835 [(set (match_dup 0) (high:SI (match_dup 1)))
836 (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))]
837 {
838 if (GET_CODE (operands[1]) == CONST_INT
839 && split_load_immediate (operands))
840 DONE;
841 /* ??? Do something about TARGET_LOW_64K. */
842 })
843
844 (define_split
845 [(set (match_operand:SF 0 "register_operand" "")
846 (match_operand:SF 1 "immediate_operand" ""))]
847 "reload_completed"
848 [(set (match_dup 2) (high:SI (match_dup 3)))
849 (set (match_dup 2) (lo_sum:SI (match_dup 2) (match_dup 3)))]
850 {
851 long values;
852
853 gcc_assert (GET_CODE (operands[1]) == CONST_DOUBLE);
854
855 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), values);
856
857 operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0]));
858 operands[3] = GEN_INT (trunc_int_for_mode (values, SImode));
859 if (values >= -32768 && values < 65536)
860 {
861 emit_move_insn (operands[2], operands[3]);
862 DONE;
863 }
864 if (split_load_immediate (operands + 2))
865 DONE;
866 })
867
868 ;; Sadly, this can't be a proper named movstrict pattern, since the compiler
869 ;; expects to be able to use registers for operand 1.
870 ;; Note that the asm instruction is defined by the manual to take an unsigned
871 ;; constant, but it doesn't matter to the assembler, and the compiler only
872 ;; deals with sign-extended constants. Hence "Ksh".
873 (define_insn "movstricthi_1"
874 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+x"))
875 (match_operand:HI 1 "immediate_operand" "Ksh"))]
876 ""
877 "%h0 = %1;"
878 [(set_attr "type" "mvi")
879 (set_attr "length" "4")])
880
881 ;; Sign and zero extensions
882
883 (define_insn_and_split "extendhisi2"
884 [(set (match_operand:SI 0 "register_operand" "=d, d")
885 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
886 ""
887 "@
888 %0 = %h1 (X);
889 %0 = W %h1 (X)%!"
890 "reload_completed && bfin_dsp_memref_p (operands[1])"
891 [(set (match_dup 2) (match_dup 1))
892 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
893 {
894 operands[2] = gen_lowpart (HImode, operands[0]);
895 }
896 [(set_attr "type" "alu0,mcld")])
897
898 (define_insn_and_split "zero_extendhisi2"
899 [(set (match_operand:SI 0 "register_operand" "=d, d")
900 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
901 ""
902 "@
903 %0 = %h1 (Z);
904 %0 = W %h1 (Z)%!"
905 "reload_completed && bfin_dsp_memref_p (operands[1])"
906 [(set (match_dup 2) (match_dup 1))
907 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
908 {
909 operands[2] = gen_lowpart (HImode, operands[0]);
910 }
911 [(set_attr "type" "alu0,mcld")])
912
913 (define_insn "zero_extendbisi2"
914 [(set (match_operand:SI 0 "register_operand" "=d")
915 (zero_extend:SI (match_operand:BI 1 "nonimmediate_operand" "C")))]
916 ""
917 "%0 = %1;"
918 [(set_attr "type" "compare")])
919
920 (define_insn "extendqihi2"
921 [(set (match_operand:HI 0 "register_operand" "=d, d")
922 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
923 ""
924 "@
925 %0 = B %1 (X)%!
926 %0 = %T1 (X);"
927 [(set_attr "type" "mcld,alu0")])
928
929 (define_insn "extendqisi2"
930 [(set (match_operand:SI 0 "register_operand" "=d, d")
931 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
932 ""
933 "@
934 %0 = B %1 (X)%!
935 %0 = %T1 (X);"
936 [(set_attr "type" "mcld,alu0")])
937
938
939 (define_insn "zero_extendqihi2"
940 [(set (match_operand:HI 0 "register_operand" "=d, d")
941 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
942 ""
943 "@
944 %0 = B %1 (Z)%!
945 %0 = %T1 (Z);"
946 [(set_attr "type" "mcld,alu0")])
947
948
949 (define_insn "zero_extendqisi2"
950 [(set (match_operand:SI 0 "register_operand" "=d, d")
951 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
952 ""
953 "@
954 %0 = B %1 (Z)%!
955 %0 = %T1 (Z);"
956 [(set_attr "type" "mcld,alu0")])
957
958 ;; DImode logical operations
959
960 (define_code_iterator any_logical [and ior xor])
961 (define_code_attr optab [(and "and")
962 (ior "ior")
963 (xor "xor")])
964 (define_code_attr op [(and "&")
965 (ior "|")
966 (xor "^")])
967 (define_code_attr high_result [(and "0")
968 (ior "%H1")
969 (xor "%H1")])
970
971 ;; Keep this pattern around to avoid generating NO_CONFLICT blocks.
972 (define_expand "<optab>di3"
973 [(set (match_operand:DI 0 "register_operand" "=d")
974 (any_logical:DI (match_operand:DI 1 "register_operand" "0")
975 (match_operand:DI 2 "general_operand" "d")))]
976 ""
977 {
978 rtx hi_half[3], lo_half[3];
979 enum insn_code icode = CODE_FOR_<optab>si3;
980 if (!reg_overlap_mentioned_p (operands[0], operands[1])
981 && !reg_overlap_mentioned_p (operands[0], operands[2]))
982 emit_clobber (operands[0]);
983 split_di (operands, 3, lo_half, hi_half);
984 if (!(*insn_data[icode].operand[2].predicate) (lo_half[2], SImode))
985 lo_half[2] = force_reg (SImode, lo_half[2]);
986 emit_insn (GEN_FCN (icode) (lo_half[0], lo_half[1], lo_half[2]));
987 if (!(*insn_data[icode].operand[2].predicate) (hi_half[2], SImode))
988 hi_half[2] = force_reg (SImode, hi_half[2]);
989 emit_insn (GEN_FCN (icode) (hi_half[0], hi_half[1], hi_half[2]));
990 DONE;
991 })
992
993 (define_insn "zero_extendqidi2"
994 [(set (match_operand:DI 0 "register_operand" "=d")
995 (zero_extend:DI (match_operand:QI 1 "register_operand" "d")))]
996 ""
997 "%0 = %T1 (Z);\\n\\t%H0 = 0;"
998 [(set_attr "length" "4")
999 (set_attr "seq_insns" "multi")])
1000
1001 (define_insn "zero_extendhidi2"
1002 [(set (match_operand:DI 0 "register_operand" "=d")
1003 (zero_extend:DI (match_operand:HI 1 "register_operand" "d")))]
1004 ""
1005 "%0 = %h1 (Z);\\n\\t%H0 = 0;"
1006 [(set_attr "length" "4")
1007 (set_attr "seq_insns" "multi")])
1008
1009 (define_insn_and_split "extendsidi2"
1010 [(set (match_operand:DI 0 "register_operand" "=d")
1011 (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))]
1012 ""
1013 "#"
1014 "reload_completed"
1015 [(set (match_dup 3) (match_dup 1))
1016 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
1017 {
1018 split_di (operands, 1, operands + 2, operands + 3);
1019 if (REGNO (operands[0]) != REGNO (operands[1]))
1020 emit_move_insn (operands[2], operands[1]);
1021 })
1022
1023 (define_insn_and_split "extendqidi2"
1024 [(set (match_operand:DI 0 "register_operand" "=d")
1025 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
1026 ""
1027 "#"
1028 "reload_completed"
1029 [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
1030 (set (match_dup 3) (sign_extend:SI (match_dup 1)))
1031 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
1032 {
1033 split_di (operands, 1, operands + 2, operands + 3);
1034 })
1035
1036 (define_insn_and_split "extendhidi2"
1037 [(set (match_operand:DI 0 "register_operand" "=d")
1038 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
1039 ""
1040 "#"
1041 "reload_completed"
1042 [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
1043 (set (match_dup 3) (sign_extend:SI (match_dup 1)))
1044 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
1045 {
1046 split_di (operands, 1, operands + 2, operands + 3);
1047 })
1048
1049 ;; DImode arithmetic operations
1050
1051 (define_insn "add_with_carry"
1052 [(set (match_operand:SI 0 "register_operand" "=d,d")
1053 (plus:SI (match_operand:SI 1 "register_operand" "%0,d")
1054 (match_operand:SI 2 "nonmemory_operand" "Ks7,d")))
1055 (set (match_operand:BI 3 "register_operand" "=C,C")
1056 (ltu:BI (not:SI (match_dup 1)) (match_dup 2)))]
1057 ""
1058 "@
1059 %0 += %2; cc = ac0;
1060 %0 = %1 + %2; cc = ac0;"
1061 [(set_attr "type" "alu0")
1062 (set_attr "length" "4")
1063 (set_attr "seq_insns" "multi")])
1064
1065 (define_insn "sub_with_carry"
1066 [(set (match_operand:SI 0 "register_operand" "=d")
1067 (minus:SI (match_operand:SI 1 "register_operand" "%d")
1068 (match_operand:SI 2 "nonmemory_operand" "d")))
1069 (set (match_operand:BI 3 "register_operand" "=C")
1070 (leu:BI (match_dup 2) (match_dup 1)))]
1071 ""
1072 "%0 = %1 - %2; cc = ac0;"
1073 [(set_attr "type" "alu0")
1074 (set_attr "length" "4")
1075 (set_attr "seq_insns" "multi")])
1076
1077 (define_expand "adddi3"
1078 [(set (match_operand:DI 0 "register_operand" "")
1079 (plus:DI (match_operand:DI 1 "register_operand" "")
1080 (match_operand:DI 2 "nonmemory_operand" "")))
1081 (clobber (match_scratch:SI 3 ""))
1082 (clobber (reg:CC 34))]
1083 ""
1084 {
1085 rtx xops[8];
1086 xops[0] = gen_lowpart (SImode, operands[0]);
1087 xops[1] = simplify_gen_subreg (SImode, operands[0], DImode, 4);
1088 xops[2] = gen_lowpart (SImode, operands[1]);
1089 xops[3] = simplify_gen_subreg (SImode, operands[1], DImode, 4);
1090 xops[4] = gen_lowpart (SImode, operands[2]);
1091 xops[5] = simplify_gen_subreg (SImode, operands[2], DImode, 4);
1092 xops[6] = gen_reg_rtx (SImode);
1093 xops[7] = gen_rtx_REG (BImode, REG_CC);
1094 if (!register_operand (xops[4], SImode)
1095 && (GET_CODE (xops[4]) != CONST_INT
1096 || !satisfies_constraint_Ks7 (xops[4])))
1097 xops[4] = force_reg (SImode, xops[4]);
1098 if (!reg_overlap_mentioned_p (operands[0], operands[1])
1099 && !reg_overlap_mentioned_p (operands[0], operands[2]))
1100 emit_clobber (operands[0]);
1101 emit_insn (gen_add_with_carry (xops[0], xops[2], xops[4], xops[7]));
1102 emit_insn (gen_movbisi (xops[6], xops[7]));
1103 if (!register_operand (xops[5], SImode)
1104 && (GET_CODE (xops[5]) != CONST_INT
1105 || !satisfies_constraint_Ks7 (xops[5])))
1106 xops[5] = force_reg (SImode, xops[5]);
1107 if (xops[5] != const0_rtx)
1108 emit_insn (gen_addsi3 (xops[1], xops[3], xops[5]));
1109 else
1110 emit_move_insn (xops[1], xops[3]);
1111 emit_insn (gen_addsi3 (xops[1], xops[1], xops[6]));
1112 DONE;
1113 })
1114
1115 (define_expand "subdi3"
1116 [(set (match_operand:DI 0 "register_operand" "")
1117 (minus:DI (match_operand:DI 1 "register_operand" "")
1118 (match_operand:DI 2 "register_operand" "")))
1119 (clobber (reg:CC 34))]
1120 ""
1121 {
1122 rtx xops[8];
1123 xops[0] = gen_lowpart (SImode, operands[0]);
1124 xops[1] = simplify_gen_subreg (SImode, operands[0], DImode, 4);
1125 xops[2] = gen_lowpart (SImode, operands[1]);
1126 xops[3] = simplify_gen_subreg (SImode, operands[1], DImode, 4);
1127 xops[4] = gen_lowpart (SImode, operands[2]);
1128 xops[5] = simplify_gen_subreg (SImode, operands[2], DImode, 4);
1129 xops[6] = gen_reg_rtx (SImode);
1130 xops[7] = gen_rtx_REG (BImode, REG_CC);
1131 if (!reg_overlap_mentioned_p (operands[0], operands[1])
1132 && !reg_overlap_mentioned_p (operands[0], operands[2]))
1133 emit_clobber (operands[0]);
1134 emit_insn (gen_sub_with_carry (xops[0], xops[2], xops[4], xops[7]));
1135 emit_insn (gen_notbi (xops[7], xops[7]));
1136 emit_insn (gen_movbisi (xops[6], xops[7]));
1137 emit_insn (gen_subsi3 (xops[1], xops[3], xops[5]));
1138 emit_insn (gen_subsi3 (xops[1], xops[1], xops[6]));
1139 DONE;
1140 })
1141
1142 ;; Combined shift/add instructions
1143
1144 (define_insn ""
1145 [(set (match_operand:SI 0 "register_operand" "=a,d")
1146 (ashift:SI (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
1147 (match_operand:SI 2 "register_operand" "a,d"))
1148 (match_operand:SI 3 "pos_scale_operand" "P1P2,P1P2")))]
1149 ""
1150 "%0 = (%0 + %2) << %3;" /* "shadd %0,%2,%3;" */
1151 [(set_attr "type" "alu0")])
1152
1153 (define_insn ""
1154 [(set (match_operand:SI 0 "register_operand" "=a")
1155 (plus:SI (match_operand:SI 1 "register_operand" "a")
1156 (mult:SI (match_operand:SI 2 "register_operand" "a")
1157 (match_operand:SI 3 "scale_by_operand" "i"))))]
1158 ""
1159 "%0 = %1 + (%2 << %X3);"
1160 [(set_attr "type" "alu0")])
1161
1162 (define_insn ""
1163 [(set (match_operand:SI 0 "register_operand" "=a")
1164 (plus:SI (match_operand:SI 1 "register_operand" "a")
1165 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1166 (match_operand:SI 3 "pos_scale_operand" "i"))))]
1167 ""
1168 "%0 = %1 + (%2 << %3);"
1169 [(set_attr "type" "alu0")])
1170
1171 (define_insn ""
1172 [(set (match_operand:SI 0 "register_operand" "=a")
1173 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "a")
1174 (match_operand:SI 2 "scale_by_operand" "i"))
1175 (match_operand:SI 3 "register_operand" "a")))]
1176 ""
1177 "%0 = %3 + (%1 << %X2);"
1178 [(set_attr "type" "alu0")])
1179
1180 (define_insn ""
1181 [(set (match_operand:SI 0 "register_operand" "=a")
1182 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "a")
1183 (match_operand:SI 2 "pos_scale_operand" "i"))
1184 (match_operand:SI 3 "register_operand" "a")))]
1185 ""
1186 "%0 = %3 + (%1 << %2);"
1187 [(set_attr "type" "alu0")])
1188
1189 (define_insn "mulhisi3"
1190 [(set (match_operand:SI 0 "register_operand" "=d")
1191 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%d"))
1192 (sign_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
1193 ""
1194 "%0 = %h1 * %h2 (IS)%!"
1195 [(set_attr "type" "dsp32")])
1196
1197 (define_insn "umulhisi3"
1198 [(set (match_operand:SI 0 "register_operand" "=d")
1199 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%d"))
1200 (zero_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
1201 ""
1202 "%0 = %h1 * %h2 (FU)%!"
1203 [(set_attr "type" "dsp32")])
1204
1205 (define_insn "usmulhisi3"
1206 [(set (match_operand:SI 0 "register_operand" "=W")
1207 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "W"))
1208 (sign_extend:SI (match_operand:HI 2 "register_operand" "W"))))]
1209 ""
1210 "%0 = %h2 * %h1 (IS,M)%!"
1211 [(set_attr "type" "dsp32")])
1212
1213 ;; The alternative involving IREGS requires that the corresponding L register
1214 ;; is zero.
1215
1216 (define_insn "addsi3"
1217 [(set (match_operand:SI 0 "register_operand" "=ad,a,d,b")
1218 (plus:SI (match_operand:SI 1 "register_operand" "%0, a,d,0")
1219 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7, a,d,fP2P4")))]
1220 ""
1221 "@
1222 %0 += %2;
1223 %0 = %1 + %2;
1224 %0 = %1 + %2;
1225 %0 += %2;"
1226 [(set_attr "type" "alu0")
1227 (set_attr "length" "2,2,2,2")])
1228
1229 (define_insn "ssaddsi3"
1230 [(set (match_operand:SI 0 "register_operand" "=d")
1231 (ss_plus:SI (match_operand:SI 1 "register_operand" "d")
1232 (match_operand:SI 2 "register_operand" "d")))]
1233 ""
1234 "%0 = %1 + %2 (S)%!"
1235 [(set_attr "type" "dsp32")])
1236
1237 (define_insn "subsi3"
1238 [(set (match_operand:SI 0 "register_operand" "=da,d,a")
1239 (minus:SI (match_operand:SI 1 "register_operand" "0,d,0")
1240 (match_operand:SI 2 "reg_or_neg7bit_operand" "KN7,d,a")))]
1241 ""
1242 {
1243 static const char *const strings_subsi3[] = {
1244 "%0 += -%2;",
1245 "%0 = %1 - %2;",
1246 "%0 -= %2;",
1247 };
1248
1249 if (CONSTANT_P (operands[2]) && INTVAL (operands[2]) < 0) {
1250 rtx tmp_op = operands[2];
1251 operands[2] = GEN_INT (-INTVAL (operands[2]));
1252 output_asm_insn ("%0 += %2;", operands);
1253 operands[2] = tmp_op;
1254 return "";
1255 }
1256
1257 return strings_subsi3[which_alternative];
1258 }
1259 [(set_attr "type" "alu0")])
1260
1261 (define_insn "sssubsi3"
1262 [(set (match_operand:SI 0 "register_operand" "=d")
1263 (ss_minus:SI (match_operand:SI 1 "register_operand" "d")
1264 (match_operand:SI 2 "register_operand" "d")))]
1265 ""
1266 "%0 = %1 - %2 (S)%!"
1267 [(set_attr "type" "dsp32")])
1268
1269 ;; Accumulator addition
1270
1271 (define_insn "addpdi3"
1272 [(set (match_operand:PDI 0 "register_operand" "=A")
1273 (ss_plus:PDI (match_operand:PDI 1 "register_operand" "%0")
1274 (match_operand:PDI 2 "nonmemory_operand" "B")))]
1275 ""
1276 "A0 += A1%!"
1277 [(set_attr "type" "dsp32")])
1278
1279 (define_insn "sum_of_accumulators"
1280 [(set (match_operand:SI 0 "register_operand" "=d")
1281 (ss_truncate:SI
1282 (ss_plus:PDI (match_operand:PDI 2 "register_operand" "1")
1283 (match_operand:PDI 3 "register_operand" "B"))))
1284 (set (match_operand:PDI 1 "register_operand" "=A")
1285 (ss_plus:PDI (match_dup 2) (match_dup 3)))]
1286 ""
1287 "%0 = (A0 += A1)%!"
1288 [(set_attr "type" "dsp32")])
1289
1290 (define_insn "us_truncpdisi2"
1291 [(set (match_operand:SI 0 "register_operand" "=D,W")
1292 (us_truncate:SI (match_operand:PDI 1 "register_operand" "A,B")))]
1293 ""
1294 "%0 = %1 (FU)%!"
1295 [(set_attr "type" "dsp32")])
1296
1297 ;; Bit test instructions
1298
1299 (define_insn "*not_bittst"
1300 [(set (match_operand:BI 0 "register_operand" "=C")
1301 (eq:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1302 (const_int 1)
1303 (match_operand:SI 2 "immediate_operand" "Ku5"))
1304 (const_int 0)))]
1305 ""
1306 "cc = !BITTST (%1,%2);"
1307 [(set_attr "type" "alu0")])
1308
1309 (define_insn "*bittst"
1310 [(set (match_operand:BI 0 "register_operand" "=C")
1311 (ne:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1312 (const_int 1)
1313 (match_operand:SI 2 "immediate_operand" "Ku5"))
1314 (const_int 0)))]
1315 ""
1316 "cc = BITTST (%1,%2);"
1317 [(set_attr "type" "alu0")])
1318
1319 (define_insn_and_split "*bit_extract"
1320 [(set (match_operand:SI 0 "register_operand" "=d")
1321 (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1322 (const_int 1)
1323 (match_operand:SI 2 "immediate_operand" "Ku5")))
1324 (clobber (reg:BI REG_CC))]
1325 ""
1326 "#"
1327 ""
1328 [(set (reg:BI REG_CC)
1329 (ne:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1330 (const_int 0)))
1331 (set (match_dup 0)
1332 (ne:SI (reg:BI REG_CC) (const_int 0)))])
1333
1334 (define_insn_and_split "*not_bit_extract"
1335 [(set (match_operand:SI 0 "register_operand" "=d")
1336 (zero_extract:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1337 (const_int 1)
1338 (match_operand:SI 2 "immediate_operand" "Ku5")))
1339 (clobber (reg:BI REG_CC))]
1340 ""
1341 "#"
1342 ""
1343 [(set (reg:BI REG_CC)
1344 (eq:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1345 (const_int 0)))
1346 (set (match_dup 0)
1347 (ne:SI (reg:BI REG_CC) (const_int 0)))])
1348
1349 (define_insn "*andsi_insn"
1350 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
1351 (and:SI (match_operand:SI 1 "register_operand" "%0,d,d,d")
1352 (match_operand:SI 2 "rhs_andsi3_operand" "L,M1,M2,d")))]
1353 ""
1354 "@
1355 BITCLR (%0,%Y2);
1356 %0 = %T1 (Z);
1357 %0 = %h1 (Z);
1358 %0 = %1 & %2;"
1359 [(set_attr "type" "alu0")])
1360
1361 (define_expand "andsi3"
1362 [(set (match_operand:SI 0 "register_operand" "")
1363 (and:SI (match_operand:SI 1 "register_operand" "")
1364 (match_operand:SI 2 "general_operand" "")))]
1365 ""
1366 {
1367 if (highbits_operand (operands[2], SImode))
1368 {
1369 operands[2] = GEN_INT (exact_log2 (-INTVAL (operands[2])));
1370 emit_insn (gen_ashrsi3 (operands[0], operands[1], operands[2]));
1371 emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
1372 DONE;
1373 }
1374 if (! rhs_andsi3_operand (operands[2], SImode))
1375 operands[2] = force_reg (SImode, operands[2]);
1376 })
1377
1378 (define_insn "iorsi3"
1379 [(set (match_operand:SI 0 "register_operand" "=d,d")
1380 (ior:SI (match_operand:SI 1 "register_operand" "%0,d")
1381 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1382 ""
1383 "@
1384 BITSET (%0, %X2);
1385 %0 = %1 | %2;"
1386 [(set_attr "type" "alu0")])
1387
1388 (define_insn "xorsi3"
1389 [(set (match_operand:SI 0 "register_operand" "=d,d")
1390 (xor:SI (match_operand:SI 1 "register_operand" "%0,d")
1391 (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1392 ""
1393 "@
1394 BITTGL (%0, %X2);
1395 %0 = %1 ^ %2;"
1396 [(set_attr "type" "alu0")])
1397
1398 (define_insn "ones"
1399 [(set (match_operand:HI 0 "register_operand" "=d")
1400 (truncate:HI
1401 (popcount:SI (match_operand:SI 1 "register_operand" "d"))))]
1402 ""
1403 "%h0 = ONES %1;"
1404 [(set_attr "type" "alu0")
1405 (set_attr "length" "4")])
1406
1407 (define_expand "popcountsi2"
1408 [(set (match_dup 2)
1409 (truncate:HI (popcount:SI (match_operand:SI 1 "register_operand" ""))))
1410 (set (match_operand:SI 0 "register_operand")
1411 (zero_extend:SI (match_dup 2)))]
1412 ""
1413 {
1414 operands[2] = gen_reg_rtx (HImode);
1415 })
1416
1417 (define_expand "popcounthi2"
1418 [(set (match_dup 2)
1419 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
1420 (set (match_operand:HI 0 "register_operand")
1421 (truncate:HI (popcount:SI (match_dup 2))))]
1422 ""
1423 {
1424 operands[2] = gen_reg_rtx (SImode);
1425 })
1426
1427 (define_insn "smaxsi3"
1428 [(set (match_operand:SI 0 "register_operand" "=d")
1429 (smax:SI (match_operand:SI 1 "register_operand" "d")
1430 (match_operand:SI 2 "register_operand" "d")))]
1431 ""
1432 "%0 = max(%1,%2)%!"
1433 [(set_attr "type" "dsp32")])
1434
1435 (define_insn "sminsi3"
1436 [(set (match_operand:SI 0 "register_operand" "=d")
1437 (smin:SI (match_operand:SI 1 "register_operand" "d")
1438 (match_operand:SI 2 "register_operand" "d")))]
1439 ""
1440 "%0 = min(%1,%2)%!"
1441 [(set_attr "type" "dsp32")])
1442
1443 (define_insn "abssi2"
1444 [(set (match_operand:SI 0 "register_operand" "=d")
1445 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
1446 ""
1447 "%0 = abs %1%!"
1448 [(set_attr "type" "dsp32")])
1449
1450 (define_insn "ssabssi2"
1451 [(set (match_operand:SI 0 "register_operand" "=d")
1452 (ss_abs:SI (match_operand:SI 1 "register_operand" "d")))]
1453 ""
1454 "%0 = abs %1%!"
1455 [(set_attr "type" "dsp32")])
1456
1457 (define_insn "negsi2"
1458 [(set (match_operand:SI 0 "register_operand" "=d")
1459 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
1460 ""
1461 "%0 = -%1;"
1462 [(set_attr "type" "alu0")])
1463
1464 (define_insn "ssnegsi2"
1465 [(set (match_operand:SI 0 "register_operand" "=d")
1466 (ss_neg:SI (match_operand:SI 1 "register_operand" "d")))]
1467 ""
1468 "%0 = -%1 (S)%!"
1469 [(set_attr "type" "dsp32")])
1470
1471 (define_insn "one_cmplsi2"
1472 [(set (match_operand:SI 0 "register_operand" "=d")
1473 (not:SI (match_operand:SI 1 "register_operand" "d")))]
1474 ""
1475 "%0 = ~%1;"
1476 [(set_attr "type" "alu0")])
1477
1478 (define_expand "clrsbsi2"
1479 [(set (match_dup 2)
1480 (truncate:HI (clrsb:SI (match_operand:SI 1 "register_operand" "d"))))
1481 (set (match_operand:SI 0 "register_operand")
1482 (zero_extend:SI (match_dup 2)))]
1483 ""
1484 {
1485 operands[2] = gen_reg_rtx (HImode);
1486 })
1487
1488 (define_insn "signbitssi2"
1489 [(set (match_operand:HI 0 "register_operand" "=d")
1490 (truncate:HI (clrsb:SI (match_operand:SI 1 "register_operand" "d"))))]
1491 ""
1492 "%h0 = signbits %1%!"
1493 [(set_attr "type" "dsp32")])
1494
1495 (define_insn "ssroundsi2"
1496 [(set (match_operand:HI 0 "register_operand" "=d")
1497 (truncate:HI
1498 (lshiftrt:SI (ss_plus:SI (match_operand:SI 1 "register_operand" "d")
1499 (const_int 32768))
1500 (const_int 16))))]
1501 ""
1502 "%h0 = %1 (RND)%!"
1503 [(set_attr "type" "dsp32")])
1504
1505 (define_insn "smaxhi3"
1506 [(set (match_operand:HI 0 "register_operand" "=d")
1507 (smax:HI (match_operand:HI 1 "register_operand" "d")
1508 (match_operand:HI 2 "register_operand" "d")))]
1509 ""
1510 "%0 = max(%1,%2) (V)%!"
1511 [(set_attr "type" "dsp32")])
1512
1513 (define_insn "sminhi3"
1514 [(set (match_operand:HI 0 "register_operand" "=d")
1515 (smin:HI (match_operand:HI 1 "register_operand" "d")
1516 (match_operand:HI 2 "register_operand" "d")))]
1517 ""
1518 "%0 = min(%1,%2) (V)%!"
1519 [(set_attr "type" "dsp32")])
1520
1521 (define_insn "abshi2"
1522 [(set (match_operand:HI 0 "register_operand" "=d")
1523 (abs:HI (match_operand:HI 1 "register_operand" "d")))]
1524 ""
1525 "%0 = abs %1 (V)%!"
1526 [(set_attr "type" "dsp32")])
1527
1528 (define_insn "neghi2"
1529 [(set (match_operand:HI 0 "register_operand" "=d")
1530 (neg:HI (match_operand:HI 1 "register_operand" "d")))]
1531 ""
1532 "%0 = -%1;"
1533 [(set_attr "type" "alu0")])
1534
1535 (define_insn "ssneghi2"
1536 [(set (match_operand:HI 0 "register_operand" "=d")
1537 (ss_neg:HI (match_operand:HI 1 "register_operand" "d")))]
1538 ""
1539 "%0 = -%1 (V)%!"
1540 [(set_attr "type" "dsp32")])
1541
1542 (define_insn "clrsbhi2"
1543 [(set (match_operand:HI 0 "register_operand" "=d")
1544 (clrsb:HI (match_operand:HI 1 "register_operand" "d")))]
1545 ""
1546 "%h0 = signbits %h1%!"
1547 [(set_attr "type" "dsp32")])
1548
1549 (define_insn "mulsi3"
1550 [(set (match_operand:SI 0 "register_operand" "=d")
1551 (mult:SI (match_operand:SI 1 "register_operand" "%0")
1552 (match_operand:SI 2 "register_operand" "d")))]
1553 ""
1554 "%0 *= %2;"
1555 [(set_attr "type" "mult")])
1556
1557 (define_expand "umulsi3_highpart"
1558 [(parallel
1559 [(set (match_operand:SI 0 "register_operand" "")
1560 (truncate:SI
1561 (lshiftrt:DI
1562 (mult:DI (zero_extend:DI
1563 (match_operand:SI 1 "nonimmediate_operand" ""))
1564 (zero_extend:DI
1565 (match_operand:SI 2 "register_operand" "")))
1566 (const_int 32))))
1567 (clobber (reg:PDI REG_A0))
1568 (clobber (reg:PDI REG_A1))])]
1569 ""
1570 {
1571 if (!optimize_size)
1572 {
1573 rtx a1reg = gen_rtx_REG (PDImode, REG_A1);
1574 rtx a0reg = gen_rtx_REG (PDImode, REG_A0);
1575 emit_insn (gen_flag_macinit1hi (a1reg,
1576 gen_lowpart (HImode, operands[1]),
1577 gen_lowpart (HImode, operands[2]),
1578 GEN_INT (MACFLAG_FU)));
1579 emit_insn (gen_lshrpdi3 (a1reg, a1reg, GEN_INT (16)));
1580 emit_insn (gen_flag_mul_macv2hi_parts_acconly (a0reg, a1reg,
1581 gen_lowpart (V2HImode, operands[1]),
1582 gen_lowpart (V2HImode, operands[2]),
1583 const1_rtx, const1_rtx,
1584 const1_rtx, const0_rtx, a1reg,
1585 const0_rtx, GEN_INT (MACFLAG_FU),
1586 GEN_INT (MACFLAG_FU)));
1587 emit_insn (gen_flag_machi_parts_acconly (a1reg,
1588 gen_lowpart (V2HImode, operands[2]),
1589 gen_lowpart (V2HImode, operands[1]),
1590 const1_rtx, const0_rtx,
1591 a1reg, const0_rtx, GEN_INT (MACFLAG_FU)));
1592 emit_insn (gen_lshrpdi3 (a1reg, a1reg, GEN_INT (16)));
1593 emit_insn (gen_addpdi3 (a0reg, a0reg, a1reg));
1594 emit_insn (gen_us_truncpdisi2 (operands[0], a0reg));
1595 }
1596 else
1597 {
1598 rtx umulsi3_highpart_libfunc
1599 = init_one_libfunc ("__umulsi3_highpart");
1600
1601 emit_library_call_value (umulsi3_highpart_libfunc,
1602 operands[0], LCT_NORMAL, SImode,
1603 operands[1], SImode, operands[2], SImode);
1604 }
1605 DONE;
1606 })
1607
1608 (define_expand "smulsi3_highpart"
1609 [(parallel
1610 [(set (match_operand:SI 0 "register_operand" "")
1611 (truncate:SI
1612 (lshiftrt:DI
1613 (mult:DI (sign_extend:DI
1614 (match_operand:SI 1 "nonimmediate_operand" ""))
1615 (sign_extend:DI
1616 (match_operand:SI 2 "register_operand" "")))
1617 (const_int 32))))
1618 (clobber (reg:PDI REG_A0))
1619 (clobber (reg:PDI REG_A1))])]
1620 ""
1621 {
1622 if (!optimize_size)
1623 {
1624 rtx a1reg = gen_rtx_REG (PDImode, REG_A1);
1625 rtx a0reg = gen_rtx_REG (PDImode, REG_A0);
1626 emit_insn (gen_flag_macinit1hi (a1reg,
1627 gen_lowpart (HImode, operands[1]),
1628 gen_lowpart (HImode, operands[2]),
1629 GEN_INT (MACFLAG_FU)));
1630 emit_insn (gen_lshrpdi3 (a1reg, a1reg, GEN_INT (16)));
1631 emit_insn (gen_flag_mul_macv2hi_parts_acconly (a0reg, a1reg,
1632 gen_lowpart (V2HImode, operands[1]),
1633 gen_lowpart (V2HImode, operands[2]),
1634 const1_rtx, const1_rtx,
1635 const1_rtx, const0_rtx, a1reg,
1636 const0_rtx, GEN_INT (MACFLAG_IS),
1637 GEN_INT (MACFLAG_IS_M)));
1638 emit_insn (gen_flag_machi_parts_acconly (a1reg,
1639 gen_lowpart (V2HImode, operands[2]),
1640 gen_lowpart (V2HImode, operands[1]),
1641 const1_rtx, const0_rtx,
1642 a1reg, const0_rtx, GEN_INT (MACFLAG_IS_M)));
1643 emit_insn (gen_ashrpdi3 (a1reg, a1reg, GEN_INT (16)));
1644 emit_insn (gen_sum_of_accumulators (operands[0], a0reg, a0reg, a1reg));
1645 }
1646 else
1647 {
1648 rtx smulsi3_highpart_libfunc
1649 = init_one_libfunc ("__smulsi3_highpart");
1650
1651 emit_library_call_value (smulsi3_highpart_libfunc,
1652 operands[0], LCT_NORMAL, SImode,
1653 operands[1], SImode, operands[2], SImode);
1654 }
1655 DONE;
1656 })
1657
1658 (define_expand "ashlsi3"
1659 [(set (match_operand:SI 0 "register_operand" "")
1660 (ashift:SI (match_operand:SI 1 "register_operand" "")
1661 (match_operand:SI 2 "nonmemory_operand" "")))]
1662 ""
1663 {
1664 if (GET_CODE (operands[2]) == CONST_INT
1665 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1666 {
1667 emit_insn (gen_movsi (operands[0], const0_rtx));
1668 DONE;
1669 }
1670 })
1671
1672 (define_insn_and_split "*ashlsi3_insn"
1673 [(set (match_operand:SI 0 "register_operand" "=d,d,a,a,a")
1674 (ashift:SI (match_operand:SI 1 "register_operand" "0,d,a,a,a")
1675 (match_operand:SI 2 "nonmemory_operand" "dKu5,Ku5,P1,P2,?P3P4")))]
1676 ""
1677 "@
1678 %0 <<= %2;
1679 %0 = %1 << %2%!
1680 %0 = %1 + %1;
1681 %0 = %1 << %2;
1682 #"
1683 "PREG_P (operands[0]) && INTVAL (operands[2]) > 2"
1684 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
1685 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
1686 "operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
1687 [(set_attr "type" "shft,dsp32shiftimm,shft,shft,*")])
1688
1689 (define_insn "ashrsi3"
1690 [(set (match_operand:SI 0 "register_operand" "=d,d")
1691 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
1692 (match_operand:SI 2 "nonmemory_operand" "dKu5,Ku5")))]
1693 ""
1694 "@
1695 %0 >>>= %2;
1696 %0 = %1 >>> %2%!"
1697 [(set_attr "type" "shft,dsp32shiftimm")])
1698
1699 (define_insn "rotl16"
1700 [(set (match_operand:SI 0 "register_operand" "=d")
1701 (rotate:SI (match_operand:SI 1 "register_operand" "d")
1702 (const_int 16)))]
1703 ""
1704 "%0 = PACK (%h1, %d1)%!"
1705 [(set_attr "type" "dsp32")])
1706
1707 (define_expand "rotlsi3"
1708 [(set (match_operand:SI 0 "register_operand" "")
1709 (rotate:SI (match_operand:SI 1 "register_operand" "")
1710 (match_operand:SI 2 "const_int_operand" "")))]
1711 ""
1712 {
1713 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 16)
1714 FAIL;
1715 })
1716
1717 (define_expand "rotrsi3"
1718 [(set (match_operand:SI 0 "register_operand" "")
1719 (rotatert:SI (match_operand:SI 1 "register_operand" "")
1720 (match_operand:SI 2 "const_int_operand" "")))]
1721 ""
1722 {
1723 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 16)
1724 FAIL;
1725 emit_insn (gen_rotl16 (operands[0], operands[1]));
1726 DONE;
1727 })
1728
1729
1730 (define_insn "ror_one"
1731 [(set (match_operand:SI 0 "register_operand" "=d")
1732 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1733 (ashift:SI (zero_extend:SI (reg:BI REG_CC)) (const_int 31))))
1734 (set (reg:BI REG_CC)
1735 (zero_extract:BI (match_dup 1) (const_int 1) (const_int 0)))]
1736 ""
1737 "%0 = ROT %1 BY -1%!"
1738 [(set_attr "type" "dsp32shiftimm")])
1739
1740 (define_insn "rol_one"
1741 [(set (match_operand:SI 0 "register_operand" "+d")
1742 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1743 (zero_extend:SI (reg:BI REG_CC))))
1744 (set (reg:BI REG_CC)
1745 (zero_extract:BI (match_dup 1) (const_int 1) (const_int 31)))]
1746 ""
1747 "%0 = ROT %1 BY 1%!"
1748 [(set_attr "type" "dsp32shiftimm")])
1749
1750 (define_expand "lshrdi3"
1751 [(set (match_operand:DI 0 "register_operand" "")
1752 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1753 (match_operand:DI 2 "general_operand" "")))]
1754 ""
1755 {
1756 rtx lo_half[2], hi_half[2];
1757
1758 if (operands[2] != const1_rtx)
1759 FAIL;
1760 if (! rtx_equal_p (operands[0], operands[1]))
1761 emit_move_insn (operands[0], operands[1]);
1762
1763 split_di (operands, 2, lo_half, hi_half);
1764
1765 emit_move_insn (bfin_cc_rtx, const0_rtx);
1766 emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1767 emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1768 DONE;
1769 })
1770
1771 (define_expand "ashrdi3"
1772 [(set (match_operand:DI 0 "register_operand" "")
1773 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1774 (match_operand:DI 2 "general_operand" "")))]
1775 ""
1776 {
1777 rtx lo_half[2], hi_half[2];
1778
1779 if (operands[2] != const1_rtx)
1780 FAIL;
1781 if (! rtx_equal_p (operands[0], operands[1]))
1782 emit_move_insn (operands[0], operands[1]);
1783
1784 split_di (operands, 2, lo_half, hi_half);
1785
1786 emit_insn (gen_compare_lt (gen_rtx_REG (BImode, REG_CC),
1787 hi_half[1], const0_rtx));
1788 emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1789 emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1790 DONE;
1791 })
1792
1793 (define_expand "ashldi3"
1794 [(set (match_operand:DI 0 "register_operand" "")
1795 (ashift:DI (match_operand:DI 1 "register_operand" "")
1796 (match_operand:DI 2 "general_operand" "")))]
1797 ""
1798 {
1799 rtx lo_half[2], hi_half[2];
1800
1801 if (operands[2] != const1_rtx)
1802 FAIL;
1803 if (! rtx_equal_p (operands[0], operands[1]))
1804 emit_move_insn (operands[0], operands[1]);
1805
1806 split_di (operands, 2, lo_half, hi_half);
1807
1808 emit_move_insn (bfin_cc_rtx, const0_rtx);
1809 emit_insn (gen_rol_one (lo_half[0], lo_half[0]));
1810 emit_insn (gen_rol_one (hi_half[0], hi_half[0]));
1811 DONE;
1812 })
1813
1814 (define_insn "lshrsi3"
1815 [(set (match_operand:SI 0 "register_operand" "=d,d,a")
1816 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d,a")
1817 (match_operand:SI 2 "nonmemory_operand" "dKu5,Ku5,P1P2")))]
1818 ""
1819 "@
1820 %0 >>= %2;
1821 %0 = %1 >> %2%!
1822 %0 = %1 >> %2;"
1823 [(set_attr "type" "shft,dsp32shiftimm,shft")])
1824
1825 (define_insn "lshrpdi3"
1826 [(set (match_operand:PDI 0 "register_operand" "=e")
1827 (lshiftrt:PDI (match_operand:PDI 1 "register_operand" "0")
1828 (match_operand:SI 2 "nonmemory_operand" "Ku5")))]
1829 ""
1830 "%0 = %1 >> %2%!"
1831 [(set_attr "type" "dsp32shiftimm")])
1832
1833 (define_insn "ashrpdi3"
1834 [(set (match_operand:PDI 0 "register_operand" "=e")
1835 (ashiftrt:PDI (match_operand:PDI 1 "register_operand" "0")
1836 (match_operand:SI 2 "nonmemory_operand" "Ku5")))]
1837 ""
1838 "%0 = %1 >>> %2%!"
1839 [(set_attr "type" "dsp32shiftimm")])
1840
1841 ;; A pattern to reload the equivalent of
1842 ;; (set (Dreg) (plus (FP) (large_constant)))
1843 ;; or
1844 ;; (set (dagreg) (plus (FP) (arbitrary_constant)))
1845 ;; using a scratch register
1846 (define_expand "reload_insi"
1847 [(parallel [(set (match_operand:SI 0 "register_operand" "=w")
1848 (match_operand:SI 1 "fp_plus_const_operand" ""))
1849 (clobber (match_operand:SI 2 "register_operand" "=&a"))])]
1850 ""
1851 {
1852 rtx fp_op = XEXP (operands[1], 0);
1853 rtx const_op = XEXP (operands[1], 1);
1854 rtx primary = operands[0];
1855 rtx scratch = operands[2];
1856
1857 emit_move_insn (scratch, const_op);
1858 emit_insn (gen_addsi3 (scratch, scratch, fp_op));
1859 emit_move_insn (primary, scratch);
1860 DONE;
1861 })
1862
1863 (define_mode_iterator AREG [PDI V2PDI])
1864
1865 (define_insn "reload_in<mode>"
1866 [(set (match_operand:AREG 0 "register_operand" "=e")
1867 (match_operand:AREG 1 "memory_operand" "m"))
1868 (clobber (match_operand:SI 2 "register_operand" "=d"))]
1869 ""
1870 {
1871 rtx xops[4];
1872 xops[0] = operands[0];
1873 xops[1] = operands[2];
1874 split_di (operands + 1, 1, xops + 2, xops + 3);
1875 output_asm_insn ("%1 = %2;", xops);
1876 output_asm_insn ("%w0 = %1;", xops);
1877 output_asm_insn ("%1 = %3;", xops);
1878 output_asm_insn ("%x0 = %1;", xops);
1879 return "";
1880 }
1881 [(set_attr "seq_insns" "multi")
1882 (set_attr "type" "mcld")
1883 (set_attr "length" "12")])
1884
1885 (define_insn "reload_out<mode>"
1886 [(set (match_operand:AREG 0 "memory_operand" "=m")
1887 (match_operand:AREG 1 "register_operand" "e"))
1888 (clobber (match_operand:SI 2 "register_operand" "=d"))]
1889 ""
1890 {
1891 rtx xops[4];
1892 xops[0] = operands[1];
1893 xops[1] = operands[2];
1894 split_di (operands, 1, xops + 2, xops + 3);
1895 output_asm_insn ("%1 = %w0;", xops);
1896 output_asm_insn ("%2 = %1;", xops);
1897 output_asm_insn ("%1 = %x0;", xops);
1898 output_asm_insn ("%3 = %1;", xops);
1899 return "";
1900 }
1901 [(set_attr "seq_insns" "multi")
1902 (set_attr "type" "mcld")
1903 (set_attr "length" "12")])
1904
1905 ;; Jump instructions
1906
1907 (define_insn "jump"
1908 [(set (pc)
1909 (label_ref (match_operand 0 "" "")))]
1910 ""
1911 {
1912 if (get_attr_length (insn) == 2)
1913 return "jump.s %0;";
1914 else
1915 return "jump.l %0;";
1916 }
1917 [(set_attr "type" "br")])
1918
1919 (define_insn "indirect_jump"
1920 [(set (pc)
1921 (match_operand:SI 0 "register_operand" "a"))]
1922 ""
1923 "jump (%0);"
1924 [(set_attr "type" "misc")])
1925
1926 (define_expand "tablejump"
1927 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1928 (use (label_ref (match_operand 1 "" "")))])]
1929 ""
1930 {
1931 /* In PIC mode, the table entries are stored PC relative.
1932 Convert the relative address to an absolute address. */
1933 if (flag_pic)
1934 {
1935 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1936
1937 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1938 op1, NULL_RTX, 0, OPTAB_DIRECT);
1939 }
1940 })
1941
1942 (define_insn "*tablejump_internal"
1943 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1944 (use (label_ref (match_operand 1 "" "")))]
1945 ""
1946 "jump (%0);"
1947 [(set_attr "type" "misc")])
1948
1949 ;; Hardware loop
1950
1951 ; operand 0 is the loop count pseudo register
1952 ; operand 1 is the label to jump to at the top of the loop
1953 (define_expand "doloop_end"
1954 [(parallel [(set (pc) (if_then_else
1955 (ne (match_operand:SI 0 "" "")
1956 (const_int 1))
1957 (label_ref (match_operand 1 "" ""))
1958 (pc)))
1959 (set (match_dup 0)
1960 (plus:SI (match_dup 0)
1961 (const_int -1)))
1962 (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1963 (clobber (match_dup 2))
1964 (clobber (reg:BI REG_CC))])] ; match_scratch
1965 ""
1966 {
1967 /* The loop optimizer doesn't check the predicates... */
1968 if (GET_MODE (operands[0]) != SImode)
1969 FAIL;
1970 bfin_hardware_loop ();
1971 operands[2] = gen_rtx_SCRATCH (SImode);
1972 })
1973
1974 (define_insn "loop_end"
1975 [(set (pc)
1976 (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,0,0")
1977 (const_int 1))
1978 (label_ref (match_operand 1 "" ""))
1979 (pc)))
1980 (set (match_operand:SI 0 "nonimmediate_operand" "=a*d,*b*v*f,m")
1981 (plus (match_dup 2)
1982 (const_int -1)))
1983 (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1984 (clobber (match_scratch:SI 3 "=X,&r,&r"))
1985 (clobber (reg:BI REG_CC))]
1986 ""
1987 "@
1988 /* loop end %0 %l1 */
1989 #
1990 #"
1991 [(set_attr "length" "6,10,14")])
1992
1993 (define_split
1994 [(set (pc)
1995 (if_then_else (ne (match_operand:SI 0 "nondp_reg_or_memory_operand")
1996 (const_int 1))
1997 (label_ref (match_operand 1 ""))
1998 (pc)))
1999 (set (match_dup 0)
2000 (plus (match_dup 0)
2001 (const_int -1)))
2002 (unspec [(const_int 0)] UNSPEC_LSETUP_END)
2003 (clobber (match_scratch:SI 2))
2004 (clobber (reg:BI REG_CC))]
2005 "memory_operand (operands[0], SImode) || splitting_loops"
2006 [(set (match_dup 2) (match_dup 0))
2007 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
2008 (set (match_dup 0) (match_dup 2))
2009 (set (reg:BI REG_CC) (eq:BI (match_dup 2) (const_int 0)))
2010 (set (pc)
2011 (if_then_else (eq (reg:BI REG_CC)
2012 (const_int 0))
2013 (label_ref (match_dup 1))
2014 (pc)))]
2015 "")
2016
2017 (define_insn "lsetup_with_autoinit"
2018 [(set (match_operand:SI 0 "lt_register_operand" "=t")
2019 (label_ref (match_operand 1 "" "")))
2020 (set (match_operand:SI 2 "lb_register_operand" "=u")
2021 (label_ref (match_operand 3 "" "")))
2022 (set (match_operand:SI 4 "lc_register_operand" "=k")
2023 (match_operand:SI 5 "register_operand" "a"))]
2024 ""
2025 "LSETUP (%1, %3) %4 = %5;"
2026 [(set_attr "length" "4")])
2027
2028 (define_insn "lsetup_without_autoinit"
2029 [(set (match_operand:SI 0 "lt_register_operand" "=t")
2030 (label_ref (match_operand 1 "" "")))
2031 (set (match_operand:SI 2 "lb_register_operand" "=u")
2032 (label_ref (match_operand 3 "" "")))
2033 (use (match_operand:SI 4 "lc_register_operand" "k"))]
2034 ""
2035 "LSETUP (%1, %3) %4;"
2036 [(set_attr "length" "4")])
2037
2038 ;; Call instructions..
2039
2040 ;; The explicit MEM inside the UNSPEC prevents the compiler from moving
2041 ;; the load before a branch after a NULL test, or before a store that
2042 ;; initializes a function descriptor.
2043
2044 (define_insn_and_split "load_funcdescsi"
2045 [(set (match_operand:SI 0 "register_operand" "=a")
2046 (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
2047 UNSPEC_VOLATILE_LOAD_FUNCDESC))]
2048 ""
2049 "#"
2050 "reload_completed"
2051 [(set (match_dup 0) (mem:SI (match_dup 1)))])
2052
2053 (define_expand "call"
2054 [(parallel [(call (match_operand:SI 0 "" "")
2055 (match_operand 1 "" ""))
2056 (use (match_operand 2 "" ""))])]
2057 ""
2058 {
2059 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 0);
2060 DONE;
2061 })
2062
2063 (define_expand "sibcall"
2064 [(parallel [(call (match_operand:SI 0 "" "")
2065 (match_operand 1 "" ""))
2066 (use (match_operand 2 "" ""))
2067 (return)])]
2068 ""
2069 {
2070 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 1);
2071 DONE;
2072 })
2073
2074 (define_expand "call_value"
2075 [(parallel [(set (match_operand 0 "register_operand" "")
2076 (call (match_operand:SI 1 "" "")
2077 (match_operand 2 "" "")))
2078 (use (match_operand 3 "" ""))])]
2079 ""
2080 {
2081 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 0);
2082 DONE;
2083 })
2084
2085 (define_expand "sibcall_value"
2086 [(parallel [(set (match_operand 0 "register_operand" "")
2087 (call (match_operand:SI 1 "" "")
2088 (match_operand 2 "" "")))
2089 (use (match_operand 3 "" ""))
2090 (return)])]
2091 ""
2092 {
2093 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 1);
2094 DONE;
2095 })
2096
2097 (define_insn "*call_symbol_fdpic"
2098 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
2099 (match_operand 1 "general_operand" "g"))
2100 (use (match_operand:SI 2 "register_operand" "Z"))
2101 (use (match_operand 3 "" ""))
2102 (clobber (reg:SI REG_RETS))]
2103 "! SIBLING_CALL_P (insn)
2104 && GET_CODE (operands[0]) == SYMBOL_REF
2105 && !bfin_longcall_p (operands[0], INTVAL (operands[3]))"
2106 "call %0;"
2107 [(set_attr "type" "call")
2108 (set_attr "length" "4")])
2109
2110 (define_insn "*sibcall_symbol_fdpic"
2111 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
2112 (match_operand 1 "general_operand" "g"))
2113 (use (match_operand:SI 2 "register_operand" "Z"))
2114 (use (match_operand 3 "" ""))
2115 (return)]
2116 "SIBLING_CALL_P (insn)
2117 && GET_CODE (operands[0]) == SYMBOL_REF
2118 && !bfin_longcall_p (operands[0], INTVAL (operands[3]))"
2119 "jump.l %0;"
2120 [(set_attr "type" "br")
2121 (set_attr "length" "4")])
2122
2123 (define_insn "*call_value_symbol_fdpic"
2124 [(set (match_operand 0 "register_operand" "=d")
2125 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
2126 (match_operand 2 "general_operand" "g")))
2127 (use (match_operand:SI 3 "register_operand" "Z"))
2128 (use (match_operand 4 "" ""))
2129 (clobber (reg:SI REG_RETS))]
2130 "! SIBLING_CALL_P (insn)
2131 && GET_CODE (operands[1]) == SYMBOL_REF
2132 && !bfin_longcall_p (operands[1], INTVAL (operands[4]))"
2133 "call %1;"
2134 [(set_attr "type" "call")
2135 (set_attr "length" "4")])
2136
2137 (define_insn "*sibcall_value_symbol_fdpic"
2138 [(set (match_operand 0 "register_operand" "=d")
2139 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
2140 (match_operand 2 "general_operand" "g")))
2141 (use (match_operand:SI 3 "register_operand" "Z"))
2142 (use (match_operand 4 "" ""))
2143 (return)]
2144 "SIBLING_CALL_P (insn)
2145 && GET_CODE (operands[1]) == SYMBOL_REF
2146 && !bfin_longcall_p (operands[1], INTVAL (operands[4]))"
2147 "jump.l %1;"
2148 [(set_attr "type" "br")
2149 (set_attr "length" "4")])
2150
2151 (define_insn "*call_insn_fdpic"
2152 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y"))
2153 (match_operand 1 "general_operand" "g"))
2154 (use (match_operand:SI 2 "register_operand" "Z"))
2155 (use (match_operand 3 "" ""))
2156 (clobber (reg:SI REG_RETS))]
2157 "! SIBLING_CALL_P (insn)"
2158 "call (%0);"
2159 [(set_attr "type" "call")
2160 (set_attr "length" "2")])
2161
2162 (define_insn "*sibcall_insn_fdpic"
2163 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y"))
2164 (match_operand 1 "general_operand" "g"))
2165 (use (match_operand:SI 2 "register_operand" "Z"))
2166 (use (match_operand 3 "" ""))
2167 (return)]
2168 "SIBLING_CALL_P (insn)"
2169 "jump (%0);"
2170 [(set_attr "type" "br")
2171 (set_attr "length" "2")])
2172
2173 (define_insn "*call_value_insn_fdpic"
2174 [(set (match_operand 0 "register_operand" "=d")
2175 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y"))
2176 (match_operand 2 "general_operand" "g")))
2177 (use (match_operand:SI 3 "register_operand" "Z"))
2178 (use (match_operand 4 "" ""))
2179 (clobber (reg:SI REG_RETS))]
2180 "! SIBLING_CALL_P (insn)"
2181 "call (%1);"
2182 [(set_attr "type" "call")
2183 (set_attr "length" "2")])
2184
2185 (define_insn "*sibcall_value_insn_fdpic"
2186 [(set (match_operand 0 "register_operand" "=d")
2187 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y"))
2188 (match_operand 2 "general_operand" "g")))
2189 (use (match_operand:SI 3 "register_operand" "Z"))
2190 (use (match_operand 4 "" ""))
2191 (return)]
2192 "SIBLING_CALL_P (insn)"
2193 "jump (%1);"
2194 [(set_attr "type" "br")
2195 (set_attr "length" "2")])
2196
2197 (define_insn "*call_symbol"
2198 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
2199 (match_operand 1 "general_operand" "g"))
2200 (use (match_operand 2 "" ""))
2201 (clobber (reg:SI REG_RETS))]
2202 "! SIBLING_CALL_P (insn)
2203 && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
2204 && GET_CODE (operands[0]) == SYMBOL_REF
2205 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
2206 "call %0;"
2207 [(set_attr "type" "call")
2208 (set_attr "length" "4")])
2209
2210 (define_insn "*sibcall_symbol"
2211 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
2212 (match_operand 1 "general_operand" "g"))
2213 (use (match_operand 2 "" ""))
2214 (return)]
2215 "SIBLING_CALL_P (insn)
2216 && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
2217 && GET_CODE (operands[0]) == SYMBOL_REF
2218 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
2219 "jump.l %0;"
2220 [(set_attr "type" "br")
2221 (set_attr "length" "4")])
2222
2223 (define_insn "*call_value_symbol"
2224 [(set (match_operand 0 "register_operand" "=d")
2225 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
2226 (match_operand 2 "general_operand" "g")))
2227 (use (match_operand 3 "" ""))
2228 (clobber (reg:SI REG_RETS))]
2229 "! SIBLING_CALL_P (insn)
2230 && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
2231 && GET_CODE (operands[1]) == SYMBOL_REF
2232 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
2233 "call %1;"
2234 [(set_attr "type" "call")
2235 (set_attr "length" "4")])
2236
2237 (define_insn "*sibcall_value_symbol"
2238 [(set (match_operand 0 "register_operand" "=d")
2239 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
2240 (match_operand 2 "general_operand" "g")))
2241 (use (match_operand 3 "" ""))
2242 (return)]
2243 "SIBLING_CALL_P (insn)
2244 && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
2245 && GET_CODE (operands[1]) == SYMBOL_REF
2246 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
2247 "jump.l %1;"
2248 [(set_attr "type" "br")
2249 (set_attr "length" "4")])
2250
2251 (define_insn "*call_insn"
2252 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a"))
2253 (match_operand 1 "general_operand" "g"))
2254 (use (match_operand 2 "" ""))
2255 (clobber (reg:SI REG_RETS))]
2256 "! SIBLING_CALL_P (insn)"
2257 "call (%0);"
2258 [(set_attr "type" "call")
2259 (set_attr "length" "2")])
2260
2261 (define_insn "*sibcall_insn"
2262 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "z"))
2263 (match_operand 1 "general_operand" "g"))
2264 (use (match_operand 2 "" ""))
2265 (return)]
2266 "SIBLING_CALL_P (insn)"
2267 "jump (%0);"
2268 [(set_attr "type" "br")
2269 (set_attr "length" "2")])
2270
2271 (define_insn "*call_value_insn"
2272 [(set (match_operand 0 "register_operand" "=d")
2273 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a"))
2274 (match_operand 2 "general_operand" "g")))
2275 (use (match_operand 3 "" ""))
2276 (clobber (reg:SI REG_RETS))]
2277 "! SIBLING_CALL_P (insn)"
2278 "call (%1);"
2279 [(set_attr "type" "call")
2280 (set_attr "length" "2")])
2281
2282 (define_insn "*sibcall_value_insn"
2283 [(set (match_operand 0 "register_operand" "=d")
2284 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "z"))
2285 (match_operand 2 "general_operand" "g")))
2286 (use (match_operand 3 "" ""))
2287 (return)]
2288 "SIBLING_CALL_P (insn)"
2289 "jump (%1);"
2290 [(set_attr "type" "br")
2291 (set_attr "length" "2")])
2292
2293 ;; Block move patterns
2294
2295 ;; We cheat. This copies one more word than operand 2 indicates.
2296
2297 (define_insn "rep_movsi"
2298 [(set (match_operand:SI 0 "register_operand" "=&a")
2299 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
2300 (ashift:SI (match_operand:SI 2 "register_operand" "a")
2301 (const_int 2)))
2302 (const_int 4)))
2303 (set (match_operand:SI 1 "register_operand" "=&b")
2304 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
2305 (ashift:SI (match_dup 2) (const_int 2)))
2306 (const_int 4)))
2307 (set (mem:BLK (match_dup 3))
2308 (mem:BLK (match_dup 4)))
2309 (use (match_dup 2))
2310 (clobber (match_scratch:HI 5 "=&d"))
2311 (clobber (reg:SI REG_LT1))
2312 (clobber (reg:SI REG_LC1))
2313 (clobber (reg:SI REG_LB1))]
2314 ""
2315 "%5 = [%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || [%3++] = %5 || %5 = [%4++]; [%3++] = %5;"
2316 [(set_attr "type" "misc")
2317 (set_attr "length" "16")
2318 (set_attr "seq_insns" "multi")])
2319
2320 (define_insn "rep_movhi"
2321 [(set (match_operand:SI 0 "register_operand" "=&a")
2322 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
2323 (ashift:SI (match_operand:SI 2 "register_operand" "a")
2324 (const_int 1)))
2325 (const_int 2)))
2326 (set (match_operand:SI 1 "register_operand" "=&b")
2327 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
2328 (ashift:SI (match_dup 2) (const_int 1)))
2329 (const_int 2)))
2330 (set (mem:BLK (match_dup 3))
2331 (mem:BLK (match_dup 4)))
2332 (use (match_dup 2))
2333 (clobber (match_scratch:HI 5 "=&d"))
2334 (clobber (reg:SI REG_LT1))
2335 (clobber (reg:SI REG_LC1))
2336 (clobber (reg:SI REG_LB1))]
2337 ""
2338 "%h5 = W[%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || W [%3++] = %5 || %h5 = W [%4++]; W [%3++] = %5;"
2339 [(set_attr "type" "misc")
2340 (set_attr "length" "16")
2341 (set_attr "seq_insns" "multi")])
2342
2343 (define_expand "cpymemsi"
2344 [(match_operand:BLK 0 "general_operand" "")
2345 (match_operand:BLK 1 "general_operand" "")
2346 (match_operand:SI 2 "const_int_operand" "")
2347 (match_operand:SI 3 "const_int_operand" "")]
2348 ""
2349 {
2350 if (bfin_expand_cpymem (operands[0], operands[1], operands[2], operands[3]))
2351 DONE;
2352 FAIL;
2353 })
2354
2355 ;; Conditional branch patterns
2356 ;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
2357
2358 (define_insn "compare_eq"
2359 [(set (match_operand:BI 0 "register_operand" "=C,C")
2360 (eq:BI (match_operand:SI 1 "register_operand" "d,a")
2361 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
2362 ""
2363 "cc =%1==%2;"
2364 [(set_attr "type" "compare")])
2365
2366 (define_insn "compare_ne"
2367 [(set (match_operand:BI 0 "register_operand" "=C,C")
2368 (ne:BI (match_operand:SI 1 "register_operand" "d,a")
2369 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
2370 "0"
2371 "cc =%1!=%2;"
2372 [(set_attr "type" "compare")])
2373
2374 (define_insn "compare_lt"
2375 [(set (match_operand:BI 0 "register_operand" "=C,C")
2376 (lt:BI (match_operand:SI 1 "register_operand" "d,a")
2377 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
2378 ""
2379 "cc =%1<%2;"
2380 [(set_attr "type" "compare")])
2381
2382 (define_insn "compare_le"
2383 [(set (match_operand:BI 0 "register_operand" "=C,C")
2384 (le:BI (match_operand:SI 1 "register_operand" "d,a")
2385 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
2386 ""
2387 "cc =%1<=%2;"
2388 [(set_attr "type" "compare")])
2389
2390 (define_insn "compare_leu"
2391 [(set (match_operand:BI 0 "register_operand" "=C,C")
2392 (leu:BI (match_operand:SI 1 "register_operand" "d,a")
2393 (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
2394 ""
2395 "cc =%1<=%2 (iu);"
2396 [(set_attr "type" "compare")])
2397
2398 (define_insn "compare_ltu"
2399 [(set (match_operand:BI 0 "register_operand" "=C,C")
2400 (ltu:BI (match_operand:SI 1 "register_operand" "d,a")
2401 (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
2402 ""
2403 "cc =%1<%2 (iu);"
2404 [(set_attr "type" "compare")])
2405
2406 ;; Same as above, but and CC with the overflow bit generated by the first
2407 ;; multiplication.
2408 (define_insn "flag_mul_macv2hi_parts_acconly_andcc0"
2409 [(set (match_operand:PDI 0 "register_operand" "=B,e,e")
2410 (unspec:PDI [(vec_select:HI
2411 (match_operand:V2HI 2 "register_operand" "d,d,d")
2412 (parallel [(match_operand 4 "const01_operand" "P0P1,P0P1,P0P1")]))
2413 (vec_select:HI
2414 (match_operand:V2HI 3 "register_operand" "d,d,d")
2415 (parallel [(match_operand 6 "const01_operand" "P0P1,P0P1,P0P1")]))
2416 (match_operand 10 "const_int_operand" "PB,PA,PA")]
2417 UNSPEC_MUL_WITH_FLAG))
2418 (set (match_operand:PDI 1 "register_operand" "=B,e,e")
2419 (unspec:PDI [(vec_select:HI
2420 (match_dup 2)
2421 (parallel [(match_operand 5 "const01_operand" "P0P1,P0P1,P0P1")]))
2422 (vec_select:HI
2423 (match_dup 3)
2424 (parallel [(match_operand 7 "const01_operand" "P0P1,P0P1,P0P1")]))
2425 (match_operand:PDI 8 "register_operand" "1,1,1")
2426 (match_operand 9 "const01_operand" "P0P1,P0P1,P0P1")
2427 (match_operand 11 "const_int_operand" "PA,PB,PA")]
2428 UNSPEC_MAC_WITH_FLAG))
2429 (set (reg:BI REG_CC)
2430 (and:BI (reg:BI REG_CC)
2431 (unspec:BI [(vec_select:HI (match_dup 2) (parallel [(match_dup 4)]))
2432 (vec_select:HI (match_dup 3) (parallel [(match_dup 6)]))
2433 (match_dup 10)]
2434 UNSPEC_MUL_WITH_FLAG)))]
2435 "MACFLAGS_MATCH_P (INTVAL (operands[10]), INTVAL (operands[11]))"
2436 {
2437 rtx xops[6];
2438 const char *templates[] = {
2439 "%0 = %h2 * %h3, %1 %b4 %h2 * %h3 %M5;\n\tCC &= %v0;",
2440 "%0 = %d2 * %h3, %1 %b4 %h2 * %h3 %M5;\n\tCC &= %v0;",
2441 "%0 = %h2 * %h3, %1 %b4 %d2 * %h3 %M5;\n\tCC &= %v0;",
2442 "%0 = %d2 * %h3, %1 %b4 %d2 * %h3 %M5;\n\tCC &= %v0;",
2443 "%0 = %h2 * %d3, %1 %b4 %h2 * %h3 %M5;\n\tCC &= %v0;",
2444 "%0 = %d2 * %d3, %1 %b4 %h2 * %h3 %M5;\n\tCC &= %v0;",
2445 "%0 = %h2 * %d3, %1 %b4 %d2 * %h3 %M5;\n\tCC &= %v0;",
2446 "%0 = %d2 * %d3, %1 %b4 %d2 * %h3 %M5;\n\tCC &= %v0;",
2447 "%0 = %h2 * %h3, %1 %b4 %h2 * %d3 %M5;\n\tCC &= %v0;",
2448 "%0 = %d2 * %h3, %1 %b4 %h2 * %d3 %M5;\n\tCC &= %v0;",
2449 "%0 = %h2 * %h3, %1 %b4 %d2 * %d3 %M5;\n\tCC &= %v0;",
2450 "%0 = %d2 * %h3, %1 %b4 %d2 * %d3 %M5;\n\tCC &= %v0;",
2451 "%0 = %h2 * %d3, %1 %b4 %h2 * %d3 %M5;\n\tCC &= %v0;",
2452 "%0 = %d2 * %d3, %1 %b4 %h2 * %d3 %M5;\n\tCC &= %v0;",
2453 "%0 = %h2 * %d3, %1 %b4 %d2 * %d3 %M5;\n\tCC &= %v0;",
2454 "%0 = %d2 * %d3, %1 %b4 %d2 * %d3 %M5;\n\tCC &= %v0;" };
2455 int alt = (INTVAL (operands[4]) + (INTVAL (operands[5]) << 1)
2456 + (INTVAL (operands[6]) << 2) + (INTVAL (operands[7]) << 3));
2457 xops[0] = operands[0];
2458 xops[1] = operands[1];
2459 xops[2] = operands[2];
2460 xops[3] = operands[3];
2461 xops[4] = operands[9];
2462 xops[5] = which_alternative == 0 ? operands[10] : operands[11];
2463 output_asm_insn (templates[alt], xops);
2464 return "";
2465 }
2466 [(set_attr "type" "misc")
2467 (set_attr "length" "6")
2468 (set_attr "seq_insns" "multi")])
2469
2470 (define_expand "cbranchsi4"
2471 [(set (pc)
2472 (if_then_else (match_operator 0 "ordered_comparison_operator"
2473 [(match_operand:SI 1 "register_operand" "")
2474 (match_operand:SI 2 "reg_or_const_int_operand" "")])
2475 (label_ref (match_operand 3 "" ""))
2476 (pc)))]
2477 ""
2478 {
2479 rtx bi_compare = bfin_gen_compare (operands[0], SImode);
2480 emit_jump_insn (gen_cbranchbi4 (bi_compare, bfin_cc_rtx, CONST0_RTX (BImode),
2481 operands[3]));
2482 DONE;
2483 })
2484
2485 (define_insn "cbranchbi4"
2486 [(set (pc)
2487 (if_then_else
2488 (match_operator 0 "bfin_bimode_comparison_operator"
2489 [(match_operand:BI 1 "register_operand" "C")
2490 (match_operand:BI 2 "immediate_operand" "P0")])
2491 (label_ref (match_operand 3 "" ""))
2492 (pc)))]
2493 ""
2494 {
2495 asm_conditional_branch (insn, operands, 0, 0);
2496 return "";
2497 }
2498 [(set_attr "type" "brcc")])
2499
2500 ;; Special cbranch patterns to deal with the speculative load problem - see
2501 ;; bfin_reorg for details.
2502
2503 (define_insn "cbranch_predicted_taken"
2504 [(set (pc)
2505 (if_then_else
2506 (match_operator 0 "bfin_bimode_comparison_operator"
2507 [(match_operand:BI 1 "register_operand" "C")
2508 (match_operand:BI 2 "immediate_operand" "P0")])
2509 (label_ref (match_operand 3 "" ""))
2510 (pc)))
2511 (unspec [(const_int 0)] UNSPEC_CBRANCH_TAKEN)]
2512 ""
2513 {
2514 asm_conditional_branch (insn, operands, 0, 1);
2515 return "";
2516 }
2517 [(set_attr "type" "brcc")])
2518
2519 (define_insn "cbranch_with_nops"
2520 [(set (pc)
2521 (if_then_else
2522 (match_operator 0 "bfin_bimode_comparison_operator"
2523 [(match_operand:BI 1 "register_operand" "C")
2524 (match_operand:BI 2 "immediate_operand" "P0")])
2525 (label_ref (match_operand 3 "" ""))
2526 (pc)))
2527 (unspec [(match_operand 4 "immediate_operand" "")] UNSPEC_CBRANCH_NOPS)]
2528 "reload_completed"
2529 {
2530 asm_conditional_branch (insn, operands, INTVAL (operands[4]), 0);
2531 return "";
2532 }
2533 [(set_attr "type" "brcc")
2534 (set_attr "length" "8")])
2535
2536 ;; setcc insns.
2537
2538 (define_expand "cstorebi4"
2539 [(set (match_dup 4)
2540 (match_operator:BI 1 "bfin_bimode_comparison_operator"
2541 [(match_operand:BI 2 "register_operand" "")
2542 (match_operand:BI 3 "reg_or_const_int_operand" "")]))
2543 (set (match_operand:SI 0 "register_operand" "")
2544 (ne:SI (match_dup 4) (const_int 0)))]
2545 ""
2546 {
2547 /* It could be expanded as a movbisi instruction, but the portable
2548 alternative produces better code. */
2549 if (GET_CODE (operands[1]) == NE)
2550 FAIL;
2551
2552 operands[4] = bfin_cc_rtx;
2553 })
2554
2555 (define_expand "cstoresi4"
2556 [(set (match_operand:SI 0 "register_operand")
2557 (match_operator:SI 1 "ordered_comparison_operator"
2558 [(match_operand:SI 2 "register_operand" "")
2559 (match_operand:SI 3 "reg_or_const_int_operand" "")]))]
2560 ""
2561 {
2562 rtx bi_compare, test;
2563
2564 if (!bfin_direct_comparison_operator (operands[1], SImode))
2565 {
2566 if (!register_operand (operands[3], SImode)
2567 || GET_CODE (operands[1]) == NE)
2568 FAIL;
2569 test = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
2570 SImode, operands[3], operands[2]);
2571 }
2572 else
2573 test = operands[1];
2574
2575 bi_compare = bfin_gen_compare (test, SImode);
2576 gcc_assert (GET_CODE (bi_compare) == NE);
2577 emit_insn (gen_movbisi (operands[0], bfin_cc_rtx));
2578 DONE;
2579 })
2580
2581 (define_insn "nop"
2582 [(const_int 0)]
2583 ""
2584 "nop;")
2585
2586 ;; A nop which stays there when emitted.
2587 (define_insn "forced_nop"
2588 [(unspec [(const_int 0)] UNSPEC_NOP)]
2589 ""
2590 "nop;")
2591
2592 (define_insn "mnop"
2593 [(unspec [(const_int 0)] UNSPEC_32BIT)]
2594 ""
2595 "mnop%!"
2596 [(set_attr "type" "dsp32")])
2597
2598 ;;;;;;;;;;;;;;;;;;;; CC2dreg ;;;;;;;;;;;;;;;;;;;;;;;;;
2599 (define_insn "movsibi"
2600 [(set (match_operand:BI 0 "register_operand" "=C")
2601 (ne:BI (match_operand:SI 1 "register_operand" "d")
2602 (const_int 0)))]
2603 ""
2604 "CC = %1;"
2605 [(set_attr "length" "2")])
2606
2607 (define_insn_and_split "movbisi"
2608 [(set (match_operand:SI 0 "register_operand" "=d")
2609 (ne:SI (match_operand:BI 1 "register_operand" "C")
2610 (const_int 0)))]
2611 ""
2612 "#"
2613 ""
2614 [(set (match_operand:SI 0 "register_operand" "")
2615 (zero_extend:SI (match_operand:BI 1 "register_operand" "")))]
2616 "")
2617
2618 (define_insn "notbi"
2619 [(set (match_operand:BI 0 "register_operand" "=C")
2620 (eq:BI (match_operand:BI 1 "register_operand" " 0")
2621 (const_int 0)))]
2622 ""
2623 "%0 = ! %0;" /* NOT CC;" */
2624 [(set_attr "type" "compare")])
2625
2626 ;; Vector and DSP insns
2627
2628 (define_insn ""
2629 [(set (match_operand:SI 0 "register_operand" "=d")
2630 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2631 (const_int 24))
2632 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2633 (const_int 8))))]
2634 ""
2635 "%0 = ALIGN8(%1, %2)%!"
2636 [(set_attr "type" "dsp32")])
2637
2638 (define_insn ""
2639 [(set (match_operand:SI 0 "register_operand" "=d")
2640 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2641 (const_int 16))
2642 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2643 (const_int 16))))]
2644 ""
2645 "%0 = ALIGN16(%1, %2)%!"
2646 [(set_attr "type" "dsp32")])
2647
2648 (define_insn ""
2649 [(set (match_operand:SI 0 "register_operand" "=d")
2650 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2651 (const_int 8))
2652 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2653 (const_int 24))))]
2654 ""
2655 "%0 = ALIGN24(%1, %2)%!"
2656 [(set_attr "type" "dsp32")])
2657
2658 ;; Prologue and epilogue.
2659
2660 (define_expand "prologue"
2661 [(const_int 1)]
2662 ""
2663 "bfin_expand_prologue (); DONE;")
2664
2665 (define_expand "epilogue"
2666 [(const_int 1)]
2667 ""
2668 "bfin_expand_epilogue (1, 0, 0); DONE;")
2669
2670 (define_expand "sibcall_epilogue"
2671 [(const_int 1)]
2672 ""
2673 "bfin_expand_epilogue (0, 0, 1); DONE;")
2674
2675 (define_expand "eh_return"
2676 [(use (match_operand:SI 0 "register_operand" ""))]
2677 ""
2678 {
2679 emit_insn (gen_eh_store_handler (EH_RETURN_HANDLER_RTX, operands[0]));
2680 emit_jump_insn (gen_eh_return_internal ());
2681 emit_barrier ();
2682 DONE;
2683 })
2684
2685 (define_insn "eh_store_handler"
2686 [(unspec_volatile [(match_operand:SI 1 "register_operand" "da")]
2687 UNSPEC_VOLATILE_STORE_EH_HANDLER)
2688 (clobber (match_operand:SI 0 "memory_operand" "=m"))]
2689 ""
2690 "%0 = %1%!"
2691 [(set_attr "type" "mcst")])
2692
2693 (define_insn_and_split "eh_return_internal"
2694 [(eh_return)]
2695 ""
2696 "#"
2697 "epilogue_completed"
2698 [(const_int 1)]
2699 "bfin_expand_epilogue (1, 1, 0); DONE;")
2700
2701 (define_insn "link"
2702 [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS))
2703 (set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:SI REG_FP))
2704 (set (reg:SI REG_FP)
2705 (plus:SI (reg:SI REG_SP) (const_int -8)))
2706 (set (reg:SI REG_SP)
2707 (plus:SI (reg:SI REG_SP) (match_operand:SI 0 "immediate_operand" "i")))]
2708 ""
2709 "LINK %Z0;"
2710 [(set_attr "length" "4")])
2711
2712 (define_insn "unlink"
2713 [(set (reg:SI REG_FP) (mem:SI (reg:SI REG_FP)))
2714 (set (reg:SI REG_RETS) (mem:SI (plus:SI (reg:SI REG_FP) (const_int 4))))
2715 (set (reg:SI REG_SP) (plus:SI (reg:SI REG_FP) (const_int 8)))]
2716 ""
2717 "UNLINK;"
2718 [(set_attr "length" "4")])
2719
2720 ;; This pattern is slightly clumsy. The stack adjust must be the final SET in
2721 ;; the pattern, otherwise dwarf2out becomes very confused about which reg goes
2722 ;; where on the stack, since it goes through all elements of the parallel in
2723 ;; sequence.
2724 (define_insn "push_multiple"
2725 [(match_parallel 0 "push_multiple_operation"
2726 [(unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_PUSH_MULTIPLE)])]
2727 ""
2728 {
2729 output_push_multiple (insn, operands);
2730 return "";
2731 })
2732
2733 (define_insn "pop_multiple"
2734 [(match_parallel 0 "pop_multiple_operation"
2735 [(set (reg:SI REG_SP)
2736 (plus:SI (reg:SI REG_SP) (match_operand:SI 1 "immediate_operand" "i")))])]
2737 ""
2738 {
2739 output_pop_multiple (insn, operands);
2740 return "";
2741 })
2742
2743 (define_insn "return_internal"
2744 [(return)
2745 (use (match_operand 0 "register_operand" ""))]
2746 "reload_completed"
2747 {
2748 switch (REGNO (operands[0]))
2749 {
2750 case REG_RETX:
2751 return "rtx;";
2752 case REG_RETN:
2753 return "rtn;";
2754 case REG_RETI:
2755 return "rti;";
2756 case REG_RETS:
2757 return "rts;";
2758 }
2759 gcc_unreachable ();
2760 })
2761
2762 ;; When used at a location where CC contains 1, causes a speculative load
2763 ;; that is later cancelled. This is used for certain workarounds in
2764 ;; interrupt handler prologues.
2765 (define_insn "dummy_load"
2766 [(unspec_volatile [(match_operand 0 "register_operand" "a")
2767 (match_operand 1 "register_operand" "C")]
2768 UNSPEC_VOLATILE_DUMMY)]
2769 ""
2770 "if cc jump 4;\n\tr7 = [%0];"
2771 [(set_attr "type" "misc")
2772 (set_attr "length" "4")
2773 (set_attr "seq_insns" "multi")])
2774
2775 ;; A placeholder insn inserted before the final scheduling pass. It is used
2776 ;; to improve scheduling of loads when workarounds for speculative loads are
2777 ;; needed, by not placing them in the first few cycles after a conditional
2778 ;; branch.
2779 (define_insn "stall"
2780 [(unspec_volatile [(match_operand 0 "const_int_operand" "P1P3")]
2781 UNSPEC_VOLATILE_STALL)]
2782 ""
2783 ""
2784 [(set_attr "type" "stall")])
2785
2786 (define_insn "csync"
2787 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
2788 ""
2789 "csync;"
2790 [(set_attr "type" "sync")])
2791
2792 (define_insn "ssync"
2793 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_SSYNC)]
2794 ""
2795 "ssync;"
2796 [(set_attr "type" "sync")])
2797
2798 (define_insn "trap"
2799 [(trap_if (const_int 1) (const_int 3))]
2800 ""
2801 "excpt 3;"
2802 [(set_attr "type" "misc")
2803 (set_attr "length" "2")])
2804
2805 (define_insn "trapifcc"
2806 [(trap_if (reg:BI REG_CC) (const_int 3))]
2807 ""
2808 "if !cc jump 4 (bp); excpt 3;"
2809 [(set_attr "type" "misc")
2810 (set_attr "length" "4")
2811 (set_attr "seq_insns" "multi")])
2812
2813 ;;; Vector instructions
2814
2815 ;; First, all sorts of move variants
2816
2817 (define_insn "movhiv2hi_low"
2818 [(set (match_operand:V2HI 0 "register_operand" "=d")
2819 (vec_concat:V2HI
2820 (match_operand:HI 2 "register_operand" "d")
2821 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2822 (parallel [(const_int 1)]))))]
2823 ""
2824 "%h0 = %h2 << 0%!"
2825 [(set_attr "type" "dsp32shiftimm")])
2826
2827 (define_insn "movhiv2hi_high"
2828 [(set (match_operand:V2HI 0 "register_operand" "=d")
2829 (vec_concat:V2HI
2830 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2831 (parallel [(const_int 0)]))
2832 (match_operand:HI 2 "register_operand" "d")))]
2833 ""
2834 "%d0 = %h2 << 0%!"
2835 [(set_attr "type" "dsp32shiftimm")])
2836
2837 ;; No earlyclobber on alternative two since our sequence ought to be safe.
2838 ;; The order of operands is intentional to match the VDSP builtin (high word
2839 ;; is passed first).
2840 (define_insn_and_split "composev2hi"
2841 [(set (match_operand:V2HI 0 "register_operand" "=d,d")
2842 (vec_concat:V2HI (match_operand:HI 2 "register_operand" "0,d")
2843 (match_operand:HI 1 "register_operand" "d,d")))]
2844 ""
2845 "@
2846 %d0 = %h1 << 0%!
2847 #"
2848 "reload_completed"
2849 [(set (match_dup 0)
2850 (vec_concat:V2HI
2851 (vec_select:HI (match_dup 0) (parallel [(const_int 0)]))
2852 (match_dup 1)))
2853 (set (match_dup 0)
2854 (vec_concat:V2HI
2855 (match_dup 2)
2856 (vec_select:HI (match_dup 0) (parallel [(const_int 1)]))))]
2857 ""
2858 [(set_attr "type" "dsp32shiftimm")])
2859
2860 ; Like composev2hi, but operating on elements of V2HI vectors.
2861 ; Useful on its own, and as a combiner bridge for the multiply and
2862 ; mac patterns.
2863 (define_insn "packv2hi"
2864 [(set (match_operand:V2HI 0 "register_operand" "=d,d,d,d,d,d,d,d")
2865 (vec_concat:V2HI (vec_select:HI
2866 (match_operand:V2HI 1 "register_operand" "0,0,d,d,d,d,d,d")
2867 (parallel [(match_operand 3 "const01_operand" "P0,P0,P0,P1,P0,P1,P0,P1")]))
2868 (vec_select:HI
2869 (match_operand:V2HI 2 "register_operand" "d,d,0,0,d,d,d,d")
2870 (parallel [(match_operand 4 "const01_operand" "P0,P1,P1,P1,P0,P0,P1,P1")]))))]
2871 ""
2872 "@
2873 %d0 = %h2 << 0%!
2874 %d0 = %d2 << 0%!
2875 %h0 = %h1 << 0%!
2876 %h0 = %d1 << 0%!
2877 %0 = PACK (%h2,%h1)%!
2878 %0 = PACK (%h2,%d1)%!
2879 %0 = PACK (%d2,%h1)%!
2880 %0 = PACK (%d2,%d1)%!"
2881 [(set_attr "type" "dsp32shiftimm,dsp32shiftimm,dsp32shiftimm,dsp32shiftimm,dsp32,dsp32,dsp32,dsp32")])
2882
2883 (define_insn "movv2hi_hi"
2884 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
2885 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0,d,d")
2886 (parallel [(match_operand 2 "const01_operand" "P0,P0,P1")])))]
2887 ""
2888 "@
2889 /* optimized out */
2890 %h0 = %h1 << 0%!
2891 %h0 = %d1 << 0%!"
2892 [(set_attr "type" "dsp32shiftimm")])
2893
2894 (define_expand "movv2hi_hi_low"
2895 [(set (match_operand:HI 0 "register_operand" "")
2896 (vec_select:HI (match_operand:V2HI 1 "register_operand" "")
2897 (parallel [(const_int 0)])))]
2898 ""
2899 "")
2900
2901 (define_expand "movv2hi_hi_high"
2902 [(set (match_operand:HI 0 "register_operand" "")
2903 (vec_select:HI (match_operand:V2HI 1 "register_operand" "")
2904 (parallel [(const_int 1)])))]
2905 ""
2906 "")
2907
2908 ;; Unusual arithmetic operations on 16-bit registers.
2909
2910 (define_code_iterator sp_or_sm [ss_plus ss_minus])
2911 (define_code_attr spm_string [(ss_plus "+") (ss_minus "-")])
2912 (define_code_attr spm_name [(ss_plus "add") (ss_minus "sub")])
2913
2914 (define_insn "ss<spm_name>hi3"
2915 [(set (match_operand:HI 0 "register_operand" "=d")
2916 (sp_or_sm:HI (match_operand:HI 1 "register_operand" "d")
2917 (match_operand:HI 2 "register_operand" "d")))]
2918 ""
2919 "%h0 = %h1 <spm_string> %h2 (S)%!"
2920 [(set_attr "type" "dsp32")])
2921
2922 (define_insn "ss<spm_name>hi3_parts"
2923 [(set (match_operand:HI 0 "register_operand" "=d")
2924 (sp_or_sm:HI (vec_select:HI
2925 (match_operand:V2HI 1 "register_operand" "d")
2926 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
2927 (vec_select:HI
2928 (match_operand:V2HI 2 "register_operand" "d")
2929 (parallel [(match_operand 4 "const01_operand" "P0P1")]))))]
2930 ""
2931 {
2932 const char *templates[] = {
2933 "%h0 = %h1 <spm_string> %h2 (S)%!",
2934 "%h0 = %d1 <spm_string> %h2 (S)%!",
2935 "%h0 = %h1 <spm_string> %d2 (S)%!",
2936 "%h0 = %d1 <spm_string> %d2 (S)%!" };
2937 int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
2938 return templates[alt];
2939 }
2940 [(set_attr "type" "dsp32")])
2941
2942 (define_insn "ss<spm_name>hi3_low_parts"
2943 [(set (match_operand:V2HI 0 "register_operand" "=d")
2944 (vec_concat:V2HI
2945 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2946 (parallel [(const_int 0)]))
2947 (sp_or_sm:HI (vec_select:HI
2948 (match_operand:V2HI 2 "register_operand" "d")
2949 (parallel [(match_operand 4 "const01_operand" "P0P1")]))
2950 (vec_select:HI
2951 (match_operand:V2HI 3 "register_operand" "d")
2952 (parallel [(match_operand 5 "const01_operand" "P0P1")])))))]
2953 ""
2954 {
2955 const char *templates[] = {
2956 "%h0 = %h2 <spm_string> %h3 (S)%!",
2957 "%h0 = %d2 <spm_string> %h3 (S)%!",
2958 "%h0 = %h2 <spm_string> %d3 (S)%!",
2959 "%h0 = %d2 <spm_string> %d3 (S)%!" };
2960 int alt = INTVAL (operands[4]) + (INTVAL (operands[5]) << 1);
2961 return templates[alt];
2962 }
2963 [(set_attr "type" "dsp32")])
2964
2965 (define_insn "ss<spm_name>hi3_high_parts"
2966 [(set (match_operand:V2HI 0 "register_operand" "=d")
2967 (vec_concat:V2HI
2968 (sp_or_sm:HI (vec_select:HI
2969 (match_operand:V2HI 2 "register_operand" "d")
2970 (parallel [(match_operand 4 "const01_operand" "P0P1")]))
2971 (vec_select:HI
2972 (match_operand:V2HI 3 "register_operand" "d")
2973 (parallel [(match_operand 5 "const01_operand" "P0P1")])))
2974 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2975 (parallel [(const_int 1)]))))]
2976 ""
2977 {
2978 const char *templates[] = {
2979 "%d0 = %h2 <spm_string> %h3 (S)%!",
2980 "%d0 = %d2 <spm_string> %h3 (S)%!",
2981 "%d0 = %h2 <spm_string> %d3 (S)%!",
2982 "%d0 = %d2 <spm_string> %d3 (S)%!" };
2983 int alt = INTVAL (operands[4]) + (INTVAL (operands[5]) << 1);
2984 return templates[alt];
2985 }
2986 [(set_attr "type" "dsp32")])
2987
2988 ;; V2HI vector insns
2989
2990 (define_insn "addv2hi3"
2991 [(set (match_operand:V2HI 0 "register_operand" "=d")
2992 (plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2993 (match_operand:V2HI 2 "register_operand" "d")))]
2994 ""
2995 "%0 = %1 +|+ %2%!"
2996 [(set_attr "type" "dsp32")])
2997
2998 (define_insn "ssaddv2hi3"
2999 [(set (match_operand:V2HI 0 "register_operand" "=d")
3000 (ss_plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
3001 (match_operand:V2HI 2 "register_operand" "d")))]
3002 ""
3003 "%0 = %1 +|+ %2 (S)%!"
3004 [(set_attr "type" "dsp32")])
3005
3006 (define_insn "subv2hi3"
3007 [(set (match_operand:V2HI 0 "register_operand" "=d")
3008 (minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
3009 (match_operand:V2HI 2 "register_operand" "d")))]
3010 ""
3011 "%0 = %1 -|- %2%!"
3012 [(set_attr "type" "dsp32")])
3013
3014 (define_insn "sssubv2hi3"
3015 [(set (match_operand:V2HI 0 "register_operand" "=d")
3016 (ss_minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
3017 (match_operand:V2HI 2 "register_operand" "d")))]
3018 ""
3019 "%0 = %1 -|- %2 (S)%!"
3020 [(set_attr "type" "dsp32")])
3021
3022 (define_insn "addsubv2hi3"
3023 [(set (match_operand:V2HI 0 "register_operand" "=d")
3024 (vec_concat:V2HI
3025 (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3026 (parallel [(const_int 0)]))
3027 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3028 (parallel [(const_int 0)])))
3029 (plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
3030 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3031 ""
3032 "%0 = %1 +|- %2%!"
3033 [(set_attr "type" "dsp32")])
3034
3035 (define_insn "subaddv2hi3"
3036 [(set (match_operand:V2HI 0 "register_operand" "=d")
3037 (vec_concat:V2HI
3038 (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3039 (parallel [(const_int 0)]))
3040 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3041 (parallel [(const_int 0)])))
3042 (minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
3043 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3044 ""
3045 "%0 = %1 -|+ %2%!"
3046 [(set_attr "type" "dsp32")])
3047
3048 (define_insn "ssaddsubv2hi3"
3049 [(set (match_operand:V2HI 0 "register_operand" "=d")
3050 (vec_concat:V2HI
3051 (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3052 (parallel [(const_int 0)]))
3053 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3054 (parallel [(const_int 0)])))
3055 (ss_plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
3056 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3057 ""
3058 "%0 = %1 +|- %2 (S)%!"
3059 [(set_attr "type" "dsp32")])
3060
3061 (define_insn "sssubaddv2hi3"
3062 [(set (match_operand:V2HI 0 "register_operand" "=d")
3063 (vec_concat:V2HI
3064 (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3065 (parallel [(const_int 0)]))
3066 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3067 (parallel [(const_int 0)])))
3068 (ss_minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
3069 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3070 ""
3071 "%0 = %1 -|+ %2 (S)%!"
3072 [(set_attr "type" "dsp32")])
3073
3074 (define_insn "sublohiv2hi3"
3075 [(set (match_operand:HI 0 "register_operand" "=d")
3076 (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3077 (parallel [(const_int 1)]))
3078 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3079 (parallel [(const_int 0)]))))]
3080 ""
3081 "%h0 = %d1 - %h2%!"
3082 [(set_attr "type" "dsp32")])
3083
3084 (define_insn "subhilov2hi3"
3085 [(set (match_operand:HI 0 "register_operand" "=d")
3086 (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3087 (parallel [(const_int 0)]))
3088 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3089 (parallel [(const_int 1)]))))]
3090 ""
3091 "%h0 = %h1 - %d2%!"
3092 [(set_attr "type" "dsp32")])
3093
3094 (define_insn "sssublohiv2hi3"
3095 [(set (match_operand:HI 0 "register_operand" "=d")
3096 (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3097 (parallel [(const_int 1)]))
3098 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3099 (parallel [(const_int 0)]))))]
3100 ""
3101 "%h0 = %d1 - %h2 (S)%!"
3102 [(set_attr "type" "dsp32")])
3103
3104 (define_insn "sssubhilov2hi3"
3105 [(set (match_operand:HI 0 "register_operand" "=d")
3106 (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3107 (parallel [(const_int 0)]))
3108 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3109 (parallel [(const_int 1)]))))]
3110 ""
3111 "%h0 = %h1 - %d2 (S)%!"
3112 [(set_attr "type" "dsp32")])
3113
3114 (define_insn "addlohiv2hi3"
3115 [(set (match_operand:HI 0 "register_operand" "=d")
3116 (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3117 (parallel [(const_int 1)]))
3118 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3119 (parallel [(const_int 0)]))))]
3120 ""
3121 "%h0 = %d1 + %h2%!"
3122 [(set_attr "type" "dsp32")])
3123
3124 (define_insn "addhilov2hi3"
3125 [(set (match_operand:HI 0 "register_operand" "=d")
3126 (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3127 (parallel [(const_int 0)]))
3128 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3129 (parallel [(const_int 1)]))))]
3130 ""
3131 "%h0 = %h1 + %d2%!"
3132 [(set_attr "type" "dsp32")])
3133
3134 (define_insn "ssaddlohiv2hi3"
3135 [(set (match_operand:HI 0 "register_operand" "=d")
3136 (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3137 (parallel [(const_int 1)]))
3138 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3139 (parallel [(const_int 0)]))))]
3140 ""
3141 "%h0 = %d1 + %h2 (S)%!"
3142 [(set_attr "type" "dsp32")])
3143
3144 (define_insn "ssaddhilov2hi3"
3145 [(set (match_operand:HI 0 "register_operand" "=d")
3146 (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3147 (parallel [(const_int 0)]))
3148 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3149 (parallel [(const_int 1)]))))]
3150 ""
3151 "%h0 = %h1 + %d2 (S)%!"
3152 [(set_attr "type" "dsp32")])
3153
3154 (define_insn "sminv2hi3"
3155 [(set (match_operand:V2HI 0 "register_operand" "=d")
3156 (smin:V2HI (match_operand:V2HI 1 "register_operand" "d")
3157 (match_operand:V2HI 2 "register_operand" "d")))]
3158 ""
3159 "%0 = MIN (%1, %2) (V)%!"
3160 [(set_attr "type" "dsp32")])
3161
3162 (define_insn "smaxv2hi3"
3163 [(set (match_operand:V2HI 0 "register_operand" "=d")
3164 (smax:V2HI (match_operand:V2HI 1 "register_operand" "d")
3165 (match_operand:V2HI 2 "register_operand" "d")))]
3166 ""
3167 "%0 = MAX (%1, %2) (V)%!"
3168 [(set_attr "type" "dsp32")])
3169
3170 ;; Multiplications.
3171
3172 ;; The Blackfin allows a lot of different options, and we need many patterns to
3173 ;; cover most of the hardware's abilities.
3174 ;; There are a few simple patterns using MULT rtx codes, but most of them use
3175 ;; an unspec with a const_int operand that determines which flag to use in the
3176 ;; instruction.
3177 ;; There are variants for single and parallel multiplications.
3178 ;; There are variants which just use 16-bit lowparts as inputs, and variants
3179 ;; which allow the user to choose just which halves to use as input values.
3180 ;; There are variants which set D registers, variants which set accumulators,
3181 ;; variants which set both, some of them optionally using the accumulators as
3182 ;; inputs for multiply-accumulate operations.
3183
3184 (define_insn "flag_mulhi"
3185 [(set (match_operand:HI 0 "register_operand" "=d")
3186 (unspec:HI [(match_operand:HI 1 "register_operand" "d")
3187 (match_operand:HI 2 "register_operand" "d")
3188 (match_operand 3 "const_int_operand" "n")]
3189 UNSPEC_MUL_WITH_FLAG))]
3190 ""
3191 "%h0 = %h1 * %h2 %M3%!"
3192 [(set_attr "type" "dsp32")])
3193
3194 (define_insn "flag_mulhi_parts"
3195 [(set (match_operand:HI 0 "register_operand" "=d")
3196 (unspec:HI [(vec_select:HI
3197 (match_operand:V2HI 1 "register_operand" "d")
3198 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
3199 (vec_select:HI
3200 (match_operand:V2HI 2 "register_operand" "d")
3201 (parallel [(match_operand 4 "const01_operand" "P0P1")]))
3202 (match_operand 5 "const_int_operand" "n")]
3203 UNSPEC_MUL_WITH_FLAG))]
3204 ""
3205 {
3206 const char *templates[] = {
3207 "%h0 = %h1 * %h2 %M5%!",
3208 "%h0 = %d1 * %h2 %M5%!",
3209 "%h0 = %h1 * %d2 %M5%!",
3210 "%h0 = %d1 * %d2 %M5%!" };
3211 int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
3212 return templates[alt];
3213 }
3214 [(set_attr "type" "dsp32")])
3215
3216 (define_insn "flag_mulhisi"
3217 [(set (match_operand:SI 0 "register_operand" "=d")
3218 (unspec:SI [(match_operand:HI 1 "register_operand" "d")
3219 (match_operand:HI 2 "register_operand" "d")
3220 (match_operand 3 "const_int_operand" "n")]
3221 UNSPEC_MUL_WITH_FLAG))]
3222 ""
3223 "%0 = %h1 * %h2 %M3%!"
3224 [(set_attr "type" "dsp32")])
3225
3226 (define_insn "flag_mulhisi_parts"
3227 [(set (match_operand:SI 0 "register_operand" "=d")
3228 (unspec:SI [(vec_select:HI
3229 (match_operand:V2HI 1 "register_operand" "d")
3230 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
3231 (vec_select:HI
3232 (match_operand:V2HI 2 "register_operand" "d")
3233 (parallel [(match_operand 4 "const01_operand" "P0P1")]))
3234 (match_operand 5 "const_int_operand" "n")]
3235 UNSPEC_MUL_WITH_FLAG))]
3236 ""
3237 {
3238 const char *templates[] = {
3239 "%0 = %h1 * %h2 %M5%!",
3240 "%0 = %d1 * %h2 %M5%!",
3241 "%0 = %h1 * %d2 %M5%!",
3242 "%0 = %d1 * %d2 %M5%!" };
3243 int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
3244 return templates[alt];
3245 }
3246 [(set_attr "type" "dsp32")])
3247
3248 ;; Three alternatives here to cover all possible allocations:
3249 ;; 0. mac flag is usable only for accumulator 1 - use A1 and odd DREG
3250 ;; 1. mac flag is usable for accumulator 0 - use A0 and even DREG
3251 ;; 2. mac flag is usable in any accumulator - use A1 and odd DREG
3252 ;; Other patterns which don't have a DREG destination can collapse cases
3253 ;; 1 and 2 into one.
3254 (define_insn "flag_machi"
3255 [(set (match_operand:HI 0 "register_operand" "=W,D,W")
3256 (unspec:HI [(match_operand:HI 2 "register_operand" "d,d,d")
3257 (match_operand:HI 3 "register_operand" "d,d,d")
3258 (match_operand 4 "register_operand" "1,1,1")
3259 (match_operand 5 "const01_operand" "P0P1,P0P1,P0P1")
3260 (match_operand 6 "const_int_operand" "PB,PA,PA")]
3261 UNSPEC_MAC_WITH_FLAG))
3262 (set (match_operand:PDI 1 "register_operand" "=B,A,B")
3263 (unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)
3264 (match_dup 4) (match_dup 5)]
3265 UNSPEC_MAC_WITH_FLAG))]
3266 ""
3267 "%h0 = (%1 %b5 %h2 * %h3) %M6%!"
3268 [(set_attr "type" "dsp32")])
3269
3270 (define_insn "flag_machi_acconly"
3271 [(set (match_operand:PDI 0 "register_operand" "=B,e")
3272 (unspec:PDI [(match_operand:HI 1 "register_operand" "d,d")
3273 (match_operand:HI 2 "register_operand" "d,d")
3274 (match_operand 3 "register_operand" "0,0")
3275 (match_operand 4 "const01_operand" "P0P1,P0P1")
3276 (match_operand 5 "const_int_operand" "PB,PA")]
3277 UNSPEC_MAC_WITH_FLAG))]
3278 ""
3279 "%0 %b4 %h1 * %h2 %M5%!"
3280 [(set_attr "type" "dsp32")])
3281
3282 (define_insn "flag_machi_parts_acconly"
3283 [(set (match_operand:PDI 0 "register_operand" "=B,e")
3284 (unspec:PDI [(vec_select:HI
3285 (match_operand:V2HI 1 "register_operand" "d,d")
3286 (parallel [(match_operand 3 "const01_operand" "P0P1,P0P1")]))
3287 (vec_select:HI
3288 (match_operand:V2HI 2 "register_operand" "d,d")
3289 (parallel [(match_operand 4 "const01_operand" "P0P1,P0P1")]))
3290 (match_operand:PDI 5 "register_operand" "0,0")
3291 (match_operand 6 "const01_operand" "P0P1,P0P1")
3292 (match_operand 7 "const_int_operand" "PB,PA")]
3293 UNSPEC_MAC_WITH_FLAG))]
3294 ""
3295 {
3296 const char *templates[] = {
3297 "%0 %b6 %h1 * %h2 %M7%!",
3298 "%0 %b6 %d1 * %h2 %M7%!",
3299 "%0 %b6 %h1 * %d2 %M7%!",
3300 "%0 %b6 %d1 * %d2 %M7%!"
3301 };
3302 int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
3303 return templates[alt];
3304 }
3305 [(set_attr "type" "dsp32")])
3306
3307 (define_insn "flag_macinithi"
3308 [(set (match_operand:HI 0 "register_operand" "=W,D,W")
3309 (unspec:HI [(match_operand:HI 1 "register_operand" "d,d,d")
3310 (match_operand:HI 2 "register_operand" "d,d,d")
3311 (match_operand 3 "const_int_operand" "PB,PA,PA")]
3312 UNSPEC_MAC_WITH_FLAG))
3313 (set (match_operand:PDI 4 "register_operand" "=B,A,B")
3314 (unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)]
3315 UNSPEC_MAC_WITH_FLAG))]
3316 ""
3317 "%h0 = (%4 = %h1 * %h2) %M3%!"
3318 [(set_attr "type" "dsp32")])
3319
3320 (define_insn "flag_macinit1hi"
3321 [(set (match_operand:PDI 0 "register_operand" "=B,e")
3322 (unspec:PDI [(match_operand:HI 1 "register_operand" "d,d")
3323 (match_operand:HI 2 "register_operand" "d,d")
3324 (match_operand 3 "const_int_operand" "PB,PA")]
3325 UNSPEC_MAC_WITH_FLAG))]
3326 ""
3327 "%0 = %h1 * %h2 %M3%!"
3328 [(set_attr "type" "dsp32")])
3329
3330 (define_insn "mulv2hi3"
3331 [(set (match_operand:V2HI 0 "register_operand" "=d")
3332 (mult:V2HI (match_operand:V2HI 1 "register_operand" "d")
3333 (match_operand:V2HI 2 "register_operand" "d")))]
3334 ""
3335 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 (IS)%!"
3336 [(set_attr "type" "dsp32")])
3337
3338 (define_insn "flag_mulv2hi"
3339 [(set (match_operand:V2HI 0 "register_operand" "=d")
3340 (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "d")
3341 (match_operand:V2HI 2 "register_operand" "d")
3342 (match_operand 3 "const_int_operand" "n")]
3343 UNSPEC_MUL_WITH_FLAG))]
3344 ""
3345 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 %M3%!"
3346 [(set_attr "type" "dsp32")])
3347
3348 (define_insn "flag_mulv2hi_parts"
3349 [(set (match_operand:V2HI 0 "register_operand" "=d")
3350 (unspec:V2HI [(vec_concat:V2HI
3351 (vec_select:HI
3352 (match_operand:V2HI 1 "register_operand" "d")
3353 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
3354 (vec_select:HI
3355 (match_dup 1)
3356 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
3357 (vec_concat:V2HI
3358 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3359 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
3360 (vec_select:HI (match_dup 2)
3361 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
3362 (match_operand 7 "const_int_operand" "n")]
3363 UNSPEC_MUL_WITH_FLAG))]
3364 ""
3365 {
3366 const char *templates[] = {
3367 "%h0 = %h1 * %h2, %d0 = %h1 * %h2 %M7%!",
3368 "%h0 = %d1 * %h2, %d0 = %h1 * %h2 %M7%!",
3369 "%h0 = %h1 * %h2, %d0 = %d1 * %h2 %M7%!",
3370 "%h0 = %d1 * %h2, %d0 = %d1 * %h2 %M7%!",
3371 "%h0 = %h1 * %d2, %d0 = %h1 * %h2 %M7%!",
3372 "%h0 = %d1 * %d2, %d0 = %h1 * %h2 %M7%!",
3373 "%h0 = %h1 * %d2, %d0 = %d1 * %h2 %M7%!",
3374 "%h0 = %d1 * %d2, %d0 = %d1 * %h2 %M7%!",
3375 "%h0 = %h1 * %h2, %d0 = %h1 * %d2 %M7%!",
3376 "%h0 = %d1 * %h2, %d0 = %h1 * %d2 %M7%!",
3377 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 %M7%!",
3378 "%h0 = %d1 * %h2, %d0 = %d1 * %d2 %M7%!",
3379 "%h0 = %h1 * %d2, %d0 = %h1 * %d2 %M7%!",
3380 "%h0 = %d1 * %d2, %d0 = %h1 * %d2 %M7%!",
3381 "%h0 = %h1 * %d2, %d0 = %d1 * %d2 %M7%!",
3382 "%h0 = %d1 * %d2, %d0 = %d1 * %d2 %M7%!" };
3383 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3384 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3385 return templates[alt];
3386 }
3387 [(set_attr "type" "dsp32")])
3388
3389 ;; A slightly complicated pattern.
3390 ;; Operand 0 is the halfword output; operand 11 is the accumulator output
3391 ;; Halfword inputs are operands 1 and 2; operands 3, 4, 5 and 6 specify which
3392 ;; parts of these 2x16 bit registers to use.
3393 ;; Operand 7 is the accumulator input.
3394 ;; Operands 8/9 specify whether low/high parts are mac (0) or msu (1)
3395 ;; Operand 10 is the macflag to be used.
3396 (define_insn "flag_macv2hi_parts"
3397 [(set (match_operand:V2HI 0 "register_operand" "=d")
3398 (unspec:V2HI [(vec_concat:V2HI
3399 (vec_select:HI
3400 (match_operand:V2HI 1 "register_operand" "d")
3401 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
3402 (vec_select:HI
3403 (match_dup 1)
3404 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
3405 (vec_concat:V2HI
3406 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3407 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
3408 (vec_select:HI (match_dup 2)
3409 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
3410 (match_operand:V2PDI 7 "register_operand" "e")
3411 (match_operand 8 "const01_operand" "P0P1")
3412 (match_operand 9 "const01_operand" "P0P1")
3413 (match_operand 10 "const_int_operand" "n")]
3414 UNSPEC_MAC_WITH_FLAG))
3415 (set (match_operand:V2PDI 11 "register_operand" "=e")
3416 (unspec:V2PDI [(vec_concat:V2HI
3417 (vec_select:HI (match_dup 1) (parallel [(match_dup 3)]))
3418 (vec_select:HI (match_dup 1) (parallel [(match_dup 4)])))
3419 (vec_concat:V2HI
3420 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)]))
3421 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)])))
3422 (match_dup 7) (match_dup 8) (match_dup 9) (match_dup 10)]
3423 UNSPEC_MAC_WITH_FLAG))]
3424 ""
3425 {
3426 const char *templates[] = {
3427 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3428 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3429 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3430 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3431 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3432 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3433 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3434 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3435 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3436 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3437 "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %d1 * %d2) %M10%!",
3438 "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %d1 * %d2) %M10%!",
3439 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3440 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3441 "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %d1 * %d2) %M10%!",
3442 "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %d1 * %d2) %M10%!" };
3443 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3444 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3445 return templates[alt];
3446 }
3447 [(set_attr "type" "dsp32")])
3448
3449 (define_insn "flag_macv2hi_parts_acconly"
3450 [(set (match_operand:V2PDI 0 "register_operand" "=e")
3451 (unspec:V2PDI [(vec_concat:V2HI
3452 (vec_select:HI
3453 (match_operand:V2HI 1 "register_operand" "d")
3454 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
3455 (vec_select:HI
3456 (match_dup 1)
3457 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
3458 (vec_concat:V2HI
3459 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3460 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
3461 (vec_select:HI (match_dup 2)
3462 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
3463 (match_operand:V2PDI 7 "register_operand" "e")
3464 (match_operand 8 "const01_operand" "P0P1")
3465 (match_operand 9 "const01_operand" "P0P1")
3466 (match_operand 10 "const_int_operand" "n")]
3467 UNSPEC_MAC_WITH_FLAG))]
3468 ""
3469 {
3470 const char *templates[] = {
3471 "A0 %b8 %h1 * %h2, A1 %b9 %h1 * %h2 %M10%!",
3472 "A0 %b8 %d1 * %h2, A1 %b9 %h1 * %h2 %M10%!",
3473 "A0 %b8 %h1 * %h2, A1 %b9 %d1 * %h2 %M10%!",
3474 "A0 %b8 %d1 * %h2, A1 %b9 %d1 * %h2 %M10%!",
3475 "A0 %b8 %h1 * %d2, A1 %b9 %h1 * %h2 %M10%!",
3476 "A0 %b8 %d1 * %d2, A1 %b9 %h1 * %h2 %M10%!",
3477 "A0 %b8 %h1 * %d2, A1 %b9 %d1 * %h2 %M10%!",
3478 "A0 %b8 %d1 * %d2, A1 %b9 %d1 * %h2 %M10%!",
3479 "A0 %b8 %h1 * %h2, A1 %b9 %h1 * %d2 %M10%!",
3480 "A0 %b8 %d1 * %h2, A1 %b9 %h1 * %d2 %M10%!",
3481 "A0 %b8 %h1 * %h2, A1 %b9 %d1 * %d2 %M10%!",
3482 "A0 %b8 %d1 * %h2, A1 %b9 %d1 * %d2 %M10%!",
3483 "A0 %b8 %h1 * %d2, A1 %b9 %h1 * %d2 %M10%!",
3484 "A0 %b8 %d1 * %d2, A1 %b9 %h1 * %d2 %M10%!",
3485 "A0 %b8 %h1 * %d2, A1 %b9 %d1 * %d2 %M10%!",
3486 "A0 %b8 %d1 * %d2, A1 %b9 %d1 * %d2 %M10%!" };
3487 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3488 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3489 return templates[alt];
3490 }
3491 [(set_attr "type" "dsp32")])
3492
3493 ;; Same as above, but initializing the accumulators and therefore a couple fewer
3494 ;; necessary operands.
3495 (define_insn "flag_macinitv2hi_parts"
3496 [(set (match_operand:V2HI 0 "register_operand" "=d")
3497 (unspec:V2HI [(vec_concat:V2HI
3498 (vec_select:HI
3499 (match_operand:V2HI 1 "register_operand" "d")
3500 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
3501 (vec_select:HI
3502 (match_dup 1)
3503 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
3504 (vec_concat:V2HI
3505 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3506 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
3507 (vec_select:HI (match_dup 2)
3508 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
3509 (match_operand 7 "const_int_operand" "n")]
3510 UNSPEC_MAC_WITH_FLAG))
3511 (set (match_operand:V2PDI 8 "register_operand" "=e")
3512 (unspec:V2PDI [(vec_concat:V2HI
3513 (vec_select:HI (match_dup 1) (parallel [(match_dup 3)]))
3514 (vec_select:HI (match_dup 1) (parallel [(match_dup 4)])))
3515 (vec_concat:V2HI
3516 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)]))
3517 (vec_select:HI (match_dup 2) (parallel [(match_dup 5)])))
3518 (match_dup 7)]
3519 UNSPEC_MAC_WITH_FLAG))]
3520 ""
3521 {
3522 const char *templates[] = {
3523 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %h1 * %h2) %M7%!",
3524 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %h1 * %h2) %M7%!",
3525 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %d1 * %h2) %M7%!",
3526 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %d1 * %h2) %M7%!",
3527 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %h1 * %h2) %M7%!",
3528 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %h1 * %h2) %M7%!",
3529 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %d1 * %h2) %M7%!",
3530 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %d1 * %h2) %M7%!",
3531 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %h1 * %d2) %M7%!",
3532 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %h1 * %d2) %M7%!",
3533 "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %d1 * %d2) %M7%!",
3534 "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %d1 * %d2) %M7%!",
3535 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %h1 * %d2) %M7%!",
3536 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %h1 * %d2) %M7%!",
3537 "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %d1 * %d2) %M7%!",
3538 "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %d1 * %d2) %M7%!" };
3539 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3540 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3541 return templates[alt];
3542 }
3543 [(set_attr "type" "dsp32")])
3544
3545 (define_insn "flag_macinit1v2hi_parts"
3546 [(set (match_operand:V2PDI 0 "register_operand" "=e")
3547 (unspec:V2PDI [(vec_concat:V2HI
3548 (vec_select:HI
3549 (match_operand:V2HI 1 "register_operand" "d")
3550 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
3551 (vec_select:HI
3552 (match_dup 1)
3553 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
3554 (vec_concat:V2HI
3555 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3556 (parallel [(match_operand 5 "const01_operand" "P0P1")]))
3557 (vec_select:HI (match_dup 2)
3558 (parallel [(match_operand 6 "const01_operand" "P0P1")])))
3559 (match_operand 7 "const_int_operand" "n")]
3560 UNSPEC_MAC_WITH_FLAG))]
3561 ""
3562 {
3563 const char *templates[] = {
3564 "A0 = %h1 * %h2, A1 = %h1 * %h2 %M7%!",
3565 "A0 = %d1 * %h2, A1 = %h1 * %h2 %M7%!",
3566 "A0 = %h1 * %h2, A1 = %d1 * %h2 %M7%!",
3567 "A0 = %d1 * %h2, A1 = %d1 * %h2 %M7%!",
3568 "A0 = %h1 * %d2, A1 = %h1 * %h2 %M7%!",
3569 "A0 = %d1 * %d2, A1 = %h1 * %h2 %M7%!",
3570 "A0 = %h1 * %d2, A1 = %d1 * %h2 %M7%!",
3571 "A0 = %d1 * %d2, A1 = %d1 * %h2 %M7%!",
3572 "A0 = %h1 * %h2, A1 = %h1 * %d2 %M7%!",
3573 "A0 = %d1 * %h2, A1 = %h1 * %d2 %M7%!",
3574 "A0 = %h1 * %h2, A1 = %d1 * %d2 %M7%!",
3575 "A0 = %d1 * %h2, A1 = %d1 * %d2 %M7%!",
3576 "A0 = %h1 * %d2, A1 = %h1 * %d2 %M7%!",
3577 "A0 = %d1 * %d2, A1 = %h1 * %d2 %M7%!",
3578 "A0 = %h1 * %d2, A1 = %d1 * %d2 %M7%!",
3579 "A0 = %d1 * %d2, A1 = %d1 * %d2 %M7%!" };
3580 int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3581 + (INTVAL (operands[5]) << 2) + (INTVAL (operands[6]) << 3));
3582 return templates[alt];
3583 }
3584 [(set_attr "type" "dsp32")])
3585
3586 ;; A mixture of multiply and multiply-accumulate for when we only want to
3587 ;; initialize one part.
3588 (define_insn "flag_mul_macv2hi_parts_acconly"
3589 [(set (match_operand:PDI 0 "register_operand" "=B,e,e")
3590 (unspec:PDI [(vec_select:HI
3591 (match_operand:V2HI 2 "register_operand" "d,d,d")
3592 (parallel [(match_operand 4 "const01_operand" "P0P1,P0P1,P0P1")]))
3593 (vec_select:HI
3594 (match_operand:V2HI 3 "register_operand" "d,d,d")
3595 (parallel [(match_operand 6 "const01_operand" "P0P1,P0P1,P0P1")]))
3596 (match_operand 10 "const_int_operand" "PB,PA,PA")]
3597 UNSPEC_MUL_WITH_FLAG))
3598 (set (match_operand:PDI 1 "register_operand" "=B,e,e")
3599 (unspec:PDI [(vec_select:HI
3600 (match_dup 2)
3601 (parallel [(match_operand 5 "const01_operand" "P0P1,P0P1,P0P1")]))
3602 (vec_select:HI
3603 (match_dup 3)
3604 (parallel [(match_operand 7 "const01_operand" "P0P1,P0P1,P0P1")]))
3605 (match_operand:PDI 8 "register_operand" "1,1,1")
3606 (match_operand 9 "const01_operand" "P0P1,P0P1,P0P1")
3607 (match_operand 11 "const_int_operand" "PA,PB,PA")]
3608 UNSPEC_MAC_WITH_FLAG))]
3609 "MACFLAGS_MATCH_P (INTVAL (operands[10]), INTVAL (operands[11]))"
3610 {
3611 rtx xops[6];
3612 const char *templates[] = {
3613 "%0 = %h2 * %h3, %1 %b4 %h2 * %h3 %M5%!",
3614 "%0 = %d2 * %h3, %1 %b4 %h2 * %h3 %M5%!",
3615 "%0 = %h2 * %h3, %1 %b4 %d2 * %h3 %M5%!",
3616 "%0 = %d2 * %h3, %1 %b4 %d2 * %h3 %M5%!",
3617 "%0 = %h2 * %d3, %1 %b4 %h2 * %h3 %M5%!",
3618 "%0 = %d2 * %d3, %1 %b4 %h2 * %h3 %M5%!",
3619 "%0 = %h2 * %d3, %1 %b4 %d2 * %h3 %M5%!",
3620 "%0 = %d2 * %d3, %1 %b4 %d2 * %h3 %M5%!",
3621 "%0 = %h2 * %h3, %1 %b4 %h2 * %d3 %M5%!",
3622 "%0 = %d2 * %h3, %1 %b4 %h2 * %d3 %M5%!",
3623 "%0 = %h2 * %h3, %1 %b4 %d2 * %d3 %M5%!",
3624 "%0 = %d2 * %h3, %1 %b4 %d2 * %d3 %M5%!",
3625 "%0 = %h2 * %d3, %1 %b4 %h2 * %d3 %M5%!",
3626 "%0 = %d2 * %d3, %1 %b4 %h2 * %d3 %M5%!",
3627 "%0 = %h2 * %d3, %1 %b4 %d2 * %d3 %M5%!",
3628 "%0 = %d2 * %d3, %1 %b4 %d2 * %d3 %M5%!" };
3629 int alt = (INTVAL (operands[4]) + (INTVAL (operands[5]) << 1)
3630 + (INTVAL (operands[6]) << 2) + (INTVAL (operands[7]) << 3));
3631 xops[0] = operands[0];
3632 xops[1] = operands[1];
3633 xops[2] = operands[2];
3634 xops[3] = operands[3];
3635 xops[4] = operands[9];
3636 xops[5] = which_alternative == 0 ? operands[10] : operands[11];
3637 output_asm_insn (templates[alt], xops);
3638 return "";
3639 }
3640 [(set_attr "type" "dsp32")])
3641
3642
3643 (define_code_iterator s_or_u [sign_extend zero_extend])
3644 (define_code_attr su_optab [(sign_extend "mul")
3645 (zero_extend "umul")])
3646 (define_code_attr su_modifier [(sign_extend "IS")
3647 (zero_extend "FU")])
3648
3649 (define_insn "<su_optab>hisi_ll"
3650 [(set (match_operand:SI 0 "register_operand" "=d")
3651 (mult:SI (s_or_u:SI
3652 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3653 (parallel [(const_int 0)])))
3654 (s_or_u:SI
3655 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3656 (parallel [(const_int 0)])))))]
3657 ""
3658 "%0 = %h1 * %h2 (<su_modifier>)%!"
3659 [(set_attr "type" "dsp32")])
3660
3661 (define_insn "<su_optab>hisi_lh"
3662 [(set (match_operand:SI 0 "register_operand" "=d")
3663 (mult:SI (s_or_u:SI
3664 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3665 (parallel [(const_int 0)])))
3666 (s_or_u:SI
3667 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3668 (parallel [(const_int 1)])))))]
3669 ""
3670 "%0 = %h1 * %d2 (<su_modifier>)%!"
3671 [(set_attr "type" "dsp32")])
3672
3673 (define_insn "<su_optab>hisi_hl"
3674 [(set (match_operand:SI 0 "register_operand" "=d")
3675 (mult:SI (s_or_u:SI
3676 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3677 (parallel [(const_int 1)])))
3678 (s_or_u:SI
3679 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3680 (parallel [(const_int 0)])))))]
3681 ""
3682 "%0 = %d1 * %h2 (<su_modifier>)%!"
3683 [(set_attr "type" "dsp32")])
3684
3685 (define_insn "<su_optab>hisi_hh"
3686 [(set (match_operand:SI 0 "register_operand" "=d")
3687 (mult:SI (s_or_u:SI
3688 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3689 (parallel [(const_int 1)])))
3690 (s_or_u:SI
3691 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3692 (parallel [(const_int 1)])))))]
3693 ""
3694 "%0 = %d1 * %d2 (<su_modifier>)%!"
3695 [(set_attr "type" "dsp32")])
3696
3697 ;; Additional variants for signed * unsigned multiply.
3698
3699 (define_insn "usmulhisi_ull"
3700 [(set (match_operand:SI 0 "register_operand" "=W")
3701 (mult:SI (zero_extend:SI
3702 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3703 (parallel [(const_int 0)])))
3704 (sign_extend:SI
3705 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3706 (parallel [(const_int 0)])))))]
3707 ""
3708 "%0 = %h2 * %h1 (IS,M)%!"
3709 [(set_attr "type" "dsp32")])
3710
3711 (define_insn "usmulhisi_ulh"
3712 [(set (match_operand:SI 0 "register_operand" "=W")
3713 (mult:SI (zero_extend:SI
3714 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3715 (parallel [(const_int 0)])))
3716 (sign_extend:SI
3717 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3718 (parallel [(const_int 1)])))))]
3719 ""
3720 "%0 = %d2 * %h1 (IS,M)%!"
3721 [(set_attr "type" "dsp32")])
3722
3723 (define_insn "usmulhisi_uhl"
3724 [(set (match_operand:SI 0 "register_operand" "=W")
3725 (mult:SI (zero_extend:SI
3726 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3727 (parallel [(const_int 1)])))
3728 (sign_extend:SI
3729 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3730 (parallel [(const_int 0)])))))]
3731 ""
3732 "%0 = %h2 * %d1 (IS,M)%!"
3733 [(set_attr "type" "dsp32")])
3734
3735 (define_insn "usmulhisi_uhh"
3736 [(set (match_operand:SI 0 "register_operand" "=W")
3737 (mult:SI (zero_extend:SI
3738 (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3739 (parallel [(const_int 1)])))
3740 (sign_extend:SI
3741 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3742 (parallel [(const_int 1)])))))]
3743 ""
3744 "%0 = %d2 * %d1 (IS,M)%!"
3745 [(set_attr "type" "dsp32")])
3746
3747 ;; Parallel versions of these operations. First, normal signed or unsigned
3748 ;; multiplies.
3749
3750 (define_insn "<su_optab>hisi_ll_lh"
3751 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3752 (mult:SI (s_or_u:SI
3753 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3754 (parallel [(const_int 0)])))
3755 (s_or_u:SI
3756 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3757 (parallel [(const_int 0)])))))
3758 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3759 (mult:SI (s_or_u:SI
3760 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3761 (s_or_u:SI
3762 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3763 ""
3764 "%0 = %h1 * %h2, %3 = %h1 * %d2 (<su_modifier>)%!"
3765 [(set_attr "type" "dsp32")])
3766
3767 (define_insn "<su_optab>hisi_ll_hl"
3768 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3769 (mult:SI (s_or_u:SI
3770 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3771 (parallel [(const_int 0)])))
3772 (s_or_u:SI
3773 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3774 (parallel [(const_int 0)])))))
3775 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3776 (mult:SI (s_or_u:SI
3777 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3778 (s_or_u:SI
3779 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3780 ""
3781 "%0 = %h1 * %h2, %3 = %d1 * %h2 (<su_modifier>)%!"
3782 [(set_attr "type" "dsp32")])
3783
3784 (define_insn "<su_optab>hisi_ll_hh"
3785 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3786 (mult:SI (s_or_u:SI
3787 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3788 (parallel [(const_int 0)])))
3789 (s_or_u:SI
3790 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3791 (parallel [(const_int 0)])))))
3792 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3793 (mult:SI (s_or_u:SI
3794 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3795 (s_or_u:SI
3796 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3797 ""
3798 "%0 = %h1 * %h2, %3 = %d1 * %d2 (<su_modifier>)%!"
3799 [(set_attr "type" "dsp32")])
3800
3801 (define_insn "<su_optab>hisi_lh_hl"
3802 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3803 (mult:SI (s_or_u:SI
3804 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3805 (parallel [(const_int 0)])))
3806 (s_or_u:SI
3807 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3808 (parallel [(const_int 1)])))))
3809 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3810 (mult:SI (s_or_u:SI
3811 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3812 (s_or_u:SI
3813 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3814 ""
3815 "%0 = %h1 * %d2, %3 = %d1 * %h2 (<su_modifier>)%!"
3816 [(set_attr "type" "dsp32")])
3817
3818 (define_insn "<su_optab>hisi_lh_hh"
3819 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3820 (mult:SI (s_or_u:SI
3821 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3822 (parallel [(const_int 0)])))
3823 (s_or_u:SI
3824 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3825 (parallel [(const_int 1)])))))
3826 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3827 (mult:SI (s_or_u:SI
3828 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3829 (s_or_u:SI
3830 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3831 ""
3832 "%0 = %h1 * %d2, %3 = %d1 * %d2 (<su_modifier>)%!"
3833 [(set_attr "type" "dsp32")])
3834
3835 (define_insn "<su_optab>hisi_hl_hh"
3836 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3837 (mult:SI (s_or_u:SI
3838 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3839 (parallel [(const_int 1)])))
3840 (s_or_u:SI
3841 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3842 (parallel [(const_int 0)])))))
3843 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3844 (mult:SI (s_or_u:SI
3845 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3846 (s_or_u:SI
3847 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3848 ""
3849 "%0 = %d1 * %h2, %3 = %d1 * %d2 (<su_modifier>)%!"
3850 [(set_attr "type" "dsp32")])
3851
3852 ;; Special signed * unsigned variants.
3853
3854 (define_insn "usmulhisi_ll_lul"
3855 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3856 (mult:SI (sign_extend:SI
3857 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3858 (parallel [(const_int 0)])))
3859 (sign_extend:SI
3860 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3861 (parallel [(const_int 0)])))))
3862 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3863 (mult:SI (sign_extend:SI
3864 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3865 (zero_extend:SI
3866 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3867 ""
3868 "%0 = %h1 * %h2, %3 = %h1 * %h2 (IS,M)%!"
3869 [(set_attr "type" "dsp32")])
3870
3871 (define_insn "usmulhisi_ll_luh"
3872 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3873 (mult:SI (sign_extend:SI
3874 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3875 (parallel [(const_int 0)])))
3876 (sign_extend:SI
3877 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3878 (parallel [(const_int 0)])))))
3879 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3880 (mult:SI (sign_extend:SI
3881 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3882 (zero_extend:SI
3883 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3884 ""
3885 "%0 = %h1 * %h2, %3 = %h1 * %d2 (IS,M)%!"
3886 [(set_attr "type" "dsp32")])
3887
3888 (define_insn "usmulhisi_ll_hul"
3889 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3890 (mult:SI (sign_extend:SI
3891 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3892 (parallel [(const_int 0)])))
3893 (sign_extend:SI
3894 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3895 (parallel [(const_int 0)])))))
3896 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3897 (mult:SI (sign_extend:SI
3898 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3899 (zero_extend:SI
3900 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3901 ""
3902 "%0 = %h1 * %h2, %3 = %d1 * %h2 (IS,M)%!"
3903 [(set_attr "type" "dsp32")])
3904
3905 (define_insn "usmulhisi_ll_huh"
3906 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3907 (mult:SI (sign_extend:SI
3908 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3909 (parallel [(const_int 0)])))
3910 (sign_extend:SI
3911 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3912 (parallel [(const_int 0)])))))
3913 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3914 (mult:SI (sign_extend:SI
3915 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3916 (zero_extend:SI
3917 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3918 ""
3919 "%0 = %h1 * %h2, %3 = %d1 * %d2 (IS,M)%!"
3920 [(set_attr "type" "dsp32")])
3921
3922 (define_insn "usmulhisi_lh_lul"
3923 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3924 (mult:SI (sign_extend:SI
3925 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3926 (parallel [(const_int 0)])))
3927 (sign_extend:SI
3928 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3929 (parallel [(const_int 1)])))))
3930 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3931 (mult:SI (sign_extend:SI
3932 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3933 (zero_extend:SI
3934 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3935 ""
3936 "%0 = %h1 * %d2, %3 = %h1 * %h2 (IS,M)%!"
3937 [(set_attr "type" "dsp32")])
3938
3939 (define_insn "usmulhisi_lh_luh"
3940 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3941 (mult:SI (sign_extend:SI
3942 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3943 (parallel [(const_int 0)])))
3944 (sign_extend:SI
3945 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3946 (parallel [(const_int 1)])))))
3947 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3948 (mult:SI (sign_extend:SI
3949 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3950 (zero_extend:SI
3951 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3952 ""
3953 "%0 = %h1 * %d2, %3 = %h1 * %d2 (IS,M)%!"
3954 [(set_attr "type" "dsp32")])
3955
3956 (define_insn "usmulhisi_lh_hul"
3957 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3958 (mult:SI (sign_extend:SI
3959 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3960 (parallel [(const_int 0)])))
3961 (sign_extend:SI
3962 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3963 (parallel [(const_int 1)])))))
3964 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3965 (mult:SI (sign_extend:SI
3966 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3967 (zero_extend:SI
3968 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3969 ""
3970 "%0 = %h1 * %d2, %3 = %d1 * %h2 (IS,M)%!"
3971 [(set_attr "type" "dsp32")])
3972
3973 (define_insn "usmulhisi_lh_huh"
3974 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3975 (mult:SI (sign_extend:SI
3976 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3977 (parallel [(const_int 0)])))
3978 (sign_extend:SI
3979 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3980 (parallel [(const_int 1)])))))
3981 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3982 (mult:SI (sign_extend:SI
3983 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3984 (zero_extend:SI
3985 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3986 ""
3987 "%0 = %h1 * %d2, %3 = %d1 * %d2 (IS,M)%!"
3988 [(set_attr "type" "dsp32")])
3989
3990 (define_insn "usmulhisi_hl_lul"
3991 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3992 (mult:SI (sign_extend:SI
3993 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3994 (parallel [(const_int 1)])))
3995 (sign_extend:SI
3996 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3997 (parallel [(const_int 0)])))))
3998 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3999 (mult:SI (sign_extend:SI
4000 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
4001 (zero_extend:SI
4002 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
4003 ""
4004 "%0 = %d1 * %h2, %3 = %h1 * %h2 (IS,M)%!"
4005 [(set_attr "type" "dsp32")])
4006
4007 (define_insn "usmulhisi_hl_luh"
4008 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4009 (mult:SI (sign_extend:SI
4010 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4011 (parallel [(const_int 1)])))
4012 (sign_extend:SI
4013 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4014 (parallel [(const_int 0)])))))
4015 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4016 (mult:SI (sign_extend:SI
4017 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
4018 (zero_extend:SI
4019 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
4020 ""
4021 "%0 = %d1 * %h2, %3 = %h1 * %d2 (IS,M)%!"
4022 [(set_attr "type" "dsp32")])
4023
4024 (define_insn "usmulhisi_hl_hul"
4025 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4026 (mult:SI (sign_extend:SI
4027 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4028 (parallel [(const_int 1)])))
4029 (sign_extend:SI
4030 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4031 (parallel [(const_int 0)])))))
4032 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4033 (mult:SI (sign_extend:SI
4034 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4035 (zero_extend:SI
4036 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
4037 ""
4038 "%0 = %d1 * %h2, %3 = %d1 * %h2 (IS,M)%!"
4039 [(set_attr "type" "dsp32")])
4040
4041 (define_insn "usmulhisi_hl_huh"
4042 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4043 (mult:SI (sign_extend:SI
4044 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4045 (parallel [(const_int 1)])))
4046 (sign_extend:SI
4047 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4048 (parallel [(const_int 0)])))))
4049 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4050 (mult:SI (sign_extend:SI
4051 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4052 (zero_extend:SI
4053 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
4054 ""
4055 "%0 = %d1 * %h2, %3 = %d1 * %d2 (IS,M)%!"
4056 [(set_attr "type" "dsp32")])
4057
4058 (define_insn "usmulhisi_hh_lul"
4059 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4060 (mult:SI (sign_extend:SI
4061 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4062 (parallel [(const_int 1)])))
4063 (sign_extend:SI
4064 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4065 (parallel [(const_int 1)])))))
4066 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4067 (mult:SI (sign_extend:SI
4068 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
4069 (zero_extend:SI
4070 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
4071 ""
4072 "%0 = %d1 * %d2, %3 = %h1 * %h2 (IS,M)%!"
4073 [(set_attr "type" "dsp32")])
4074
4075 (define_insn "usmulhisi_hh_luh"
4076 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4077 (mult:SI (sign_extend:SI
4078 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4079 (parallel [(const_int 1)])))
4080 (sign_extend:SI
4081 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4082 (parallel [(const_int 1)])))))
4083 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4084 (mult:SI (sign_extend:SI
4085 (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
4086 (zero_extend:SI
4087 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
4088 ""
4089 "%0 = %d1 * %d2, %3 = %h1 * %d2 (IS,M)%!"
4090 [(set_attr "type" "dsp32")])
4091
4092 (define_insn "usmulhisi_hh_hul"
4093 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4094 (mult:SI (sign_extend:SI
4095 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4096 (parallel [(const_int 1)])))
4097 (sign_extend:SI
4098 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4099 (parallel [(const_int 1)])))))
4100 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4101 (mult:SI (sign_extend:SI
4102 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4103 (zero_extend:SI
4104 (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
4105 ""
4106 "%0 = %d1 * %d2, %3 = %d1 * %h2 (IS,M)%!"
4107 [(set_attr "type" "dsp32")])
4108
4109 (define_insn "usmulhisi_hh_huh"
4110 [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4111 (mult:SI (sign_extend:SI
4112 (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4113 (parallel [(const_int 1)])))
4114 (sign_extend:SI
4115 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4116 (parallel [(const_int 1)])))))
4117 (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4118 (mult:SI (sign_extend:SI
4119 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4120 (zero_extend:SI
4121 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
4122 ""
4123 "%0 = %d1 * %d2, %3 = %d1 * %d2 (IS,M)%!"
4124 [(set_attr "type" "dsp32")])
4125
4126 ;; Vector neg/abs.
4127
4128 (define_insn "ssnegv2hi2"
4129 [(set (match_operand:V2HI 0 "register_operand" "=d")
4130 (ss_neg:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
4131 ""
4132 "%0 = - %1 (V)%!"
4133 [(set_attr "type" "dsp32")])
4134
4135 (define_insn "ssabsv2hi2"
4136 [(set (match_operand:V2HI 0 "register_operand" "=d")
4137 (ss_abs:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
4138 ""
4139 "%0 = ABS %1 (V)%!"
4140 [(set_attr "type" "dsp32")])
4141
4142 ;; Shifts.
4143
4144 (define_insn "ssashiftv2hi3"
4145 [(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
4146 (if_then_else:V2HI
4147 (lt (match_operand:HI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
4148 (ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" "d,d,d")
4149 (match_dup 2))
4150 (ss_ashift:V2HI (match_dup 1) (match_dup 2))))]
4151 ""
4152 "@
4153 %0 = ASHIFT %1 BY %h2 (V, S)%!
4154 %0 = %1 << %2 (V,S)%!
4155 %0 = %1 >>> %N2 (V,S)%!"
4156 [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
4157
4158 (define_insn "ssashifthi3"
4159 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
4160 (if_then_else:HI
4161 (lt (match_operand:HI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
4162 (ashiftrt:HI (match_operand:HI 1 "register_operand" "d,d,d")
4163 (match_dup 2))
4164 (ss_ashift:HI (match_dup 1) (match_dup 2))))]
4165 ""
4166 "@
4167 %0 = ASHIFT %1 BY %h2 (V, S)%!
4168 %0 = %1 << %2 (V,S)%!
4169 %0 = %1 >>> %N2 (V,S)%!"
4170 [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
4171
4172 (define_insn "ssashiftsi3"
4173 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
4174 (if_then_else:SI
4175 (lt (match_operand:HI 2 "reg_or_const_int_operand" "d,Ku5,Ks5") (const_int 0))
4176 (ashiftrt:SI (match_operand:HI 1 "register_operand" "d,d,d")
4177 (match_dup 2))
4178 (ss_ashift:SI (match_dup 1) (match_dup 2))))]
4179 ""
4180 "@
4181 %0 = ASHIFT %1 BY %h2 (S)%!
4182 %0 = %1 << %2 (S)%!
4183 %0 = %1 >>> %N2 (S)%!"
4184 [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
4185
4186 (define_insn "lshiftv2hi3"
4187 [(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
4188 (if_then_else:V2HI
4189 (lt (match_operand:HI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
4190 (lshiftrt:V2HI (match_operand:V2HI 1 "register_operand" "d,d,d")
4191 (match_dup 2))
4192 (ashift:V2HI (match_dup 1) (match_dup 2))))]
4193 ""
4194 "@
4195 %0 = LSHIFT %1 BY %h2 (V)%!
4196 %0 = %1 << %2 (V)%!
4197 %0 = %1 >> %N2 (V)%!"
4198 [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
4199
4200 (define_insn "lshifthi3"
4201 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
4202 (if_then_else:HI
4203 (lt (match_operand:HI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
4204 (lshiftrt:HI (match_operand:HI 1 "register_operand" "d,d,d")
4205 (match_dup 2))
4206 (ashift:HI (match_dup 1) (match_dup 2))))]
4207 ""
4208 "@
4209 %0 = LSHIFT %1 BY %h2 (V)%!
4210 %0 = %1 << %2 (V)%!
4211 %0 = %1 >> %N2 (V)%!"
4212 [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
4213
4214 ;; Load without alignment exception (masking off low bits)
4215
4216 (define_insn "loadbytes"
4217 [(set (match_operand:SI 0 "register_operand" "=d")
4218 (mem:SI (and:SI (match_operand:SI 1 "register_operand" "b")
4219 (const_int -4))))]
4220 ""
4221 "DISALGNEXCPT || %0 = [%1];"
4222 [(set_attr "type" "mcld")
4223 (set_attr "length" "8")])
4224
4225 (include "sync.md")