OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [sh/] [sh.md] - Blame information for rev 849

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
;;- Machine description for Renesas / SuperH SH.
2
;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3
;;  2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4
;;  Free Software Foundation, Inc.
5
;;  Contributed by Steve Chamberlain (sac@cygnus.com).
6
;;  Improved by Jim Wilson (wilson@cygnus.com).
7
 
8
;; This file is part of GCC.
9
 
10
;; GCC is free software; you can redistribute it and/or modify
11
;; it under the terms of the GNU General Public License as published by
12
;; the Free Software Foundation; either version 3, or (at your option)
13
;; any later version.
14
 
15
;; GCC is distributed in the hope that it will be useful,
16
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
;; GNU General Public License for more details.
19
 
20
;; You should have received a copy of the GNU General Public License
21
;; along with GCC; see the file COPYING3.  If not see
22
;; .
23
 
24
 
25
;; ??? Should prepend a * to all pattern names which are not used.
26
;; This will make the compiler smaller, and rebuilds after changes faster.
27
 
28
;; ??? Should be enhanced to include support for many more GNU superoptimizer
29
;; sequences.  Especially the sequences for arithmetic right shifts.
30
 
31
;; ??? Should check all DImode patterns for consistency and usefulness.
32
 
33
;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34
;; way to generate them.
35
 
36
;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37
;; for a str* inline function.
38
 
39
;; BSR is not generated by the compiler proper, but when relaxing, it
40
;; generates .uses pseudo-ops that allow linker relaxation to create
41
;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
42
 
43
;; Special constraints for SH machine description:
44
;;
45
;;    t -- T
46
;;    x -- mac
47
;;    l -- pr
48
;;    z -- r0
49
;;
50
;; Special formats used for outputting SH instructions:
51
;;
52
;;   %.  --  print a .s if insn needs delay slot
53
;;   %@  --  print rte/rts if is/isn't an interrupt function
54
;;   %#  --  output a nop if there is nothing to put in the delay slot
55
;;   %O  --  print a constant without the #
56
;;   %R  --  print the lsw reg of a double
57
;;   %S  --  print the msw reg of a double
58
;;   %T  --  print next word of a double REG or MEM
59
;;
60
;; Special predicates:
61
;;
62
;;  arith_operand          -- operand is valid source for arithmetic op
63
;;  arith_reg_operand      -- operand is valid register for arithmetic op
64
;;  general_movdst_operand -- operand is valid move destination
65
;;  general_movsrc_operand -- operand is valid move source
66
;;  logical_operand        -- operand is valid source for logical op
67
 
68
;; -------------------------------------------------------------------------
69
;; Constants
70
;; -------------------------------------------------------------------------
71
 
72
(define_constants [
73
  (AP_REG       145)
74
  (PR_REG       146)
75
  (T_REG        147)
76
  (GBR_REG      144)
77
  (MACH_REG     148)
78
  (MACL_REG     149)
79
  (FPUL_REG     150)
80
  (RAP_REG      152)
81
 
82
  (FPSCR_REG    151)
83
 
84
  (PIC_REG      12)
85
  (FP_REG       14)
86
  (SP_REG       15)
87
 
88
  (PR_MEDIA_REG 18)
89
  (T_MEDIA_REG  19)
90
 
91
  (R0_REG       0)
92
  (R1_REG       1)
93
  (R2_REG       2)
94
  (R3_REG       3)
95
  (R4_REG       4)
96
  (R5_REG       5)
97
  (R6_REG       6)
98
  (R7_REG       7)
99
  (R8_REG       8)
100
  (R9_REG       9)
101
  (R10_REG      10)
102
  (R20_REG      20)
103
  (R21_REG      21)
104
  (R22_REG      22)
105
  (R23_REG      23)
106
 
107
  (DR0_REG      64)
108
  (DR2_REG      66)
109
  (DR4_REG      68)
110
  (FR23_REG     87)
111
 
112
  (TR0_REG      128)
113
  (TR1_REG      129)
114
  (TR2_REG      130)
115
 
116
  (XD0_REG      136)
117
 
118
  ;; These are used with unspec.
119
  (UNSPEC_COMPACT_ARGS  0)
120
  (UNSPEC_MOVA          1)
121
  (UNSPEC_CASESI        2)
122
  (UNSPEC_DATALABEL     3)
123
  (UNSPEC_BBR           4)
124
  (UNSPEC_SFUNC         5)
125
  (UNSPEC_PIC           6)
126
  (UNSPEC_GOT           7)
127
  (UNSPEC_GOTOFF        8)
128
  (UNSPEC_PLT           9)
129
  (UNSPEC_CALLER        10)
130
  (UNSPEC_GOTPLT        11)
131
  (UNSPEC_ICACHE        12)
132
  (UNSPEC_INIT_TRAMP    13)
133
  (UNSPEC_FCOSA         14)
134
  (UNSPEC_FSRRA         15)
135
  (UNSPEC_FSINA         16)
136
  (UNSPEC_NSB           17)
137
  (UNSPEC_ALLOCO        18)
138
  (UNSPEC_TLSGD         20)
139
  (UNSPEC_TLSLDM        21)
140
  (UNSPEC_TLSIE         22)
141
  (UNSPEC_DTPOFF        23)
142
  (UNSPEC_GOTTPOFF      24)
143
  (UNSPEC_TPOFF         25)
144
  (UNSPEC_RA            26)
145
  (UNSPEC_DIV_INV_M0    30)
146
  (UNSPEC_DIV_INV_M1    31)
147
  (UNSPEC_DIV_INV_M2    32)
148
  (UNSPEC_DIV_INV_M3    33)
149
  (UNSPEC_DIV_INV20     34)
150
  (UNSPEC_DIV_INV_TABLE 37)
151
  (UNSPEC_ASHIFTRT      35)
152
  (UNSPEC_THUNK         36)
153
  (UNSPEC_CHKADD        38)
154
  (UNSPEC_SP_SET        40)
155
  (UNSPEC_SP_TEST       41)
156
  (UNSPEC_MOVUA         42)
157
 
158
  ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
159
  ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
160
  (UNSPEC_EXTRACT_S16   43)
161
  (UNSPEC_EXTRACT_U16   44)
162
 
163
  ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
164
  (UNSPEC_SYMOFF        45)
165
 
166
  ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
167
  (UNSPEC_PCREL_SYMOFF  46)
168
 
169
  ;; These are used with unspec_volatile.
170
  (UNSPECV_BLOCKAGE     0)
171
  (UNSPECV_ALIGN        1)
172
  (UNSPECV_CONST2       2)
173
  (UNSPECV_CONST4       4)
174
  (UNSPECV_CONST8       6)
175
  (UNSPECV_WINDOW_END   10)
176
  (UNSPECV_CONST_END    11)
177
  (UNSPECV_EH_RETURN    12)
178
])
179
 
180
;; -------------------------------------------------------------------------
181
;; Attributes
182
;; -------------------------------------------------------------------------
183
 
184
;; Target CPU.
185
 
186
(define_attr "cpu"
187
 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
188
  (const (symbol_ref "sh_cpu_attr")))
189
 
190
(define_attr "endian" "big,little"
191
 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
192
                      (const_string "little") (const_string "big"))))
193
 
194
;; Indicate if the default fpu mode is single precision.
195
(define_attr "fpu_single" "yes,no"
196
  (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
197
                         (const_string "yes") (const_string "no"))))
198
 
199
(define_attr "fmovd" "yes,no"
200
  (const (if_then_else (symbol_ref "TARGET_FMOVD")
201
                       (const_string "yes") (const_string "no"))))
202
;; pipeline model
203
(define_attr "pipe_model" "sh1,sh4,sh5media"
204
  (const
205
   (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
206
          (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
207
         (const_string "sh1"))))
208
 
209
;; cbranch      conditional branch instructions
210
;; jump         unconditional jumps
211
;; arith        ordinary arithmetic
212
;; arith3       a compound insn that behaves similarly to a sequence of
213
;;              three insns of type arith
214
;; arith3b      like above, but might end with a redirected branch
215
;; load         from memory
216
;; load_si      Likewise, SImode variant for general register.
217
;; fload        Likewise, but load to fp register.
218
;; store        to memory
219
;; fstore       floating point register to memory
220
;; move         general purpose register to register
221
;; movi8        8-bit immediate to general purpose register
222
;; mt_group     other sh4 mt instructions
223
;; fmove        register to register, floating point
224
;; smpy         word precision integer multiply
225
;; dmpy         longword or doublelongword precision integer multiply
226
;; return       rts
227
;; pload        load of pr reg, which can't be put into delay slot of rts
228
;; prset        copy register to pr reg, ditto
229
;; pstore       store of pr reg, which can't be put into delay slot of jsr
230
;; prget        copy pr to register, ditto
231
;; pcload       pc relative load of constant value
232
;; pcfload      Likewise, but load to fp register.
233
;; pcload_si    Likewise, SImode variant for general register.
234
;; rte          return from exception
235
;; sfunc        special function call with known used registers
236
;; call         function call
237
;; fp           floating point
238
;; fpscr_toggle toggle a bit in the fpscr
239
;; fdiv         floating point divide (or square root)
240
;; gp_fpul      move from general purpose register to fpul
241
;; fpul_gp      move from fpul to general purpose register
242
;; mac_gp       move from mac[lh] to general purpose register
243
;; gp_mac       move from general purpose register to mac[lh]
244
;; mac_mem      move from mac[lh] to memory
245
;; mem_mac      move from memory to mac[lh]
246
;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
247
;; ftrc_s       fix_truncsfsi2_i4
248
;; dfdiv        double precision floating point divide (or square root)
249
;; cwb          ic_invalidate_line_i
250
;; movua        SH4a unaligned load
251
;; fsrra        square root reciprocal approximate
252
;; fsca         sine and cosine approximate
253
;; tls_load     load TLS related address
254
;; arith_media  SHmedia arithmetic, logical, and shift instructions
255
;; cbranch_media SHmedia conditional branch instructions
256
;; cmp_media    SHmedia compare instructions
257
;; dfdiv_media  SHmedia double precision divide and square root
258
;; dfmul_media  SHmedia double precision multiply instruction
259
;; dfparith_media SHmedia double precision floating point arithmetic
260
;; dfpconv_media SHmedia double precision floating point conversions
261
;; dmpy_media   SHmedia longword multiply
262
;; fcmp_media   SHmedia floating point compare instructions
263
;; fdiv_media   SHmedia single precision divide and square root
264
;; fload_media  SHmedia floating point register load instructions
265
;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
266
;; fparith_media SHmedia single precision floating point arithmetic
267
;; fpconv_media SHmedia single precision floating point conversions
268
;; fstore_media SHmedia floating point register store instructions
269
;; gettr_media  SHmedia gettr instruction
270
;; invalidate_line_media SHmedia invalidate_line sequence
271
;; jump_media   SHmedia unconditional branch instructions
272
;; load_media   SHmedia general register load instructions
273
;; pt_media     SHmedia pt instruction (expanded by assembler)
274
;; ptabs_media  SHmedia ptabs instruction
275
;; store_media  SHmedia general register store instructions
276
;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
277
;; mac_media    SHmedia mac-style fixed point operations
278
;; d2mpy_media  SHmedia: two 32-bit integer multiplies
279
;; atrans_media SHmedia approximate transcendental functions
280
;; ustore_media SHmedia unaligned stores
281
;; nil          no-op move, will be deleted.
282
 
283
(define_attr "type"
284
 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
285
  (const_string "other"))
286
 
287
;; We define a new attribute namely "insn_class".We use
288
;; this for the DFA based pipeline description.
289
;;
290
;; mt_group      SH4 "mt" group instructions.
291
;;
292
;; ex_group      SH4 "ex" group instructions.
293
;;
294
;; ls_group      SH4 "ls" group instructions.
295
;;
296
 
297
(define_attr "insn_class"
298
  "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
299
  (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
300
         (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
301
         (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
302
         (eq_attr "type" "cbranch,jump") (const_string "br_group")
303
         (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
304
           (const_string "fe_group")
305
         (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
306
        (const_string "none")))
307
;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
308
;; so these do not belong in an insn group, although they are modeled
309
;; with their own define_insn_reservations.
310
 
311
;; Indicate what precision must be selected in fpscr for this insn, if any.
312
 
313
(define_attr "fp_mode" "single,double,none" (const_string "none"))
314
 
315
;; Indicate if the fpu mode is set by this instruction
316
;; "unknown" must have the value as "none" in fp_mode, and means
317
;; that the instruction/abi has left the processor in an unknown
318
;; state.
319
;; "none" means that nothing has changed and no mode is set.
320
;; This attribute is only used for the Renesas ABI.
321
(define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
322
 
323
; If a conditional branch destination is within -252..258 bytes away
324
; from the instruction it can be 2 bytes long.  Something in the
325
; range -4090..4100 bytes can be 6 bytes long.  All other conditional
326
; branches are initially assumed to be 16 bytes long.
327
; In machine_dependent_reorg, we split all branches that are longer than
328
; 2 bytes.
329
 
330
;; The maximum range used for SImode constant pool entries is 1018.  A final
331
;; instruction can add 8 bytes while only being 4 bytes in size, thus we
332
;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
333
;; instruction around the pool table, 2 bytes of alignment before the table,
334
;; and 30 bytes of alignment after the table.  That gives a maximum total
335
;; pool size of 1058 bytes.
336
;; Worst case code/pool content size ratio is 1:2 (using asms).
337
;; Thus, in the worst case, there is one instruction in front of a maximum
338
;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
339
;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
340
;; If we have a forward branch, the initial table will be put after the
341
;; unconditional branch.
342
;;
343
;; ??? We could do much better by keeping track of the actual pcloads within
344
;; the branch range and in the pcload range in front of the branch range.
345
 
346
;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
347
;; inside an le.
348
(define_attr "short_cbranch_p" "no,yes"
349
  (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
350
         (const_string "no")
351
         (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
352
         (const_string "yes")
353
         (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
354
         (const_string "no")
355
         (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
356
         (const_string "yes")
357
         ] (const_string "no")))
358
 
359
(define_attr "med_branch_p" "no,yes"
360
  (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
361
              (const_int 1988))
362
         (const_string "yes")
363
         (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
364
         (const_string "no")
365
         (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
366
              (const_int 8186))
367
         (const_string "yes")
368
         ] (const_string "no")))
369
 
370
(define_attr "med_cbranch_p" "no,yes"
371
  (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
372
              (const_int 1986))
373
         (const_string "yes")
374
         (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
375
         (const_string "no")
376
         (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
377
               (const_int 8184))
378
         (const_string "yes")
379
         ] (const_string "no")))
380
 
381
(define_attr "braf_branch_p" "no,yes"
382
  (cond [(match_test "! TARGET_SH2")
383
         (const_string "no")
384
         (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
385
              (const_int 20660))
386
         (const_string "yes")
387
         (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
388
         (const_string "no")
389
         (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
390
              (const_int 65530))
391
         (const_string "yes")
392
         ] (const_string "no")))
393
 
394
(define_attr "braf_cbranch_p" "no,yes"
395
  (cond [(match_test "! TARGET_SH2")
396
         (const_string "no")
397
         (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
398
              (const_int 20658))
399
         (const_string "yes")
400
         (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
401
         (const_string "no")
402
         (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
403
              (const_int 65528))
404
         (const_string "yes")
405
         ] (const_string "no")))
406
 
407
; An unconditional jump in the range -4092..4098 can be 2 bytes long.
408
; For wider ranges, we need a combination of a code and a data part.
409
; If we can get a scratch register for a long range jump, the code
410
; part can be 4 bytes long; otherwise, it must be 8 bytes long.
411
; If the jump is in the range -32764..32770, the data part can be 2 bytes
412
; long; otherwise, it must be 6 bytes long.
413
 
414
; All other instructions are two bytes long by default.
415
 
416
;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
417
;; but getattrtab doesn't understand this.
418
(define_attr "length" ""
419
  (cond [(eq_attr "type" "cbranch")
420
         (cond [(eq_attr "short_cbranch_p" "yes")
421
                (const_int 2)
422
                (eq_attr "med_cbranch_p" "yes")
423
                (const_int 6)
424
                (eq_attr "braf_cbranch_p" "yes")
425
                (const_int 12)
426
;; ??? using pc is not computed transitively.
427
                (ne (match_dup 0) (match_dup 0))
428
                (const_int 14)
429
                (match_test "flag_pic")
430
                (const_int 24)
431
                ] (const_int 16))
432
         (eq_attr "type" "jump")
433
         (cond [(eq_attr "med_branch_p" "yes")
434
                (const_int 2)
435
                (and (match_test "prev_nonnote_insn (insn)")
436
                     (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")                              (symbol_ref "INSN"))
437
                          (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")                             (symbol_ref "code_for_indirect_jump_scratch"))))
438
                (cond [(eq_attr "braf_branch_p" "yes")
439
                       (const_int 6)
440
                       (not (match_test "flag_pic"))
441
                       (const_int 10)
442
                       (match_test "TARGET_SH2")
443
                       (const_int 10)] (const_int 18))
444
                (eq_attr "braf_branch_p" "yes")
445
                (const_int 10)
446
;; ??? using pc is not computed transitively.
447
                (ne (match_dup 0) (match_dup 0))
448
                (const_int 12)
449
                (match_test "flag_pic")
450
                (const_int 22)
451
                ] (const_int 14))
452
         (eq_attr "type" "pt_media")
453
         (if_then_else (match_test "TARGET_SHMEDIA64")
454
                       (const_int 20) (const_int 12))
455
         (and (eq_attr "type" "jump_media")
456
              (match_test "TARGET_SH5_CUT2_WORKAROUND"))
457
         (const_int 8)
458
         ] (if_then_else (match_test "TARGET_SHMEDIA")
459
                         (const_int 4)
460
                         (const_int 2))))
461
 
462
;; DFA descriptions for the pipelines
463
 
464
(include "sh1.md")
465
(include "shmedia.md")
466
(include "sh4.md")
467
 
468
(include "predicates.md")
469
(include "constraints.md")
470
 
471
;; Definitions for filling delay slots
472
 
473
(define_attr "needs_delay_slot" "yes,no" (const_string "no"))
474
 
475
(define_attr "banked" "yes,no"
476
        (cond [(match_test "sh_loads_bankedreg_p (insn)")
477
               (const_string "yes")]
478
              (const_string "no")))
479
 
480
;; ??? This should be (nil) instead of (const_int 0)
481
(define_attr "hit_stack" "yes,no"
482
        (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
483
               (const_string "no")]
484
              (const_string "yes")))
485
 
486
(define_attr "interrupt_function" "no,yes"
487
  (const (symbol_ref "current_function_interrupt")))
488
 
489
(define_attr "in_delay_slot" "yes,no"
490
  (cond [(eq_attr "type" "cbranch") (const_string "no")
491
         (eq_attr "type" "pcload,pcload_si") (const_string "no")
492
         (eq_attr "needs_delay_slot" "yes") (const_string "no")
493
         (eq_attr "length" "2") (const_string "yes")
494
         ] (const_string "no")))
495
 
496
(define_attr "cond_delay_slot" "yes,no"
497
  (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
498
         ] (const_string "no")))
499
 
500
(define_attr "is_sfunc" ""
501
  (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
502
 
503
(define_attr "is_mac_media" ""
504
  (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
505
 
506
(define_attr "branch_zero" "yes,no"
507
  (cond [(eq_attr "type" "!cbranch") (const_string "no")
508
         (ne (symbol_ref "(next_active_insn (insn)\
509
                           == (prev_active_insn\
510
                               (XEXP (SET_SRC (PATTERN (insn)), 1))))\
511
                          && get_attr_length (next_active_insn (insn)) == 2")
512
             (const_int 0))
513
         (const_string "yes")]
514
        (const_string "no")))
515
 
516
;; SH4 Double-precision computation with double-precision result -
517
;; the two halves are ready at different times.
518
(define_attr "dfp_comp" "yes,no"
519
  (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
520
        (const_string "no")))
521
 
522
;; Insns for which the latency of a preceding fp insn is decreased by one.
523
(define_attr "late_fp_use" "yes,no" (const_string "no"))
524
;; And feeding insns for which this relevant.
525
(define_attr "any_fp_comp" "yes,no"
526
  (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
527
         (const_string "yes")]
528
        (const_string "no")))
529
 
530
(define_attr "any_int_load" "yes,no"
531
  (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
532
         (const_string "yes")]
533
        (const_string "no")))
534
 
535
(define_attr "highpart" "user, ignore, extend, depend, must_split"
536
  (const_string "user"))
537
 
538
(define_delay
539
  (eq_attr "needs_delay_slot" "yes")
540
  [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
541
 
542
;; On the SH and SH2, the rte instruction reads the return pc from the stack,
543
;; and thus we can't put a pop instruction in its delay slot.
544
;; ??? On the SH3, the rte instruction does not use the stack, so a pop
545
;; instruction can go in the delay slot.
546
 
547
;; Since a normal return (rts) implicitly uses the PR register,
548
;; we can't allow PR register loads in an rts delay slot.
549
 
550
(define_delay
551
  (eq_attr "type" "return")
552
  [(and (eq_attr "in_delay_slot" "yes")
553
        (ior (and (eq_attr "interrupt_function" "no")
554
                  (eq_attr "type" "!pload,prset"))
555
             (and (eq_attr "interrupt_function" "yes")
556
                  (ior
557
                   (not (match_test "TARGET_SH3"))
558
                   (eq_attr "hit_stack" "no")
559
                   (eq_attr "banked" "no"))))) (nil) (nil)])
560
 
561
;; Since a call implicitly uses the PR register, we can't allow
562
;; a PR register store in a jsr delay slot.
563
 
564
(define_delay
565
  (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
566
  [(and (eq_attr "in_delay_slot" "yes")
567
        (eq_attr "type" "!pstore,prget")) (nil) (nil)])
568
 
569
;; Say that we have annulled true branches, since this gives smaller and
570
;; faster code when branches are predicted as not taken.
571
 
572
;; ??? The non-annulled condition should really be "in_delay_slot",
573
;; but insns that can be filled in non-annulled get priority over insns
574
;; that can only be filled in anulled.
575
 
576
(define_delay
577
  (and (eq_attr "type" "cbranch")
578
       (match_test "TARGET_SH2"))
579
  ;; SH2e has a hardware bug that pretty much prohibits the use of
580
  ;; annuled delay slots.
581
  [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
582
                                          (not (eq_attr "cpu" "sh2e"))) (nil)])
583
 
584
;; -------------------------------------------------------------------------
585
;; SImode signed integer comparisons
586
;; -------------------------------------------------------------------------
587
 
588
;; Various patterns to generate the TST #imm, R0 instruction.
589
;; Although this adds some pressure on the R0 register, it can potentially
590
;; result in faster code, even if the operand has to be moved to R0 first.
591
;; This is because on SH4 TST #imm, R0 and MOV Rm, Rn are both MT group
592
;; instructions and thus will be executed in parallel.  On SH4A TST #imm, R0
593
;; is an EX group instruction but still can be executed in parallel with the
594
;; MT group MOV Rm, Rn instruction.
595
 
596
;; Usual TST #imm, R0 patterns for SI, HI and QI
597
;; This is usually used for bit patterns other than contiguous bits
598
;; and single bits.
599
 
600
(define_insn "tstsi_t"
601
  [(set (reg:SI T_REG)
602
        (eq:SI (and:SI (match_operand:SI 0 "logical_operand" "%z,r")
603
                       (match_operand:SI 1 "logical_operand" "K08,r"))
604
               (const_int 0)))]
605
  "TARGET_SH1"
606
  "tst  %1,%0"
607
  [(set_attr "type" "mt_group")])
608
 
609
(define_insn "tsthi_t"
610
  [(set (reg:SI T_REG)
611
        (eq:SI (subreg:SI (and:HI (match_operand:HI 0 "logical_operand" "%z")
612
                                  (match_operand 1 "const_int_operand")) 0)
613
               (const_int 0)))]
614
  "TARGET_SH1
615
   && CONST_OK_FOR_K08 (INTVAL (operands[1]))"
616
  "tst  %1,%0"
617
  [(set_attr "type" "mt_group")])
618
 
619
(define_insn "tstqi_t"
620
  [(set (reg:SI T_REG)
621
        (eq:SI (subreg:SI (and:QI (match_operand:QI 0 "logical_operand" "%z")
622
                                  (match_operand 1 "const_int_operand")) 0)
623
               (const_int 0)))]
624
  "TARGET_SH1
625
   && (CONST_OK_FOR_K08 (INTVAL (operands[1]))
626
       || CONST_OK_FOR_I08 (INTVAL (operands[1])))"
627
{
628
  operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
629
  return "tst   %1,%0";
630
}
631
  [(set_attr "type" "mt_group")])
632
 
633
;; Test low QI subreg against zero.
634
;; This avoids unecessary zero extension before the test.
635
 
636
(define_insn "tstqi_t_zero"
637
  [(set (reg:SI T_REG)
638
        (eq:SI (match_operand:QI 0 "logical_operand" "z") (const_int 0)))]
639
  "TARGET_SH1"
640
  "tst  #255,%0"
641
  [(set_attr "type" "mt_group")])
642
 
643
;; Extract LSB, negate and store in T bit.
644
 
645
(define_insn "tstsi_t_and_not"
646
  [(set (reg:SI T_REG)
647
         (and:SI (not:SI (match_operand:SI 0 "logical_operand" "z"))
648
                 (const_int 1)))]
649
  "TARGET_SH1"
650
  "tst  #1,%0"
651
  [(set_attr "type" "mt_group")])
652
 
653
;; Extract contiguous bits and compare them against zero.
654
 
655
(define_insn "tstsi_t_zero_extract_eq"
656
  [(set (reg:SI T_REG)
657
        (eq:SI (zero_extract:SI (match_operand 0 "logical_operand" "z")
658
                (match_operand:SI 1 "const_int_operand")
659
                (match_operand:SI 2 "const_int_operand"))
660
         (const_int 0)))]
661
  "TARGET_SH1
662
   && CONST_OK_FOR_K08 (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]))"
663
{
664
  operands[1] = GEN_INT (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]));
665
  return "tst   %1,%0";
666
}
667
  [(set_attr "type" "mt_group")])
668
 
669
;; This split is required when testing bits in a QI subreg.
670
 
671
(define_split
672
  [(set (reg:SI T_REG)
673
   (eq:SI (if_then_else:SI (zero_extract:SI
674
                            (match_operand 0 "logical_operand" "")
675
                            (match_operand 1 "const_int_operand")
676
                            (match_operand 2 "const_int_operand"))
677
                           (match_operand 3 "const_int_operand")
678
                           (const_int 0))
679
          (const_int 0)))]
680
  "TARGET_SH1
681
   && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
682
   && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
683
  [(set (reg:SI T_REG) (eq:SI (and:SI (match_dup 0) (match_dup 3))
684
                              (const_int 0)))]
685
  "
686
{
687
  if (GET_MODE (operands[0]) == QImode)
688
    operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
689
}")
690
 
691
;; Extract single bit, negate and store it in the T bit.
692
;; Not used for SH4A.
693
 
694
(define_insn "tstsi_t_zero_extract_xor"
695
  [(set (reg:SI T_REG)
696
        (zero_extract:SI (xor:SI (match_operand:SI 0 "logical_operand" "z")
697
                          (match_operand:SI 3 "const_int_operand"))
698
                         (match_operand:SI 1 "const_int_operand")
699
                         (match_operand:SI 2 "const_int_operand")))]
700
  "TARGET_SH1
701
   && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
702
   && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
703
  "tst  %3,%0"
704
  [(set_attr "type" "mt_group")])
705
 
706
;; Extract single bit, negate and store it in the T bit.
707
;; Used for SH4A little endian.
708
 
709
(define_insn "tstsi_t_zero_extract_subreg_xor_little"
710
  [(set (reg:SI T_REG)
711
        (zero_extract:SI
712
         (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
713
                            (match_operand:SI 3 "const_int_operand")) 0)
714
         (match_operand:SI 1 "const_int_operand")
715
         (match_operand:SI 2 "const_int_operand")))]
716
  "TARGET_SH1 && TARGET_LITTLE_ENDIAN
717
   && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
718
      == (INTVAL (operands[3]) & 255)
719
   && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
720
{
721
  operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
722
  return "tst   %3,%0";
723
}
724
  [(set_attr "type" "mt_group")])
725
 
726
;; Extract single bit, negate and store it in the T bit.
727
;; Used for SH4A big endian.
728
 
729
(define_insn "tstsi_t_zero_extract_subreg_xor_big"
730
  [(set (reg:SI T_REG)
731
        (zero_extract:SI
732
         (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
733
                            (match_operand:SI 3 "const_int_operand")) 3)
734
         (match_operand:SI 1 "const_int_operand")
735
         (match_operand:SI 2 "const_int_operand")))]
736
  "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN
737
   && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
738
      == (INTVAL (operands[3]) & 255)
739
   && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
740
{
741
  operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
742
  return "tst   %3,%0";
743
}
744
  [(set_attr "type" "mt_group")])
745
 
746
;; ??? Perhaps should only accept reg/constant if the register is reg 0.
747
;; That would still allow reload to create cmpi instructions, but would
748
;; perhaps allow forcing the constant into a register when that is better.
749
;; Probably should use r0 for mem/imm compares, but force constant into a
750
;; register for pseudo/imm compares.
751
 
752
(define_insn "cmpeqsi_t"
753
  [(set (reg:SI T_REG)
754
        (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
755
               (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
756
  "TARGET_SH1"
757
  "@
758
        tst     %0,%0
759
        cmp/eq  %1,%0
760
        cmp/eq  %1,%0"
761
   [(set_attr "type" "mt_group")])
762
 
763
(define_insn "cmpgtsi_t"
764
  [(set (reg:SI T_REG)
765
        (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
766
               (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
767
  "TARGET_SH1"
768
  "@
769
        cmp/gt  %1,%0
770
        cmp/pl  %0"
771
   [(set_attr "type" "mt_group")])
772
 
773
(define_insn "cmpgesi_t"
774
  [(set (reg:SI T_REG)
775
        (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
776
               (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
777
  "TARGET_SH1"
778
  "@
779
        cmp/ge  %1,%0
780
        cmp/pz  %0"
781
   [(set_attr "type" "mt_group")])
782
 
783
;; -------------------------------------------------------------------------
784
;; SImode compare and branch
785
;; -------------------------------------------------------------------------
786
 
787
(define_expand "cbranchsi4"
788
  [(set (pc)
789
        (if_then_else (match_operator 0 "comparison_operator"
790
                        [(match_operand:SI 1 "arith_operand" "")
791
                         (match_operand:SI 2 "arith_operand" "")])
792
                      (label_ref (match_operand 3 "" ""))
793
                      (pc)))
794
   (clobber (reg:SI T_REG))]
795
  ""
796
  "if (TARGET_SHMEDIA)
797
      emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
798
                                             operands[2], operands[3]));
799
   else if (TARGET_CBRANCHDI4)
800
     expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
801
   else
802
     sh_emit_compare_and_branch (operands, SImode);
803
   DONE;")
804
 
805
;; -------------------------------------------------------------------------
806
;; SImode unsigned integer comparisons
807
;; -------------------------------------------------------------------------
808
 
809
(define_insn_and_split "cmpgeusi_t"
810
  [(set (reg:SI T_REG)
811
        (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
812
                (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
813
  "TARGET_SH1"
814
  "cmp/hs       %1,%0"
815
  "&& operands[1] == CONST0_RTX (SImode)"
816
  [(pc)]
817
  "
818
{
819
  emit_insn (gen_sett ());
820
  DONE;
821
}"
822
   [(set_attr "type" "mt_group")])
823
 
824
(define_insn "cmpgtusi_t"
825
  [(set (reg:SI T_REG)
826
        (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
827
                (match_operand:SI 1 "arith_reg_operand" "r")))]
828
  "TARGET_SH1"
829
  "cmp/hi       %1,%0"
830
   [(set_attr "type" "mt_group")])
831
 
832
 
833
;; -------------------------------------------------------------------------
834
;; DImode compare and branch
835
;; -------------------------------------------------------------------------
836
 
837
 
838
;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
839
;; Therefore, we aim to have a set of three branches that go straight to the
840
;; destination, i.e. only one of them is taken at any one time.
841
;; This mechanism should also be slightly better for the sh4-200.
842
 
843
(define_expand "cbranchdi4"
844
  [(set (pc)
845
        (if_then_else (match_operator 0 "comparison_operator"
846
                        [(match_operand:DI 1 "arith_operand" "")
847
                         (match_operand:DI 2 "arith_operand" "")])
848
                      (label_ref (match_operand 3 "" ""))
849
                      (pc)))
850
   (clobber (match_dup 4))
851
   (clobber (reg:SI T_REG))]
852
  "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
853
  "
854
{
855
  enum rtx_code comparison;
856
 
857
  if (TARGET_SHMEDIA)
858
    {
859
      emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
860
                                             operands[2], operands[3]));
861
      DONE;
862
    }
863
 
864
  else if (!TARGET_CBRANCHDI4)
865
    {
866
      sh_emit_compare_and_branch (operands, DImode);
867
      DONE;
868
    }
869
 
870
  else
871
    {
872
      if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
873
        DONE;
874
 
875
      comparison = prepare_cbranch_operands (operands, DImode,
876
                                             LAST_AND_UNUSED_RTX_CODE);
877
      if (comparison != GET_CODE (operands[0]))
878
        operands[0]
879
          = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
880
       operands[4] = gen_rtx_SCRATCH (SImode);
881
    }
882
}")
883
 
884
(define_insn_and_split "cbranchdi4_i"
885
  [(set (pc)
886
        (if_then_else (match_operator 0 "comparison_operator"
887
                        [(match_operand:DI 1 "arith_operand" "r,r")
888
                         (match_operand:DI 2 "arith_operand" "rN,I08")])
889
                      (label_ref (match_operand 3 "" ""))
890
                      (pc)))
891
   (clobber (match_scratch:SI 4 "=X,&r"))
892
   (clobber (reg:SI T_REG))]
893
  "TARGET_CBRANCHDI4"
894
  "#"
895
  "&& reload_completed"
896
  [(pc)]
897
  "
898
{
899
  if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
900
    FAIL;
901
  DONE;
902
}")
903
 
904
;; -------------------------------------------------------------------------
905
;; DImode signed integer comparisons
906
;; -------------------------------------------------------------------------
907
 
908
(define_insn ""
909
  [(set (reg:SI T_REG)
910
        (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
911
                       (match_operand:DI 1 "arith_operand" "r"))
912
               (const_int 0)))]
913
  "TARGET_SH1"
914
  "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
915
                                 insn, operands);"
916
  [(set_attr "length" "6")
917
   (set_attr "type" "arith3b")])
918
 
919
(define_insn "cmpeqdi_t"
920
  [(set (reg:SI T_REG)
921
        (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
922
               (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
923
  "TARGET_SH1"
924
  "@
925
        tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
926
        cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
927
  [(set_attr "length" "6")
928
   (set_attr "type" "arith3b")])
929
 
930
(define_split
931
  [(set (reg:SI T_REG)
932
        (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
933
               (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
934
;; If we applied this split when not optimizing, it would only be
935
;; applied during the machine-dependent reorg, when no new basic blocks
936
;; may be created.
937
  "TARGET_SH1 && reload_completed && optimize"
938
  [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
939
   (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
940
                           (label_ref (match_dup 6))
941
                           (pc)))
942
   (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
943
   (match_dup 6)]
944
  "
945
{
946
  operands[2]
947
    = gen_rtx_REG (SImode,
948
                   true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
949
  operands[3]
950
    = (operands[1] == const0_rtx
951
       ? const0_rtx
952
       : gen_rtx_REG (SImode,
953
                      true_regnum (operands[1])
954
                      + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
955
  operands[4] = gen_lowpart (SImode, operands[0]);
956
  operands[5] = gen_lowpart (SImode, operands[1]);
957
  operands[6] = gen_label_rtx ();
958
}")
959
 
960
(define_insn "cmpgtdi_t"
961
  [(set (reg:SI T_REG)
962
        (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
963
               (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
964
  "TARGET_SH2"
965
  "@
966
        cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
967
        tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
968
  [(set_attr "length" "8")
969
   (set_attr "type" "arith3")])
970
 
971
(define_insn "cmpgedi_t"
972
  [(set (reg:SI T_REG)
973
        (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
974
               (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
975
  "TARGET_SH2"
976
  "@
977
        cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
978
        cmp/pz\\t%S0"
979
  [(set_attr "length" "8,2")
980
   (set_attr "type" "arith3,mt_group")])
981
 
982
;; -------------------------------------------------------------------------
983
;; DImode unsigned integer comparisons
984
;; -------------------------------------------------------------------------
985
 
986
(define_insn "cmpgeudi_t"
987
  [(set (reg:SI T_REG)
988
        (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
989
                (match_operand:DI 1 "arith_reg_operand" "r")))]
990
  "TARGET_SH2"
991
  "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
992
  [(set_attr "length" "8")
993
   (set_attr "type" "arith3")])
994
 
995
(define_insn "cmpgtudi_t"
996
  [(set (reg:SI T_REG)
997
        (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
998
                (match_operand:DI 1 "arith_reg_operand" "r")))]
999
  "TARGET_SH2"
1000
  "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
1001
  [(set_attr "length" "8")
1002
   (set_attr "type" "arith3")])
1003
 
1004
(define_insn "cmpeqsi_media"
1005
  [(set (match_operand:SI 0 "register_operand" "=r")
1006
        (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1007
               (match_operand:SI 2 "cmp_operand" "Nr")))]
1008
  "TARGET_SHMEDIA"
1009
  "cmpeq        %1, %N2, %0"
1010
  [(set_attr "type" "cmp_media")])
1011
 
1012
(define_insn "cmpeqdi_media"
1013
  [(set (match_operand:SI 0 "register_operand" "=r")
1014
        (eq:SI (match_operand:DI 1 "register_operand" "%r")
1015
               (match_operand:DI 2 "cmp_operand" "Nr")))]
1016
  "TARGET_SHMEDIA"
1017
  "cmpeq        %1, %N2, %0"
1018
  [(set_attr "type" "cmp_media")])
1019
 
1020
(define_insn "cmpgtsi_media"
1021
  [(set (match_operand:SI 0 "register_operand" "=r")
1022
        (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1023
               (match_operand:SI 2 "cmp_operand" "rN")))]
1024
  "TARGET_SHMEDIA"
1025
  "cmpgt        %N1, %N2, %0"
1026
  [(set_attr "type" "cmp_media")])
1027
 
1028
(define_insn "cmpgtdi_media"
1029
  [(set (match_operand:SI 0 "register_operand" "=r")
1030
        (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1031
               (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1032
  "TARGET_SHMEDIA"
1033
  "cmpgt        %N1, %N2, %0"
1034
  [(set_attr "type" "cmp_media")])
1035
 
1036
(define_insn "cmpgtusi_media"
1037
  [(set (match_operand:SI 0 "register_operand" "=r")
1038
        (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1039
                (match_operand:SI 2 "cmp_operand" "rN")))]
1040
  "TARGET_SHMEDIA"
1041
  "cmpgtu       %N1, %N2, %0"
1042
  [(set_attr "type" "cmp_media")])
1043
 
1044
(define_insn "cmpgtudi_media"
1045
  [(set (match_operand:SI 0 "register_operand" "=r")
1046
        (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1047
                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1048
  "TARGET_SHMEDIA"
1049
  "cmpgtu       %N1, %N2, %0"
1050
  [(set_attr "type" "cmp_media")])
1051
 
1052
; These two patterns are for combine.
1053
(define_insn "*cmpne0sisi_media"
1054
  [(set (match_operand:SI 0 "register_operand" "=r")
1055
        (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1056
  "TARGET_SHMEDIA"
1057
  "cmpgtu       %1,r63,%0"
1058
  [(set_attr "type" "cmp_media")])
1059
 
1060
;; -------------------------------------------------------------------------
1061
;; Conditional move instructions
1062
;; -------------------------------------------------------------------------
1063
 
1064
;; The insn names may seem reversed, but note that cmveq performs the move
1065
;; if op1 == 0, and cmvne does it if op1 != 0.
1066
 
1067
(define_insn "movdicc_false"
1068
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1069
        (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1070
                             (const_int 0))
1071
         (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1072
         (match_operand:DI 3 "arith_reg_operand" "0")))]
1073
  "TARGET_SHMEDIA"
1074
  "cmveq        %1, %N2, %0"
1075
  [(set_attr "type" "arith_media")])
1076
 
1077
(define_insn "movdicc_true"
1078
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1079
        (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1080
                             (const_int 0))
1081
         (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1082
         (match_operand:DI 3 "arith_reg_operand" "0")))]
1083
  "TARGET_SHMEDIA"
1084
  "cmvne        %1, %N2, %0"
1085
  [(set_attr "type" "arith_media")])
1086
 
1087
(define_peephole2
1088
  [(set (match_operand:DI 0 "arith_reg_dest" "")
1089
        (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1090
                           [(match_operand:DI 1 "arith_reg_operand" "")
1091
                            (const_int 0)])
1092
         (match_operand:DI 2 "arith_reg_dest" "")
1093
         (match_dup 0)))
1094
   (set (match_dup 2) (match_dup 0))]
1095
  "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1096
  [(set (match_dup 2)
1097
        (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1098
  "
1099
{
1100
  operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1101
                                VOIDmode, operands[1], CONST0_RTX (DImode));
1102
}")
1103
 
1104
(define_peephole2
1105
  [(set (match_operand:DI 0 "general_movdst_operand" "")
1106
        (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1107
   (set (match_operand:DI 2 "arith_reg_dest" "")
1108
        (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1109
                           [(match_operand:DI 3 "arith_reg_operand" "")
1110
                            (const_int 0)])
1111
         (match_dup 0)
1112
         (match_dup 2)))]
1113
  "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1114
  [(set (match_dup 2)
1115
        (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1116
  "")
1117
 
1118
(define_expand "movdicc"
1119
  [(set (match_operand:DI 0 "register_operand" "")
1120
        (if_then_else:DI (match_operand 1 "comparison_operator" "")
1121
                         (match_operand:DI 2 "register_operand" "")
1122
                         (match_operand:DI 3 "register_operand" "")))]
1123
  "TARGET_SHMEDIA"
1124
  "
1125
{
1126
  if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1127
      && GET_MODE (XEXP (operands[1], 0)) == DImode
1128
      && XEXP (operands[1], 1) == const0_rtx)
1129
    ;
1130
  else
1131
    {
1132
      if (!can_create_pseudo_p ())
1133
        FAIL;
1134
 
1135
      operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1136
                                              GET_CODE (operands[1]),
1137
                                              XEXP (operands[1], 0),
1138
                                              XEXP (operands[1], 1));
1139
      if (!operands[1])
1140
        FAIL;
1141
    }
1142
}")
1143
 
1144
;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1145
;; SImode to DImode.
1146
(define_insn "movsicc_false"
1147
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1148
        (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1149
                          (const_int 0))
1150
         (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1151
         (match_operand:SI 3 "arith_reg_operand" "0")))]
1152
  "TARGET_SHMEDIA"
1153
  "cmveq        %1, %N2, %0"
1154
  [(set_attr "type" "arith_media")])
1155
 
1156
(define_insn "movsicc_true"
1157
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1158
        (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1159
                          (const_int 0))
1160
         (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1161
         (match_operand:SI 3 "arith_reg_operand" "0")))]
1162
  "TARGET_SHMEDIA"
1163
  "cmvne        %1, %N2, %0"
1164
  [(set_attr "type" "arith_media")])
1165
 
1166
(define_peephole2
1167
  [(set (match_operand:SI 0 "arith_reg_dest" "")
1168
        (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1169
                           [(match_operand:SI 1 "arith_reg_operand" "")
1170
                            (const_int 0)])
1171
         (match_operand:SI 2 "arith_reg_dest" "")
1172
         (match_dup 0)))
1173
   (set (match_dup 2) (match_dup 0))]
1174
  "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1175
  [(set (match_dup 2)
1176
        (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1177
  "
1178
{
1179
  operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1180
                                VOIDmode, operands[1], CONST0_RTX (SImode));
1181
}")
1182
 
1183
(define_peephole2
1184
  [(set (match_operand:SI 0 "general_movdst_operand" "")
1185
        (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1186
   (set (match_operand:SI 2 "arith_reg_dest" "")
1187
        (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1188
                           [(match_operand:SI 3 "arith_reg_operand" "")
1189
                            (const_int 0)])
1190
         (match_dup 0)
1191
         (match_dup 2)))]
1192
  "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1193
   && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1194
  [(set (match_dup 2)
1195
        (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1196
  "
1197
{
1198
  replace_rtx (operands[4], operands[0], operands[1]);
1199
}")
1200
 
1201
(define_peephole2
1202
  [(set (match_operand 0 "any_register_operand" "")
1203
        (match_operand 1 "any_register_operand" ""))
1204
   (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1205
   (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1206
  "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1207
    <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1208
   && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1209
   && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1210
   && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1211
   && ! reg_overlap_mentioned_p (operands[0], operands[3])
1212
   && ! reg_overlap_mentioned_p (operands[2], operands[0])
1213
   && ! reg_overlap_mentioned_p (operands[0], operands[1])
1214
   && (REGNO_REG_CLASS (REGNO (operands[0]))
1215
       == REGNO_REG_CLASS (REGNO (operands[2])))
1216
   && (REGNO_REG_CLASS (REGNO (operands[1]))
1217
       == REGNO_REG_CLASS (REGNO (operands[0])))"
1218
  [(set (match_dup 0) (match_dup 3))
1219
   (set (match_dup 4) (match_dup 5))]
1220
  "
1221
{
1222
  rtx set1, set2, insn2;
1223
  rtx replacements[4];
1224
 
1225
  /* We want to replace occurrences of operands[0] with operands[1] and
1226
     operands[2] with operands[0] in operands[4]/operands[5].
1227
     Doing just two replace_rtx calls naively would result in the second
1228
     replacement undoing all that the first did if operands[1] and operands[2]
1229
     are identical, so we must do this simultaneously.  */
1230
  replacements[0] = operands[0];
1231
  replacements[1] = operands[1];
1232
  replacements[2] = operands[2];
1233
  replacements[3] = operands[0];
1234
  if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1235
      || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1236
      || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1237
    FAIL;
1238
 
1239
  operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1240
  replace_n_hard_rtx (operands[4], replacements, 2, 1);
1241
  operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1242
  /* The operands array is aliased to recog_data.operand, which gets
1243
     clobbered by extract_insn, so finish with it now.  */
1244
  set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1245
  set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1246
  /* ??? The last insn might be a jump insn, but the generic peephole2 code
1247
     always uses emit_insn.  */
1248
  /* Check that we don't violate matching constraints or earlyclobbers.  */
1249
  extract_insn (emit_insn (set1));
1250
  if (! constrain_operands (1))
1251
    goto failure;
1252
  insn2 = emit (set2);
1253
  if (GET_CODE (insn2) == BARRIER)
1254
    goto failure;
1255
  extract_insn (insn2);
1256
  if (! constrain_operands (1))
1257
    {
1258
      rtx tmp;
1259
    failure:
1260
      tmp = replacements[0];
1261
      replacements[0] = replacements[1];
1262
      replacements[1] = tmp;
1263
      tmp = replacements[2];
1264
      replacements[2] = replacements[3];
1265
      replacements[3] = tmp;
1266
      replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1267
      replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1268
      replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1269
      FAIL;
1270
    }
1271
  DONE;
1272
}")
1273
 
1274
;; The register allocator is rather clumsy in handling multi-way conditional
1275
;; moves, so allow the combiner to make them, and we split them up after
1276
;; reload.  */
1277
(define_insn_and_split "*movsicc_umin"
1278
  [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1279
        (umin:SI (if_then_else:SI
1280
                   (eq (match_operand:SI 1 "arith_reg_operand" "r")
1281
                       (const_int 0))
1282
                   (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1283
                   (match_operand:SI 3 "register_operand" "0"))
1284
                 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1285
   (clobber (match_scratch:SI 5 "=&r"))]
1286
  "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1287
  "#"
1288
  "TARGET_SHMEDIA && reload_completed"
1289
  [(pc)]
1290
  "
1291
{
1292
  emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1293
                                operands[3]));
1294
  emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1295
  emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1296
                                operands[0]));
1297
  DONE;
1298
}")
1299
 
1300
(define_insn "*movsicc_t_false"
1301
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1302
        (if_then_else (eq (reg:SI T_REG) (const_int 0))
1303
                      (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1304
                      (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1305
  "TARGET_PRETEND_CMOVE
1306
   && (arith_reg_operand (operands[1], SImode)
1307
       || (immediate_operand (operands[1], SImode)
1308
           && satisfies_constraint_I08 (operands[1])))"
1309
  "bt   0f\;mov %1,%0\\n0:"
1310
  [(set_attr "type" "mt_group,arith") ;; poor approximation
1311
   (set_attr "length" "4")])
1312
 
1313
(define_insn "*movsicc_t_true"
1314
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1315
        (if_then_else (ne (reg:SI T_REG) (const_int 0))
1316
                      (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1317
                      (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1318
  "TARGET_PRETEND_CMOVE
1319
   && (arith_reg_operand (operands[1], SImode)
1320
       || (immediate_operand (operands[1], SImode)
1321
           && satisfies_constraint_I08 (operands[1])))"
1322
  "bf   0f\;mov %1,%0\\n0:"
1323
  [(set_attr "type" "mt_group,arith") ;; poor approximation
1324
   (set_attr "length" "4")])
1325
 
1326
(define_expand "movsicc"
1327
  [(set (match_operand:SI 0 "arith_reg_dest" "")
1328
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
1329
                         (match_operand:SI 2 "arith_reg_or_0_operand" "")
1330
                         (match_operand:SI 3 "arith_reg_operand" "")))]
1331
  "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1332
  "
1333
{
1334
  if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1335
      && GET_MODE (XEXP (operands[1], 0)) == SImode
1336
      && (TARGET_SHMEDIA
1337
          || (REG_P (XEXP (operands[1], 0))
1338
              && REGNO (XEXP (operands[1], 0)) == T_REG))
1339
      && XEXP (operands[1], 1) == const0_rtx)
1340
    ;
1341
 
1342
  else if (TARGET_PRETEND_CMOVE)
1343
    {
1344
      enum rtx_code code = GET_CODE (operands[1]);
1345
      enum rtx_code new_code = code;
1346
      rtx op0 = XEXP (operands[1], 0);
1347
      rtx op1 = XEXP (operands[1], 1);
1348
 
1349
      if (! currently_expanding_to_rtl)
1350
        FAIL;
1351
      switch (code)
1352
        {
1353
        case LT: case LE: case LEU: case LTU:
1354
          if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1355
            break;
1356
        case NE:
1357
          new_code = reverse_condition (code);
1358
          break;
1359
        case EQ: case GT: case GE: case GEU: case GTU:
1360
          break;
1361
        default:
1362
          FAIL;
1363
        }
1364
      sh_emit_scc_to_t (new_code, op0, op1);
1365
      operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1366
                                    gen_rtx_REG (SImode, T_REG), const0_rtx);
1367
    }
1368
  else
1369
    {
1370
      if (!can_create_pseudo_p ())
1371
        FAIL;
1372
 
1373
      operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1374
                                              GET_CODE (operands[1]),
1375
                                              XEXP (operands[1], 0),
1376
                                              XEXP (operands[1], 1));
1377
      if (!operands[1])
1378
        FAIL;
1379
    }
1380
}")
1381
 
1382
(define_expand "movqicc"
1383
  [(set (match_operand:QI 0 "register_operand" "")
1384
        (if_then_else:QI (match_operand 1 "comparison_operator" "")
1385
                         (match_operand:QI 2 "register_operand" "")
1386
                         (match_operand:QI 3 "register_operand" "")))]
1387
  "TARGET_SHMEDIA"
1388
  "
1389
{
1390
  operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1391
  operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1392
  operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1393
  emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1394
  DONE;
1395
}")
1396
 
1397
;; -------------------------------------------------------------------------
1398
;; Addition instructions
1399
;; -------------------------------------------------------------------------
1400
 
1401
(define_expand "adddi3"
1402
  [(set (match_operand:DI 0 "arith_reg_operand" "")
1403
        (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1404
                 (match_operand:DI 2 "arith_operand" "")))]
1405
  ""
1406
  "
1407
{
1408
  if (TARGET_SH1)
1409
    {
1410
      if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1411
        FAIL;
1412
      operands[2] = force_reg (DImode, operands[2]);
1413
      emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1414
      DONE;
1415
    }
1416
}")
1417
 
1418
(define_insn "*adddi3_media"
1419
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1420
        (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1421
                 (match_operand:DI 2 "arith_operand" "r,I10")))]
1422
  "TARGET_SHMEDIA"
1423
  "@
1424
        add     %1, %2, %0
1425
        addi    %1, %2, %0"
1426
  [(set_attr "type" "arith_media")])
1427
 
1428
(define_insn "*adddisi3_media"
1429
  [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1430
        (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1431
                 (match_operand:DI 2 "arith_operand" "r,I10")))]
1432
  "TARGET_SHMEDIA"
1433
  "@
1434
        add.l   %1, %2, %0
1435
        addi.l  %1, %2, %0"
1436
  [(set_attr "type" "arith_media")
1437
   (set_attr "highpart" "ignore")])
1438
 
1439
(define_insn "adddi3z_media"
1440
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1441
        (zero_extend:DI
1442
         (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1443
                  (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1444
  "TARGET_SHMEDIA"
1445
  "addz.l       %1, %N2, %0"
1446
  [(set_attr "type" "arith_media")
1447
   (set_attr "highpart" "ignore")])
1448
 
1449
(define_insn "adddi3_compact"
1450
  [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1451
        (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1452
                 (match_operand:DI 2 "arith_reg_operand" "r")))
1453
   (clobber (reg:SI T_REG))]
1454
  "TARGET_SH1"
1455
  "#"
1456
  [(set_attr "length" "6")])
1457
 
1458
(define_split
1459
  [(set (match_operand:DI 0 "arith_reg_dest" "")
1460
        (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1461
                 (match_operand:DI 2 "arith_reg_operand" "")))
1462
   (clobber (reg:SI T_REG))]
1463
  "TARGET_SH1 && reload_completed"
1464
  [(const_int 0)]
1465
  "
1466
{
1467
  rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1468
  high0 = gen_rtx_REG (SImode,
1469
                       true_regnum (operands[0])
1470
                       + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1471
  high2 = gen_rtx_REG (SImode,
1472
                       true_regnum (operands[2])
1473
                       + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1474
  emit_insn (gen_clrt ());
1475
  emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1476
  emit_insn (gen_addc1 (high0, high0, high2));
1477
  DONE;
1478
}")
1479
 
1480
(define_insn "addc"
1481
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1482
        (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1483
                          (match_operand:SI 2 "arith_reg_operand" "r"))
1484
                 (reg:SI T_REG)))
1485
   (set (reg:SI T_REG)
1486
        (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1487
  "TARGET_SH1"
1488
  "addc %2,%0"
1489
  [(set_attr "type" "arith")])
1490
 
1491
(define_insn "addc1"
1492
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1493
        (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1494
                          (match_operand:SI 2 "arith_reg_operand" "r"))
1495
                 (reg:SI T_REG)))
1496
   (clobber (reg:SI T_REG))]
1497
  "TARGET_SH1"
1498
  "addc %2,%0"
1499
  [(set_attr "type" "arith")])
1500
 
1501
(define_expand "addsi3"
1502
  [(set (match_operand:SI 0 "arith_reg_operand" "")
1503
        (plus:SI (match_operand:SI 1 "arith_operand" "")
1504
                 (match_operand:SI 2 "arith_operand" "")))]
1505
  ""
1506
  "
1507
{
1508
  if (TARGET_SHMEDIA)
1509
    operands[1] = force_reg (SImode, operands[1]);
1510
}")
1511
 
1512
(define_insn "addsi3_media"
1513
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1514
        (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1515
                 (match_operand:SI 2 "arith_operand" "r,I10")))]
1516
  "TARGET_SHMEDIA"
1517
  "@
1518
        add.l   %1, %2, %0
1519
        addi.l  %1, %2, %0"
1520
  [(set_attr "type" "arith_media")
1521
   (set_attr "highpart" "ignore")])
1522
 
1523
(define_insn "addsidi3_media"
1524
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1525
        (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1526
                                  "%r,r")
1527
                                 (match_operand:SI 2 "arith_operand"
1528
                                  "r,I10"))))]
1529
  "TARGET_SHMEDIA"
1530
  "@
1531
        add.l   %1, %2, %0
1532
        addi.l  %1, %2, %0"
1533
  [(set_attr "type" "arith_media")
1534
   (set_attr "highpart" "ignore")])
1535
 
1536
(define_insn "*addsi3_compact"
1537
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1538
        (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1539
                 (match_operand:SI 2 "arith_operand" "rI08")))]
1540
  "TARGET_SH1"
1541
  "add  %2,%0"
1542
  [(set_attr "type" "arith")])
1543
 
1544
;; -------------------------------------------------------------------------
1545
;; Subtraction instructions
1546
;; -------------------------------------------------------------------------
1547
 
1548
(define_expand "subdi3"
1549
  [(set (match_operand:DI 0 "arith_reg_operand" "")
1550
        (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1551
                  (match_operand:DI 2 "arith_reg_operand" "")))]
1552
  ""
1553
  "
1554
{
1555
  if (TARGET_SH1)
1556
    {
1557
      operands[1] = force_reg (DImode, operands[1]);
1558
      emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1559
      DONE;
1560
    }
1561
}")
1562
 
1563
(define_insn "*subdi3_media"
1564
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1565
        (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1566
                  (match_operand:DI 2 "arith_reg_operand" "r")))]
1567
  "TARGET_SHMEDIA"
1568
  "sub  %N1, %2, %0"
1569
  [(set_attr "type" "arith_media")])
1570
 
1571
(define_insn "subdisi3_media"
1572
  [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1573
        (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1574
                  (match_operand:DI 2 "arith_reg_operand" "r")))]
1575
  "TARGET_SHMEDIA"
1576
  "sub.l        %N1, %2, %0"
1577
  [(set_attr "type" "arith_media")
1578
   (set_attr "highpart" "ignore")])
1579
 
1580
(define_insn "subdi3_compact"
1581
  [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1582
        (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1583
                 (match_operand:DI 2 "arith_reg_operand" "r")))
1584
   (clobber (reg:SI T_REG))]
1585
  "TARGET_SH1"
1586
  "#"
1587
  [(set_attr "length" "6")])
1588
 
1589
(define_split
1590
  [(set (match_operand:DI 0 "arith_reg_dest" "")
1591
        (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1592
                  (match_operand:DI 2 "arith_reg_operand" "")))
1593
   (clobber (reg:SI T_REG))]
1594
  "TARGET_SH1 && reload_completed"
1595
  [(const_int 0)]
1596
  "
1597
{
1598
  rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1599
  high0 = gen_rtx_REG (SImode,
1600
                       true_regnum (operands[0])
1601
                       + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1602
  high2 = gen_rtx_REG (SImode,
1603
                       true_regnum (operands[2])
1604
                       + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1605
  emit_insn (gen_clrt ());
1606
  emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1607
  emit_insn (gen_subc1 (high0, high0, high2));
1608
  DONE;
1609
}")
1610
 
1611
(define_insn "subc"
1612
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1613
        (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1614
                            (match_operand:SI 2 "arith_reg_operand" "r"))
1615
                  (reg:SI T_REG)))
1616
   (set (reg:SI T_REG)
1617
        (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1618
                          (reg:SI T_REG))
1619
                (match_dup 1)))]
1620
  "TARGET_SH1"
1621
  "subc %2,%0"
1622
  [(set_attr "type" "arith")])
1623
 
1624
(define_insn "subc1"
1625
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1626
        (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1627
                            (match_operand:SI 2 "arith_reg_operand" "r"))
1628
                  (reg:SI T_REG)))
1629
   (clobber (reg:SI T_REG))]
1630
  "TARGET_SH1"
1631
  "subc %2,%0"
1632
  [(set_attr "type" "arith")])
1633
 
1634
;; life_analysis thinks rn is live before subc rn,rn, so make a special
1635
;; pattern for this case.  This helps multimedia applications that compute
1636
;; the sum of absolute differences.
1637
(define_insn "mov_neg_si_t"
1638
  [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1639
  "TARGET_SH1"
1640
  "subc %0,%0"
1641
  [(set_attr "type" "arith")])
1642
 
1643
(define_insn "*subsi3_internal"
1644
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1645
        (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1646
                  (match_operand:SI 2 "arith_reg_operand" "r")))]
1647
  "TARGET_SH1"
1648
  "sub  %2,%0"
1649
  [(set_attr "type" "arith")])
1650
 
1651
(define_insn_and_split "*subsi3_media"
1652
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1653
        (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1654
                  (match_operand:SI 2 "extend_reg_operand" "r")))]
1655
  "TARGET_SHMEDIA
1656
   && (operands[1] != constm1_rtx
1657
       || (GET_CODE (operands[2]) != TRUNCATE
1658
           && GET_CODE (operands[2]) != SUBREG))"
1659
  "sub.l        %N1, %2, %0"
1660
  "operands[1] == constm1_rtx"
1661
  [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1662
  ""
1663
  [(set_attr "type" "arith_media")
1664
   (set_attr "highpart" "ignore")])
1665
 
1666
(define_split
1667
  [(set (match_operand:SI 0 "arith_reg_dest" "")
1668
        (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1669
                                                       "general_extend_operand"
1670
                                                       "") 0)) 0)))]
1671
  "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1672
  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1673
   (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1674
  "")
1675
 
1676
(define_split
1677
  [(set (match_operand:SI 0 "arith_reg_dest" "")
1678
        (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1679
                                                       "general_extend_operand"
1680
                                                       "") 0)) 3)))]
1681
  "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1682
  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1683
   (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1684
  "")
1685
;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1686
;; will sometimes save one instruction.  Otherwise we might get
1687
;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1688
;; are the same.
1689
 
1690
(define_expand "subsi3"
1691
  [(set (match_operand:SI 0 "arith_reg_operand" "")
1692
        (minus:SI (match_operand:SI 1 "arith_operand" "")
1693
                  (match_operand:SI 2 "arith_reg_operand" "")))]
1694
  ""
1695
  "
1696
{
1697
  if (TARGET_SH1 && CONST_INT_P (operands[1]))
1698
    {
1699
      emit_insn (gen_negsi2 (operands[0], operands[2]));
1700
      emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1701
      DONE;
1702
    }
1703
  if (TARGET_SHMEDIA)
1704
    {
1705
      if (!can_create_pseudo_p ()
1706
          && ! arith_reg_or_0_operand (operands[1], SImode))
1707
        FAIL;
1708
      if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1709
        operands[1] = force_reg (SImode, operands[1]);
1710
    }
1711
}")
1712
 
1713
;; -------------------------------------------------------------------------
1714
;; Division instructions
1715
;; -------------------------------------------------------------------------
1716
 
1717
;; We take advantage of the library routines which don't clobber as many
1718
;; registers as a normal function call would.
1719
 
1720
;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1721
;; also has an effect on the register that holds the address of the sfunc.
1722
;; To make this work, we have an extra dummy insn that shows the use
1723
;; of this register for reorg.
1724
 
1725
(define_insn "use_sfunc_addr"
1726
  [(set (reg:SI PR_REG)
1727
        (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1728
  "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1729
  ""
1730
  [(set_attr "length" "0")])
1731
 
1732
(define_insn "udivsi3_sh2a"
1733
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1734
        (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1735
                (match_operand:SI 2 "arith_reg_operand" "z")))]
1736
  "TARGET_SH2A"
1737
  "divu %2,%1"
1738
  [(set_attr "type" "arith")
1739
   (set_attr "in_delay_slot" "no")])
1740
 
1741
;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1742
;; hard register 0.  If we used hard register 0, then the next instruction
1743
;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1744
;; gets allocated to a stack slot that needs its address reloaded, then
1745
;; there is nothing to prevent reload from using r0 to reload the address.
1746
;; This reload would clobber the value in r0 we are trying to store.
1747
;; If we let reload allocate r0, then this problem can never happen.
1748
 
1749
(define_insn "udivsi3_i1"
1750
  [(set (match_operand:SI 0 "register_operand" "=z")
1751
        (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1752
   (clobber (reg:SI T_REG))
1753
   (clobber (reg:SI PR_REG))
1754
   (clobber (reg:SI R4_REG))
1755
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1756
  "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1757
  "jsr  @%1%#"
1758
  [(set_attr "type" "sfunc")
1759
   (set_attr "needs_delay_slot" "yes")])
1760
 
1761
; Since shmedia-nofpu code could be linked against shcompact code, and
1762
; the udivsi3 libcall has the same name, we must consider all registers
1763
; clobbered that are in the union of the registers clobbered by the
1764
; shmedia and the shcompact implementation.  Note, if the shcompact
1765
; implementation actually used shcompact code, we'd need to clobber
1766
; also r23 and fr23.
1767
(define_insn "udivsi3_i1_media"
1768
  [(set (match_operand:SI 0 "register_operand" "=z")
1769
        (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1770
   (clobber (reg:SI T_MEDIA_REG))
1771
   (clobber (reg:SI PR_MEDIA_REG))
1772
   (clobber (reg:SI R20_REG))
1773
   (clobber (reg:SI R21_REG))
1774
   (clobber (reg:SI R22_REG))
1775
   (clobber (reg:DI TR0_REG))
1776
   (clobber (reg:DI TR1_REG))
1777
   (clobber (reg:DI TR2_REG))
1778
   (use (match_operand 1 "target_reg_operand" "b"))]
1779
  "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1780
  "blink        %1, r18"
1781
  [(set_attr "type" "sfunc")
1782
   (set_attr "needs_delay_slot" "yes")])
1783
 
1784
(define_expand "udivsi3_i4_media"
1785
  [(set (match_dup 3)
1786
        (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1787
   (set (match_dup 4)
1788
        (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1789
   (set (match_dup 5) (float:DF (match_dup 3)))
1790
   (set (match_dup 6) (float:DF (match_dup 4)))
1791
   (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1792
   (set (match_dup 8) (fix:DI (match_dup 7)))
1793
   (set (match_operand:SI 0 "register_operand" "")
1794
        (truncate:SI (match_dup 8)))]
1795
  "TARGET_SHMEDIA_FPU"
1796
  "
1797
{
1798
  operands[3] = gen_reg_rtx (DImode);
1799
  operands[4] = gen_reg_rtx (DImode);
1800
  operands[5] = gen_reg_rtx (DFmode);
1801
  operands[6] = gen_reg_rtx (DFmode);
1802
  operands[7] = gen_reg_rtx (DFmode);
1803
  operands[8] = gen_reg_rtx (DImode);
1804
}")
1805
 
1806
(define_insn "udivsi3_i4"
1807
  [(set (match_operand:SI 0 "register_operand" "=y")
1808
        (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1809
   (clobber (reg:SI T_REG))
1810
   (clobber (reg:SI PR_REG))
1811
   (clobber (reg:DF DR0_REG))
1812
   (clobber (reg:DF DR2_REG))
1813
   (clobber (reg:DF DR4_REG))
1814
   (clobber (reg:SI R0_REG))
1815
   (clobber (reg:SI R1_REG))
1816
   (clobber (reg:SI R4_REG))
1817
   (clobber (reg:SI R5_REG))
1818
   (use (reg:PSI FPSCR_REG))
1819
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1820
  "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1821
  "jsr  @%1%#"
1822
  [(set_attr "type" "sfunc")
1823
   (set_attr "fp_mode" "double")
1824
   (set_attr "needs_delay_slot" "yes")])
1825
 
1826
(define_insn "udivsi3_i4_single"
1827
  [(set (match_operand:SI 0 "register_operand" "=y")
1828
        (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1829
   (clobber (reg:SI T_REG))
1830
   (clobber (reg:SI PR_REG))
1831
   (clobber (reg:DF DR0_REG))
1832
   (clobber (reg:DF DR2_REG))
1833
   (clobber (reg:DF DR4_REG))
1834
   (clobber (reg:SI R0_REG))
1835
   (clobber (reg:SI R1_REG))
1836
   (clobber (reg:SI R4_REG))
1837
   (clobber (reg:SI R5_REG))
1838
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1839
  "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1840
  "jsr  @%1%#"
1841
  [(set_attr "type" "sfunc")
1842
   (set_attr "needs_delay_slot" "yes")])
1843
 
1844
(define_insn "udivsi3_i4_int"
1845
  [(set (match_operand:SI 0 "register_operand" "=z")
1846
        (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1847
   (clobber (reg:SI T_REG))
1848
   (clobber (reg:SI R1_REG))
1849
   (clobber (reg:SI PR_REG))
1850
   (clobber (reg:SI MACH_REG))
1851
   (clobber (reg:SI MACL_REG))
1852
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1853
  "TARGET_SH1"
1854
  "jsr  @%1%#"
1855
  [(set_attr "type" "sfunc")
1856
   (set_attr "needs_delay_slot" "yes")])
1857
 
1858
 
1859
(define_expand "udivsi3"
1860
  [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1861
   (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1862
   (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1863
   (parallel [(set (match_operand:SI 0 "register_operand" "")
1864
                   (udiv:SI (reg:SI R4_REG)
1865
                            (reg:SI R5_REG)))
1866
              (clobber (reg:SI T_REG))
1867
              (clobber (reg:SI PR_REG))
1868
              (clobber (reg:SI R4_REG))
1869
              (use (match_dup 3))])]
1870
  ""
1871
  "
1872
{
1873
  rtx last;
1874
 
1875
  operands[3] = gen_reg_rtx (Pmode);
1876
  /* Emit the move of the address to a pseudo outside of the libcall.  */
1877
  if (TARGET_DIVIDE_CALL_TABLE)
1878
    {
1879
      /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1880
         that causes problems when the divide code is supposed to come from a
1881
         separate library.  Division by zero is undefined, so dividing 1 can be
1882
         implemented by comparing with the divisor.  */
1883
      if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1884
        {
1885
          rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1886
          emit_insn (gen_cstoresi4 (operands[0], test,
1887
                                    operands[1], operands[2]));
1888
          DONE;
1889
        }
1890
      else if (operands[2] == const0_rtx)
1891
        {
1892
          emit_move_insn (operands[0], operands[2]);
1893
          DONE;
1894
        }
1895
      function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1896
      last = gen_udivsi3_i4_int (operands[0], operands[3]);
1897
    }
1898
  else if (TARGET_DIVIDE_CALL_FP)
1899
    {
1900
      function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1901
      if (TARGET_FPU_SINGLE)
1902
        last = gen_udivsi3_i4_single (operands[0], operands[3]);
1903
      else
1904
        last = gen_udivsi3_i4 (operands[0], operands[3]);
1905
    }
1906
  else if (TARGET_SHMEDIA_FPU)
1907
    {
1908
      operands[1] = force_reg (SImode, operands[1]);
1909
      operands[2] = force_reg (SImode, operands[2]);
1910
      emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1911
      DONE;
1912
    }
1913
  else if (TARGET_SH2A)
1914
    {
1915
      operands[1] = force_reg (SImode, operands[1]);
1916
      operands[2] = force_reg (SImode, operands[2]);
1917
      emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1918
      DONE;
1919
    }
1920
  else if (TARGET_SH5)
1921
    {
1922
      function_symbol (operands[3],
1923
                       TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1924
                       SFUNC_STATIC);
1925
 
1926
      if (TARGET_SHMEDIA)
1927
        last = gen_udivsi3_i1_media (operands[0], operands[3]);
1928
      else if (TARGET_FPU_ANY)
1929
        last = gen_udivsi3_i4_single (operands[0], operands[3]);
1930
      else
1931
        last = gen_udivsi3_i1 (operands[0], operands[3]);
1932
    }
1933
  else
1934
    {
1935
      function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1936
      last = gen_udivsi3_i1 (operands[0], operands[3]);
1937
    }
1938
  emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1939
  emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1940
  emit_insn (last);
1941
  DONE;
1942
}")
1943
 
1944
(define_insn "divsi3_sh2a"
1945
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1946
        (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1947
                (match_operand:SI 2 "arith_reg_operand" "z")))]
1948
  "TARGET_SH2A"
1949
  "divs %2,%1"
1950
  [(set_attr "type" "arith")
1951
   (set_attr "in_delay_slot" "no")])
1952
 
1953
(define_insn "divsi3_i1"
1954
  [(set (match_operand:SI 0 "register_operand" "=z")
1955
        (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1956
   (clobber (reg:SI T_REG))
1957
   (clobber (reg:SI PR_REG))
1958
   (clobber (reg:SI R1_REG))
1959
   (clobber (reg:SI R2_REG))
1960
   (clobber (reg:SI R3_REG))
1961
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1962
  "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1963
  "jsr  @%1%#"
1964
  [(set_attr "type" "sfunc")
1965
   (set_attr "needs_delay_slot" "yes")])
1966
 
1967
(define_insn "divsi3_i1_media"
1968
  [(set (match_operand:SI 0 "register_operand" "=z")
1969
        (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1970
   (clobber (reg:SI T_MEDIA_REG))
1971
   (clobber (reg:SI PR_MEDIA_REG))
1972
   (clobber (reg:SI R1_REG))
1973
   (clobber (reg:SI R20_REG))
1974
   (clobber (reg:SI R21_REG))
1975
   (clobber (reg:SI TR0_REG))
1976
   (use (match_operand 1 "target_reg_operand" "b"))]
1977
  "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1978
  "blink        %1, r18"
1979
  [(set_attr "type" "sfunc")])
1980
 
1981
(define_insn "divsi3_media_2"
1982
  [(set (match_operand:SI 0 "register_operand" "=z")
1983
        (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1984
   (clobber (reg:SI T_MEDIA_REG))
1985
   (clobber (reg:SI PR_MEDIA_REG))
1986
   (clobber (reg:SI R1_REG))
1987
   (clobber (reg:SI R21_REG))
1988
   (clobber (reg:SI TR0_REG))
1989
   (use (reg:SI R20_REG))
1990
   (use (match_operand 1 "target_reg_operand" "b"))]
1991
  "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1992
  "blink        %1, r18"
1993
  [(set_attr "type" "sfunc")])
1994
 
1995
;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1996
;; hard reg clobbers and data dependencies that we need when we want
1997
;; to rematerialize the division into a call.
1998
(define_insn_and_split "divsi_inv_call"
1999
  [(set (match_operand:SI 0 "register_operand" "=r")
2000
        (div:SI (match_operand:SI 1 "register_operand" "r")
2001
                (match_operand:SI 2 "register_operand" "r")))
2002
   (clobber (reg:SI R4_REG))
2003
   (clobber (reg:SI R5_REG))
2004
   (clobber (reg:SI T_MEDIA_REG))
2005
   (clobber (reg:SI PR_MEDIA_REG))
2006
   (clobber (reg:SI R1_REG))
2007
   (clobber (reg:SI R21_REG))
2008
   (clobber (reg:SI TR0_REG))
2009
   (clobber (reg:SI R20_REG))
2010
   (use (match_operand:SI 3 "register_operand" "r"))]
2011
  "TARGET_SHMEDIA"
2012
  "#"
2013
  "&& (high_life_started || reload_completed)"
2014
  [(set (match_dup 0) (match_dup 3))]
2015
  ""
2016
  [(set_attr "highpart" "must_split")])
2017
 
2018
;; This is the combiner pattern for -mdiv=inv:call .
2019
(define_insn_and_split "*divsi_inv_call_combine"
2020
  [(set (match_operand:SI 0 "register_operand" "=z")
2021
        (div:SI (match_operand:SI 1 "register_operand" "r")
2022
                (match_operand:SI 2 "register_operand" "r")))
2023
   (clobber (reg:SI R4_REG))
2024
   (clobber (reg:SI R5_REG))
2025
   (clobber (reg:SI T_MEDIA_REG))
2026
   (clobber (reg:SI PR_MEDIA_REG))
2027
   (clobber (reg:SI R1_REG))
2028
   (clobber (reg:SI R21_REG))
2029
   (clobber (reg:SI TR0_REG))
2030
   (clobber (reg:SI R20_REG))
2031
   (use (unspec:SI [(match_dup 1)
2032
                    (match_operand:SI 3 "" "")
2033
                    (unspec:SI [(match_operand:SI 4 "" "")
2034
                                (match_dup 3)
2035
                                (match_operand:DI 5 "" "")]
2036
                     UNSPEC_DIV_INV_M2)
2037
                    (match_operand:DI 6 "" "")
2038
                    (const_int 0)
2039
                    (const_int 0)]
2040
         UNSPEC_DIV_INV_M3))]
2041
  "TARGET_SHMEDIA"
2042
  "#"
2043
  "&& (high_life_started || reload_completed)"
2044
  [(pc)]
2045
  "
2046
{
2047
  const char *name = sh_divsi3_libfunc;
2048
  enum sh_function_kind kind = SFUNC_GOT;
2049
  rtx sym;
2050
 
2051
  emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2052
  emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2053
  while (TARGET_DIVIDE_INV_CALL2)
2054
    {
2055
      rtx x = operands[3];
2056
 
2057
      if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2058
        break;
2059
      x = XVECEXP (x, 0, 0);
2060
      name = \"__sdivsi3_2\";
2061
      kind = SFUNC_STATIC;
2062
      emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2063
      break;
2064
    }
2065
  sym = function_symbol (NULL, name, kind);
2066
  emit_insn (gen_divsi3_media_2 (operands[0], sym));
2067
  DONE;
2068
}"
2069
  [(set_attr "highpart" "must_split")])
2070
 
2071
(define_expand "divsi3_i4_media"
2072
  [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2073
   (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2074
   (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2075
   (set (match_operand:SI 0 "register_operand" "=r")
2076
        (fix:SI (match_dup 5)))]
2077
  "TARGET_SHMEDIA_FPU"
2078
  "
2079
{
2080
  operands[3] = gen_reg_rtx (DFmode);
2081
  operands[4] = gen_reg_rtx (DFmode);
2082
  operands[5] = gen_reg_rtx (DFmode);
2083
}")
2084
 
2085
(define_insn "divsi3_i4"
2086
  [(set (match_operand:SI 0 "register_operand" "=y")
2087
        (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2088
   (clobber (reg:SI PR_REG))
2089
   (clobber (reg:DF DR0_REG))
2090
   (clobber (reg:DF DR2_REG))
2091
   (use (reg:PSI FPSCR_REG))
2092
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2093
  "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2094
  "jsr  @%1%#"
2095
  [(set_attr "type" "sfunc")
2096
   (set_attr "fp_mode" "double")
2097
   (set_attr "needs_delay_slot" "yes")])
2098
 
2099
(define_insn "divsi3_i4_single"
2100
  [(set (match_operand:SI 0 "register_operand" "=y")
2101
        (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2102
   (clobber (reg:SI PR_REG))
2103
   (clobber (reg:DF DR0_REG))
2104
   (clobber (reg:DF DR2_REG))
2105
   (clobber (reg:SI R2_REG))
2106
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2107
  "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2108
  "jsr  @%1%#"
2109
  [(set_attr "type" "sfunc")
2110
   (set_attr "needs_delay_slot" "yes")])
2111
 
2112
(define_insn "divsi3_i4_int"
2113
  [(set (match_operand:SI 0 "register_operand" "=z")
2114
        (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2115
   (clobber (reg:SI T_REG))
2116
   (clobber (reg:SI PR_REG))
2117
   (clobber (reg:SI R1_REG))
2118
   (clobber (reg:SI MACH_REG))
2119
   (clobber (reg:SI MACL_REG))
2120
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2121
  "TARGET_SH1"
2122
  "jsr  @%1%#"
2123
  [(set_attr "type" "sfunc")
2124
   (set_attr "needs_delay_slot" "yes")])
2125
 
2126
(define_expand "divsi3"
2127
  [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2128
   (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2129
   (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2130
   (parallel [(set (match_operand:SI 0 "register_operand" "")
2131
                   (div:SI (reg:SI R4_REG)
2132
                           (reg:SI R5_REG)))
2133
              (clobber (reg:SI T_REG))
2134
              (clobber (reg:SI PR_REG))
2135
              (clobber (reg:SI R1_REG))
2136
              (clobber (reg:SI R2_REG))
2137
              (clobber (reg:SI R3_REG))
2138
              (use (match_dup 3))])]
2139
  ""
2140
  "
2141
{
2142
  rtx last;
2143
 
2144
  operands[3] = gen_reg_rtx (Pmode);
2145
  /* Emit the move of the address to a pseudo outside of the libcall.  */
2146
  if (TARGET_DIVIDE_CALL_TABLE)
2147
    {
2148
      function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2149
      last = gen_divsi3_i4_int (operands[0], operands[3]);
2150
    }
2151
  else if (TARGET_DIVIDE_CALL_FP)
2152
    {
2153
      function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2154
      if (TARGET_FPU_SINGLE)
2155
        last = gen_divsi3_i4_single (operands[0], operands[3]);
2156
      else
2157
        last = gen_divsi3_i4 (operands[0], operands[3]);
2158
    }
2159
  else if (TARGET_SH2A)
2160
    {
2161
      operands[1] = force_reg (SImode, operands[1]);
2162
      operands[2] = force_reg (SImode, operands[2]);
2163
      emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2164
      DONE;
2165
    }
2166
  else if (TARGET_DIVIDE_INV)
2167
    {
2168
      rtx dividend = operands[1];
2169
      rtx divisor = operands[2];
2170
      rtx tab_base;
2171
      rtx nsb_res = gen_reg_rtx (DImode);
2172
      rtx norm64 = gen_reg_rtx (DImode);
2173
      rtx tab_ix = gen_reg_rtx (DImode);
2174
      rtx norm32 = gen_reg_rtx (SImode);
2175
      rtx i92 = force_reg (DImode, GEN_INT (92));
2176
      rtx scratch0a = gen_reg_rtx (DImode);
2177
      rtx scratch0b = gen_reg_rtx (DImode);
2178
      rtx inv0 = gen_reg_rtx (SImode);
2179
      rtx scratch1a = gen_reg_rtx (DImode);
2180
      rtx scratch1b = gen_reg_rtx (DImode);
2181
      rtx shift = gen_reg_rtx (DImode);
2182
      rtx i2p27, i43;
2183
      rtx inv1 = gen_reg_rtx (SImode);
2184
      rtx scratch2a = gen_reg_rtx (DImode);
2185
      rtx scratch2b = gen_reg_rtx (SImode);
2186
      rtx inv2 = gen_reg_rtx (SImode);
2187
      rtx scratch3a = gen_reg_rtx (DImode);
2188
      rtx scratch3b = gen_reg_rtx (DImode);
2189
      rtx scratch3c = gen_reg_rtx (DImode);
2190
      rtx scratch3d = gen_reg_rtx (SImode);
2191
      rtx scratch3e = gen_reg_rtx (DImode);
2192
      rtx result = gen_reg_rtx (SImode);
2193
 
2194
      if (! arith_reg_or_0_operand (dividend, SImode))
2195
        dividend = force_reg (SImode, dividend);
2196
      if (! arith_reg_operand (divisor, SImode))
2197
        divisor = force_reg (SImode, divisor);
2198
      if (flag_pic && Pmode != DImode)
2199
        {
2200
          tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2201
          tab_base = gen_datalabel_ref (tab_base);
2202
          tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2203
        }
2204
      else
2205
        {
2206
          tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2207
          tab_base = gen_datalabel_ref (tab_base);
2208
          tab_base = force_reg (DImode, tab_base);
2209
        }
2210
      if (TARGET_DIVIDE_INV20U)
2211
        i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2212
      else
2213
        i2p27 = GEN_INT (0);
2214
      if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2215
        i43 = force_reg (DImode, GEN_INT (43));
2216
      else
2217
        i43 = GEN_INT (0);
2218
      emit_insn (gen_nsbdi (nsb_res,
2219
                            simplify_gen_subreg (DImode, divisor, SImode, 0)));
2220
      emit_insn (gen_ashldi3_media (norm64,
2221
                                    gen_rtx_SUBREG (DImode, divisor, 0),
2222
                                    nsb_res));
2223
      emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2224
      emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2225
      emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2226
                                   inv0, scratch0a, scratch0b,
2227
                                   scratch1a, scratch1b));
2228
      emit_insn (gen_subdi3 (shift, i92, nsb_res));
2229
      emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2230
                                   scratch2a));
2231
      emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2232
                                   i2p27, i43,
2233
                                   scratch3a, scratch3b, scratch3c,
2234
                                   scratch2a, scratch2b, scratch3d, scratch3e));
2235
      if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2236
        emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2237
      else if (TARGET_DIVIDE_INV_FP)
2238
        emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2239
                                     gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2240
                                     gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2241
                                     gen_reg_rtx (DFmode)));
2242
      else
2243
        emit_move_insn (operands[0], result);
2244
      DONE;
2245
    }
2246
  else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2247
    {
2248
      operands[1] = force_reg (SImode, operands[1]);
2249
      operands[2] = force_reg (SImode, operands[2]);
2250
      emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2251
      DONE;
2252
    }
2253
  else if (TARGET_SH5)
2254
    {
2255
      if (TARGET_DIVIDE_CALL2)
2256
        {
2257
          rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2258
          tab_base = gen_datalabel_ref (tab_base);
2259
          emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2260
        }
2261
      if (TARGET_FPU_ANY && TARGET_SH1)
2262
        function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2263
      else if (TARGET_DIVIDE_CALL2)
2264
        function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2265
      else
2266
        function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2267
 
2268
      if (TARGET_SHMEDIA)
2269
        last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2270
                (operands[0], operands[3]));
2271
      else if (TARGET_FPU_ANY)
2272
        last = gen_divsi3_i4_single (operands[0], operands[3]);
2273
      else
2274
        last = gen_divsi3_i1 (operands[0], operands[3]);
2275
    }
2276
  else
2277
    {
2278
      function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2279
      last = gen_divsi3_i1 (operands[0], operands[3]);
2280
    }
2281
  emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2282
  emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2283
  emit_insn (last);
2284
  DONE;
2285
}")
2286
 
2287
;; operands: scratch, tab_base, tab_ix
2288
;; These are unspecs because we could generate an indexed addressing mode
2289
;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2290
;; confuse reload.  See PR27117.
2291
 
2292
(define_insn "divsi_inv_qitable"
2293
  [(set (match_operand:DI 0 "register_operand" "=r")
2294
        (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2295
                                    (match_operand:DI 2 "register_operand" "r")]
2296
                         UNSPEC_DIV_INV_TABLE)))]
2297
  "TARGET_SHMEDIA"
2298
  "@
2299
        ldx.ub  %1, %2, %0"
2300
  [(set_attr "type" "load_media")
2301
   (set_attr "highpart" "user")])
2302
 
2303
;; operands: scratch, tab_base, tab_ix
2304
(define_insn "divsi_inv_hitable"
2305
  [(set (match_operand:DI 0 "register_operand" "=r")
2306
        (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2307
                                    (match_operand:DI 2 "register_operand" "r")]
2308
                         UNSPEC_DIV_INV_TABLE)))]
2309
  "TARGET_SHMEDIA"
2310
  "@
2311
        ldx.w   %1, %2, %0"
2312
  [(set_attr "type" "load_media")
2313
   (set_attr "highpart" "user")])
2314
 
2315
;; operands: inv0, tab_base, tab_ix, norm32
2316
;; scratch equiv in sdivsi3_2: r19, r21
2317
(define_expand "divsi_inv_m0"
2318
  [(set (match_operand:SI 0 "register_operand" "=r")
2319
        (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2320
                    (match_operand:DI 2 "register_operand" "r")
2321
                    (match_operand:SI 3 "register_operand" "r")]
2322
         UNSPEC_DIV_INV_M0))
2323
   (clobber (match_operand:DI 4 "register_operand" "=r"))
2324
   (clobber (match_operand:DI 5 "register_operand" "=r"))]
2325
  "TARGET_SHMEDIA"
2326
  "
2327
{
2328
/*
2329
tab_base: r20
2330
tab_ix: r21
2331
norm32: r25
2332
 ldx.ub r20, r21, r19 // u0.8
2333
 shlli r21, 1, r21
2334
 muls.l r25, r19, r19 // s2.38
2335
 ldx.w r20, r21, r21  // s2.14
2336
 shari r19, 24, r19   // truncate to s2.14
2337
 sub r21, r19, r19    // some 11 bit inverse in s1.14
2338
*/
2339
 
2340
  rtx inv0 = operands[0];
2341
  rtx tab_base = operands[1];
2342
  rtx tab_ix = operands[2];
2343
  rtx norm32 = operands[3];
2344
  rtx scratch0 = operands[4];
2345
  rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2346
  rtx scratch1 = operands[5];
2347
 
2348
  emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2349
  emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2350
  emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2351
  emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2352
  emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2353
  emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2354
  DONE;
2355
}")
2356
 
2357
;; operands: inv1, tab_base, tab_ix, norm32
2358
(define_insn_and_split "divsi_inv_m1"
2359
  [(set (match_operand:SI 0 "register_operand" "=r")
2360
        (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2361
                    (match_operand:DI 2 "register_operand" "r")
2362
                    (match_operand:SI 3 "register_operand" "r")]
2363
         UNSPEC_DIV_INV_M1))
2364
   (clobber (match_operand:SI 4 "register_operand" "=r"))
2365
   (clobber (match_operand:DI 5 "register_operand" "=r"))
2366
   (clobber (match_operand:DI 6 "register_operand" "=r"))
2367
   (clobber (match_operand:DI 7 "register_operand" "=r"))
2368
   (clobber (match_operand:DI 8 "register_operand" "=r"))]
2369
  "TARGET_SHMEDIA"
2370
  "#"
2371
  "&& !can_create_pseudo_p ()"
2372
  [(pc)]
2373
  "
2374
{
2375
/* inv0: r19
2376
 muls.l r19, r19, r18 // u0.28
2377
 muls.l r25, r18, r18 // s2.58
2378
 shlli r19, 45, r0    // multiply by two and convert to s2.58
2379
 sub r0, r18, r18
2380
 shari r18, 28, r18   // some 18 bit inverse in s1.30
2381
*/
2382
 
2383
  rtx inv1 = operands[0];
2384
  rtx tab_base = operands[1];
2385
  rtx tab_ix = operands[2];
2386
  rtx norm32 = operands[3];
2387
  rtx inv0 = operands[4];
2388
  rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2389
  rtx scratch0a = operands[5];
2390
  rtx scratch0b = operands[6];
2391
  rtx scratch0 = operands[7];
2392
  rtx scratch1 = operands[8];
2393
  rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2394
 
2395
  emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2396
                               scratch0a, scratch0b));
2397
  emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2398
  emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2399
  emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2400
  emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2401
  emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2402
  DONE;
2403
}")
2404
 
2405
;; operands: inv2, norm32, inv1, i92
2406
(define_insn_and_split "divsi_inv_m2"
2407
  [(set (match_operand:SI 0 "register_operand" "=r")
2408
        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2409
                    (match_operand:SI 2 "register_operand" "r")
2410
                    (match_operand:DI 3 "register_operand" "r")]
2411
         UNSPEC_DIV_INV_M2))
2412
   (clobber (match_operand:DI 4 "register_operand" "=r"))]
2413
  "TARGET_SHMEDIA"
2414
  "#"
2415
  "&& !can_create_pseudo_p ()"
2416
  [(pc)]
2417
  "
2418
{
2419
/*
2420
 muls.l r18, r25, r0  // s2.60
2421
 shari r0, 16, r0     // s-16.44
2422
  sub
2423
 muls.l r0, r18, r19  // s-16.74
2424
 shari r19, 30, r19   // s-16.44
2425
*/
2426
  rtx inv2 = operands[0];
2427
  rtx norm32 = operands[1];
2428
  rtx inv1 = operands[2];
2429
  rtx i92 = operands[3];
2430
  rtx scratch0 = operands[4];
2431
  rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2432
 
2433
  emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2434
  emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2435
  emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2436
  emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2437
  emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2438
  DONE;
2439
}")
2440
 
2441
(define_insn_and_split "divsi_inv_m3"
2442
  [(set (match_operand:SI 0 "register_operand" "=r")
2443
        (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2444
                    (match_operand:SI 2 "register_operand" "r")
2445
                    (match_operand:SI 3 "register_operand" "r")
2446
                    (match_operand:DI 4 "register_operand" "r")
2447
                    (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2448
                    (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2449
         UNSPEC_DIV_INV_M3))
2450
   (clobber (match_operand:DI 7 "register_operand" "=r"))
2451
   (clobber (match_operand:DI 8 "register_operand" "=r"))
2452
   (clobber (match_operand:DI 9 "register_operand" "=r"))
2453
   (clobber (match_operand:DI 10 "register_operand" "=r"))
2454
   (clobber (match_operand:SI 11 "register_operand" "=r"))
2455
   (clobber (match_operand:SI 12 "register_operand" "=r"))
2456
   (clobber (match_operand:DI 13 "register_operand" "=r"))]
2457
  "TARGET_SHMEDIA"
2458
  "#"
2459
  "&& !can_create_pseudo_p ()"
2460
  [(pc)]
2461
  "
2462
{
2463
/*
2464
  r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2465
  r0: scratch0  r19: scratch1 r21: scratch2
2466
 
2467
  muls.l r18, r4, r25 // s32.30
2468
 muls.l r19, r4, r19  // s15.30
2469
 shari r25, 63, r21
2470
  shari r19, 14, r19  // s18.-14
2471
 sub r25, r19, r0
2472
 shard r0, r1, r0
2473
 sub r0, r21, r0
2474
*/
2475
 
2476
  rtx result = operands[0];
2477
  rtx dividend = operands[1];
2478
  rtx inv1 = operands[2];
2479
  rtx inv2 = operands[3];
2480
  rtx shift = operands[4];
2481
  rtx scratch0 = operands[7];
2482
  rtx scratch1 = operands[8];
2483
  rtx scratch2 = operands[9];
2484
 
2485
  if (satisfies_constraint_N (dividend))
2486
    {
2487
      emit_move_insn (result, dividend);
2488
      DONE;
2489
    }
2490
 
2491
  emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2492
  emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2493
  emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2494
  emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2495
  emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2496
  emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2497
  emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2498
  DONE;
2499
}")
2500
 
2501
;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2502
;; inv1: tab_base, tab_ix, norm32
2503
;; inv2: norm32, inv1, i92
2504
(define_insn_and_split "divsi_inv_m1_3"
2505
  [(set (match_operand:SI 0 "register_operand" "=r")
2506
        (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2507
                    (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2508
                                (match_operand:DI 3 "register_operand" "r")
2509
                                (match_operand:SI 4 "register_operand" "r")]
2510
                     UNSPEC_DIV_INV_M1)
2511
                    (unspec:SI [(match_dup 4)
2512
                                (unspec:SI [(match_dup 2)
2513
                                            (match_dup 3)
2514
                                            (match_dup 4)] UNSPEC_DIV_INV_M1)
2515
                                (match_operand:SI 5 "" "")]
2516
                     UNSPEC_DIV_INV_M2)
2517
                    (match_operand:DI 6 "register_operand" "r")
2518
                    (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2519
                    (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2520
         UNSPEC_DIV_INV_M3))
2521
   (clobber (match_operand:DI 9 "register_operand" "=r"))
2522
   (clobber (match_operand:DI 10 "register_operand" "=r"))
2523
   (clobber (match_operand:DI 11 "register_operand" "=r"))
2524
   (clobber (match_operand:DI 12 "register_operand" "=r"))
2525
   (clobber (match_operand:SI 13 "register_operand" "=r"))
2526
   (clobber (match_operand:SI 14 "register_operand" "=r"))
2527
   (clobber (match_operand:DI 15 "register_operand" "=r"))]
2528
  "TARGET_SHMEDIA
2529
   && (TARGET_DIVIDE_INV_MINLAT
2530
       || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2531
  "#"
2532
  "&& !can_create_pseudo_p ()"
2533
  [(pc)]
2534
  "
2535
{
2536
  rtx result = operands[0];
2537
  rtx dividend = operands[1];
2538
  rtx tab_base = operands[2];
2539
  rtx tab_ix = operands[3];
2540
  rtx norm32 = operands[4];
2541
  /* rtx i92 = operands[5]; */
2542
  rtx shift = operands[6];
2543
  rtx i2p27 = operands[7];
2544
  rtx i43 = operands[8];
2545
  rtx scratch0 = operands[9];
2546
  rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2547
  rtx scratch1 = operands[10];
2548
  rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2549
  rtx scratch2 = operands[11];
2550
  rtx scratch3 = operands[12];
2551
  rtx scratch4 = operands[13];
2552
  rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2553
  rtx scratch5 = operands[14];
2554
  rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2555
  rtx scratch6 = operands[15];
2556
 
2557
  emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2558
                               scratch0, scratch1));
2559
  /* inv0 == scratch4 */
2560
  if (! TARGET_DIVIDE_INV20U)
2561
    {
2562
      emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2563
      i2p27 = scratch0;
2564
      emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2565
    }
2566
  else
2567
    {
2568
      emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2569
      emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2570
    }
2571
  emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2572
  emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2573
  emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2574
  /* inv1 == scratch4 */
2575
 
2576
  if (TARGET_DIVIDE_INV_MINLAT)
2577
    {
2578
      emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2579
      emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2580
      emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2581
      emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2582
      emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2583
      emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2584
      emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2585
      emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2586
      emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2587
      emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2588
      emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2589
    }
2590
  else
2591
    {
2592
      rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2593
      /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2594
      emit_insn (gen_nsbdi (scratch6,
2595
                            simplify_gen_subreg (DImode, dividend, SImode, 0)));
2596
      emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2597
      emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2598
      emit_insn (gen_divsi_inv20 (scratch2,
2599
                                  norm32, scratch4, dividend,
2600
                                  scratch6, scratch3, i43,
2601
                                  /* scratch0 may be shared with i2p27.  */
2602
                                  scratch0, scratch1, scratch5,
2603
                                  label, label, i2p27));
2604
    }
2605
  emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2606
  emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2607
  DONE;
2608
}")
2609
 
2610
(define_insn "divsi_inv20"
2611
  [(set (match_operand:DI 0 "register_operand" "=&r")
2612
        (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2613
                    (match_operand:SI 2 "register_operand" "r")
2614
                    (match_operand:SI 3 "register_operand" "r")
2615
                    (match_operand:DI 4 "register_operand" "r")
2616
                    (match_operand:DI 5 "register_operand" "r")
2617
                    (match_operand:DI 6 "register_operand" "r")
2618
                    (match_operand:DI 12 "register_operand" "r")
2619
                    (match_operand 10 "target_operand" "b")
2620
                    (match_operand 11 "immediate_operand" "i")]
2621
         UNSPEC_DIV_INV20))
2622
   (clobber (match_operand:DI 7 "register_operand" "=&r"))
2623
   (clobber (match_operand:DI 8 "register_operand" "=&r"))
2624
   (clobber (match_operand:SI 9 "register_operand" "=r"))]
2625
  "TARGET_SHMEDIA
2626
   && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2627
  "*
2628
{
2629
/* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2630
             %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2631
             %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2632
             %10 label (tr), %11 label (imm)
2633
 
2634
 muls.l inv1, norm32, scratch0  // s2.60
2635
  muls.l inv1, dividend, result // s32.30
2636
  xor i2p27, result_sign, round_scratch
2637
 bge/u dividend_nsb, i43, tr.. (label)
2638
 shari scratch0, 16, scratch0   // s-16.44
2639
 muls.l sratch0_si, inv1, scratch0 // s-16.74
2640
  sub result, round_scratch, result
2641
  shari dividend, 14, scratch1   // s19.-14
2642
 shari scratch0, 30, scratch0   // s-16.44
2643
 muls.l scratch0, scratch1, round_scratch // s15.30
2644
label:
2645
 sub result, round_scratch, result */
2646
 
2647
  int likely = TARGET_DIVIDE_INV20L;
2648
 
2649
  if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2650
  output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2651
  output_asm_insn (likely
2652
                   ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2653
                   : \"bge/u\t%4, %6, %10\", operands);
2654
  output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2655
  if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2656
  output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2657
  return (likely
2658
          ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2659
          : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2660
}")
2661
 
2662
(define_insn_and_split "divsi_inv_fp"
2663
  [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2664
        (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2665
                (match_operand:SI 2 "register_operand" "rf")))
2666
   (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2667
   (clobber (match_operand:SI 4 "register_operand" "=r"))
2668
   (clobber (match_operand:SI 5 "register_operand" "=r"))
2669
   (clobber (match_operand:DF 6 "register_operand" "=r"))
2670
   (clobber (match_operand:DF 7 "register_operand" "=r"))
2671
   (clobber (match_operand:DF 8 "register_operand" "=r"))]
2672
  "TARGET_SHMEDIA_FPU"
2673
  "#"
2674
  "&& (high_life_started || reload_completed)"
2675
  [(set (match_dup 0) (match_dup 3))]
2676
  ""
2677
  [(set_attr "highpart" "must_split")])
2678
 
2679
;; If a matching group of divide-by-inverse instructions is in the same
2680
;; basic block after gcse & loop optimizations, we want to transform them
2681
;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2682
(define_insn_and_split "*divsi_inv_fp_combine"
2683
  [(set (match_operand:SI 0 "register_operand" "=f")
2684
        (div:SI (match_operand:SI 1 "register_operand" "f")
2685
                (match_operand:SI 2 "register_operand" "f")))
2686
   (use (unspec:SI [(match_dup 1)
2687
                    (match_operand:SI 3 "" "")
2688
                    (unspec:SI [(match_operand:SI 4 "" "")
2689
                                (match_dup 3)
2690
                                (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2691
                    (match_operand:DI 6 "" "")
2692
                    (const_int 0)
2693
                    (const_int 0)] UNSPEC_DIV_INV_M3))
2694
   (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2695
   (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2696
   (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2697
   (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2698
   (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2699
  "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2700
  "#"
2701
  "&& 1"
2702
  [(set (match_dup 9) (float:DF (match_dup 1)))
2703
   (set (match_dup 10) (float:DF (match_dup 2)))
2704
   (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2705
   (set (match_dup 8)
2706
        (fix:SI (match_dup 11)))
2707
   (set (match_dup 0) (match_dup 8))]
2708
  "
2709
{
2710
  if (! fp_arith_reg_operand (operands[1], SImode))
2711
    {
2712
      emit_move_insn (operands[7], operands[1]);
2713
      operands[1] = operands[7];
2714
    }
2715
  if (! fp_arith_reg_operand (operands[2], SImode))
2716
    {
2717
      emit_move_insn (operands[8], operands[2]);
2718
      operands[2] = operands[8];
2719
    }
2720
}"
2721
  [(set_attr "highpart" "must_split")])
2722
 
2723
;; -------------------------------------------------------------------------
2724
;; Multiplication instructions
2725
;; -------------------------------------------------------------------------
2726
 
2727
(define_insn "umulhisi3_i"
2728
  [(set (reg:SI MACL_REG)
2729
        (mult:SI (zero_extend:SI
2730
                  (match_operand:HI 0 "arith_reg_operand" "r"))
2731
                 (zero_extend:SI
2732
                  (match_operand:HI 1 "arith_reg_operand" "r"))))]
2733
  "TARGET_SH1"
2734
  "mulu.w       %1,%0"
2735
  [(set_attr "type" "smpy")])
2736
 
2737
(define_insn "mulhisi3_i"
2738
  [(set (reg:SI MACL_REG)
2739
        (mult:SI (sign_extend:SI
2740
                  (match_operand:HI 0 "arith_reg_operand" "r"))
2741
                 (sign_extend:SI
2742
                  (match_operand:HI 1 "arith_reg_operand" "r"))))]
2743
  "TARGET_SH1"
2744
  "muls.w       %1,%0"
2745
  [(set_attr "type" "smpy")])
2746
 
2747
(define_expand "mulhisi3"
2748
  [(set (reg:SI MACL_REG)
2749
        (mult:SI (sign_extend:SI
2750
                  (match_operand:HI 1 "arith_reg_operand" ""))
2751
                 (sign_extend:SI
2752
                  (match_operand:HI 2 "arith_reg_operand" ""))))
2753
   (set (match_operand:SI 0 "arith_reg_operand" "")
2754
        (reg:SI MACL_REG))]
2755
  "TARGET_SH1"
2756
  "
2757
{
2758
  rtx insn, macl;
2759
 
2760
  macl = gen_rtx_REG (SImode, MACL_REG);
2761
  start_sequence ();
2762
  emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2763
  insn = get_insns ();
2764
  end_sequence ();
2765
  /* expand_binop can't find a suitable code in umul_widen_optab to
2766
     make a REG_EQUAL note from, so make one here.
2767
     See also smulsi3_highpart.
2768
     ??? Alternatively, we could put this at the calling site of expand_binop,
2769
     i.e. expand_expr.  */
2770
  /* Use emit_libcall_block for loop invariant code motion and to make
2771
     a REG_EQUAL note.  */
2772
  emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2773
 
2774
  DONE;
2775
}")
2776
 
2777
(define_expand "umulhisi3"
2778
  [(set (reg:SI MACL_REG)
2779
        (mult:SI (zero_extend:SI
2780
                  (match_operand:HI 1 "arith_reg_operand" ""))
2781
                 (zero_extend:SI
2782
                  (match_operand:HI 2 "arith_reg_operand" ""))))
2783
   (set (match_operand:SI 0 "arith_reg_operand" "")
2784
        (reg:SI MACL_REG))]
2785
  "TARGET_SH1"
2786
  "
2787
{
2788
  rtx insn, macl;
2789
 
2790
  macl = gen_rtx_REG (SImode, MACL_REG);
2791
  start_sequence ();
2792
  emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2793
  insn = get_insns ();
2794
  end_sequence ();
2795
  /* expand_binop can't find a suitable code in umul_widen_optab to
2796
     make a REG_EQUAL note from, so make one here.
2797
     See also smulsi3_highpart.
2798
     ??? Alternatively, we could put this at the calling site of expand_binop,
2799
     i.e. expand_expr.  */
2800
  /* Use emit_libcall_block for loop invariant code motion and to make
2801
     a REG_EQUAL note.  */
2802
  emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2803
 
2804
  DONE;
2805
}")
2806
 
2807
;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2808
;; a call to a routine which clobbers known registers.
2809
 
2810
(define_insn ""
2811
  [(set (match_operand:SI 1 "register_operand" "=z")
2812
        (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2813
   (clobber (reg:SI MACL_REG))
2814
   (clobber (reg:SI T_REG))
2815
   (clobber (reg:SI PR_REG))
2816
   (clobber (reg:SI R3_REG))
2817
   (clobber (reg:SI R2_REG))
2818
   (clobber (reg:SI R1_REG))
2819
   (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2820
  "TARGET_SH1"
2821
  "jsr  @%0%#"
2822
  [(set_attr "type" "sfunc")
2823
   (set_attr "needs_delay_slot" "yes")])
2824
 
2825
(define_expand "mulsi3_call"
2826
  [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2827
   (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2828
   (parallel[(set (match_operand:SI 0 "register_operand" "")
2829
                  (mult:SI (reg:SI R4_REG)
2830
                           (reg:SI R5_REG)))
2831
             (clobber (reg:SI MACL_REG))
2832
             (clobber (reg:SI T_REG))
2833
             (clobber (reg:SI PR_REG))
2834
             (clobber (reg:SI R3_REG))
2835
             (clobber (reg:SI R2_REG))
2836
             (clobber (reg:SI R1_REG))
2837
             (use (match_operand:SI 3 "register_operand" ""))])]
2838
  "TARGET_SH1"
2839
  "")
2840
 
2841
(define_insn "mul_r"
2842
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2843
        (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2844
                 (match_operand:SI 2 "arith_reg_operand" "z")))]
2845
  "TARGET_SH2A"
2846
  "mulr %2,%0"
2847
  [(set_attr "type" "dmpy")])
2848
 
2849
(define_insn "mul_l"
2850
  [(set (reg:SI MACL_REG)
2851
        (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2852
                 (match_operand:SI 1 "arith_reg_operand" "r")))]
2853
  "TARGET_SH2"
2854
  "mul.l        %1,%0"
2855
  [(set_attr "type" "dmpy")])
2856
 
2857
(define_expand "mulsi3"
2858
  [(set (reg:SI MACL_REG)
2859
        (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2860
                  (match_operand:SI 2 "arith_reg_operand" "")))
2861
   (set (match_operand:SI 0 "arith_reg_operand" "")
2862
        (reg:SI MACL_REG))]
2863
  "TARGET_SH1"
2864
  "
2865
{
2866
  if (!TARGET_SH2)
2867
    {
2868
      /* The address must be set outside the libcall,
2869
         since it goes into a pseudo.  */
2870
      rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2871
      rtx addr = force_reg (SImode, sym);
2872
      rtx insns = gen_mulsi3_call (operands[0], operands[1],
2873
                                   operands[2], addr);
2874
      emit_insn (insns);
2875
    }
2876
  else
2877
    {
2878
      rtx macl = gen_rtx_REG (SImode, MACL_REG);
2879
 
2880
      emit_insn (gen_mul_l (operands[1], operands[2]));
2881
      /* consec_sets_giv can only recognize the first insn that sets a
2882
         giv as the giv insn.  So we must tag this also with a REG_EQUAL
2883
         note.  */
2884
      emit_insn (gen_movsi_i ((operands[0]), macl));
2885
    }
2886
  DONE;
2887
}")
2888
 
2889
(define_insn "mulsidi3_i"
2890
  [(set (reg:SI MACH_REG)
2891
        (truncate:SI
2892
         (lshiftrt:DI
2893
          (mult:DI
2894
           (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2895
           (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2896
          (const_int 32))))
2897
   (set (reg:SI MACL_REG)
2898
        (mult:SI (match_dup 0)
2899
                 (match_dup 1)))]
2900
  "TARGET_SH2"
2901
  "dmuls.l      %1,%0"
2902
  [(set_attr "type" "dmpy")])
2903
 
2904
(define_expand "mulsidi3"
2905
  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2906
        (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2907
                 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2908
  "TARGET_SH2 || TARGET_SHMEDIA"
2909
  "
2910
{
2911
  if (TARGET_SH2)
2912
    {
2913
       emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2914
                                        operands[2]));
2915
       DONE;
2916
    }
2917
}")
2918
 
2919
(define_insn "mulsidi3_media"
2920
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2921
        (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2922
                 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2923
  "TARGET_SHMEDIA"
2924
  "muls.l       %1, %2, %0"
2925
  [(set_attr "type" "dmpy_media")
2926
   (set_attr "highpart" "ignore")])
2927
 
2928
(define_insn "mulsidi3_compact"
2929
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2930
        (mult:DI
2931
         (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2932
         (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2933
   (clobber (reg:SI MACH_REG))
2934
   (clobber (reg:SI MACL_REG))]
2935
  "TARGET_SH2"
2936
  "#")
2937
 
2938
(define_split
2939
  [(set (match_operand:DI 0 "arith_reg_dest" "")
2940
        (mult:DI
2941
         (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2942
         (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2943
   (clobber (reg:SI MACH_REG))
2944
   (clobber (reg:SI MACL_REG))]
2945
  "TARGET_SH2"
2946
  [(const_int 0)]
2947
  "
2948
{
2949
  rtx low_dst = gen_lowpart (SImode, operands[0]);
2950
  rtx high_dst = gen_highpart (SImode, operands[0]);
2951
 
2952
  emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2953
 
2954
  emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2955
  emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2956
  /* We need something to tag the possible REG_EQUAL notes on to.  */
2957
  emit_move_insn (operands[0], operands[0]);
2958
  DONE;
2959
}")
2960
 
2961
(define_insn "umulsidi3_i"
2962
  [(set (reg:SI MACH_REG)
2963
        (truncate:SI
2964
         (lshiftrt:DI
2965
          (mult:DI
2966
           (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2967
           (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2968
          (const_int 32))))
2969
   (set (reg:SI MACL_REG)
2970
        (mult:SI (match_dup 0)
2971
                 (match_dup 1)))]
2972
  "TARGET_SH2"
2973
  "dmulu.l      %1,%0"
2974
  [(set_attr "type" "dmpy")])
2975
 
2976
(define_expand "umulsidi3"
2977
  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2978
        (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2979
                 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2980
  "TARGET_SH2 || TARGET_SHMEDIA"
2981
  "
2982
{
2983
  if (TARGET_SH2)
2984
    {
2985
       emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2986
                                         operands[2]));
2987
       DONE;
2988
    }
2989
}")
2990
 
2991
(define_insn "umulsidi3_media"
2992
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2993
        (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2994
                 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2995
  "TARGET_SHMEDIA"
2996
  "mulu.l       %1, %2, %0"
2997
  [(set_attr "type" "dmpy_media")
2998
   (set_attr "highpart" "ignore")])
2999
 
3000
(define_insn "umulsidi3_compact"
3001
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3002
        (mult:DI
3003
         (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3004
         (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3005
   (clobber (reg:SI MACH_REG))
3006
   (clobber (reg:SI MACL_REG))]
3007
  "TARGET_SH2"
3008
  "#")
3009
 
3010
(define_split
3011
  [(set (match_operand:DI 0 "arith_reg_dest" "")
3012
        (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3013
                 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3014
   (clobber (reg:SI MACH_REG))
3015
   (clobber (reg:SI MACL_REG))]
3016
  "TARGET_SH2"
3017
  [(const_int 0)]
3018
  "
3019
{
3020
  rtx low_dst = gen_lowpart (SImode, operands[0]);
3021
  rtx high_dst = gen_highpart (SImode, operands[0]);
3022
 
3023
  emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3024
 
3025
  emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3026
  emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3027
  /* We need something to tag the possible REG_EQUAL notes on to.  */
3028
  emit_move_insn (operands[0], operands[0]);
3029
  DONE;
3030
}")
3031
 
3032
(define_insn "smulsi3_highpart_i"
3033
  [(set (reg:SI MACH_REG)
3034
        (truncate:SI
3035
         (lshiftrt:DI
3036
          (mult:DI
3037
           (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3038
           (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3039
          (const_int 32))))
3040
   (clobber (reg:SI MACL_REG))]
3041
  "TARGET_SH2"
3042
  "dmuls.l      %1,%0"
3043
  [(set_attr "type" "dmpy")])
3044
 
3045
(define_expand "smulsi3_highpart"
3046
  [(parallel
3047
    [(set (reg:SI MACH_REG)
3048
          (truncate:SI
3049
           (lshiftrt:DI
3050
            (mult:DI
3051
             (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3052
             (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3053
            (const_int 32))))
3054
    (clobber (reg:SI MACL_REG))])
3055
   (set (match_operand:SI 0 "arith_reg_operand" "")
3056
        (reg:SI MACH_REG))]
3057
  "TARGET_SH2"
3058
  "
3059
{
3060
  rtx insn, mach;
3061
 
3062
  mach = gen_rtx_REG (SImode, MACH_REG);
3063
  start_sequence ();
3064
  emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3065
  insn = get_insns ();
3066
  end_sequence ();
3067
  /* expand_binop can't find a suitable code in mul_highpart_optab to
3068
     make a REG_EQUAL note from, so make one here.
3069
     See also {,u}mulhisi.
3070
     ??? Alternatively, we could put this at the calling site of expand_binop,
3071
     i.e. expand_mult_highpart.  */
3072
  /* Use emit_libcall_block for loop invariant code motion and to make
3073
     a REG_EQUAL note.  */
3074
  emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3075
 
3076
  DONE;
3077
}")
3078
 
3079
(define_insn "umulsi3_highpart_i"
3080
  [(set (reg:SI MACH_REG)
3081
        (truncate:SI
3082
         (lshiftrt:DI
3083
          (mult:DI
3084
           (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3085
           (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3086
          (const_int 32))))
3087
   (clobber (reg:SI MACL_REG))]
3088
  "TARGET_SH2"
3089
  "dmulu.l      %1,%0"
3090
  [(set_attr "type" "dmpy")])
3091
 
3092
(define_expand "umulsi3_highpart"
3093
  [(parallel
3094
    [(set (reg:SI MACH_REG)
3095
          (truncate:SI
3096
           (lshiftrt:DI
3097
            (mult:DI
3098
             (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3099
             (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3100
            (const_int 32))))
3101
    (clobber (reg:SI MACL_REG))])
3102
   (set (match_operand:SI 0 "arith_reg_operand" "")
3103
        (reg:SI MACH_REG))]
3104
  "TARGET_SH2"
3105
  "
3106
{
3107
  rtx insn, mach;
3108
 
3109
  mach = gen_rtx_REG (SImode, MACH_REG);
3110
  start_sequence ();
3111
  emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3112
  insn = get_insns ();
3113
  end_sequence ();
3114
  /* Use emit_libcall_block for loop invariant code motion and to make
3115
     a REG_EQUAL note.  */
3116
  emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3117
 
3118
  DONE;
3119
}")
3120
 
3121
(define_insn_and_split "muldi3"
3122
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3123
        (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3124
                 (match_operand:DI 2 "arith_reg_operand" "r")))
3125
   (clobber (match_scratch:DI 3 "=&r"))
3126
   (clobber (match_scratch:DI 4 "=r"))]
3127
  "TARGET_SHMEDIA"
3128
  "#"
3129
  "reload_completed"
3130
  [(const_int 0)]
3131
  "
3132
{
3133
  rtx op3_v2si, op2_v2si;
3134
 
3135
  op3_v2si = operands[3];
3136
  if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3137
    {
3138
      op3_v2si = XEXP (op3_v2si, 0);
3139
      op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3140
    }
3141
  op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3142
  op2_v2si = operands[2];
3143
  if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3144
    {
3145
      op2_v2si = XEXP (op2_v2si, 0);
3146
      op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3147
    }
3148
  op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3149
  emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3150
  emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3151
  emit_insn (gen_umulsidi3_media (operands[4],
3152
                                 sh_gen_truncate (SImode, operands[1], 0),
3153
                                 sh_gen_truncate (SImode, operands[2], 0)));
3154
  emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3155
  emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3156
  emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3157
  emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3158
  DONE;
3159
}")
3160
 
3161
 
3162
;; -------------------------------------------------------------------------
3163
;; Logical operations
3164
;; -------------------------------------------------------------------------
3165
 
3166
(define_insn "*andsi3_compact"
3167
  [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3168
        (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3169
                (match_operand:SI 2 "logical_operand" "K08,r")))]
3170
  "TARGET_SH1"
3171
  "and  %2,%0"
3172
  [(set_attr "type" "arith")])
3173
 
3174
(define_insn "*andsi3_media"
3175
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3176
        (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3177
                (match_operand:SI 2 "logical_operand" "r,I10")))]
3178
  "TARGET_SHMEDIA"
3179
  "@
3180
        and     %1, %2, %0
3181
        andi    %1, %2, %0"
3182
  [(set_attr "type" "arith_media")])
3183
 
3184
(define_insn "*andsi3_bclr"
3185
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3186
        (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3187
                (match_operand:SI 2 "const_int_operand" "Psz")))]
3188
  "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3189
  "bclr\\t%W2,%0"
3190
  [(set_attr "type" "arith")])
3191
 
3192
;; If the constant is 255, then emit an extu.b instruction instead of an
3193
;; and, since that will give better code.
3194
 
3195
(define_expand "andsi3"
3196
  [(set (match_operand:SI 0 "arith_reg_operand" "")
3197
        (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3198
                (match_operand:SI 2 "logical_operand" "")))]
3199
  ""
3200
  "
3201
{
3202
  if (TARGET_SH1
3203
      && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3204
    {
3205
      emit_insn (gen_zero_extendqisi2 (operands[0],
3206
                                       gen_lowpart (QImode, operands[1])));
3207
      DONE;
3208
    }
3209
}")
3210
 
3211
(define_insn_and_split "anddi3"
3212
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3213
        (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3214
                (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3215
  "TARGET_SHMEDIA"
3216
  "@
3217
        and     %1, %2, %0
3218
        andi    %1, %2, %0
3219
        #"
3220
  "reload_completed
3221
   && ! logical_operand (operands[2], DImode)"
3222
  [(const_int 0)]
3223
  "
3224
{
3225
  if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3226
    emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3227
  else
3228
    emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3229
  DONE;
3230
}"
3231
  [(set_attr "type" "arith_media")])
3232
 
3233
(define_insn "andcsi3"
3234
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3235
        (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3236
                (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3237
  "TARGET_SHMEDIA"
3238
  "andc %1,%2,%0"
3239
  [(set_attr "type" "arith_media")])
3240
 
3241
(define_insn "andcdi3"
3242
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3243
        (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3244
                (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3245
  "TARGET_SHMEDIA"
3246
  "andc %1,%2,%0"
3247
  [(set_attr "type" "arith_media")])
3248
 
3249
(define_expand "iorsi3"
3250
  [(set (match_operand:SI 0 "arith_reg_operand" "")
3251
        (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3252
                (match_operand:SI 2 "logical_operand" "")))]
3253
  ""
3254
  "")
3255
 
3256
(define_insn "*iorsi3_compact"
3257
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3258
        (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3259
                (match_operand:SI 2 "logical_operand" "r,K08")))]
3260
  "TARGET_SH1
3261
   && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3262
  "or   %2,%0"
3263
  [(set_attr "type" "arith")])
3264
 
3265
(define_insn "*iorsi3_media"
3266
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3267
        (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3268
                (match_operand:SI 2 "logical_operand" "r,I10")))]
3269
  "TARGET_SHMEDIA"
3270
  "@
3271
        or      %1, %2, %0
3272
        ori     %1, %2, %0"
3273
  [(set_attr "type" "arith_media")])
3274
 
3275
(define_insn "*iorsi3_bset"
3276
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3277
        (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3278
        (match_operand:SI 2 "const_int_operand" "Pso")))]
3279
  "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3280
  "bset\\t%V2,%0"
3281
  [(set_attr "type" "arith")])
3282
 
3283
(define_insn "iordi3"
3284
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3285
        (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3286
                (match_operand:DI 2 "logical_operand" "r,I10")))]
3287
  "TARGET_SHMEDIA"
3288
  "@
3289
        or      %1, %2, %0
3290
        ori     %1, %2, %0"
3291
  [(set_attr "type" "arith_media")])
3292
 
3293
(define_insn_and_split "*logical_sidi3"
3294
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3295
        (sign_extend:DI (match_operator:SI 3 "logical_operator"
3296
                          [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3297
                           (match_operand:SI 2 "logical_operand" "r,I10")])))]
3298
  "TARGET_SHMEDIA"
3299
  "#"
3300
  "&& reload_completed"
3301
  [(set (match_dup 0) (match_dup 3))]
3302
  "
3303
{
3304
  operands[3]
3305
    = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3306
                      simplify_gen_subreg (DImode, operands[1], SImode, 0),
3307
                      simplify_gen_subreg (DImode, operands[2], SImode, 0));
3308
}")
3309
 
3310
(define_insn_and_split "*logical_sidisi3"
3311
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3312
        (truncate:SI (sign_extend:DI
3313
                        (match_operator:SI 3 "logical_operator"
3314
                          [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3315
                           (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3316
  "TARGET_SHMEDIA"
3317
  "#"
3318
  "&& 1"
3319
  [(set (match_dup 0) (match_dup 3))])
3320
 
3321
(define_insn_and_split "*logical_sidi3_2"
3322
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3323
        (sign_extend:DI (truncate:SI (sign_extend:DI
3324
                        (match_operator:SI 3 "logical_operator"
3325
                          [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3326
                           (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3327
  "TARGET_SHMEDIA"
3328
  "#"
3329
  "&& 1"
3330
  [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3331
 
3332
(define_expand "xorsi3"
3333
  [(set (match_operand:SI 0 "arith_reg_operand" "")
3334
        (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3335
                (match_operand:SI 2 "xor_operand" "")))]
3336
  ""
3337
  "")
3338
 
3339
(define_insn "*xorsi3_compact"
3340
  [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3341
        (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3342
                (match_operand:SI 2 "logical_operand" "K08,r")))]
3343
  "TARGET_SH1"
3344
  "xor  %2,%0"
3345
  [(set_attr "type" "arith")])
3346
 
3347
(define_insn "*xorsi3_media"
3348
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3349
        (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3350
                (match_operand:SI 2 "xor_operand" "r,I06")))]
3351
  "TARGET_SHMEDIA"
3352
  "@
3353
        xor     %1, %2, %0
3354
        xori    %1, %2, %0"
3355
  [(set_attr "type" "arith_media")])
3356
 
3357
;; Store the complements of the T bit in a register.
3358
(define_insn "xorsi3_movrt"
3359
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3360
        (xor:SI (reg:SI T_REG)
3361
                (const_int 1)))]
3362
  "TARGET_SH2A"
3363
  "movrt\\t%0"
3364
  [(set_attr "type" "arith")])
3365
 
3366
(define_insn "xordi3"
3367
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3368
        (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3369
                (match_operand:DI 2 "xor_operand" "r,I06")))]
3370
  "TARGET_SHMEDIA"
3371
  "@
3372
        xor     %1, %2, %0
3373
        xori    %1, %2, %0"
3374
  [(set_attr "type" "arith_media")])
3375
 
3376
;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3377
;; converts 2 * sign extend -> logical op into logical op -> sign extend
3378
(define_split
3379
  [(set (match_operand:DI 0 "arith_reg_dest" "")
3380
        (sign_extend:DI (match_operator 4 "binary_logical_operator"
3381
                          [(match_operand 1 "any_register_operand" "")
3382
                           (match_operand 2 "any_register_operand" "")])))]
3383
  "TARGET_SHMEDIA"
3384
  [(set (match_dup 5) (match_dup 4))
3385
   (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3386
"
3387
{
3388
  enum machine_mode inmode = GET_MODE (operands[1]);
3389
  int offset = 0;
3390
 
3391
  if (GET_CODE (operands[0]) == SUBREG)
3392
    {
3393
      offset = SUBREG_BYTE (operands[0]);
3394
      operands[0] = SUBREG_REG (operands[0]);
3395
    }
3396
  gcc_assert (REG_P (operands[0]));
3397
  if (! TARGET_LITTLE_ENDIAN)
3398
    offset += 8 - GET_MODE_SIZE (inmode);
3399
  operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3400
}")
3401
 
3402
;; -------------------------------------------------------------------------
3403
;; Shifts and rotates
3404
;; -------------------------------------------------------------------------
3405
 
3406
(define_expand "rotldi3"
3407
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3408
        (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3409
                   (match_operand:HI 2 "mextr_bit_offset" "i")))]
3410
  "TARGET_SHMEDIA"
3411
  "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3412
 
3413
(define_insn "rotldi3_mextr"
3414
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3415
        (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3416
                   (match_operand:HI 2 "mextr_bit_offset" "i")))]
3417
  "TARGET_SHMEDIA"
3418
  "*
3419
{
3420
  static char templ[16];
3421
 
3422
  sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3423
           8 - (int) (INTVAL (operands[2]) >> 3));
3424
  return templ;
3425
}"
3426
  [(set_attr "type" "arith_media")])
3427
 
3428
(define_expand "rotrdi3"
3429
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3430
        (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3431
                     (match_operand:HI 2 "mextr_bit_offset" "i")))]
3432
  "TARGET_SHMEDIA"
3433
  "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3434
 
3435
(define_insn "rotrdi3_mextr"
3436
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3437
        (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3438
                     (match_operand:HI 2 "mextr_bit_offset" "i")))]
3439
  "TARGET_SHMEDIA"
3440
  "*
3441
{
3442
  static char templ[16];
3443
 
3444
  sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3445
  return templ;
3446
}"
3447
  [(set_attr "type" "arith_media")])
3448
 
3449
(define_split
3450
  [(set (match_operand:DI 0 "arith_reg_dest" "")
3451
        (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3452
                                         "ua_address_operand" "")))
3453
                (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3454
                           (const_int 8))))
3455
   (clobber (match_operand:DI 3 "register_operand" ""))]
3456
  "TARGET_SHMEDIA"
3457
  [(match_dup 4) (match_dup 5)]
3458
  "
3459
{
3460
  operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3461
                 (operands[3], operands[1]));
3462
  operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3463
                              GEN_INT (56), GEN_INT (8));
3464
}")
3465
 
3466
(define_insn "rotlsi3_1"
3467
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3468
        (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3469
                   (const_int 1)))
3470
   (set (reg:SI T_REG)
3471
        (lshiftrt:SI (match_dup 1) (const_int 31)))]
3472
  "TARGET_SH1"
3473
  "rotl %0"
3474
  [(set_attr "type" "arith")])
3475
 
3476
(define_insn "rotlsi3_31"
3477
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3478
        (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3479
                   (const_int 31)))
3480
   (clobber (reg:SI T_REG))]
3481
  "TARGET_SH1"
3482
  "rotr %0"
3483
  [(set_attr "type" "arith")])
3484
 
3485
(define_insn "rotlsi3_16"
3486
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3487
        (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3488
                   (const_int 16)))]
3489
  "TARGET_SH1"
3490
  "swap.w       %1,%0"
3491
  [(set_attr "type" "arith")])
3492
 
3493
(define_expand "rotlsi3"
3494
  [(set (match_operand:SI 0 "arith_reg_dest" "")
3495
        (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3496
                   (match_operand:SI 2 "immediate_operand" "")))]
3497
  "TARGET_SH1"
3498
  "
3499
{
3500
  static const char rot_tab[] = {
3501
    000, 000, 000, 000, 000, 000, 010, 001,
3502
    001, 001, 011, 013, 003, 003, 003, 003,
3503
    003, 003, 003, 003, 003, 013, 012, 002,
3504
    002, 002, 010, 000, 000, 000, 000, 000,
3505
  };
3506
 
3507
  int count, choice;
3508
 
3509
  if (!CONST_INT_P (operands[2]))
3510
    FAIL;
3511
  count = INTVAL (operands[2]);
3512
  choice = rot_tab[count];
3513
  if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3514
    FAIL;
3515
  choice &= 7;
3516
  switch (choice)
3517
    {
3518
    case 0:
3519
      emit_move_insn (operands[0], operands[1]);
3520
      count -= (count & 16) * 2;
3521
      break;
3522
    case 3:
3523
     emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3524
     count -= 16;
3525
     break;
3526
    case 1:
3527
    case 2:
3528
      {
3529
        rtx parts[2];
3530
        parts[0] = gen_reg_rtx (SImode);
3531
        parts[1] = gen_reg_rtx (SImode);
3532
        emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3533
        emit_move_insn (parts[choice-1], operands[1]);
3534
        emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3535
        emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3536
        emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3537
        count = (count & ~16) - 8;
3538
      }
3539
    }
3540
 
3541
  for (; count > 0; count--)
3542
    emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3543
  for (; count < 0; count++)
3544
    emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3545
 
3546
  DONE;
3547
}")
3548
 
3549
(define_insn "*rotlhi3_8"
3550
  [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3551
        (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3552
                   (const_int 8)))]
3553
  "TARGET_SH1"
3554
  "swap.b       %1,%0"
3555
  [(set_attr "type" "arith")])
3556
 
3557
(define_expand "rotlhi3"
3558
  [(set (match_operand:HI 0 "arith_reg_operand" "")
3559
        (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3560
                   (match_operand:HI 2 "immediate_operand" "")))]
3561
  "TARGET_SH1"
3562
  "
3563
{
3564
  if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3565
    FAIL;
3566
}")
3567
 
3568
;;
3569
;; shift left
3570
 
3571
;; This pattern is used by init_expmed for computing the costs of shift
3572
;; insns.
3573
 
3574
(define_insn_and_split "ashlsi3_std"
3575
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3576
        (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3577
                   (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3578
   (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3579
  "(TARGET_SH3 || TARGET_SH2A)
3580
   || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3581
  "@
3582
   shld %2,%0
3583
   add  %0,%0
3584
   shll%O2      %0
3585
   #"
3586
  "(TARGET_SH3 || TARGET_SH2A)
3587
   && reload_completed
3588
   && CONST_INT_P (operands[2])
3589
   && ! satisfies_constraint_P27 (operands[2])"
3590
  [(set (match_dup 3) (match_dup 2))
3591
   (parallel
3592
    [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3593
     (clobber (match_dup 4))])]
3594
  "operands[4] = gen_rtx_SCRATCH (SImode);"
3595
  [(set_attr "length" "*,*,*,4")
3596
   (set_attr "type" "dyn_shift,arith,arith,arith")])
3597
 
3598
(define_insn "ashlhi3_k"
3599
  [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3600
        (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3601
                   (match_operand:HI 2 "const_int_operand" "M,P27")))]
3602
  "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3603
  "@
3604
        add     %0,%0
3605
        shll%O2 %0"
3606
  [(set_attr "type" "arith")])
3607
 
3608
(define_insn "ashlsi3_n"
3609
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3610
        (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3611
                   (match_operand:SI 2 "const_int_operand" "n")))
3612
   (clobber (reg:SI T_REG))]
3613
  "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3614
  "#"
3615
  [(set (attr "length")
3616
        (cond [(match_test "shift_insns_rtx (insn)")
3617
               (const_string "2")
3618
               (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3619
               (const_string "4")
3620
               (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3621
               (const_string "6")]
3622
              (const_string "8")))
3623
   (set_attr "type" "arith")])
3624
 
3625
(define_split
3626
  [(set (match_operand:SI 0 "arith_reg_dest" "")
3627
        (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3628
                   (match_operand:SI 2 "const_int_operand" "")))
3629
   (clobber (reg:SI T_REG))]
3630
  "TARGET_SH1 && reload_completed"
3631
  [(use (reg:SI R0_REG))]
3632
  "
3633
{
3634
  gen_shifty_op (ASHIFT, operands);
3635
  DONE;
3636
}")
3637
 
3638
(define_insn "ashlsi3_media"
3639
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3640
        (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3641
                   (match_operand:SI 2 "shift_count_operand" "r,n")))]
3642
  "TARGET_SHMEDIA"
3643
  "@
3644
        shlld.l %1, %2, %0
3645
        shlli.l %1, %2, %0"
3646
  [(set_attr "type" "arith_media")
3647
   (set_attr "highpart" "ignore")])
3648
 
3649
(define_expand "ashlsi3"
3650
  [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3651
                   (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3652
                              (match_operand:SI 2 "nonmemory_operand" "")))
3653
              (clobber (reg:SI T_REG))])]
3654
  ""
3655
  "
3656
{
3657
  if (TARGET_SHMEDIA)
3658
    {
3659
      emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3660
      DONE;
3661
    }
3662
  if (CONST_INT_P (operands[2])
3663
      && sh_dynamicalize_shift_p (operands[2]))
3664
    operands[2] = force_reg (SImode, operands[2]);
3665
  if (TARGET_SH3 || TARGET_SH2A)
3666
    {
3667
      emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3668
      DONE;
3669
    }
3670
  if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3671
    FAIL;
3672
}")
3673
 
3674
(define_insn "*ashlhi3_n"
3675
  [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3676
        (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3677
                   (match_operand:HI 2 "const_int_operand" "n")))
3678
   (clobber (reg:SI T_REG))]
3679
  "TARGET_SH1"
3680
  "#"
3681
  [(set (attr "length")
3682
        (cond [(match_test "shift_insns_rtx (insn)")
3683
               (const_string "2")
3684
               (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3685
               (const_string "4")]
3686
              (const_string "6")))
3687
   (set_attr "type" "arith")])
3688
 
3689
(define_expand "ashlhi3"
3690
  [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3691
                   (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3692
                              (match_operand:SI 2 "nonmemory_operand" "")))
3693
              (clobber (reg:SI T_REG))])]
3694
  "TARGET_SH1"
3695
  "
3696
{
3697
  if (!CONST_INT_P (operands[2]))
3698
    FAIL;
3699
  /* It may be possible to call gen_ashlhi3 directly with more generic
3700
     operands.  Make sure operands[1] is a HImode register here.  */
3701
  if (!arith_reg_operand (operands[1], HImode))
3702
    operands[1] = copy_to_mode_reg (HImode, operands[1]);
3703
}")
3704
 
3705
(define_split
3706
  [(set (match_operand:HI 0 "arith_reg_dest" "")
3707
        (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3708
                   (match_operand:HI 2 "const_int_operand" "")))
3709
   (clobber (reg:SI T_REG))]
3710
  "TARGET_SH1 && reload_completed"
3711
  [(use (reg:SI R0_REG))]
3712
  "
3713
{
3714
  gen_shifty_hi_op (ASHIFT, operands);
3715
  DONE;
3716
}")
3717
 
3718
;
3719
; arithmetic shift right
3720
;
3721
 
3722
(define_insn "ashrsi3_k"
3723
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3724
        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3725
                     (match_operand:SI 2 "const_int_operand" "M")))
3726
   (clobber (reg:SI T_REG))]
3727
  "TARGET_SH1 && INTVAL (operands[2]) == 1"
3728
  "shar %0"
3729
  [(set_attr "type" "arith")])
3730
 
3731
;; We can't do HImode right shifts correctly unless we start out with an
3732
;; explicit zero / sign extension; doing that would result in worse overall
3733
;; code, so just let the machine independent code widen the mode.
3734
;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3735
 
3736
 
3737
;; ??? This should be a define expand.
3738
 
3739
(define_insn "ashrsi2_16"
3740
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3741
        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3742
                     (const_int 16)))]
3743
  "TARGET_SH1"
3744
  "#"
3745
  [(set_attr "length" "4")])
3746
 
3747
(define_split
3748
  [(set (match_operand:SI 0 "arith_reg_dest" "")
3749
        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3750
                     (const_int 16)))]
3751
  "TARGET_SH1"
3752
  [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3753
   (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3754
  "operands[2] = gen_lowpart (HImode, operands[0]);")
3755
 
3756
;; ??? This should be a define expand.
3757
 
3758
(define_insn "ashrsi2_31"
3759
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3760
        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3761
                     (const_int 31)))
3762
   (clobber (reg:SI T_REG))]
3763
  "TARGET_SH1"
3764
  "#"
3765
  [(set_attr "length" "4")])
3766
 
3767
(define_split
3768
  [(set (match_operand:SI 0 "arith_reg_dest" "")
3769
        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3770
                     (const_int 31)))
3771
   (clobber (reg:SI T_REG))]
3772
  "TARGET_SH1"
3773
  [(const_int 0)]
3774
  "
3775
{
3776
  emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3777
  emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3778
  DONE;
3779
}")
3780
 
3781
(define_peephole2
3782
  [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3783
   (set (reg:SI T_REG)
3784
        (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3785
  "TARGET_SH1
3786
   && peep2_reg_dead_p (2, operands[0])
3787
   && peep2_reg_dead_p (2, operands[1])"
3788
  [(const_int 0)]
3789
  "
3790
{
3791
  emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3792
  DONE;
3793
}")
3794
 
3795
(define_insn "ashlsi_c"
3796
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3797
        (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3798
   (set (reg:SI T_REG)
3799
        (lt:SI (match_dup 1) (const_int 0)))]
3800
  "TARGET_SH1"
3801
  "shll %0"
3802
  [(set_attr "type" "arith")])
3803
 
3804
(define_insn "*ashlsi_c_void"
3805
  [(set (reg:SI T_REG)
3806
        (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3807
   (clobber (match_scratch:SI 1 "=0"))]
3808
  "TARGET_SH1 && cse_not_expected"
3809
  "shll %0"
3810
  [(set_attr "type" "arith")])
3811
 
3812
(define_insn "ashrsi3_d"
3813
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3814
        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3815
                     (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3816
  "TARGET_SH3 || TARGET_SH2A"
3817
  "shad %2,%0"
3818
  [(set_attr "type" "dyn_shift")])
3819
 
3820
(define_insn "ashrsi3_n"
3821
  [(set (reg:SI R4_REG)
3822
        (ashiftrt:SI (reg:SI R4_REG)
3823
                     (match_operand:SI 0 "const_int_operand" "i")))
3824
   (clobber (reg:SI T_REG))
3825
   (clobber (reg:SI PR_REG))
3826
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3827
  "TARGET_SH1"
3828
  "jsr  @%1%#"
3829
  [(set_attr "type" "sfunc")
3830
   (set_attr "needs_delay_slot" "yes")])
3831
 
3832
(define_insn "ashrsi3_media"
3833
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3834
        (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3835
                     (match_operand:SI 2 "shift_count_operand" "r,n")))]
3836
  "TARGET_SHMEDIA"
3837
  "@
3838
        shard.l %1, %2, %0
3839
        shari.l %1, %2, %0"
3840
  [(set_attr "type" "arith_media")
3841
   (set_attr "highpart" "ignore")])
3842
 
3843
(define_expand "ashrsi3"
3844
  [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3845
                   (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3846
                                (match_operand:SI 2 "nonmemory_operand" "")))
3847
              (clobber (reg:SI T_REG))])]
3848
  ""
3849
  "
3850
{
3851
  if (TARGET_SHMEDIA)
3852
    {
3853
      emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3854
      DONE;
3855
    }
3856
  if (expand_ashiftrt (operands))
3857
    DONE;
3858
  else
3859
    FAIL;
3860
}")
3861
 
3862
;; logical shift right
3863
 
3864
(define_insn "lshrsi3_d"
3865
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3866
        (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3867
                     (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3868
  "TARGET_SH3 || TARGET_SH2A"
3869
  "shld %2,%0"
3870
  [(set_attr "type" "dyn_shift")])
3871
 
3872
;;  Only the single bit shift clobbers the T bit.
3873
 
3874
(define_insn "lshrsi3_m"
3875
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3876
        (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3877
                     (match_operand:SI 2 "const_int_operand" "M")))
3878
   (clobber (reg:SI T_REG))]
3879
  "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3880
  "shlr %0"
3881
  [(set_attr "type" "arith")])
3882
 
3883
(define_insn "lshrsi3_k"
3884
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3885
        (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3886
                     (match_operand:SI 2 "const_int_operand" "P27")))]
3887
  "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3888
   && ! satisfies_constraint_M (operands[2])"
3889
  "shlr%O2      %0"
3890
  [(set_attr "type" "arith")])
3891
 
3892
(define_insn "lshrsi3_n"
3893
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3894
        (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3895
                     (match_operand:SI 2 "const_int_operand" "n")))
3896
   (clobber (reg:SI T_REG))]
3897
  "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3898
  "#"
3899
  [(set (attr "length")
3900
        (cond [(match_test "shift_insns_rtx (insn)")
3901
               (const_string "2")
3902
               (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3903
               (const_string "4")
3904
               (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3905
               (const_string "6")]
3906
              (const_string "8")))
3907
   (set_attr "type" "arith")])
3908
 
3909
(define_split
3910
  [(set (match_operand:SI 0 "arith_reg_dest" "")
3911
        (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3912
                     (match_operand:SI 2 "const_int_operand" "")))
3913
   (clobber (reg:SI T_REG))]
3914
  "TARGET_SH1 && reload_completed"
3915
  [(use (reg:SI R0_REG))]
3916
  "
3917
{
3918
  gen_shifty_op (LSHIFTRT, operands);
3919
  DONE;
3920
}")
3921
 
3922
(define_insn "lshrsi3_media"
3923
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3924
        (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3925
                     (match_operand:SI 2 "shift_count_operand" "r,n")))]
3926
  "TARGET_SHMEDIA"
3927
  "@
3928
        shlrd.l %1, %2, %0
3929
        shlri.l %1, %2, %0"
3930
  [(set_attr "type" "arith_media")
3931
   (set_attr "highpart" "ignore")])
3932
 
3933
(define_expand "lshrsi3"
3934
  [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3935
                   (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3936
                                (match_operand:SI 2 "nonmemory_operand" "")))
3937
              (clobber (reg:SI T_REG))])]
3938
  ""
3939
  "
3940
{
3941
  if (TARGET_SHMEDIA)
3942
    {
3943
      emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3944
      DONE;
3945
    }
3946
  if (CONST_INT_P (operands[2])
3947
      && sh_dynamicalize_shift_p (operands[2]))
3948
    operands[2] = force_reg (SImode, operands[2]);
3949
  if ((TARGET_SH3 || TARGET_SH2A)
3950
      && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3951
    {
3952
      rtx count = copy_to_mode_reg (SImode, operands[2]);
3953
      emit_insn (gen_negsi2 (count, count));
3954
      emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3955
      DONE;
3956
    }
3957
  if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3958
    FAIL;
3959
}")
3960
 
3961
;; ??? This should be a define expand.
3962
 
3963
(define_insn "ashldi3_k"
3964
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3965
        (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3966
                   (const_int 1)))
3967
   (clobber (reg:SI T_REG))]
3968
  "TARGET_SH1"
3969
  "shll %R0\;rotcl      %S0"
3970
  [(set_attr "length" "4")
3971
   (set_attr "type" "arith")])
3972
 
3973
;; Expander for DImode shift left with SImode operations.
3974
 
3975
(define_expand "ashldi3_std"
3976
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3977
        (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3978
                   (match_operand:DI 2 "const_int_operand" "n")))]
3979
  "TARGET_SH1 && INTVAL (operands[2]) < 32"
3980
  "
3981
{
3982
  int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3983
  int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3984
  rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3985
  rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3986
  rtx dst = gen_reg_rtx (DImode);
3987
  rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3988
  rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3989
  rtx tmp0, tmp1;
3990
 
3991
  tmp0 = gen_reg_rtx (SImode);
3992
  tmp1 = gen_reg_rtx (SImode);
3993
  emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3994
  emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
3995
  emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
3996
  emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3997
  emit_move_insn (operands[0], dst);
3998
  DONE;
3999
}")
4000
 
4001
(define_insn "ashldi3_media"
4002
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4003
        (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4004
                   (match_operand:DI 2 "shift_count_operand" "r,n")))]
4005
  "TARGET_SHMEDIA"
4006
  "@
4007
        shlld   %1, %2, %0
4008
        shlli   %1, %2, %0"
4009
  [(set_attr "type" "arith_media")])
4010
 
4011
(define_insn "*ashldisi3_media"
4012
  [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4013
        (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4014
                   (match_operand:DI 2 "const_int_operand" "n")))]
4015
  "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4016
  "shlli.l      %1, %2, %0"
4017
  [(set_attr "type" "arith_media")
4018
   (set_attr "highpart" "ignore")])
4019
 
4020
(define_expand "ashldi3"
4021
  [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4022
                   (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4023
                              (match_operand:DI 2 "immediate_operand" "")))
4024
              (clobber (reg:SI T_REG))])]
4025
  ""
4026
  "
4027
{
4028
  if (TARGET_SHMEDIA)
4029
    {
4030
      emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4031
      DONE;
4032
    }
4033
  if (CONST_INT_P (operands[2])
4034
      && INTVAL (operands[2]) == 1)
4035
    {
4036
      emit_insn (gen_ashldi3_k (operands[0], operands[1]));
4037
      DONE;
4038
    }
4039
  else if (CONST_INT_P (operands[2])
4040
      && INTVAL (operands[2]) < 32)
4041
    {
4042
      emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
4043
      DONE;
4044
    }
4045
  else
4046
    FAIL;
4047
}")
4048
 
4049
;; ??? This should be a define expand.
4050
 
4051
(define_insn "lshrdi3_k"
4052
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4053
        (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4054
                     (const_int 1)))
4055
   (clobber (reg:SI T_REG))]
4056
  "TARGET_SH1"
4057
  "shlr %S0\;rotcr      %R0"
4058
  [(set_attr "length" "4")
4059
   (set_attr "type" "arith")])
4060
 
4061
(define_insn "lshrdi3_media"
4062
  [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4063
        (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4064
                     (match_operand:DI 2 "shift_count_operand" "r,n")))]
4065
  "TARGET_SHMEDIA
4066
   && (arith_reg_dest (operands[0], DImode)
4067
       || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
4068
  "@
4069
        shlrd   %1, %2, %0
4070
        shlri   %1, %2, %0"
4071
  [(set_attr "type" "arith_media")])
4072
 
4073
(define_insn "*lshrdisi3_media"
4074
  [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4075
        (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4076
                     (match_operand:DI 2 "const_int_operand" "n")))]
4077
  "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4078
  "shlri.l      %1, %2, %0"
4079
  [(set_attr "type" "arith_media")
4080
   (set_attr "highpart" "ignore")])
4081
 
4082
(define_expand "lshrdi3"
4083
  [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4084
                   (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4085
                               (match_operand:DI 2 "immediate_operand" "")))
4086
             (clobber (reg:SI T_REG))])]
4087
  ""
4088
  "
4089
{
4090
  if (TARGET_SHMEDIA)
4091
    {
4092
      emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4093
      DONE;
4094
    }
4095
  if (!CONST_INT_P (operands[2])
4096
      || INTVAL (operands[2]) != 1)
4097
    FAIL;
4098
}")
4099
 
4100
;; ??? This should be a define expand.
4101
 
4102
(define_insn "ashrdi3_k"
4103
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4104
        (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4105
                     (const_int 1)))
4106
   (clobber (reg:SI T_REG))]
4107
  "TARGET_SH1"
4108
  "shar %S0\;rotcr      %R0"
4109
  [(set_attr "length" "4")
4110
   (set_attr "type" "arith")])
4111
 
4112
(define_insn "ashrdi3_media"
4113
  [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4114
        (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4115
                     (match_operand:DI 2 "shift_count_operand" "r,n")))]
4116
  "TARGET_SHMEDIA
4117
   && (arith_reg_dest (operands[0], DImode)
4118
       || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4119
  "@
4120
        shard   %1, %2, %0
4121
        shari   %1, %2, %0"
4122
  [(set_attr "type" "arith_media")])
4123
 
4124
(define_insn "*ashrdisi3_media"
4125
  [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4126
        (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4127
                     (match_operand:DI 2 "const_int_operand" "n")))]
4128
  "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4129
  "shari.l      %1, %2, %0"
4130
  [(set_attr "type" "arith_media")
4131
   (set_attr "highpart" "ignore")])
4132
 
4133
(define_insn "ashrdisi3_media_high"
4134
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4135
        (truncate:SI
4136
           (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4137
                        (match_operand:DI 2 "const_int_operand" "n"))))]
4138
  "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4139
  "shari        %1, %2, %0"
4140
  [(set_attr "type" "arith_media")])
4141
 
4142
(define_insn "ashrdisi3_media_opaque"
4143
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4144
        (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4145
                    (match_operand:DI 2 "const_int_operand" "n")]
4146
         UNSPEC_ASHIFTRT))]
4147
  "TARGET_SHMEDIA"
4148
  "shari        %1, %2, %0"
4149
  [(set_attr "type" "arith_media")])
4150
 
4151
(define_expand "ashrdi3"
4152
  [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4153
                   (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4154
                                (match_operand:DI 2 "immediate_operand" "")))
4155
              (clobber (reg:SI T_REG))])]
4156
  ""
4157
  "
4158
{
4159
  if (TARGET_SHMEDIA)
4160
    {
4161
      emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4162
      DONE;
4163
    }
4164
  if (!CONST_INT_P (operands[2])
4165
      || INTVAL (operands[2]) != 1)
4166
    FAIL;
4167
}")
4168
 
4169
;; combined left/right shift
4170
 
4171
(define_split
4172
  [(set (match_operand:SI 0 "register_operand" "")
4173
        (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4174
                           (match_operand:SI 2 "const_int_operand" ""))
4175
                (match_operand:SI 3 "const_int_operand" "")))]
4176
  "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4177
  [(use (reg:SI R0_REG))]
4178
  "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4179
   DONE;")
4180
 
4181
(define_split
4182
  [(set (match_operand:SI 0 "register_operand" "")
4183
        (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4184
                           (match_operand:SI 2 "const_int_operand" ""))
4185
                (match_operand:SI 3 "const_int_operand" "")))
4186
   (clobber (reg:SI T_REG))]
4187
  "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4188
  [(use (reg:SI R0_REG))]
4189
  "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4190
   DONE;")
4191
 
4192
(define_insn ""
4193
  [(set (match_operand:SI 0 "register_operand" "=r")
4194
        (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4195
                           (match_operand:SI 2 "const_int_operand" "n"))
4196
                (match_operand:SI 3 "const_int_operand" "n")))
4197
   (clobber (reg:SI T_REG))]
4198
  "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4199
 "#"
4200
  [(set (attr "length")
4201
        (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4202
               (const_string "4")
4203
               (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4204
               (const_string "6")
4205
               (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4206
               (const_string "8")
4207
               (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4208
               (const_string "10")
4209
               (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4210
               (const_string "12")
4211
               (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4212
               (const_string "14")
4213
               (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4214
               (const_string "16")]
4215
              (const_string "18")))
4216
   (set_attr "type" "arith")])
4217
 
4218
(define_insn ""
4219
  [(set (match_operand:SI 0 "register_operand" "=z")
4220
        (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4221
                           (match_operand:SI 2 "const_int_operand" "n"))
4222
                (match_operand:SI 3 "const_int_operand" "n")))
4223
   (clobber (reg:SI T_REG))]
4224
  "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4225
 "#"
4226
  [(set (attr "length")
4227
        (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4228
               (const_string "4")
4229
               (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4230
               (const_string "6")
4231
               (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4232
               (const_string "8")]
4233
              (const_string "10")))
4234
   (set_attr "type" "arith")])
4235
 
4236
;; shift left / and combination with a scratch register: The combine pass
4237
;; does not accept the individual instructions, even though they are
4238
;; cheap.  But it needs a precise description so that it is usable after
4239
;; reload.
4240
(define_insn "and_shl_scratch"
4241
  [(set (match_operand:SI 0 "register_operand" "=r,&r")
4242
        (lshiftrt:SI
4243
         (ashift:SI
4244
          (and:SI
4245
           (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4246
                        (match_operand:SI 2 "const_int_operand" "N,n"))
4247
           (match_operand:SI 3 "" "0,r"))
4248
          (match_operand:SI 4 "const_int_operand" "n,n"))
4249
         (match_operand:SI 5 "const_int_operand" "n,n")))
4250
   (clobber (reg:SI T_REG))]
4251
  "TARGET_SH1"
4252
  "#"
4253
  [(set (attr "length")
4254
        (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4255
               (const_string "4")
4256
               (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4257
               (const_string "6")
4258
               (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4259
               (const_string "8")
4260
               (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4261
               (const_string "10")]
4262
              (const_string "12")))
4263
   (set_attr "type" "arith")])
4264
 
4265
(define_split
4266
  [(set (match_operand:SI 0 "register_operand" "")
4267
        (lshiftrt:SI
4268
         (ashift:SI
4269
          (and:SI
4270
           (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4271
                        (match_operand:SI 2 "const_int_operand" ""))
4272
           (match_operand:SI 3 "register_operand" ""))
4273
          (match_operand:SI 4 "const_int_operand" ""))
4274
         (match_operand:SI 5 "const_int_operand" "")))
4275
   (clobber (reg:SI T_REG))]
4276
  "TARGET_SH1"
4277
  [(use (reg:SI R0_REG))]
4278
  "
4279
{
4280
  rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4281
 
4282
  if (INTVAL (operands[2]))
4283
    {
4284
      gen_shifty_op (LSHIFTRT, operands);
4285
    }
4286
  emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4287
  operands[2] = operands[4];
4288
  gen_shifty_op (ASHIFT, operands);
4289
  if (INTVAL (operands[5]))
4290
    {
4291
      operands[2] = operands[5];
4292
      gen_shifty_op (LSHIFTRT, operands);
4293
    }
4294
  DONE;
4295
}")
4296
 
4297
;; signed left/right shift combination.
4298
(define_split
4299
  [(set (match_operand:SI 0 "register_operand" "")
4300
        (sign_extract:SI
4301
         (ashift:SI (match_operand:SI 1 "register_operand" "")
4302
                    (match_operand:SI 2 "const_int_operand" ""))
4303
         (match_operand:SI 3 "const_int_operand" "")
4304
         (const_int 0)))
4305
   (clobber (reg:SI T_REG))]
4306
  "TARGET_SH1"
4307
  [(use (reg:SI R0_REG))]
4308
  "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4309
   DONE;")
4310
 
4311
(define_insn "shl_sext_ext"
4312
  [(set (match_operand:SI 0 "register_operand" "=r")
4313
        (sign_extract:SI
4314
         (ashift:SI (match_operand:SI 1 "register_operand" "0")
4315
                    (match_operand:SI 2 "const_int_operand" "n"))
4316
         (match_operand:SI 3 "const_int_operand" "n")
4317
         (const_int 0)))
4318
   (clobber (reg:SI T_REG))]
4319
  "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4320
  "#"
4321
  [(set (attr "length")
4322
        (cond [(match_test "shl_sext_length (insn)")
4323
               (const_string "2")
4324
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4325
               (const_string "4")
4326
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4327
               (const_string "6")
4328
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4329
               (const_string "8")
4330
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4331
               (const_string "10")
4332
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4333
               (const_string "12")
4334
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4335
               (const_string "14")
4336
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4337
               (const_string "16")]
4338
              (const_string "18")))
4339
    (set_attr "type" "arith")])
4340
 
4341
(define_insn "shl_sext_sub"
4342
  [(set (match_operand:SI 0 "register_operand" "=z")
4343
        (sign_extract:SI
4344
         (ashift:SI (match_operand:SI 1 "register_operand" "0")
4345
                    (match_operand:SI 2 "const_int_operand" "n"))
4346
         (match_operand:SI 3 "const_int_operand" "n")
4347
         (const_int 0)))
4348
   (clobber (reg:SI T_REG))]
4349
  "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4350
  "#"
4351
  [(set (attr "length")
4352
        (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4353
               (const_string "6")
4354
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4355
               (const_string "8")
4356
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4357
               (const_string "10")
4358
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4359
               (const_string "12")]
4360
              (const_string "14")))
4361
    (set_attr "type" "arith")])
4362
 
4363
;; These patterns are found in expansions of DImode shifts by 16, and
4364
;; allow the xtrct instruction to be generated from C source.
4365
 
4366
(define_insn "xtrct_left"
4367
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4368
        (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4369
                           (const_int 16))
4370
                (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4371
                             (const_int 16))))]
4372
  "TARGET_SH1"
4373
  "xtrct        %1,%0"
4374
  [(set_attr "type" "arith")])
4375
 
4376
(define_insn "xtrct_right"
4377
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4378
        (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4379
                             (const_int 16))
4380
                (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4381
                           (const_int 16))))]
4382
  "TARGET_SH1"
4383
  "xtrct        %2,%0"
4384
  [(set_attr "type" "arith")])
4385
 
4386
;; -------------------------------------------------------------------------
4387
;; Unary arithmetic
4388
;; -------------------------------------------------------------------------
4389
 
4390
(define_insn "negc"
4391
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4392
        (neg:SI (plus:SI (reg:SI T_REG)
4393
                         (match_operand:SI 1 "arith_reg_operand" "r"))))
4394
   (set (reg:SI T_REG)
4395
        (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4396
               (const_int 0)))]
4397
  "TARGET_SH1"
4398
  "negc %1,%0"
4399
  [(set_attr "type" "arith")])
4400
 
4401
(define_insn "*negdi_media"
4402
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4403
        (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4404
  "TARGET_SHMEDIA"
4405
  "sub  r63, %1, %0"
4406
  [(set_attr "type" "arith_media")])
4407
 
4408
;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be
4409
;; combined.
4410
(define_expand "negdi2"
4411
  [(set (match_operand:DI 0 "arith_reg_dest" "")
4412
        (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
4413
   (clobber (reg:SI T_REG))]
4414
  ""
4415
  "")
4416
 
4417
(define_insn_and_split "*negdi2"
4418
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4419
        (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4420
  "TARGET_SH1"
4421
  "#"
4422
  "TARGET_SH1"
4423
  [(const_int 0)]
4424
  "
4425
{
4426
  int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4427
  int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4428
 
4429
  rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4430
  rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4431
 
4432
  rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4433
  rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4434
 
4435
  emit_insn (gen_clrt ());
4436
  emit_insn (gen_negc (low_dst, low_src));
4437
  emit_insn (gen_negc (high_dst, high_src));
4438
  DONE;
4439
}")
4440
 
4441
(define_insn "negsi2"
4442
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4443
        (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4444
  "TARGET_SH1"
4445
  "neg  %1,%0"
4446
  [(set_attr "type" "arith")])
4447
 
4448
(define_insn "one_cmplsi2"
4449
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4450
        (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4451
  "TARGET_SH1"
4452
  "not  %1,%0"
4453
  [(set_attr "type" "arith")])
4454
 
4455
(define_expand "one_cmpldi2"
4456
  [(set (match_operand:DI 0 "arith_reg_dest" "")
4457
        (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4458
                (const_int -1)))]
4459
  "TARGET_SHMEDIA" "")
4460
 
4461
(define_expand "abssi2"
4462
  [(set (match_operand:SI 0 "arith_reg_dest" "")
4463
        (abs:SI (match_operand:SI 1 "arith_reg_operand" "")))
4464
   (clobber (reg:SI T_REG))]
4465
  ""
4466
  "")
4467
 
4468
(define_insn_and_split "*abssi2"
4469
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4470
        (abs:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4471
  "TARGET_SH1"
4472
  "#"
4473
  "TARGET_SH1"
4474
  [(const_int 0)]
4475
  "
4476
{
4477
  emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4478
  emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4479
                 const1_rtx));
4480
  DONE;
4481
}")
4482
 
4483
(define_insn_and_split "*negabssi2"
4484
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4485
        (neg:SI (abs:SI (match_operand:SI 1 "arith_reg_operand" "r"))))]
4486
  "TARGET_SH1"
4487
  "#"
4488
  "TARGET_SH1"
4489
  [(const_int 0)]
4490
  "
4491
{
4492
  emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4493
  emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4494
                 const0_rtx));
4495
  DONE;
4496
}")
4497
 
4498
;; The SH4 202 can do zero-offset branches without pipeline stalls.
4499
;; This can be used as some kind of conditional execution, which is useful
4500
;; for abs.
4501
;; Actually the instruction scheduling should decide whether to use a
4502
;; zero-offset branch or not for any generic case involving a single
4503
;; instruction on SH4 202.
4504
 
4505
(define_insn_and_split "negsi_cond"
4506
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4507
        (if_then_else:SI (eq:SI (reg:SI T_REG)
4508
                          (match_operand:SI 3 "const_int_operand" "M,N"))
4509
         (match_operand:SI 1 "arith_reg_operand" "0,0")
4510
         (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
4511
  "TARGET_HARD_SH4"
4512
  "@
4513
        bt\\t0f\;neg\\t%2,%0\\n0:
4514
        bf\\t0f\;neg\\t%2,%0\\n0:"
4515
  "!TARGET_HARD_SH4"
4516
  [(const_int 0)]
4517
  "
4518
{
4519
  rtx skip_neg_label = gen_label_rtx ();
4520
 
4521
  emit_insn (gen_movsi (operands[0], operands[1]));
4522
 
4523
  emit_jump_insn (INTVAL (operands[3])
4524
                  ? gen_branch_true (skip_neg_label)
4525
                  : gen_branch_false (skip_neg_label));
4526
 
4527
  emit_label_after (skip_neg_label,
4528
                    emit_insn (gen_negsi2 (operands[0], operands[1])));
4529
  DONE;
4530
}"
4531
  [(set_attr "type" "arith") ;; poor approximation
4532
   (set_attr "length" "4")])
4533
 
4534
 
4535
;; -------------------------------------------------------------------------
4536
;; Zero extension instructions
4537
;; -------------------------------------------------------------------------
4538
 
4539
(define_insn "zero_extendsidi2"
4540
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4541
        (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4542
  "TARGET_SHMEDIA"
4543
  "addz.l       %1, r63, %0"
4544
  [(set_attr "type" "arith_media")
4545
   (set_attr "highpart" "extend")])
4546
 
4547
(define_insn "zero_extendhidi2"
4548
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4549
        (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4550
  "TARGET_SHMEDIA"
4551
  "@
4552
        #
4553
        ld%M1.uw        %m1, %0"
4554
  [(set_attr "type" "*,load_media")
4555
   (set (attr "highpart")
4556
        (cond [(match_test "sh_contains_memref_p (insn)")
4557
               (const_string "user")]
4558
              (const_string "ignore")))])
4559
 
4560
(define_split
4561
  [(set (match_operand:DI 0 "register_operand" "")
4562
        (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4563
  "TARGET_SHMEDIA && reload_completed"
4564
  [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4565
   (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4566
  "
4567
{
4568
  if (GET_CODE (operands[1]) == TRUNCATE)
4569
    operands[1] = XEXP (operands[1], 0);
4570
}")
4571
 
4572
;; ??? when a truncated input to a zero_extend is reloaded, reload will
4573
;; reload the entire truncate expression.
4574
(define_insn_and_split "*loaddi_trunc"
4575
  [(set (match_operand 0 "any_register_operand" "=r")
4576
        (truncate (match_operand:DI 1 "memory_operand" "m")))]
4577
  "TARGET_SHMEDIA && reload_completed"
4578
  "#"
4579
  "TARGET_SHMEDIA && reload_completed"
4580
  [(set (match_dup 0) (match_dup 1))]
4581
  "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4582
 
4583
(define_insn "zero_extendqidi2"
4584
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4585
        (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4586
  "TARGET_SHMEDIA"
4587
  "@
4588
        andi    %1, 255, %0
4589
        ld%M1.ub        %m1, %0"
4590
  [(set_attr "type" "arith_media,load_media")
4591
   (set (attr "highpart")
4592
        (cond [(match_test "sh_contains_memref_p (insn)")
4593
               (const_string "user")]
4594
              (const_string "ignore")))])
4595
 
4596
(define_expand "zero_extendhisi2"
4597
  [(set (match_operand:SI 0 "arith_reg_operand" "")
4598
        (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4599
  ""
4600
  "
4601
{
4602
  if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4603
    operands[1] = copy_to_mode_reg (HImode, operands[1]);
4604
}")
4605
 
4606
(define_insn "*zero_extendhisi2_compact"
4607
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4608
        (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4609
  "TARGET_SH1"
4610
  "extu.w       %1,%0"
4611
  [(set_attr "type" "arith")])
4612
 
4613
(define_insn "*zero_extendhisi2_media"
4614
  [(set (match_operand:SI 0 "register_operand" "=r,r")
4615
        (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4616
  "TARGET_SHMEDIA"
4617
  "@
4618
        #
4619
        ld%M1.uw        %m1, %0"
4620
  [(set_attr "type" "arith_media,load_media")
4621
   (set (attr "highpart")
4622
        (cond [(match_test "sh_contains_memref_p (insn)")
4623
               (const_string "user")]
4624
              (const_string "ignore")))])
4625
 
4626
(define_split
4627
  [(set (match_operand:SI 0 "register_operand" "")
4628
        (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4629
  "TARGET_SHMEDIA && reload_completed"
4630
  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4631
   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4632
  "
4633
{
4634
  rtx op1 = operands[1];
4635
 
4636
  if (GET_CODE (op1) == TRUNCATE)
4637
    op1 = XEXP (op1, 0);
4638
  operands[2]
4639
    = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4640
                           subreg_lowpart_offset (SImode, GET_MODE (op1)));
4641
}")
4642
 
4643
(define_expand "zero_extendqisi2"
4644
  [(set (match_operand:SI 0 "arith_reg_operand" "")
4645
        (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4646
  ""
4647
  "
4648
{
4649
  if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4650
    operands[1] = copy_to_mode_reg (QImode, operands[1]);
4651
}")
4652
 
4653
(define_insn "*zero_extendqisi2_compact"
4654
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4655
        (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4656
  "TARGET_SH1"
4657
  "extu.b       %1,%0"
4658
  [(set_attr "type" "arith")])
4659
 
4660
(define_insn "*zero_extendqisi2_media"
4661
  [(set (match_operand:SI 0 "register_operand" "=r,r")
4662
        (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4663
  "TARGET_SHMEDIA"
4664
  "@
4665
        andi    %1, 255, %0
4666
        ld%M1.ub        %m1, %0"
4667
  [(set_attr "type" "arith_media,load_media")
4668
   (set (attr "highpart")
4669
        (cond [(match_test "sh_contains_memref_p (insn)")
4670
               (const_string "user")]
4671
              (const_string "ignore")))])
4672
 
4673
(define_insn "zero_extendqihi2"
4674
  [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4675
        (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4676
  "TARGET_SH1"
4677
  "extu.b       %1,%0"
4678
  [(set_attr "type" "arith")])
4679
 
4680
;; -------------------------------------------------------------------------
4681
;; Sign extension instructions
4682
;; -------------------------------------------------------------------------
4683
 
4684
;; ??? This should be a define expand.
4685
;; ??? Or perhaps it should be dropped?
4686
 
4687
;; convert_move generates good code for SH[1-4].
4688
(define_insn "extendsidi2"
4689
  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4690
        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4691
  "TARGET_SHMEDIA"
4692
  "@
4693
        add.l   %1, r63, %0
4694
        ld%M1.l %m1, %0
4695
        fmov.sl %1, %0"
4696
  [(set_attr "type" "arith_media,load_media,fpconv_media")
4697
   (set (attr "highpart")
4698
        (cond [(match_test "sh_contains_memref_p (insn)")
4699
               (const_string "user")]
4700
              (const_string "extend")))])
4701
 
4702
(define_insn "extendhidi2"
4703
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4704
        (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4705
  "TARGET_SHMEDIA"
4706
  "@
4707
        #
4708
        ld%M1.w %m1, %0"
4709
  [(set_attr "type" "*,load_media")
4710
   (set (attr "highpart")
4711
        (cond [(match_test "sh_contains_memref_p (insn)")
4712
               (const_string "user")]
4713
              (const_string "ignore")))])
4714
 
4715
(define_split
4716
  [(set (match_operand:DI 0 "register_operand" "")
4717
        (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4718
  "TARGET_SHMEDIA && reload_completed"
4719
  [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4720
   (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4721
  "
4722
{
4723
  if (GET_CODE (operands[1]) == TRUNCATE)
4724
    operands[1] = XEXP (operands[1], 0);
4725
}")
4726
 
4727
(define_insn "extendqidi2"
4728
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4729
        (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4730
  "TARGET_SHMEDIA"
4731
  "@
4732
        #
4733
        ld%M1.b %m1, %0"
4734
  [(set_attr "type" "*,load_media")
4735
   (set (attr "highpart")
4736
        (cond [(match_test "sh_contains_memref_p (insn)")
4737
               (const_string "user")]
4738
              (const_string "ignore")))])
4739
 
4740
(define_split
4741
  [(set (match_operand:DI 0 "register_operand" "")
4742
        (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4743
  "TARGET_SHMEDIA && reload_completed"
4744
  [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4745
   (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4746
  "
4747
{
4748
  if (GET_CODE (operands[1]) == TRUNCATE)
4749
    operands[1] = XEXP (operands[1], 0);
4750
}")
4751
 
4752
(define_expand "extendhisi2"
4753
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4754
        (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4755
  ""
4756
  "")
4757
 
4758
(define_insn "*extendhisi2_compact"
4759
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4760
        (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4761
  "TARGET_SH1"
4762
  "@
4763
        exts.w  %1,%0
4764
        mov.w   %1,%0"
4765
  [(set_attr "type" "arith,load")])
4766
 
4767
(define_insn "*extendhisi2_media"
4768
  [(set (match_operand:SI 0 "register_operand" "=r,r")
4769
        (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4770
  "TARGET_SHMEDIA"
4771
  "@
4772
        #
4773
        ld%M1.w %m1, %0"
4774
  [(set_attr "type" "arith_media,load_media")
4775
   (set (attr "highpart")
4776
        (cond [(match_test "sh_contains_memref_p (insn)")
4777
               (const_string "user")]
4778
              (const_string "ignore")))])
4779
 
4780
(define_split
4781
  [(set (match_operand:SI 0 "register_operand" "")
4782
        (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4783
  "TARGET_SHMEDIA && reload_completed"
4784
  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4785
   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4786
  "
4787
{
4788
  rtx op1 = operands[1];
4789
  if (GET_CODE (op1) == TRUNCATE)
4790
    op1 = XEXP (op1, 0);
4791
  operands[2]
4792
    = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4793
                           subreg_lowpart_offset (SImode, GET_MODE (op1)));
4794
}")
4795
 
4796
(define_expand "extendqisi2"
4797
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4798
        (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4799
  ""
4800
  "")
4801
 
4802
(define_insn "*extendqisi2_compact"
4803
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4804
        (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4805
  "TARGET_SH1"
4806
  "@
4807
        exts.b  %1,%0
4808
        mov.b   %1,%0"
4809
  [(set_attr "type" "arith,load")
4810
   (set_attr_alternative "length"
4811
     [(const_int 2)
4812
       (if_then_else
4813
        (match_test "TARGET_SH2A")
4814
        (const_int 4) (const_int 2))])])
4815
 
4816
(define_insn "*extendqisi2_media"
4817
  [(set (match_operand:SI 0 "register_operand" "=r,r")
4818
        (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4819
  "TARGET_SHMEDIA"
4820
  "@
4821
        #
4822
        ld%M1.b %m1, %0"
4823
  [(set_attr "type" "arith_media,load_media")
4824
   (set (attr "highpart")
4825
        (cond [(match_test "sh_contains_memref_p (insn)")
4826
               (const_string "user")]
4827
              (const_string "ignore")))])
4828
 
4829
(define_split
4830
  [(set (match_operand:SI 0 "register_operand" "")
4831
        (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4832
  "TARGET_SHMEDIA && reload_completed"
4833
  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4834
   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4835
   "
4836
{
4837
  rtx op1 = operands[1];
4838
  if (GET_CODE (op1) == TRUNCATE)
4839
    op1 = XEXP (op1, 0);
4840
  operands[2]
4841
    = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4842
                           subreg_lowpart_offset (SImode, GET_MODE (op1)));
4843
}")
4844
 
4845
(define_insn "extendqihi2"
4846
  [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4847
        (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4848
  "TARGET_SH1"
4849
  "@
4850
        exts.b  %1,%0
4851
        mov.b   %1,%0"
4852
  [(set_attr "type" "arith,load")
4853
   (set_attr_alternative "length"
4854
     [(const_int 2)
4855
       (if_then_else
4856
        (match_test "TARGET_SH2A")
4857
        (const_int 4) (const_int 2))])])
4858
 
4859
/* It would seem useful to combine the truncXi patterns into the movXi
4860
   patterns, but unary operators are ignored when matching constraints,
4861
   so we need separate patterns.  */
4862
(define_insn "truncdisi2"
4863
  [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4864
        (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4865
  "TARGET_SHMEDIA"
4866
  "@
4867
        add.l   %1, r63, %0
4868
        st%M0.l %m0, %1
4869
        fst%M0.s        %m0, %T1
4870
        fmov.ls %1, %0
4871
        fmov.sl %T1, %0
4872
        fmov.s  %T1, %0"
4873
  [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4874
   (set (attr "highpart")
4875
        (cond [(match_test "sh_contains_memref_p (insn)")
4876
               (const_string "user")]
4877
              (const_string "extend")))])
4878
 
4879
(define_insn "truncdihi2"
4880
  [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4881
        (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4882
  "TARGET_SHMEDIA"
4883
  "@
4884
        shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4885
        st%M0.w %m0, %1"
4886
  [(set_attr "type"   "arith_media,store_media")
4887
   (set_attr "length" "8,4")
4888
   (set (attr "highpart")
4889
        (cond [(match_test "sh_contains_memref_p (insn)")
4890
               (const_string "user")]
4891
              (const_string "extend")))])
4892
 
4893
; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4894
; Because we use zero extension, we can't provide signed QImode compares
4895
; using a simple compare or conditional branch insn.
4896
(define_insn "truncdiqi2"
4897
  [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4898
        (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4899
  "TARGET_SHMEDIA"
4900
  "@
4901
        andi    %1, 255, %0
4902
        st%M0.b %m0, %1"
4903
  [(set_attr "type"   "arith_media,store")
4904
   (set (attr "highpart")
4905
        (cond [(match_test "sh_contains_memref_p (insn)")
4906
               (const_string "user")]
4907
              (const_string "extend")))])
4908
;; -------------------------------------------------------------------------
4909
;; Move instructions
4910
;; -------------------------------------------------------------------------
4911
 
4912
;; define push and pop so it is easy for sh.c
4913
;; We can't use push and pop on SHcompact because the stack must always
4914
;; be 8-byte aligned.
4915
 
4916
(define_expand "push"
4917
  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4918
        (match_operand:SI 0 "register_operand" "r,l,x"))]
4919
  "TARGET_SH1 && ! TARGET_SH5"
4920
  "")
4921
 
4922
(define_expand "pop"
4923
  [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4924
        (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4925
  "TARGET_SH1 && ! TARGET_SH5"
4926
  "")
4927
 
4928
(define_expand "push_e"
4929
  [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4930
                   (match_operand:SF 0 "" ""))
4931
              (use (reg:PSI FPSCR_REG))
4932
              (clobber (scratch:SI))])]
4933
  "TARGET_SH1 && ! TARGET_SH5"
4934
  "")
4935
 
4936
(define_insn "push_fpul"
4937
  [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4938
  "TARGET_SH2E && ! TARGET_SH5"
4939
  "sts.l        fpul,@-r15"
4940
  [(set_attr "type" "fstore")
4941
   (set_attr "late_fp_use" "yes")
4942
   (set_attr "hit_stack" "yes")])
4943
 
4944
;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4945
;; so use that.
4946
(define_expand "push_4"
4947
  [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4948
                   (match_operand:DF 0 "" ""))
4949
              (use (reg:PSI FPSCR_REG))
4950
              (clobber (scratch:SI))])]
4951
  "TARGET_SH1 && ! TARGET_SH5"
4952
  "")
4953
 
4954
(define_expand "pop_e"
4955
  [(parallel [(set (match_operand:SF 0 "" "")
4956
              (mem:SF (post_inc:SI (reg:SI SP_REG))))
4957
              (use (reg:PSI FPSCR_REG))
4958
              (clobber (scratch:SI))])]
4959
  "TARGET_SH1 && ! TARGET_SH5"
4960
  "")
4961
 
4962
(define_insn "pop_fpul"
4963
  [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4964
  "TARGET_SH2E && ! TARGET_SH5"
4965
  "lds.l        @r15+,fpul"
4966
  [(set_attr "type" "load")
4967
   (set_attr "hit_stack" "yes")])
4968
 
4969
(define_expand "pop_4"
4970
  [(parallel [(set (match_operand:DF 0 "" "")
4971
                   (mem:DF (post_inc:SI (reg:SI SP_REG))))
4972
              (use (reg:PSI FPSCR_REG))
4973
              (clobber (scratch:SI))])]
4974
  "TARGET_SH1 && ! TARGET_SH5"
4975
  "")
4976
 
4977
(define_expand "push_fpscr"
4978
  [(const_int 0)]
4979
  "TARGET_SH2E"
4980
  "
4981
{
4982
  rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4983
                                                 gen_rtx_PRE_DEC (Pmode,
4984
                                                          stack_pointer_rtx)),
4985
                                        get_fpscr_rtx ()));
4986
  add_reg_note (insn, REG_INC, stack_pointer_rtx);
4987
  DONE;
4988
}")
4989
 
4990
(define_expand "pop_fpscr"
4991
  [(const_int 0)]
4992
  "TARGET_SH2E"
4993
  "
4994
{
4995
  rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4996
                                        gen_frame_mem (PSImode,
4997
                                                 gen_rtx_POST_INC (Pmode,
4998
                                                          stack_pointer_rtx))));
4999
  add_reg_note (insn, REG_INC, stack_pointer_rtx);
5000
  DONE;
5001
}")
5002
 
5003
;; These two patterns can happen as the result of optimization, when
5004
;; comparisons get simplified to a move of zero or 1 into the T reg.
5005
;; They don't disappear completely, because the T reg is a fixed hard reg.
5006
 
5007
(define_insn "clrt"
5008
  [(set (reg:SI T_REG) (const_int 0))]
5009
  "TARGET_SH1"
5010
  "clrt")
5011
 
5012
(define_insn "sett"
5013
  [(set (reg:SI T_REG) (const_int 1))]
5014
  "TARGET_SH1"
5015
  "sett")
5016
 
5017
;; Define additional pop for SH1 and SH2 so it does not get
5018
;; placed in the delay slot.
5019
(define_insn "*movsi_pop"
5020
  [(set (match_operand:SI 0 "register_operand" "=r,x,l")
5021
        (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
5022
  "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
5023
   && ! TARGET_SH3"
5024
  "@
5025
   mov.l   %1,%0
5026
   lds.l   %1,%0
5027
   lds.l   %1,%0"
5028
  [(set_attr "type" "load_si,mem_mac,pload")
5029
   (set_attr "length" "2,2,2")
5030
   (set_attr "in_delay_slot" "no,no,no")])
5031
 
5032
;; t/r must come after r/r, lest reload will try to reload stuff like
5033
;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
5034
;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
5035
(define_insn "movsi_i"
5036
  [(set (match_operand:SI 0 "general_movdst_operand"
5037
            "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
5038
        (match_operand:SI 1 "general_movsrc_operand"
5039
         "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
5040
  "TARGET_SH1
5041
   && ! TARGET_SH2E
5042
   && ! TARGET_SH2A
5043
   && (register_operand (operands[0], SImode)
5044
       || register_operand (operands[1], SImode))"
5045
  "@
5046
        mov.l   %1,%0
5047
        mov     %1,%0
5048
        mov     %1,%0
5049
        cmp/pl  %1
5050
        mov.l   %1,%0
5051
        sts     %1,%0
5052
        sts     %1,%0
5053
        movt    %0
5054
        mov.l   %1,%0
5055
        sts.l   %1,%0
5056
        sts.l   %1,%0
5057
        lds     %1,%0
5058
        lds     %1,%0
5059
        lds.l   %1,%0
5060
        lds.l   %1,%0
5061
        fake    %1,%0"
5062
  [(set_attr "type" "pcload_si,move,movi8,mt_group,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
5063
   (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
5064
 
5065
;; t/r must come after r/r, lest reload will try to reload stuff like
5066
;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
5067
;; ??? This allows moves from macl to fpul to be recognized, but these moves
5068
;; will require a reload.
5069
;; ??? We can't include f/f because we need the proper FPSCR setting when
5070
;; TARGET_FMOVD is in effect, and mode switching is done before reload.
5071
(define_insn "movsi_ie"
5072
  [(set (match_operand:SI 0 "general_movdst_operand"
5073
            "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
5074
        (match_operand:SI 1 "general_movsrc_operand"
5075
         "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
5076
  "(TARGET_SH2E || TARGET_SH2A)
5077
   && (register_operand (operands[0], SImode)
5078
       || register_operand (operands[1], SImode))"
5079
  "@
5080
        mov.l   %1,%0
5081
        mov     %1,%0
5082
        mov     %1,%0
5083
        movi20  %1,%0
5084
        movi20s %1,%0
5085
        cmp/pl  %1
5086
        mov.l   %1,%0
5087
        sts     %1,%0
5088
        sts     %1,%0
5089
        movt    %0
5090
        mov.l   %1,%0
5091
        sts.l   %1,%0
5092
        sts.l   %1,%0
5093
        lds     %1,%0
5094
        lds     %1,%0
5095
        lds.l   %1,%0
5096
        lds.l   %1,%0
5097
        lds.l   %1,%0
5098
        sts.l   %1,%0
5099
        fake    %1,%0
5100
        lds     %1,%0
5101
        sts     %1,%0
5102
        fsts    fpul,%0
5103
        flds    %1,fpul
5104
        fmov    %1,%0
5105
        ! move optimized away"
5106
  [(set_attr "type" "pcload_si,move,movi8,move,move,*,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
5107
   (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
5108
   (set_attr_alternative "length"
5109
     [(const_int 2)
5110
      (const_int 2)
5111
      (const_int 2)
5112
      (const_int 4)
5113
      (const_int 4)
5114
      (const_int 2)
5115
      (if_then_else
5116
        (match_test "TARGET_SH2A")
5117
        (const_int 4) (const_int 2))
5118
      (const_int 2)
5119
      (const_int 2)
5120
      (const_int 2)
5121
      (if_then_else
5122
        (match_test "TARGET_SH2A")
5123
        (const_int 4) (const_int 2))
5124
      (const_int 2)
5125
      (const_int 2)
5126
      (const_int 2)
5127
      (const_int 2)
5128
      (const_int 2)
5129
      (const_int 2)
5130
      (const_int 2)
5131
      (const_int 2)
5132
      (const_int 2)
5133
      (const_int 2)
5134
      (const_int 2)
5135
      (const_int 2)
5136
      (const_int 2)
5137
      (const_int 2)
5138
      (const_int 0)])])
5139
 
5140
(define_insn "movsi_i_lowpart"
5141
  [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5142
        (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5143
   "TARGET_SH1
5144
    && (register_operand (operands[0], SImode)
5145
        || register_operand (operands[1], SImode))"
5146
  "@
5147
        mov.l   %1,%0
5148
        mov     %1,%0
5149
        mov     %1,%0
5150
        mov.l   %1,%0
5151
        sts     %1,%0
5152
        sts     %1,%0
5153
        movt    %0
5154
        mov.l   %1,%0
5155
        fake    %1,%0"
5156
  [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5157
 
5158
(define_insn_and_split "load_ra"
5159
  [(set (match_operand:SI 0 "general_movdst_operand" "")
5160
        (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5161
  "TARGET_SH1"
5162
  "#"
5163
  "&& ! currently_expanding_to_rtl"
5164
  [(set (match_dup 0) (match_dup 1))]
5165
  "
5166
{
5167
  if (TARGET_SHCOMPACT && crtl->saves_all_registers)
5168
    operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5169
}")
5170
 
5171
;; The '?'s in the following constraints may not reflect the time taken
5172
;; to perform the move. They are there to discourage the use of floating-
5173
;; point registers for storing integer values.
5174
(define_insn "*movsi_media"
5175
  [(set (match_operand:SI 0 "general_movdst_operand"
5176
                "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5177
        (match_operand:SI 1 "general_movsrc_operand"
5178
         "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5179
  "TARGET_SHMEDIA_FPU
5180
   && (register_operand (operands[0], SImode)
5181
       || sh_register_operand (operands[1], SImode)
5182
       || GET_CODE (operands[1]) == TRUNCATE)"
5183
  "@
5184
        add.l   %1, r63, %0
5185
        movi    %1, %0
5186
        #
5187
        ld%M1.l %m1, %0
5188
        st%M0.l %m0, %N1
5189
        fld%M1.s        %m1, %0
5190
        fst%M0.s        %m0, %1
5191
        fmov.ls %N1, %0
5192
        fmov.sl %1, %0
5193
        fmov.s  %1, %0
5194
        ptabs   %1, %0
5195
        gettr   %1, %0
5196
        pt      %1, %0"
5197
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,fpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
5198
   (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5199
   (set (attr "highpart")
5200
        (cond [(match_test "sh_contains_memref_p (insn)")
5201
               (const_string "user")]
5202
              (const_string "ignore")))])
5203
 
5204
(define_insn "*movsi_media_nofpu"
5205
  [(set (match_operand:SI 0 "general_movdst_operand"
5206
                "=r,r,r,r,m,*b,r,*b")
5207
        (match_operand:SI 1 "general_movsrc_operand"
5208
         "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5209
  "TARGET_SHMEDIA
5210
   && (register_operand (operands[0], SImode)
5211
       || sh_register_operand (operands[1], SImode)
5212
       || GET_CODE (operands[1]) == TRUNCATE)"
5213
  "@
5214
        add.l   %1, r63, %0
5215
        movi    %1, %0
5216
        #
5217
        ld%M1.l %m1, %0
5218
        st%M0.l %m0, %N1
5219
        ptabs   %1, %0
5220
        gettr   %1, %0
5221
        pt      %1, %0"
5222
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5223
   (set_attr "length" "4,4,8,4,4,4,4,12")
5224
   (set (attr "highpart")
5225
        (cond [(match_test "sh_contains_memref_p (insn)")
5226
               (const_string "user")]
5227
              (const_string "ignore")))])
5228
 
5229
(define_expand "movsi_const"
5230
  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5231
        (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5232
                              (const_int 16)] UNSPEC_EXTRACT_S16)))
5233
   (set (match_dup 0)
5234
        (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5235
                (const:SI (unspec:SI [(match_dup 1)
5236
                                      (const_int 0)] UNSPEC_EXTRACT_U16))))]
5237
  "TARGET_SHMEDIA && reload_completed
5238
   && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5239
  "
5240
{
5241
  if (GET_CODE (operands[1]) == LABEL_REF
5242
      && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5243
    LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5244
  else if (GOTOFF_P (operands[1]))
5245
    {
5246
      rtx unspec = XEXP (operands[1], 0);
5247
 
5248
      if (! UNSPEC_GOTOFF_P (unspec))
5249
        {
5250
          unspec = XEXP (unspec, 0);
5251
          if (! UNSPEC_GOTOFF_P (unspec))
5252
            abort ();
5253
        }
5254
      if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5255
          && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5256
        LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5257
    }
5258
}")
5259
 
5260
(define_expand "movsi_const_16bit"
5261
  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5262
        (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5263
                              (const_int 0)] UNSPEC_EXTRACT_S16)))]
5264
  "TARGET_SHMEDIA && flag_pic && reload_completed
5265
   && GET_CODE (operands[1]) == SYMBOL_REF"
5266
  "")
5267
 
5268
(define_split
5269
  [(set (match_operand:SI 0 "arith_reg_dest" "")
5270
        (match_operand:SI 1 "immediate_operand" ""))]
5271
  "TARGET_SHMEDIA && reload_completed
5272
   && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5273
  [(const_int 0)]
5274
  "
5275
{
5276
  rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5277
 
5278
  set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5279
 
5280
  DONE;
5281
}")
5282
 
5283
(define_split
5284
  [(set (match_operand:SI 0 "register_operand" "")
5285
        (match_operand:SI 1 "immediate_operand" ""))]
5286
  "TARGET_SHMEDIA && reload_completed
5287
   && ((CONST_INT_P (operands[1])
5288
        && ! satisfies_constraint_I16 (operands[1]))
5289
       || GET_CODE (operands[1]) == CONST_DOUBLE)"
5290
  [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5291
 
5292
(define_expand "movsi"
5293
  [(set (match_operand:SI 0 "general_movdst_operand" "")
5294
        (match_operand:SI 1 "general_movsrc_operand" ""))]
5295
  ""
5296
  "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5297
 
5298
(define_expand "ic_invalidate_line"
5299
  [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5300
                                (match_dup 1)] UNSPEC_ICACHE)
5301
              (clobber (scratch:SI))])]
5302
  "TARGET_HARD_SH4 || TARGET_SH5"
5303
  "
5304
{
5305
  if (TARGET_SHMEDIA)
5306
    {
5307
      emit_insn (gen_ic_invalidate_line_media (operands[0]));
5308
      DONE;
5309
    }
5310
  else if (TARGET_SHCOMPACT)
5311
    {
5312
      operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5313
      operands[1] = force_reg (Pmode, operands[1]);
5314
      emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5315
      DONE;
5316
    }
5317
  else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5318
    {
5319
      emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5320
      DONE;
5321
    }
5322
  operands[0] = force_reg (Pmode, operands[0]);
5323
  operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5324
                                                               Pmode)));
5325
}")
5326
 
5327
;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5328
;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5329
;; the requirement *1*00 for associative address writes.  The alignment of
5330
;; %0 implies that its least significant bit is cleared,
5331
;; thus we clear the V bit of a matching entry if there is one.
5332
(define_insn "ic_invalidate_line_i"
5333
  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5334
                     (match_operand:SI 1 "register_operand" "r")]
5335
                     UNSPEC_ICACHE)
5336
   (clobber (match_scratch:SI 2 "=&r"))]
5337
  "TARGET_HARD_SH4"
5338
  "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5339
  [(set_attr "length" "8")
5340
   (set_attr "type" "cwb")])
5341
 
5342
(define_insn "ic_invalidate_line_sh4a"
5343
  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5344
                    UNSPEC_ICACHE)]
5345
  "TARGET_SH4A_ARCH || TARGET_SH4_300"
5346
  "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5347
  [(set_attr "length" "16")
5348
   (set_attr "type" "cwb")])
5349
 
5350
;; ??? could make arg 0 an offsettable memory operand to allow to save
5351
;; an add in the code that calculates the address.
5352
(define_insn "ic_invalidate_line_media"
5353
  [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5354
                    UNSPEC_ICACHE)]
5355
  "TARGET_SHMEDIA"
5356
  "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5357
  [(set_attr "length" "16")
5358
   (set_attr "type" "invalidate_line_media")])
5359
 
5360
(define_insn "ic_invalidate_line_compact"
5361
  [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5362
                     (match_operand:SI 1 "register_operand" "r")]
5363
                    UNSPEC_ICACHE)
5364
   (clobber (reg:SI PR_REG))]
5365
  "TARGET_SHCOMPACT"
5366
  "jsr @%1%#"
5367
  [(set_attr "type" "sfunc")
5368
   (set_attr "needs_delay_slot" "yes")])
5369
 
5370
(define_expand "initialize_trampoline"
5371
  [(match_operand:SI 0 "" "")
5372
   (match_operand:SI 1 "" "")
5373
   (match_operand:SI 2 "" "")]
5374
  "TARGET_SHCOMPACT"
5375
  "
5376
{
5377
  rtx sfun, tramp;
5378
 
5379
  tramp = force_reg (Pmode, operands[0]);
5380
  sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5381
                                            SFUNC_STATIC));
5382
  emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5383
  emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5384
 
5385
  emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5386
  DONE;
5387
}")
5388
 
5389
(define_insn "initialize_trampoline_compact"
5390
  [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5391
                     (match_operand:SI 1 "register_operand" "r")
5392
                     (reg:SI R2_REG) (reg:SI R3_REG)]
5393
                    UNSPEC_INIT_TRAMP)
5394
 
5395
   (clobber (reg:SI PR_REG))]
5396
  "TARGET_SHCOMPACT"
5397
  "jsr @%1%#"
5398
  [(set_attr "type" "sfunc")
5399
   (set_attr "needs_delay_slot" "yes")])
5400
 
5401
(define_insn "movqi_i"
5402
  [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5403
        (match_operand:QI 1 "general_movsrc_operand"  "r,i,m,r,t,l,r"))]
5404
  "TARGET_SH1
5405
   && (arith_reg_operand (operands[0], QImode)
5406
       || arith_reg_operand (operands[1], QImode))"
5407
  "@
5408
        mov     %1,%0
5409
        mov     %1,%0
5410
        mov.b   %1,%0
5411
        mov.b   %1,%0
5412
        movt    %0
5413
        sts     %1,%0
5414
        lds     %1,%0"
5415
 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5416
  (set_attr_alternative "length"
5417
     [(const_int 2)
5418
      (const_int 2)
5419
      (if_then_else
5420
        (match_test "TARGET_SH2A")
5421
        (const_int 4) (const_int 2))
5422
      (if_then_else
5423
        (match_test "TARGET_SH2A")
5424
        (const_int 4) (const_int 2))
5425
      (const_int 2)
5426
      (const_int 2)
5427
      (const_int 2)])])
5428
 
5429
(define_insn "*movqi_media"
5430
  [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5431
        (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5432
  "TARGET_SHMEDIA
5433
   && (arith_reg_operand (operands[0], QImode)
5434
       || extend_reg_or_0_operand (operands[1], QImode))"
5435
  "@
5436
        add.l   %1, r63, %0
5437
        movi    %1, %0
5438
        ld%M1.ub        %m1, %0
5439
        st%M0.b %m0, %N1"
5440
  [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5441
   (set (attr "highpart")
5442
        (cond [(match_test "sh_contains_memref_p (insn)")
5443
               (const_string "user")]
5444
              (const_string "ignore")))])
5445
 
5446
(define_expand "movqi"
5447
  [(set (match_operand:QI 0 "general_operand" "")
5448
        (match_operand:QI 1 "general_operand"  ""))]
5449
  ""
5450
  "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5451
 
5452
(define_expand "reload_inqi"
5453
  [(set (match_operand:SI 2 "" "=&r")
5454
        (match_operand:QI 1 "inqhi_operand" ""))
5455
   (set (match_operand:QI 0 "arith_reg_operand" "=r")
5456
        (truncate:QI (match_dup 3)))]
5457
  "TARGET_SHMEDIA"
5458
  "
5459
{
5460
  rtx inner = XEXP (operands[1], 0);
5461
  int regno = REGNO (inner);
5462
 
5463
  regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5464
  operands[1] = gen_rtx_REG (SImode, regno);
5465
  operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5466
}")
5467
 
5468
;; When storing r0, we have to avoid reg+reg addressing.
5469
(define_insn "movhi_i"
5470
  [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5471
        (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5472
  "TARGET_SH1
5473
   && (arith_reg_operand (operands[0], HImode)
5474
       || arith_reg_operand (operands[1], HImode))
5475
   && (!MEM_P (operands[0])
5476
       || GET_CODE (XEXP (operands[0], 0)) != PLUS
5477
       || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5478
       || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5479
  "@
5480
        mov.w   %1,%0
5481
        mov     %1,%0
5482
        mov.w   %1,%0
5483
        movt    %0
5484
        mov.w   %1,%0
5485
        sts     %1,%0
5486
        lds     %1,%0
5487
        fake    %1,%0"
5488
  [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5489
 
5490
(define_insn "*movhi_media"
5491
  [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5492
        (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5493
  "TARGET_SHMEDIA
5494
   && (arith_reg_operand (operands[0], HImode)
5495
       || arith_reg_or_0_operand (operands[1], HImode))"
5496
  "@
5497
        add.l   %1, r63, %0
5498
        movi    %1, %0
5499
        #
5500
        ld%M1.w %m1, %0
5501
        st%M0.w %m0, %N1"
5502
  [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5503
   (set (attr "highpart")
5504
        (cond [(match_test "sh_contains_memref_p (insn)")
5505
               (const_string "user")]
5506
              (const_string "ignore")))])
5507
 
5508
(define_split
5509
  [(set (match_operand:HI 0 "register_operand" "")
5510
        (match_operand:HI 1 "immediate_operand" ""))]
5511
  "TARGET_SHMEDIA && reload_completed
5512
   && ! satisfies_constraint_I16 (operands[1])"
5513
  [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5514
 
5515
(define_expand "movhi"
5516
  [(set (match_operand:HI 0 "general_movdst_operand" "")
5517
        (match_operand:HI 1 "general_movsrc_operand"  ""))]
5518
  ""
5519
  "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5520
 
5521
(define_expand "reload_inhi"
5522
  [(set (match_operand:SI 2 "" "=&r")
5523
        (match_operand:HI 1 "inqhi_operand" ""))
5524
   (set (match_operand:HI 0 "arith_reg_operand" "=r")
5525
        (truncate:HI (match_dup 3)))]
5526
  "TARGET_SHMEDIA"
5527
  "
5528
{
5529
  rtx inner = XEXP (operands[1], 0);
5530
  int regno = REGNO (inner);
5531
 
5532
  regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5533
  operands[1] = gen_rtx_REG (SImode, regno);
5534
  operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5535
}")
5536
 
5537
;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5538
;; compiled with -m2 -ml -O3 -funroll-loops
5539
(define_insn "*movdi_i"
5540
  [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5541
        (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5542
  "TARGET_SH1
5543
   && (arith_reg_operand (operands[0], DImode)
5544
       || arith_reg_operand (operands[1], DImode))"
5545
  "* return output_movedouble (insn, operands, DImode);"
5546
  [(set_attr "length" "4")
5547
   (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5548
 
5549
;; If the output is a register and the input is memory or a register, we have
5550
;; to be careful and see which word needs to be loaded first.
5551
 
5552
(define_split
5553
  [(set (match_operand:DI 0 "general_movdst_operand" "")
5554
        (match_operand:DI 1 "general_movsrc_operand" ""))]
5555
  "TARGET_SH1 && reload_completed"
5556
  [(set (match_dup 2) (match_dup 3))
5557
   (set (match_dup 4) (match_dup 5))]
5558
  "
5559
{
5560
  int regno;
5561
 
5562
  if ((MEM_P (operands[0])
5563
       && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5564
      || (MEM_P (operands[1])
5565
          && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5566
    FAIL;
5567
 
5568
  switch (GET_CODE (operands[0]))
5569
    {
5570
    case REG:
5571
      regno = REGNO (operands[0]);
5572
      break;
5573
    case SUBREG:
5574
      regno = subreg_regno (operands[0]);
5575
      break;
5576
    case MEM:
5577
      regno = -1;
5578
      break;
5579
    default:
5580
      gcc_unreachable ();
5581
    }
5582
 
5583
  if (regno == -1
5584
      || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5585
    {
5586
      operands[2] = operand_subword (operands[0], 0, 0, DImode);
5587
      operands[3] = operand_subword (operands[1], 0, 0, DImode);
5588
      operands[4] = operand_subword (operands[0], 1, 0, DImode);
5589
      operands[5] = operand_subword (operands[1], 1, 0, DImode);
5590
    }
5591
  else
5592
    {
5593
      operands[2] = operand_subword (operands[0], 1, 0, DImode);
5594
      operands[3] = operand_subword (operands[1], 1, 0, DImode);
5595
      operands[4] = operand_subword (operands[0], 0, 0, DImode);
5596
      operands[5] = operand_subword (operands[1], 0, 0, DImode);
5597
    }
5598
 
5599
  if (operands[2] == 0 || operands[3] == 0
5600
      || operands[4] == 0 || operands[5] == 0)
5601
    FAIL;
5602
}")
5603
 
5604
;; The '?'s in the following constraints may not reflect the time taken
5605
;; to perform the move. They are there to discourage the use of floating-
5606
;; point registers for storing integer values.
5607
(define_insn "*movdi_media"
5608
  [(set (match_operand:DI 0 "general_movdst_operand"
5609
                 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5610
        (match_operand:DI 1 "general_movsrc_operand"
5611
         "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5612
  "TARGET_SHMEDIA_FPU
5613
   && (register_operand (operands[0], DImode)
5614
       || sh_register_operand (operands[1], DImode))"
5615
  "@
5616
        add     %1, r63, %0
5617
        movi    %1, %0
5618
        #
5619
        ld%M1.q %m1, %0
5620
        st%M0.q %m0, %N1
5621
        fld%M1.d        %m1, %0
5622
        fst%M0.d        %m0, %1
5623
        fmov.qd %N1, %0
5624
        fmov.dq %1, %0
5625
        fmov.d  %1, %0
5626
        ptabs   %1, %0
5627
        gettr   %1, %0
5628
        pt      %1, %0"
5629
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,dfpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
5630
   (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5631
 
5632
(define_insn "*movdi_media_nofpu"
5633
  [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5634
        (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5635
  "TARGET_SHMEDIA
5636
   && (register_operand (operands[0], DImode)
5637
       || sh_register_operand (operands[1], DImode))"
5638
  "@
5639
        add     %1, r63, %0
5640
        movi    %1, %0
5641
        #
5642
        ld%M1.q %m1, %0
5643
        st%M0.q %m0, %N1
5644
        ptabs   %1, %0
5645
        gettr   %1, %0
5646
        pt      %1, %0"
5647
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5648
   (set_attr "length" "4,4,16,4,4,4,4,*")])
5649
 
5650
(define_insn "*movdi_media_I16"
5651
  [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5652
        (match_operand:DI 1 "const_int_operand" "I16"))]
5653
  "TARGET_SHMEDIA && reload_completed"
5654
  "movi %1, %0"
5655
  [(set_attr "type" "arith_media")
5656
   (set_attr "length" "4")])
5657
 
5658
(define_split
5659
  [(set (match_operand:DI 0 "arith_reg_dest" "")
5660
        (match_operand:DI 1 "immediate_operand" ""))]
5661
  "TARGET_SHMEDIA && reload_completed
5662
   && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5663
  [(set (match_dup 0) (match_dup 1))]
5664
  "
5665
{
5666
  rtx insn;
5667
 
5668
  if (TARGET_SHMEDIA64)
5669
    insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5670
  else
5671
    insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5672
 
5673
  set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5674
 
5675
  DONE;
5676
}")
5677
 
5678
(define_expand "movdi_const"
5679
  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5680
        (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5681
                              (const_int 48)] UNSPEC_EXTRACT_S16)))
5682
   (set (match_dup 0)
5683
        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5684
                (const:DI (unspec:DI [(match_dup 1)
5685
                                      (const_int 32)] UNSPEC_EXTRACT_U16))))
5686
   (set (match_dup 0)
5687
        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5688
                (const:DI (unspec:DI [(match_dup 1)
5689
                                      (const_int 16)] UNSPEC_EXTRACT_U16))))
5690
   (set (match_dup 0)
5691
        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5692
                (const:DI (unspec:DI [(match_dup 1)
5693
                                      (const_int 0)] UNSPEC_EXTRACT_U16))))]
5694
  "TARGET_SHMEDIA64 && reload_completed
5695
   && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5696
  "
5697
{
5698
  sh_mark_label (operands[1], 4);
5699
}")
5700
 
5701
(define_expand "movdi_const_32bit"
5702
  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5703
        (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5704
                              (const_int 16)] UNSPEC_EXTRACT_S16)))
5705
   (set (match_dup 0)
5706
        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5707
                (const:DI (unspec:DI [(match_dup 1)
5708
                                      (const_int 0)] UNSPEC_EXTRACT_U16))))]
5709
  "TARGET_SHMEDIA32 && reload_completed
5710
   && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5711
  "
5712
{
5713
  sh_mark_label (operands[1], 2);
5714
}")
5715
 
5716
(define_expand "movdi_const_16bit"
5717
  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5718
        (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5719
                              (const_int 0)] UNSPEC_EXTRACT_S16)))]
5720
  "TARGET_SHMEDIA && flag_pic && reload_completed
5721
   && GET_CODE (operands[1]) == SYMBOL_REF"
5722
  "")
5723
 
5724
(define_split
5725
  [(set (match_operand:DI 0 "ext_dest_operand" "")
5726
        (match_operand:DI 1 "immediate_operand" ""))]
5727
  "TARGET_SHMEDIA && reload_completed
5728
   && CONST_INT_P (operands[1])
5729
   && ! satisfies_constraint_I16 (operands[1])"
5730
  [(set (match_dup 0) (match_dup 2))
5731
   (match_dup 1)]
5732
  "
5733
{
5734
  unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5735
  unsigned HOST_WIDE_INT low = val;
5736
  unsigned HOST_WIDE_INT high = val;
5737
  unsigned HOST_WIDE_INT sign;
5738
  unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5739
 
5740
  /* Zero-extend the 16 least-significant bits.  */
5741
  low &= 0xffff;
5742
 
5743
  /* Arithmetic shift right the word by 16 bits.  */
5744
  high >>= 16;
5745
  if (GET_CODE (operands[0]) == SUBREG
5746
      && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5747
    {
5748
      high &= 0xffff;
5749
      high ^= 0x8000;
5750
      high -= 0x8000;
5751
    }
5752
  else
5753
    {
5754
      sign = 1;
5755
      sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5756
      high ^= sign;
5757
      high -= sign;
5758
    }
5759
  do
5760
    {
5761
      /* If we can't generate the constant with a two-insn movi / shori
5762
         sequence, try some other strategies.  */
5763
      if (! CONST_OK_FOR_I16 (high))
5764
        {
5765
          /* Try constant load / left shift.  We know VAL != 0.  */
5766
          val2 = val ^ (val-1);
5767
          if (val2 > 0x1ffff)
5768
            {
5769
              int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5770
 
5771
              if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5772
                  || (! CONST_OK_FOR_I16 (high >> 16)
5773
                      && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5774
                {
5775
                  val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5776
                  operands[1] = gen_ashldi3_media (operands[0], operands[0],
5777
                                                   GEN_INT (trailing_zeroes));
5778
                  break;
5779
                }
5780
            }
5781
          /* Try constant load / right shift.  */
5782
          val2 = (val >> 15) + 1;
5783
          if (val2 == (val2 & -val2))
5784
            {
5785
              int shift = 49 - exact_log2 (val2);
5786
 
5787
              val2 = trunc_int_for_mode (val << shift, DImode);
5788
              if (CONST_OK_FOR_I16 (val2))
5789
                {
5790
                  operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5791
                                                   GEN_INT (shift));
5792
                  break;
5793
                }
5794
            }
5795
          /* Try mperm.w .  */
5796
          val2 = val & 0xffff;
5797
          if ((val >> 16 & 0xffff) == val2
5798
              && (val >> 32 & 0xffff) == val2
5799
              && (val >> 48 & 0xffff) == val2)
5800
            {
5801
              val2 = (HOST_WIDE_INT) val >> 48;
5802
              operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5803
              operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5804
              break;
5805
            }
5806
          /* Try movi / mshflo.l  */
5807
          val2 = (HOST_WIDE_INT) val >> 32;
5808
          if (val2 == ((unsigned HOST_WIDE_INT)
5809
                        trunc_int_for_mode (val, SImode)))
5810
            {
5811
              operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5812
                                             operands[0]);
5813
              break;
5814
            }
5815
          /* Try movi / mshflo.l w/ r63.  */
5816
          val2 = val + ((HOST_WIDE_INT) -1 << 32);
5817
          if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5818
            {
5819
              operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5820
                                             const0_rtx);
5821
              break;
5822
            }
5823
        }
5824
      val2 = high;
5825
      operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5826
    }
5827
  while (0);
5828
  operands[2] = GEN_INT (val2);
5829
}")
5830
 
5831
(define_split
5832
  [(set (match_operand:DI 0 "ext_dest_operand" "")
5833
        (match_operand:DI 1 "immediate_operand" ""))]
5834
  "TARGET_SHMEDIA && reload_completed
5835
   && GET_CODE (operands[1]) == CONST_DOUBLE"
5836
  [(set (match_dup 0) (match_dup 2))
5837
  (set (match_dup 0)
5838
       (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5839
  "
5840
{
5841
  unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5842
  unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5843
  unsigned HOST_WIDE_INT val = low;
5844
  unsigned HOST_WIDE_INT sign;
5845
 
5846
  /* Zero-extend the 16 least-significant bits.  */
5847
  val &= 0xffff;
5848
  operands[1] = GEN_INT (val);
5849
 
5850
  /* Arithmetic shift right the double-word by 16 bits.  */
5851
  low >>= 16;
5852
  low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5853
  high >>= 16;
5854
  sign = 1;
5855
  sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5856
  high ^= sign;
5857
  high -= sign;
5858
 
5859
  /* This will only be true if high is a sign-extension of low, i.e.,
5860
     it must be either 0 or (unsigned)-1, and be zero iff the
5861
     most-significant bit of low is set.  */
5862
  if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5863
    operands[2] = GEN_INT (low);
5864
  else
5865
    operands[2] = immed_double_const (low, high, DImode);
5866
}")
5867
 
5868
(define_insn "shori_media"
5869
  [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5870
        (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5871
                           (const_int 16))
5872
                (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5873
  "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5874
  "@
5875
        shori   %u2, %0
5876
        #"
5877
  [(set_attr "type" "arith_media,*")])
5878
 
5879
(define_insn "*shori_media_si"
5880
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5881
        (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5882
                           (const_int 16))
5883
                (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5884
  "TARGET_SHMEDIA"
5885
  "shori        %u2, %0")
5886
 
5887
(define_expand "movdi"
5888
  [(set (match_operand:DI 0 "general_movdst_operand" "")
5889
        (match_operand:DI 1 "general_movsrc_operand" ""))]
5890
  ""
5891
  "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5892
 
5893
(define_insn "movdf_media"
5894
  [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5895
        (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5896
  "TARGET_SHMEDIA_FPU
5897
   && (register_operand (operands[0], DFmode)
5898
       || sh_register_operand (operands[1], DFmode))"
5899
  "@
5900
        fmov.d  %1, %0
5901
        fmov.qd %N1, %0
5902
        fmov.dq %1, %0
5903
        add     %1, r63, %0
5904
        #
5905
        fld%M1.d        %m1, %0
5906
        fst%M0.d        %m0, %1
5907
        ld%M1.q %m1, %0
5908
        st%M0.q %m0, %N1"
5909
  [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5910
 
5911
(define_insn "movdf_media_nofpu"
5912
  [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5913
        (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5914
  "TARGET_SHMEDIA
5915
   && (register_operand (operands[0], DFmode)
5916
       || sh_register_operand (operands[1], DFmode))"
5917
  "@
5918
        add     %1, r63, %0
5919
        #
5920
        ld%M1.q %m1, %0
5921
        st%M0.q %m0, %N1"
5922
  [(set_attr "type" "arith_media,*,load_media,store_media")])
5923
 
5924
(define_split
5925
  [(set (match_operand:DF 0 "arith_reg_dest" "")
5926
        (match_operand:DF 1 "immediate_operand" ""))]
5927
  "TARGET_SHMEDIA && reload_completed"
5928
  [(set (match_dup 3) (match_dup 2))]
5929
  "
5930
{
5931
  int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5932
  long values[2];
5933
  REAL_VALUE_TYPE value;
5934
 
5935
  REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5936
  REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5937
 
5938
  if (HOST_BITS_PER_WIDE_INT >= 64)
5939
    operands[2] = immed_double_const ((unsigned long) values[endian]
5940
                                      | ((HOST_WIDE_INT) values[1 - endian]
5941
                                         << 32), 0, DImode);
5942
  else
5943
    {
5944
      gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5945
      operands[2] = immed_double_const (values[endian], values[1 - endian],
5946
                                        DImode);
5947
    }
5948
 
5949
  operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5950
}")
5951
 
5952
;; ??? This should be a define expand.
5953
 
5954
(define_insn "movdf_k"
5955
  [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5956
        (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5957
  "TARGET_SH1
5958
   && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5959
       /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5960
       || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5961
       || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5962
   && (arith_reg_operand (operands[0], DFmode)
5963
       || arith_reg_operand (operands[1], DFmode))"
5964
  "* return output_movedouble (insn, operands, DFmode);"
5965
  [(set_attr "length" "4")
5966
   (set_attr "type" "move,pcload,load,store")])
5967
 
5968
;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5969
;; However, the d/F/c/z alternative cannot be split directly; it is converted
5970
;; with special code in machine_dependent_reorg into a load of the R0_REG and
5971
;; the d/m/c/X alternative, which is split later into single-precision
5972
;; instructions.  And when not optimizing, no splits are done before fixing
5973
;; up pcloads, so we need usable length information for that.
5974
(define_insn "movdf_i4"
5975
  [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5976
        (match_operand:DF 1 "general_movsrc_operand"  "d,r,F,m,d,FQ,m,r,d,r"))
5977
   (use (match_operand:PSI 2 "fpscr_operand"          "c,c,c,c,c,c,c,c,c,c"))
5978
   (clobber (match_scratch:SI 3                      "=X,X,&z,X,X,X,X,X,X,X"))]
5979
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5980
   && (arith_reg_operand (operands[0], DFmode)
5981
       || arith_reg_operand (operands[1], DFmode))"
5982
  {
5983
    switch (which_alternative)
5984
    {
5985
    case 0:
5986
      if (TARGET_FMOVD)
5987
        return "fmov    %1,%0";
5988
      else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
5989
        return "fmov    %R1,%R0\n\tfmov %S1,%S0";
5990
      else
5991
        return "fmov    %S1,%S0\n\tfmov %R1,%R0";
5992
    case 3:
5993
    case 4:
5994
      return "fmov.d    %1,%0";
5995
    default:
5996
      return "#";
5997
    }
5998
  }
5999
  [(set_attr_alternative "length"
6000
     [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
6001
      (const_int 4)
6002
      (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6003
      (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6004
      (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6005
      (const_int 4)
6006
      (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
6007
      ;; We can't use 4-byte push/pop on SHcompact, so we have to
6008
      ;; increment or decrement r15 explicitly.
6009
      (if_then_else
6010
       (match_test "TARGET_SHCOMPACT")
6011
       (const_int 10) (const_int 8))
6012
      (if_then_else
6013
       (match_test "TARGET_SHCOMPACT")
6014
       (const_int 10) (const_int 8))])
6015
   (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
6016
   (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
6017
   (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6018
                                           (const_string "double")
6019
                                           (const_string "none")))])
6020
 
6021
;; Moving DFmode between fp/general registers through memory
6022
;; (the top of the stack) is faster than moving through fpul even for
6023
;; little endian.  Because the type of an instruction is important for its
6024
;; scheduling,  it is beneficial to split these operations, rather than
6025
;; emitting them in one single chunk, even if this will expose a stack
6026
;; use that will prevent scheduling of other stack accesses beyond this
6027
;; instruction.
6028
(define_split
6029
  [(set (match_operand:DF 0 "register_operand" "")
6030
        (match_operand:DF 1 "register_operand" ""))
6031
   (use (match_operand:PSI 2 "fpscr_operand" ""))
6032
   (clobber (match_scratch:SI 3 "=X"))]
6033
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
6034
   && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
6035
  [(const_int 0)]
6036
  "
6037
{
6038
  rtx insn, tos;
6039
 
6040
  if (TARGET_SH5 && true_regnum (operands[1]) < 16)
6041
    {
6042
      emit_move_insn (stack_pointer_rtx,
6043
                      plus_constant (stack_pointer_rtx, -8));
6044
      tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6045
    }
6046
  else
6047
    tos = gen_tmp_stack_mem (DFmode,
6048
                             gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
6049
  insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
6050
  if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
6051
    add_reg_note (insn, REG_INC, stack_pointer_rtx);
6052
  if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6053
    tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6054
  else
6055
    tos = gen_tmp_stack_mem (DFmode,
6056
                             gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
6057
  insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
6058
  if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6059
    emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
6060
  else
6061
    add_reg_note (insn, REG_INC, stack_pointer_rtx);
6062
  DONE;
6063
}")
6064
 
6065
;; local-alloc sometimes allocates scratch registers even when not required,
6066
;; so we must be prepared to handle these.
6067
 
6068
;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
6069
(define_split
6070
  [(set (match_operand:DF 0 "general_movdst_operand" "")
6071
        (match_operand:DF 1 "general_movsrc_operand"  ""))
6072
   (use (match_operand:PSI 2 "fpscr_operand" ""))
6073
   (clobber (match_scratch:SI 3 ""))]
6074
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6075
   && reload_completed
6076
   && true_regnum (operands[0]) < 16
6077
   && true_regnum (operands[1]) < 16"
6078
  [(set (match_dup 0) (match_dup 1))]
6079
  "
6080
{
6081
  /* If this was a reg <-> mem operation with base + index reg addressing,
6082
     we have to handle this in a special way.  */
6083
  rtx mem = operands[0];
6084
  int store_p = 1;
6085
  if (! memory_operand (mem, DFmode))
6086
    {
6087
      mem = operands[1];
6088
      store_p = 0;
6089
    }
6090
  if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
6091
    mem = SUBREG_REG (mem);
6092
  if (MEM_P (mem))
6093
    {
6094
      rtx addr = XEXP (mem, 0);
6095
      if (GET_CODE (addr) == PLUS
6096
          && REG_P (XEXP (addr, 0))
6097
          && REG_P (XEXP (addr, 1)))
6098
        {
6099
          int offset;
6100
          rtx reg0 = gen_rtx_REG (Pmode, 0);
6101
          rtx regop = operands[store_p], word0 ,word1;
6102
 
6103
          if (GET_CODE (regop) == SUBREG)
6104
            alter_subreg (®op);
6105
          if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
6106
            offset = 2;
6107
          else
6108
            offset = 4;
6109
          mem = copy_rtx (mem);
6110
          PUT_MODE (mem, SImode);
6111
          word0 = gen_rtx_SUBREG (SImode, regop, 0);
6112
          alter_subreg (&word0);
6113
          word1 = gen_rtx_SUBREG (SImode, regop, 4);
6114
          alter_subreg (&word1);
6115
          if (store_p || ! refers_to_regno_p (REGNO (word0),
6116
                                              REGNO (word0) + 1, addr, 0))
6117
            {
6118
              emit_insn (store_p
6119
                         ? gen_movsi_ie (mem, word0)
6120
                         : gen_movsi_ie (word0, mem));
6121
              emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6122
              mem = copy_rtx (mem);
6123
              emit_insn (store_p
6124
                         ? gen_movsi_ie (mem, word1)
6125
                         : gen_movsi_ie (word1, mem));
6126
              emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6127
            }
6128
          else
6129
            {
6130
              emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6131
              emit_insn (gen_movsi_ie (word1, mem));
6132
              emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6133
              mem = copy_rtx (mem);
6134
              emit_insn (gen_movsi_ie (word0, mem));
6135
            }
6136
          DONE;
6137
        }
6138
    }
6139
}")
6140
 
6141
;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6142
(define_split
6143
  [(set (match_operand:DF 0 "register_operand" "")
6144
        (match_operand:DF 1 "memory_operand"  ""))
6145
   (use (match_operand:PSI 2 "fpscr_operand" ""))
6146
   (clobber (reg:SI R0_REG))]
6147
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6148
  [(parallel [(set (match_dup 0) (match_dup 1))
6149
              (use (match_dup 2))
6150
              (clobber (scratch:SI))])]
6151
  "")
6152
 
6153
(define_expand "reload_indf__frn"
6154
  [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6155
                   (match_operand:DF 1 "immediate_operand" "FQ"))
6156
              (use (reg:PSI FPSCR_REG))
6157
              (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6158
  "TARGET_SH1"
6159
  "")
6160
 
6161
(define_expand "reload_outdf__RnFRm"
6162
  [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6163
                   (match_operand:DF 1 "register_operand" "af,r"))
6164
              (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6165
  "TARGET_SH1"
6166
  "")
6167
 
6168
;; Simplify no-op moves.
6169
(define_split
6170
  [(set (match_operand:SF 0 "register_operand" "")
6171
        (match_operand:SF 1 "register_operand" ""))
6172
   (use (match_operand:PSI 2 "fpscr_operand" ""))
6173
   (clobber (match_scratch:SI 3 ""))]
6174
  "TARGET_SH2E && reload_completed
6175
   && true_regnum (operands[0]) == true_regnum (operands[1])"
6176
  [(set (match_dup 0) (match_dup 0))]
6177
  "")
6178
 
6179
;; fmovd substitute post-reload splits
6180
(define_split
6181
  [(set (match_operand:DF 0 "register_operand" "")
6182
        (match_operand:DF 1 "register_operand" ""))
6183
   (use (match_operand:PSI 2 "fpscr_operand" ""))
6184
   (clobber (match_scratch:SI 3 ""))]
6185
  "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6186
   && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6187
   && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6188
  [(const_int 0)]
6189
  "
6190
{
6191
  int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6192
  emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6193
                           gen_rtx_REG (SFmode, src), operands[2]));
6194
  emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6195
                           gen_rtx_REG (SFmode, src + 1), operands[2]));
6196
  DONE;
6197
}")
6198
 
6199
(define_split
6200
  [(set (match_operand:DF 0 "register_operand" "")
6201
        (mem:DF (match_operand:SI 1 "register_operand" "")))
6202
   (use (match_operand:PSI 2 "fpscr_operand" ""))
6203
   (clobber (match_scratch:SI 3 ""))]
6204
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6205
   && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6206
   && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6207
  [(const_int 0)]
6208
  "
6209
{
6210
  int regno = true_regnum (operands[0]);
6211
  rtx insn;
6212
  rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6213
  rtx mem2
6214
    = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6215
  insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6216
                                           regno + !! TARGET_LITTLE_ENDIAN),
6217
                                  mem2, operands[2]));
6218
  add_reg_note (insn, REG_INC, operands[1]);
6219
  insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6220
                                               regno + ! TARGET_LITTLE_ENDIAN),
6221
                                  change_address (mem, SFmode, NULL_RTX),
6222
                                  operands[2]));
6223
  DONE;
6224
}")
6225
 
6226
(define_split
6227
  [(set (match_operand:DF 0 "register_operand" "")
6228
        (match_operand:DF 1 "memory_operand" ""))
6229
   (use (match_operand:PSI 2 "fpscr_operand" ""))
6230
   (clobber (match_scratch:SI 3 ""))]
6231
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6232
   && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6233
  [(const_int 0)]
6234
{
6235
  int regno = true_regnum (operands[0]);
6236
  rtx addr, insn;
6237
  rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6238
  rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6239
  rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6240
 
6241
  operands[1] = copy_rtx (mem2);
6242
  addr = XEXP (mem2, 0);
6243
 
6244
  switch (GET_CODE (addr))
6245
    {
6246
    case REG:
6247
      /* This is complicated.  If the register is an arithmetic register
6248
         we can just fall through to the REG+DISP case below.  Otherwise
6249
         we have to use a combination of POST_INC and REG addressing...  */
6250
      if (! arith_reg_operand (operands[1], SFmode))
6251
        {
6252
          XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6253
          insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6254
          add_reg_note (insn, REG_INC, XEXP (addr, 0));
6255
 
6256
          emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6257
 
6258
          /* If we have modified the stack pointer, the value that we have
6259
             read with post-increment might be modified by an interrupt,
6260
             so write it back.  */
6261
          if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6262
            emit_insn (gen_push_e (reg0));
6263
          else
6264
            emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6265
          break;
6266
        }
6267
      /* Fall through.  */
6268
 
6269
    case PLUS:
6270
      emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6271
      operands[1] = copy_rtx (operands[1]);
6272
      XEXP (operands[1], 0) = plus_constant (addr, 4);
6273
      emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6274
      break;
6275
 
6276
    case POST_INC:
6277
      insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6278
      add_reg_note (insn, REG_INC, XEXP (addr, 0));
6279
 
6280
      insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6281
      add_reg_note (insn, REG_INC, XEXP (addr, 0));
6282
      break;
6283
 
6284
    default:
6285
      debug_rtx (addr);
6286
      gcc_unreachable ();
6287
    }
6288
 
6289
  DONE;
6290
})
6291
 
6292
(define_split
6293
  [(set (match_operand:DF 0 "memory_operand" "")
6294
        (match_operand:DF 1 "register_operand" ""))
6295
   (use (match_operand:PSI 2 "fpscr_operand" ""))
6296
   (clobber (match_scratch:SI 3 ""))]
6297
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6298
   && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6299
  [(const_int 0)]
6300
{
6301
  int regno = true_regnum (operands[1]);
6302
  rtx insn, addr;
6303
  rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6304
  rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6305
 
6306
  operands[0] = copy_rtx (operands[0]);
6307
  PUT_MODE (operands[0], SFmode);
6308
  addr = XEXP (operands[0], 0);
6309
 
6310
  switch (GET_CODE (addr))
6311
    {
6312
    case REG:
6313
      /* This is complicated.  If the register is an arithmetic register
6314
         we can just fall through to the REG+DISP case below.  Otherwise
6315
         we have to use a combination of REG and PRE_DEC addressing...  */
6316
      if (! arith_reg_operand (operands[0], SFmode))
6317
        {
6318
          emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6319
          emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6320
 
6321
          operands[0] = copy_rtx (operands[0]);
6322
          XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6323
 
6324
          insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6325
          add_reg_note (insn, REG_INC, XEXP (addr, 0));
6326
          break;
6327
        }
6328
      /* Fall through.  */
6329
 
6330
    case PLUS:
6331
      /* Since REG+DISP addressing has already been decided upon by gcc
6332
         we can rely upon it having chosen an arithmetic register as the
6333
         register component of the address.  Just emit the lower numbered
6334
         register first, to the lower address, then the higher numbered
6335
         register to the higher address.  */
6336
      emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6337
 
6338
      operands[0] = copy_rtx (operands[0]);
6339
      XEXP (operands[0], 0) = plus_constant (addr, 4);
6340
 
6341
      emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6342
      break;
6343
 
6344
    case PRE_DEC:
6345
      /* This is easy.  Output the word to go to the higher address
6346
         first (ie the word in the higher numbered register) then the
6347
         word to go to the lower address.  */
6348
 
6349
      insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6350
      add_reg_note (insn, REG_INC, XEXP (addr, 0));
6351
 
6352
      insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6353
      add_reg_note (insn, REG_INC, XEXP (addr, 0));
6354
      break;
6355
 
6356
    default:
6357
      /* FAIL; */
6358
      debug_rtx (addr);
6359
      gcc_unreachable ();
6360
    }
6361
 
6362
  DONE;
6363
})
6364
 
6365
;; If the output is a register and the input is memory or a register, we have
6366
;; to be careful and see which word needs to be loaded first.
6367
 
6368
(define_split
6369
  [(set (match_operand:DF 0 "general_movdst_operand" "")
6370
        (match_operand:DF 1 "general_movsrc_operand" ""))]
6371
  "TARGET_SH1 && reload_completed"
6372
  [(set (match_dup 2) (match_dup 3))
6373
   (set (match_dup 4) (match_dup 5))]
6374
  "
6375
{
6376
  int regno;
6377
 
6378
  if ((MEM_P (operands[0])
6379
       && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6380
      || (MEM_P (operands[1])
6381
          && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6382
    FAIL;
6383
 
6384
  switch (GET_CODE (operands[0]))
6385
    {
6386
    case REG:
6387
      regno = REGNO (operands[0]);
6388
      break;
6389
    case SUBREG:
6390
      regno = subreg_regno (operands[0]);
6391
      break;
6392
    case MEM:
6393
      regno = -1;
6394
      break;
6395
    default:
6396
      gcc_unreachable ();
6397
    }
6398
 
6399
  if (regno == -1
6400
      || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6401
    {
6402
      operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6403
      operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6404
      operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6405
      operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6406
    }
6407
  else
6408
    {
6409
      operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6410
      operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6411
      operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6412
      operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6413
    }
6414
 
6415
  if (operands[2] == 0 || operands[3] == 0
6416
      || operands[4] == 0 || operands[5] == 0)
6417
    FAIL;
6418
}")
6419
 
6420
;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6421
;; used only once, let combine add in the index again.
6422
 
6423
(define_split
6424
  [(set (match_operand:SI 0 "register_operand" "")
6425
        (match_operand:SI 1 "" ""))
6426
   (clobber (match_operand 2 "register_operand" ""))]
6427
  "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6428
   && ALLOW_INDEXED_ADDRESS"
6429
  [(use (reg:SI R0_REG))]
6430
  "
6431
{
6432
  rtx addr, reg, const_int;
6433
 
6434
  if (!MEM_P (operands[1]))
6435
    FAIL;
6436
  addr = XEXP (operands[1], 0);
6437
  if (GET_CODE (addr) != PLUS)
6438
    FAIL;
6439
  reg = XEXP (addr, 0);
6440
  const_int = XEXP (addr, 1);
6441
  if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6442
         && CONST_INT_P (const_int)))
6443
    FAIL;
6444
  emit_move_insn (operands[2], const_int);
6445
  emit_move_insn (operands[0],
6446
                  change_address (operands[1], VOIDmode,
6447
                                  gen_rtx_PLUS (SImode, reg, operands[2])));
6448
  DONE;
6449
}")
6450
 
6451
(define_split
6452
  [(set (match_operand:SI 1 "" "")
6453
        (match_operand:SI 0 "register_operand" ""))
6454
   (clobber (match_operand 2 "register_operand" ""))]
6455
  "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6456
   && ALLOW_INDEXED_ADDRESS"
6457
  [(use (reg:SI R0_REG))]
6458
  "
6459
{
6460
  rtx addr, reg, const_int;
6461
 
6462
  if (!MEM_P (operands[1]))
6463
    FAIL;
6464
  addr = XEXP (operands[1], 0);
6465
  if (GET_CODE (addr) != PLUS)
6466
    FAIL;
6467
  reg = XEXP (addr, 0);
6468
  const_int = XEXP (addr, 1);
6469
  if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6470
         && CONST_INT_P (const_int)))
6471
    FAIL;
6472
  emit_move_insn (operands[2], const_int);
6473
  emit_move_insn (change_address (operands[1], VOIDmode,
6474
                                  gen_rtx_PLUS (SImode, reg, operands[2])),
6475
                  operands[0]);
6476
  DONE;
6477
}")
6478
 
6479
(define_expand "movdf"
6480
  [(set (match_operand:DF 0 "general_movdst_operand" "")
6481
        (match_operand:DF 1 "general_movsrc_operand" ""))]
6482
  ""
6483
  "
6484
{
6485
  if (prepare_move_operands (operands, DFmode)) DONE;
6486
  if (TARGET_SHMEDIA)
6487
    {
6488
      if (TARGET_SHMEDIA_FPU)
6489
        emit_insn (gen_movdf_media (operands[0], operands[1]));
6490
      else
6491
        emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6492
      DONE;
6493
    }
6494
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6495
    {
6496
      emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6497
      DONE;
6498
    }
6499
}")
6500
 
6501
;;This is incompatible with the way gcc uses subregs.
6502
;;(define_insn "movv2sf_i"
6503
;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6504
;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6505
;;  "TARGET_SHMEDIA_FPU
6506
;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6507
;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6508
;;  "@
6509
;;      #
6510
;;      fld%M1.p        %m1, %0
6511
;;      fst%M0.p        %m0, %1"
6512
;;  [(set_attr "type" "*,fload_media,fstore_media")])
6513
 
6514
(define_insn_and_split "movv2sf_i"
6515
  [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6516
        (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6517
  "TARGET_SHMEDIA_FPU"
6518
  "#"
6519
  "TARGET_SHMEDIA_FPU && reload_completed"
6520
  [(set (match_dup 0) (match_dup 1))]
6521
  "
6522
{
6523
  operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6524
  operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6525
}")
6526
 
6527
(define_expand "movv2sf"
6528
  [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6529
        (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6530
  "TARGET_SHMEDIA_FPU"
6531
  "
6532
{
6533
  if (prepare_move_operands (operands, V2SFmode))
6534
    DONE;
6535
}")
6536
 
6537
(define_expand "addv2sf3"
6538
  [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6539
   (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6540
   (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6541
  "TARGET_SHMEDIA_FPU"
6542
  "
6543
{
6544
  sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6545
  DONE;
6546
}")
6547
 
6548
(define_expand "subv2sf3"
6549
  [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6550
   (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6551
   (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6552
  "TARGET_SHMEDIA_FPU"
6553
  "
6554
{
6555
  sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6556
  DONE;
6557
}")
6558
 
6559
(define_expand "mulv2sf3"
6560
  [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6561
   (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6562
   (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6563
  "TARGET_SHMEDIA_FPU"
6564
  "
6565
{
6566
  sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6567
  DONE;
6568
}")
6569
 
6570
(define_expand "divv2sf3"
6571
  [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6572
   (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6573
   (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6574
  "TARGET_SHMEDIA_FPU"
6575
  "
6576
{
6577
  sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6578
  DONE;
6579
}")
6580
 
6581
(define_insn_and_split "*movv4sf_i"
6582
  [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6583
        (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6584
  "TARGET_SHMEDIA_FPU"
6585
  "#"
6586
  "&& reload_completed"
6587
  [(const_int 0)]
6588
  "
6589
{
6590
  int i;
6591
 
6592
  for (i = 0; i < 4/2; i++)
6593
    {
6594
      rtx x, y;
6595
 
6596
      if (MEM_P (operands[0]))
6597
        x = adjust_address (operands[0], V2SFmode,
6598
                            i * GET_MODE_SIZE (V2SFmode));
6599
      else
6600
        x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6601
 
6602
      if (MEM_P (operands[1]))
6603
        y = adjust_address (operands[1], V2SFmode,
6604
                            i * GET_MODE_SIZE (V2SFmode));
6605
      else
6606
        y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6607
 
6608
      emit_insn (gen_movv2sf_i (x, y));
6609
    }
6610
 
6611
  DONE;
6612
}"
6613
  [(set_attr "length" "8")])
6614
 
6615
(define_expand "movv4sf"
6616
  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6617
        (match_operand:V4SF 1 "general_operand" ""))]
6618
  "TARGET_SHMEDIA_FPU"
6619
  "
6620
{
6621
  if (prepare_move_operands (operands, V4SFmode))
6622
    DONE;
6623
}")
6624
 
6625
(define_insn_and_split "*movv16sf_i"
6626
  [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6627
        (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6628
  "TARGET_SHMEDIA_FPU"
6629
  "#"
6630
  "&& reload_completed"
6631
  [(const_int 0)]
6632
  "
6633
{
6634
  int i;
6635
 
6636
  for (i = 0; i < 16/2; i++)
6637
    {
6638
      rtx x,y;
6639
 
6640
      if (MEM_P (operands[0]))
6641
        x = adjust_address (operands[0], V2SFmode,
6642
                            i * GET_MODE_SIZE (V2SFmode));
6643
      else
6644
        {
6645
          x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6646
          alter_subreg (&x);
6647
        }
6648
 
6649
      if (MEM_P (operands[1]))
6650
        y = adjust_address (operands[1], V2SFmode,
6651
                            i * GET_MODE_SIZE (V2SFmode));
6652
      else
6653
        {
6654
          y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6655
          alter_subreg (&y);
6656
        }
6657
 
6658
      emit_insn (gen_movv2sf_i (x, y));
6659
    }
6660
 
6661
  DONE;
6662
}"
6663
  [(set_attr "length" "32")])
6664
 
6665
(define_expand "movv16sf"
6666
  [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6667
        (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6668
  "TARGET_SHMEDIA_FPU"
6669
  "
6670
{
6671
  if (prepare_move_operands (operands, V16SFmode))
6672
    DONE;
6673
}")
6674
 
6675
(define_insn "movsf_media"
6676
  [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6677
        (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6678
  "TARGET_SHMEDIA_FPU
6679
   && (register_operand (operands[0], SFmode)
6680
       || sh_register_operand (operands[1], SFmode))"
6681
  "@
6682
        fmov.s  %1, %0
6683
        fmov.ls %N1, %0
6684
        fmov.sl %1, %0
6685
        add.l   %1, r63, %0
6686
        #
6687
        fld%M1.s        %m1, %0
6688
        fst%M0.s        %m0, %1
6689
        ld%M1.l %m1, %0
6690
        st%M0.l %m0, %N1"
6691
  [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6692
   (set (attr "highpart")
6693
        (cond [(match_test "sh_contains_memref_p (insn)")
6694
               (const_string "user")]
6695
              (const_string "ignore")))])
6696
 
6697
(define_insn "movsf_media_nofpu"
6698
  [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6699
        (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6700
  "TARGET_SHMEDIA
6701
   && (register_operand (operands[0], SFmode)
6702
       || sh_register_operand (operands[1], SFmode))"
6703
  "@
6704
        add.l   %1, r63, %0
6705
        #
6706
        ld%M1.l %m1, %0
6707
        st%M0.l %m0, %N1"
6708
  [(set_attr "type" "arith_media,*,load_media,store_media")
6709
   (set (attr "highpart")
6710
        (cond [(match_test "sh_contains_memref_p (insn)")
6711
               (const_string "user")]
6712
              (const_string "ignore")))])
6713
 
6714
(define_split
6715
  [(set (match_operand:SF 0 "arith_reg_dest" "")
6716
        (match_operand:SF 1 "immediate_operand" ""))]
6717
  "TARGET_SHMEDIA && reload_completed
6718
   && ! FP_REGISTER_P (true_regnum (operands[0]))"
6719
  [(set (match_dup 3) (match_dup 2))]
6720
  "
6721
{
6722
  long values;
6723
  REAL_VALUE_TYPE value;
6724
 
6725
  REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6726
  REAL_VALUE_TO_TARGET_SINGLE (value, values);
6727
  operands[2] = GEN_INT (values);
6728
 
6729
  operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6730
}")
6731
 
6732
(define_insn "movsf_i"
6733
  [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6734
        (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6735
  "TARGET_SH1
6736
   && (! TARGET_SH2E
6737
       /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6738
       || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6739
       || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6740
   && (arith_reg_operand (operands[0], SFmode)
6741
       || arith_reg_operand (operands[1], SFmode))"
6742
  "@
6743
        mov     %1,%0
6744
        mov     #0,%0
6745
        mov.l   %1,%0
6746
        mov.l   %1,%0
6747
        mov.l   %1,%0
6748
        lds     %1,%0
6749
        sts     %1,%0"
6750
  [(set_attr "type" "move,move,pcload,load,store,move,move")])
6751
 
6752
;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6753
;; update_flow_info would not know where to put REG_EQUAL notes
6754
;; when the destination changes mode.
6755
(define_insn "movsf_ie"
6756
  [(set (match_operand:SF 0 "general_movdst_operand"
6757
         "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6758
        (match_operand:SF 1 "general_movsrc_operand"
6759
          "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6760
   (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c"))
6761
   (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6762
 
6763
  "TARGET_SH2E
6764
   && (arith_reg_operand (operands[0], SFmode)
6765
       || arith_reg_operand (operands[1], SFmode)
6766
       || arith_reg_operand (operands[3], SImode)
6767
       || (fpul_operand (operands[0], SFmode)
6768
           && memory_operand (operands[1], SFmode)
6769
           && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6770
       || (fpul_operand (operands[1], SFmode)
6771
           && memory_operand (operands[0], SFmode)
6772
           && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6773
  "@
6774
        fmov    %1,%0
6775
        mov     %1,%0
6776
        fldi0   %0
6777
        fldi1   %0
6778
        #
6779
        fmov.s  %1,%0
6780
        fmov.s  %1,%0
6781
        mov.l   %1,%0
6782
        mov.l   %1,%0
6783
        mov.l   %1,%0
6784
        fsts    fpul,%0
6785
        flds    %1,fpul
6786
        lds.l   %1,%0
6787
        #
6788
        sts     %1,%0
6789
        lds     %1,%0
6790
        sts.l   %1,%0
6791
        lds.l   %1,%0
6792
        ! move optimized away"
6793
  [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6794
   (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6795
   (set_attr_alternative "length"
6796
     [(const_int 2)
6797
      (const_int 2)
6798
      (const_int 2)
6799
      (const_int 2)
6800
      (const_int 4)
6801
      (if_then_else
6802
        (match_test "TARGET_SH2A")
6803
        (const_int 4) (const_int 2))
6804
      (if_then_else
6805
        (match_test "TARGET_SH2A")
6806
        (const_int 4) (const_int 2))
6807
      (const_int 2)
6808
      (if_then_else
6809
        (match_test "TARGET_SH2A")
6810
        (const_int 4) (const_int 2))
6811
      (if_then_else
6812
        (match_test "TARGET_SH2A")
6813
        (const_int 4) (const_int 2))
6814
      (const_int 2)
6815
      (const_int 2)
6816
      (const_int 2)
6817
      (const_int 4)
6818
      (const_int 2)
6819
      (const_int 2)
6820
      (const_int 2)
6821
      (const_int 2)
6822
      (const_int 0)])
6823
   (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6824
                                           (const_string "single")
6825
                                           (const_string "single")))])
6826
 
6827
(define_split
6828
  [(set (match_operand:SF 0 "register_operand" "")
6829
        (match_operand:SF 1 "register_operand" ""))
6830
   (use (match_operand:PSI 2 "fpscr_operand" ""))
6831
   (clobber (reg:SI FPUL_REG))]
6832
  "TARGET_SH1"
6833
  [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6834
              (use (match_dup 2))
6835
              (clobber (scratch:SI))])
6836
   (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6837
              (use (match_dup 2))
6838
              (clobber (scratch:SI))])]
6839
  "")
6840
 
6841
(define_expand "movsf"
6842
  [(set (match_operand:SF 0 "general_movdst_operand" "")
6843
        (match_operand:SF 1 "general_movsrc_operand" ""))]
6844
  ""
6845
  "
6846
{
6847
  if (prepare_move_operands (operands, SFmode))
6848
    DONE;
6849
  if (TARGET_SHMEDIA)
6850
    {
6851
      if (TARGET_SHMEDIA_FPU)
6852
        emit_insn (gen_movsf_media (operands[0], operands[1]));
6853
      else
6854
        emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6855
      DONE;
6856
    }
6857
  if (TARGET_SH2E)
6858
    {
6859
      emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6860
      DONE;
6861
    }
6862
}")
6863
 
6864
(define_insn "mov_nop"
6865
  [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6866
  "TARGET_SH2E"
6867
  ""
6868
  [(set_attr "length" "0")
6869
   (set_attr "type" "nil")])
6870
 
6871
(define_expand "reload_insf__frn"
6872
  [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6873
                   (match_operand:SF 1 "immediate_operand" "FQ"))
6874
              (use (reg:PSI FPSCR_REG))
6875
              (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6876
  "TARGET_SH1"
6877
  "")
6878
 
6879
(define_expand "reload_insi__i_fpul"
6880
  [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6881
                   (match_operand:SI 1 "immediate_operand" "i"))
6882
              (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6883
  "TARGET_SH1"
6884
  "")
6885
 
6886
(define_expand "ptabs"
6887
  [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6888
  "TARGET_SHMEDIA"
6889
  "
6890
{
6891
  if (!TARGET_PT_FIXED)
6892
    {
6893
      rtx eq = operands[1];
6894
 
6895
      /* ??? For canonical RTL we really should remove any CONST from EQ
6896
         before wrapping it in the AND, and finally wrap the EQ into a
6897
         const if is constant.  However, for reload we must expose the
6898
         input register or symbolic constant, and we can't have
6899
         different insn structures outside of the operands for different
6900
         alternatives of the same pattern.  */
6901
      eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6902
                       GEN_INT (3));
6903
      operands[1]
6904
        = (gen_rtx_IF_THEN_ELSE
6905
            (PDImode,
6906
             eq,
6907
             gen_rtx_MEM (PDImode, operands[1]),
6908
             gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6909
                            PDImode, operands[1])));
6910
    }
6911
}")
6912
 
6913
;; expanded by ptabs expander.
6914
(define_insn "*extendsipdi_media"
6915
  [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6916
        (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6917
                                                          "r,Csy")
6918
                                      (const_int 3))
6919
                              (const_int 3))
6920
                          (mem:PDI (match_dup 1))
6921
                          (sign_extend:PDI (match_dup 1))))]
6922
  "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6923
  "@
6924
        ptabs   %1, %0
6925
        pt      %1, %0"
6926
  [(set_attr "type"   "ptabs_media,pt_media")
6927
   (set_attr "length" "4,*")])
6928
 
6929
(define_insn "*truncdipdi_media"
6930
  [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6931
        (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6932
                                                          "r,Csy")
6933
                                      (const_int 3))
6934
                              (const_int 3))
6935
                          (mem:PDI (match_dup 1))
6936
                          (truncate:PDI (match_dup 1))))]
6937
  "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6938
  "@
6939
        ptabs   %1, %0
6940
        pt      %1, %0"
6941
  [(set_attr "type"   "ptabs_media,pt_media")
6942
   (set_attr "length" "4,*")])
6943
 
6944
(define_insn "*movsi_y"
6945
  [(set (match_operand:SI 0 "register_operand" "=y,y")
6946
        (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6947
   (clobber (match_scratch:SI 2 "=&z,r"))]
6948
  "TARGET_SH2E
6949
   && (reload_in_progress || reload_completed)"
6950
  "#"
6951
  [(set_attr "length" "4")
6952
   (set_attr "type" "pcload,move")])
6953
 
6954
(define_split
6955
  [(set (match_operand:SI 0 "register_operand" "")
6956
        (match_operand:SI 1 "immediate_operand" ""))
6957
   (clobber (match_operand:SI 2 "register_operand" ""))]
6958
  "TARGET_SH1"
6959
  [(set (match_dup 2) (match_dup 1))
6960
   (set (match_dup 0) (match_dup 2))]
6961
  "")
6962
 
6963
(define_split
6964
  [(set (match_operand:SI 0 "register_operand" "")
6965
        (match_operand:SI 1 "memory_operand" ""))
6966
   (clobber (reg:SI R0_REG))]
6967
  "TARGET_SH1"
6968
  [(set (match_dup 0) (match_dup 1))]
6969
  "")
6970
 
6971
;; ------------------------------------------------------------------------
6972
;; Define the real conditional branch instructions.
6973
;; ------------------------------------------------------------------------
6974
 
6975
(define_insn "branch_true"
6976
  [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6977
                           (label_ref (match_operand 0 "" ""))
6978
                           (pc)))]
6979
  "TARGET_SH1"
6980
  "* return output_branch (1, insn, operands);"
6981
  [(set_attr "type" "cbranch")])
6982
 
6983
(define_insn "branch_false"
6984
  [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6985
                           (label_ref (match_operand 0 "" ""))
6986
                           (pc)))]
6987
  "TARGET_SH1"
6988
  "* return output_branch (0, insn, operands);"
6989
  [(set_attr "type" "cbranch")])
6990
 
6991
;; Patterns to prevent reorg from re-combining a condbranch with a branch
6992
;; which destination is too far away.
6993
;; The const_int_operand is distinct for each branch target; it avoids
6994
;; unwanted matches with redundant_insn.
6995
(define_insn "block_branch_redirect"
6996
  [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6997
  "TARGET_SH1"
6998
  ""
6999
  [(set_attr "length" "0")])
7000
 
7001
;; This one has the additional purpose to record a possible scratch register
7002
;; for the following branch.
7003
;; ??? Unfortunately, just setting the scratch register is not good enough,
7004
;; because the insn then might be deemed dead and deleted.  And we can't
7005
;; make the use in the jump insn explicit because that would disable
7006
;; delay slot scheduling from the target.
7007
(define_insn "indirect_jump_scratch"
7008
  [(set (match_operand:SI 0 "register_operand" "=r")
7009
        (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
7010
   (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
7011
  "TARGET_SH1"
7012
  ""
7013
  [(set_attr "length" "0")])
7014
 
7015
;; This one is used to preemt an insn from beyond the bra / braf / jmp
7016
;; being pulled into the delay slot of a condbranch that has been made to
7017
;; jump around the unconditional jump because it was out of range.
7018
(define_insn "stuff_delay_slot"
7019
  [(set (pc)
7020
        (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
7021
                 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
7022
  "TARGET_SH1"
7023
  ""
7024
  [(set_attr "length" "0")
7025
   (set_attr "cond_delay_slot" "yes")])
7026
 
7027
;; Conditional branch insns
7028
 
7029
(define_expand "cbranchint4_media"
7030
  [(set (pc)
7031
        (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
7032
                       [(match_operand 1 "" "")
7033
                        (match_operand 2 "" "")])
7034
                      (match_operand 3 "" "")
7035
                      (pc)))]
7036
  "TARGET_SHMEDIA"
7037
  "
7038
{
7039
  enum machine_mode mode = GET_MODE (operands[1]);
7040
  if (mode == VOIDmode)
7041
    mode = GET_MODE (operands[2]);
7042
  if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
7043
    {
7044
      operands[1] = force_reg (mode, operands[1]);
7045
      if (CONSTANT_P (operands[2])
7046
          && (! satisfies_constraint_I06 (operands[2])))
7047
        operands[2] = force_reg (mode, operands[2]);
7048
    }
7049
  else
7050
    {
7051
      if (operands[1] != const0_rtx)
7052
        operands[1] = force_reg (mode, operands[1]);
7053
      if (operands[2] != const0_rtx)
7054
        operands[2] = force_reg (mode, operands[2]);
7055
    }
7056
  switch (GET_CODE (operands[0]))
7057
    {
7058
    case LEU:
7059
    case LE:
7060
    case LTU:
7061
    case LT:
7062
      operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
7063
                                    VOIDmode, operands[2], operands[1]);
7064
      operands[1] = XEXP (operands[0], 0);
7065
      operands[2] = XEXP (operands[0], 1);
7066
      break;
7067
    default:
7068
      operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
7069
                                    VOIDmode, operands[1], operands[2]);
7070
      break;
7071
    }
7072
  operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7073
}")
7074
 
7075
(define_expand "cbranchfp4_media"
7076
  [(set (pc)
7077
        (if_then_else (match_operator 0 "sh_float_comparison_operator"
7078
                       [(match_operand 1 "" "")
7079
                        (match_operand 2 "" "")])
7080
                      (match_operand 3 "" "")
7081
                      (pc)))]
7082
  "TARGET_SHMEDIA"
7083
  "
7084
{
7085
  rtx tmp = gen_reg_rtx (SImode);
7086
  rtx cmp;
7087
  if (GET_CODE (operands[0]) == NE)
7088
    cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
7089
  else
7090
    cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
7091
                          operands[1], operands[2]);
7092
 
7093
  emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
7094
 
7095
  if (GET_CODE (cmp) == GET_CODE (operands[0]))
7096
    operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
7097
  else
7098
    operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
7099
  operands[1] = tmp;
7100
  operands[2] = const0_rtx;
7101
  operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7102
}")
7103
 
7104
(define_insn "*beq_media_i"
7105
  [(set (pc)
7106
        (if_then_else (match_operator 3 "equality_comparison_operator"
7107
                        [(match_operand:DI 1 "arith_reg_operand" "r,r")
7108
                         (match_operand:DI 2 "arith_operand" "r,I06")])
7109
                      (match_operand 0 "target_operand" "b,b")
7110
                      (pc)))]
7111
  "TARGET_SHMEDIA"
7112
  "@
7113
        b%o3%'  %1, %2, %0%>
7114
        b%o3i%' %1, %2, %0%>"
7115
  [(set_attr "type" "cbranch_media")])
7116
 
7117
(define_insn "*beq_media_i32"
7118
  [(set (pc)
7119
        (if_then_else (match_operator 3 "equality_comparison_operator"
7120
                        [(match_operand:SI 1 "arith_reg_operand" "r,r")
7121
                         (match_operand:SI 2 "arith_operand" "r,I06")])
7122
                      (match_operand 0 "target_operand" "b,b")
7123
                      (pc)))]
7124
  "TARGET_SHMEDIA"
7125
  "@
7126
        b%o3%'  %1, %2, %0%>
7127
        b%o3i%' %1, %2, %0%>"
7128
  [(set_attr "type" "cbranch_media")])
7129
 
7130
(define_insn "*bgt_media_i"
7131
  [(set (pc)
7132
        (if_then_else (match_operator 3 "greater_comparison_operator"
7133
                        [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7134
                         (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7135
                      (match_operand 0 "target_operand" "b")
7136
                      (pc)))]
7137
  "TARGET_SHMEDIA"
7138
  "b%o3%'       %N1, %N2, %0%>"
7139
  [(set_attr "type" "cbranch_media")])
7140
 
7141
(define_insn "*bgt_media_i32"
7142
  [(set (pc)
7143
        (if_then_else (match_operator 3 "greater_comparison_operator"
7144
                        [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7145
                         (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7146
                      (match_operand 0 "target_operand" "b")
7147
                      (pc)))]
7148
  "TARGET_SHMEDIA"
7149
  "b%o3%'       %N1, %N2, %0%>"
7150
  [(set_attr "type" "cbranch_media")])
7151
 
7152
;; These are only needed to make invert_jump() happy - otherwise, jump
7153
;; optimization will be silently disabled.
7154
(define_insn "*blt_media_i"
7155
  [(set (pc)
7156
        (if_then_else (match_operator 3 "less_comparison_operator"
7157
                        [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7158
                         (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7159
                      (match_operand 0 "target_operand" "b")
7160
                      (pc)))]
7161
  "TARGET_SHMEDIA"
7162
  "b%o3%'       %N2, %N1, %0%>"
7163
  [(set_attr "type" "cbranch_media")])
7164
 
7165
(define_insn "*blt_media_i32"
7166
  [(set (pc)
7167
        (if_then_else (match_operator 3 "less_comparison_operator"
7168
                        [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7169
                         (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7170
                      (match_operand 0 "target_operand" "b")
7171
                      (pc)))]
7172
  "TARGET_SHMEDIA"
7173
  "b%o3%'       %N2, %N1, %0%>"
7174
  [(set_attr "type" "cbranch_media")])
7175
 
7176
;; combiner splitter for test-and-branch on single bit in register.  This
7177
;; is endian dependent because the non-paradoxical subreg looks different
7178
;; on big endian.
7179
(define_split
7180
  [(set (pc)
7181
        (if_then_else
7182
          (match_operator 3 "equality_comparison_operator"
7183
            [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7184
                                                      "extend_reg_operand" "")
7185
                                                    0)
7186
                                         (const_int 1)
7187
                                         (match_operand 2
7188
                                          "const_int_operand" "")) 0)
7189
             (const_int 0)])
7190
          (match_operand 0 "target_operand" "")
7191
          (pc)))
7192
   (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7193
  "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7194
  [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7195
   (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7196
 
7197
  "
7198
{
7199
  operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7200
  operands[6] = (GET_CODE (operands[3]) == EQ
7201
                 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7202
                 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7203
}")
7204
 
7205
; operand 0 is the loop count pseudo register
7206
; operand 1 is the number of loop iterations or 0 if it is unknown
7207
; operand 2 is the maximum number of loop iterations
7208
; operand 3 is the number of levels of enclosed loops
7209
; operand 4 is the label to jump to at the top of the loop
7210
 
7211
(define_expand "doloop_end"
7212
  [(parallel [(set (pc) (if_then_else
7213
                          (ne:SI (match_operand:SI 0 "" "")
7214
                              (const_int 1))
7215
                          (label_ref (match_operand 4 "" ""))
7216
                          (pc)))
7217
              (set (match_dup 0)
7218
                   (plus:SI (match_dup 0) (const_int -1)))
7219
              (clobber (reg:SI T_REG))])]
7220
  "TARGET_SH2"
7221
  "
7222
{
7223
  if (GET_MODE (operands[0]) != SImode)
7224
    FAIL;
7225
}
7226
")
7227
 
7228
(define_insn_and_split "doloop_end_split"
7229
  [(set (pc)
7230
        (if_then_else (ne:SI  (match_operand:SI 2 "arith_reg_dest" "0")
7231
                          (const_int 1))
7232
                      (label_ref (match_operand 1 "" ""))
7233
                      (pc)))
7234
   (set (match_operand:SI 0 "arith_reg_dest" "=r")
7235
        (plus (match_dup 2) (const_int -1)))
7236
   (clobber (reg:SI T_REG))]
7237
  "TARGET_SH2"
7238
  "#"
7239
  ""
7240
  [(parallel [(set (reg:SI T_REG)
7241
                   (eq:SI (match_dup 2) (const_int 1)))
7242
              (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7243
   (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7244
                           (label_ref (match_dup 1))
7245
                           (pc)))]
7246
""
7247
   [(set_attr "type" "cbranch")])
7248
 
7249
 
7250
;; ------------------------------------------------------------------------
7251
;; Jump and linkage insns
7252
;; ------------------------------------------------------------------------
7253
 
7254
(define_insn "jump_compact"
7255
  [(set (pc)
7256
        (label_ref (match_operand 0 "" "")))]
7257
  "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7258
  "*
7259
{
7260
  /* The length is 16 if the delay slot is unfilled.  */
7261
  if (get_attr_length(insn) > 4)
7262
    return output_far_jump(insn, operands[0]);
7263
  else
7264
    return   \"bra      %l0%#\";
7265
}"
7266
  [(set_attr "type" "jump")
7267
   (set_attr "needs_delay_slot" "yes")])
7268
 
7269
;; ??? It would be much saner to explicitly use the scratch register
7270
;; in the jump insn, and have indirect_jump_scratch only set it,
7271
;; but fill_simple_delay_slots would refuse to do delay slot filling
7272
;; from the target then, as it uses simplejump_p.
7273
;;(define_insn "jump_compact_far"
7274
;;  [(set (pc)
7275
;;      (label_ref (match_operand 0 "" "")))
7276
;;   (use (match_operand 1 "register_operand" "r")]
7277
;;  "TARGET_SH1"
7278
;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7279
;;  [(set_attr "type" "jump")
7280
;;   (set_attr "needs_delay_slot" "yes")])
7281
 
7282
(define_insn "jump_media"
7283
  [(set (pc)
7284
        (match_operand 0 "target_operand" "b"))]
7285
  "TARGET_SHMEDIA"
7286
  "blink        %0, r63%>"
7287
  [(set_attr "type" "jump_media")])
7288
 
7289
(define_expand "jump"
7290
  [(set (pc)
7291
        (label_ref (match_operand 0 "" "")))]
7292
  ""
7293
  "
7294
{
7295
  if (TARGET_SH1)
7296
    emit_jump_insn (gen_jump_compact (operands[0]));
7297
  else if (TARGET_SHMEDIA)
7298
    {
7299
      if (reload_in_progress || reload_completed)
7300
        FAIL;
7301
      emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7302
                                                         operands[0])));
7303
    }
7304
  DONE;
7305
}")
7306
 
7307
(define_insn "force_mode_for_call"
7308
  [(use (reg:PSI FPSCR_REG))]
7309
  "TARGET_SHCOMPACT"
7310
  ""
7311
  [(set_attr "length" "0")
7312
   (set (attr "fp_mode")
7313
        (if_then_else (eq_attr "fpu_single" "yes")
7314
                      (const_string "single") (const_string "double")))])
7315
 
7316
(define_insn "calli"
7317
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7318
         (match_operand 1 "" ""))
7319
   (use (reg:PSI FPSCR_REG))
7320
   (clobber (reg:SI PR_REG))]
7321
  "TARGET_SH1"
7322
  "*
7323
   {
7324
     if (TARGET_SH2A && (dbr_sequence_length () == 0))
7325
        return \"jsr/n\\t@%0\";
7326
     else
7327
        return \"jsr\\t@%0%#\";
7328
   }"
7329
 
7330
  [(set_attr "type" "call")
7331
   (set (attr "fp_mode")
7332
        (if_then_else (eq_attr "fpu_single" "yes")
7333
                      (const_string "single") (const_string "double")))
7334
   (set_attr "needs_delay_slot" "yes")
7335
   (set_attr "fp_set" "unknown")])
7336
 
7337
;; This is TBR relative jump instruction for SH2A architecture.
7338
;; Its use is enabled assigning an attribute "function_vector"
7339
;; and the vector number to a function during its declaration.
7340
 
7341
(define_insn "calli_tbr_rel"
7342
  [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7343
         (match_operand 1 "" ""))
7344
   (use (reg:PSI FPSCR_REG))
7345
   (clobber (reg:SI PR_REG))]
7346
  "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7347
  "*
7348
{
7349
  unsigned HOST_WIDE_INT vect_num;
7350
  vect_num = sh2a_get_function_vector_number (operands[0]);
7351
  operands[2] = GEN_INT (vect_num * 4);
7352
 
7353
  return \"jsr/n\\t@@(%O2,tbr)\";
7354
}"
7355
  [(set_attr "type" "call")
7356
   (set (attr "fp_mode")
7357
        (if_then_else (eq_attr "fpu_single" "yes")
7358
                      (const_string "single") (const_string "double")))
7359
   (set_attr "needs_delay_slot" "no")
7360
   (set_attr "fp_set" "unknown")])
7361
 
7362
;; This is a pc-rel call, using bsrf, for use with PIC.
7363
 
7364
(define_insn "calli_pcrel"
7365
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7366
         (match_operand 1 "" ""))
7367
   (use (reg:PSI FPSCR_REG))
7368
   (use (reg:SI PIC_REG))
7369
   (use (match_operand 2 "" ""))
7370
   (clobber (reg:SI PR_REG))]
7371
  "TARGET_SH2"
7372
  "bsrf %0\\n%O2:%#"
7373
  [(set_attr "type" "call")
7374
   (set (attr "fp_mode")
7375
        (if_then_else (eq_attr "fpu_single" "yes")
7376
                      (const_string "single") (const_string "double")))
7377
   (set_attr "needs_delay_slot" "yes")
7378
   (set_attr "fp_set" "unknown")])
7379
 
7380
(define_insn_and_split "call_pcrel"
7381
  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7382
         (match_operand 1 "" ""))
7383
   (use (reg:PSI FPSCR_REG))
7384
   (use (reg:SI PIC_REG))
7385
   (clobber (reg:SI PR_REG))
7386
   (clobber (match_scratch:SI 2 "=r"))]
7387
  "TARGET_SH2"
7388
  "#"
7389
  "reload_completed"
7390
  [(const_int 0)]
7391
  "
7392
{
7393
  rtx lab = PATTERN (gen_call_site ());
7394
 
7395
  if (SYMBOL_REF_LOCAL_P (operands[0]))
7396
    emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7397
  else
7398
    emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7399
  emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7400
  DONE;
7401
}"
7402
  [(set_attr "type" "call")
7403
   (set (attr "fp_mode")
7404
        (if_then_else (eq_attr "fpu_single" "yes")
7405
                      (const_string "single") (const_string "double")))
7406
   (set_attr "needs_delay_slot" "yes")
7407
   (set_attr "fp_set" "unknown")])
7408
 
7409
(define_insn "call_compact"
7410
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7411
         (match_operand 1 "" ""))
7412
   (match_operand 2 "immediate_operand" "n")
7413
   (use (reg:SI R0_REG))
7414
   (use (reg:SI R1_REG))
7415
   (use (reg:PSI FPSCR_REG))
7416
   (clobber (reg:SI PR_REG))]
7417
  "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7418
  "jsr  @%0%#"
7419
  [(set_attr "type" "call")
7420
   (set (attr "fp_mode")
7421
        (if_then_else (eq_attr "fpu_single" "yes")
7422
                      (const_string "single") (const_string "double")))
7423
   (set_attr "needs_delay_slot" "yes")])
7424
 
7425
(define_insn "call_compact_rettramp"
7426
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7427
         (match_operand 1 "" ""))
7428
   (match_operand 2 "immediate_operand" "n")
7429
   (use (reg:SI R0_REG))
7430
   (use (reg:SI R1_REG))
7431
   (use (reg:PSI FPSCR_REG))
7432
   (clobber (reg:SI R10_REG))
7433
   (clobber (reg:SI PR_REG))]
7434
  "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7435
  "jsr  @%0%#"
7436
  [(set_attr "type" "call")
7437
   (set (attr "fp_mode")
7438
        (if_then_else (eq_attr "fpu_single" "yes")
7439
                      (const_string "single") (const_string "double")))
7440
   (set_attr "needs_delay_slot" "yes")])
7441
 
7442
(define_insn "call_media"
7443
  [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7444
         (match_operand 1 "" ""))
7445
   (clobber (reg:DI PR_MEDIA_REG))]
7446
  "TARGET_SHMEDIA"
7447
  "blink        %0, r18"
7448
  [(set_attr "type" "jump_media")])
7449
 
7450
(define_insn "call_valuei"
7451
  [(set (match_operand 0 "" "=rf")
7452
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7453
              (match_operand 2 "" "")))
7454
   (use (reg:PSI FPSCR_REG))
7455
   (clobber (reg:SI PR_REG))]
7456
  "TARGET_SH1"
7457
  "*
7458
   {
7459
     if (TARGET_SH2A && (dbr_sequence_length () == 0))
7460
        return \"jsr/n\\t@%1\";
7461
     else
7462
        return \"jsr\\t@%1%#\";
7463
   }"
7464
  [(set_attr "type" "call")
7465
   (set (attr "fp_mode")
7466
        (if_then_else (eq_attr "fpu_single" "yes")
7467
                      (const_string "single") (const_string "double")))
7468
   (set_attr "needs_delay_slot" "yes")
7469
   (set_attr "fp_set" "unknown")])
7470
 
7471
;; This is TBR relative jump instruction for SH2A architecture.
7472
;; Its use is enabled by assigning an attribute "function_vector"
7473
;; and the vector number to a function during its declaration.
7474
 
7475
(define_insn "call_valuei_tbr_rel"
7476
  [(set (match_operand 0 "" "=rf")
7477
        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7478
              (match_operand 2 "" "")))
7479
   (use (reg:PSI FPSCR_REG))
7480
   (clobber (reg:SI PR_REG))]
7481
  "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7482
  "*
7483
{
7484
  unsigned HOST_WIDE_INT vect_num;
7485
  vect_num = sh2a_get_function_vector_number (operands[1]);
7486
  operands[3] = GEN_INT (vect_num * 4);
7487
 
7488
  return \"jsr/n\\t@@(%O3,tbr)\";
7489
}"
7490
  [(set_attr "type" "call")
7491
   (set (attr "fp_mode")
7492
        (if_then_else (eq_attr "fpu_single" "yes")
7493
                      (const_string "single") (const_string "double")))
7494
   (set_attr "needs_delay_slot" "no")
7495
   (set_attr "fp_set" "unknown")])
7496
 
7497
(define_insn "call_valuei_pcrel"
7498
  [(set (match_operand 0 "" "=rf")
7499
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7500
              (match_operand 2 "" "")))
7501
   (use (reg:PSI FPSCR_REG))
7502
   (use (reg:SI PIC_REG))
7503
   (use (match_operand 3 "" ""))
7504
   (clobber (reg:SI PR_REG))]
7505
  "TARGET_SH2"
7506
  "bsrf %1\\n%O3:%#"
7507
  [(set_attr "type" "call")
7508
   (set (attr "fp_mode")
7509
        (if_then_else (eq_attr "fpu_single" "yes")
7510
                      (const_string "single") (const_string "double")))
7511
   (set_attr "needs_delay_slot" "yes")
7512
   (set_attr "fp_set" "unknown")])
7513
 
7514
(define_insn_and_split "call_value_pcrel"
7515
  [(set (match_operand 0 "" "=rf")
7516
        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7517
              (match_operand 2 "" "")))
7518
   (use (reg:PSI FPSCR_REG))
7519
   (use (reg:SI PIC_REG))
7520
   (clobber (reg:SI PR_REG))
7521
   (clobber (match_scratch:SI 3 "=r"))]
7522
  "TARGET_SH2"
7523
  "#"
7524
  "reload_completed"
7525
  [(const_int 0)]
7526
  "
7527
{
7528
  rtx lab = PATTERN (gen_call_site ());
7529
 
7530
  if (SYMBOL_REF_LOCAL_P (operands[1]))
7531
    emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7532
  else
7533
    emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7534
  emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7535
                                         operands[2], copy_rtx (lab)));
7536
  DONE;
7537
}"
7538
  [(set_attr "type" "call")
7539
   (set (attr "fp_mode")
7540
        (if_then_else (eq_attr "fpu_single" "yes")
7541
                      (const_string "single") (const_string "double")))
7542
   (set_attr "needs_delay_slot" "yes")
7543
   (set_attr "fp_set" "unknown")])
7544
 
7545
(define_insn "call_value_compact"
7546
  [(set (match_operand 0 "" "=rf")
7547
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7548
              (match_operand 2 "" "")))
7549
   (match_operand 3 "immediate_operand" "n")
7550
   (use (reg:SI R0_REG))
7551
   (use (reg:SI R1_REG))
7552
   (use (reg:PSI FPSCR_REG))
7553
   (clobber (reg:SI PR_REG))]
7554
  "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7555
  "jsr  @%1%#"
7556
  [(set_attr "type" "call")
7557
   (set (attr "fp_mode")
7558
        (if_then_else (eq_attr "fpu_single" "yes")
7559
                      (const_string "single") (const_string "double")))
7560
   (set_attr "needs_delay_slot" "yes")])
7561
 
7562
(define_insn "call_value_compact_rettramp"
7563
  [(set (match_operand 0 "" "=rf")
7564
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7565
              (match_operand 2 "" "")))
7566
   (match_operand 3 "immediate_operand" "n")
7567
   (use (reg:SI R0_REG))
7568
   (use (reg:SI R1_REG))
7569
   (use (reg:PSI FPSCR_REG))
7570
   (clobber (reg:SI R10_REG))
7571
   (clobber (reg:SI PR_REG))]
7572
  "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7573
  "jsr  @%1%#"
7574
  [(set_attr "type" "call")
7575
   (set (attr "fp_mode")
7576
        (if_then_else (eq_attr "fpu_single" "yes")
7577
                      (const_string "single") (const_string "double")))
7578
   (set_attr "needs_delay_slot" "yes")])
7579
 
7580
(define_insn "call_value_media"
7581
  [(set (match_operand 0 "" "=rf")
7582
        (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7583
              (match_operand 2 "" "")))
7584
   (clobber (reg:DI PR_MEDIA_REG))]
7585
  "TARGET_SHMEDIA"
7586
  "blink        %1, r18"
7587
  [(set_attr "type" "jump_media")])
7588
 
7589
(define_expand "call"
7590
  [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7591
                            (match_operand 1 "" ""))
7592
              (match_operand 2 "" "")
7593
              (use (reg:PSI FPSCR_REG))
7594
              (clobber (reg:SI PR_REG))])]
7595
  ""
7596
  "
7597
{
7598
  if (TARGET_SHMEDIA)
7599
    {
7600
      operands[0] = shmedia_prepare_call_address (operands[0], 0);
7601
      emit_call_insn (gen_call_media (operands[0], operands[1]));
7602
      DONE;
7603
    }
7604
  else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7605
    {
7606
      rtx cookie_rtx = operands[2];
7607
      long cookie = INTVAL (cookie_rtx);
7608
      rtx func = XEXP (operands[0], 0);
7609
      rtx r0, r1;
7610
 
7611
      if (flag_pic)
7612
        {
7613
          if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7614
            {
7615
              rtx reg = gen_reg_rtx (Pmode);
7616
 
7617
              emit_insn (gen_symGOTPLT2reg (reg, func));
7618
              func = reg;
7619
            }
7620
          else
7621
            func = legitimize_pic_address (func, Pmode, 0);
7622
        }
7623
 
7624
      r0 = gen_rtx_REG (SImode, R0_REG);
7625
      r1 = gen_rtx_REG (SImode, R1_REG);
7626
 
7627
      /* Since such a call function may use all call-clobbered
7628
         registers, we force a mode switch earlier, so that we don't
7629
         run out of registers when adjusting fpscr for the call.  */
7630
      emit_insn (gen_force_mode_for_call ());
7631
 
7632
      operands[0]
7633
        = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7634
                           SFUNC_GOT);
7635
      operands[0] = force_reg (SImode, operands[0]);
7636
 
7637
      emit_move_insn (r0, func);
7638
      emit_move_insn (r1, cookie_rtx);
7639
 
7640
      if (cookie & CALL_COOKIE_RET_TRAMP (1))
7641
        emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7642
                                                   operands[2]));
7643
      else
7644
        emit_call_insn (gen_call_compact (operands[0], operands[1],
7645
                                          operands[2]));
7646
 
7647
      DONE;
7648
    }
7649
  else if (TARGET_SHCOMPACT && flag_pic
7650
           && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7651
           && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7652
    {
7653
      rtx reg = gen_reg_rtx (Pmode);
7654
 
7655
      emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7656
      XEXP (operands[0], 0) = reg;
7657
    }
7658
  if (!flag_pic && TARGET_SH2A
7659
      && MEM_P (operands[0])
7660
      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7661
    {
7662
      if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7663
        {
7664
          emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7665
                                             operands[1]));
7666
          DONE;
7667
        }
7668
    }
7669
  if (flag_pic && TARGET_SH2
7670
      && MEM_P (operands[0])
7671
      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7672
    {
7673
      emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7674
      DONE;
7675
    }
7676
  else
7677
  {
7678
    operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7679
    operands[1] = operands[2];
7680
  }
7681
 
7682
  emit_call_insn (gen_calli (operands[0], operands[1]));
7683
  DONE;
7684
}")
7685
 
7686
(define_insn "call_pop_compact"
7687
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7688
         (match_operand 1 "" ""))
7689
   (match_operand 2 "immediate_operand" "n")
7690
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7691
                                 (match_operand 3 "immediate_operand" "n")))
7692
   (use (reg:SI R0_REG))
7693
   (use (reg:SI R1_REG))
7694
   (use (reg:PSI FPSCR_REG))
7695
   (clobber (reg:SI PR_REG))]
7696
  "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7697
  "jsr  @%0%#"
7698
  [(set_attr "type" "call")
7699
   (set (attr "fp_mode")
7700
        (if_then_else (eq_attr "fpu_single" "yes")
7701
                      (const_string "single") (const_string "double")))
7702
   (set_attr "needs_delay_slot" "yes")])
7703
 
7704
(define_insn "call_pop_compact_rettramp"
7705
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7706
         (match_operand 1 "" ""))
7707
   (match_operand 2 "immediate_operand" "n")
7708
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7709
                                 (match_operand 3 "immediate_operand" "n")))
7710
   (use (reg:SI R0_REG))
7711
   (use (reg:SI R1_REG))
7712
   (use (reg:PSI FPSCR_REG))
7713
   (clobber (reg:SI R10_REG))
7714
   (clobber (reg:SI PR_REG))]
7715
  "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7716
  "jsr  @%0%#"
7717
  [(set_attr "type" "call")
7718
   (set (attr "fp_mode")
7719
        (if_then_else (eq_attr "fpu_single" "yes")
7720
                      (const_string "single") (const_string "double")))
7721
   (set_attr "needs_delay_slot" "yes")])
7722
 
7723
(define_expand "call_pop"
7724
  [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7725
                    (match_operand 1 "" ""))
7726
             (match_operand 2 "" "")
7727
             (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7728
                                           (match_operand 3 "" "")))])]
7729
  "TARGET_SHCOMPACT"
7730
  "
7731
{
7732
  rtx cookie_rtx;
7733
  long cookie;
7734
  rtx func;
7735
  rtx r0, r1;
7736
 
7737
  gcc_assert (operands[2] && INTVAL (operands[2]));
7738
  cookie_rtx = operands[2];
7739
  cookie = INTVAL (cookie_rtx);
7740
  func = XEXP (operands[0], 0);
7741
 
7742
  if (flag_pic)
7743
    {
7744
      if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7745
        {
7746
          rtx reg = gen_reg_rtx (Pmode);
7747
          emit_insn (gen_symGOTPLT2reg (reg, func));
7748
          func = reg;
7749
        }
7750
      else
7751
        func = legitimize_pic_address (func, Pmode, 0);
7752
    }
7753
 
7754
  r0 = gen_rtx_REG (SImode, R0_REG);
7755
  r1 = gen_rtx_REG (SImode, R1_REG);
7756
 
7757
  /* Since such a call function may use all call-clobbered
7758
     registers, we force a mode switch earlier, so that we don't
7759
     run out of registers when adjusting fpscr for the call.  */
7760
  emit_insn (gen_force_mode_for_call ());
7761
 
7762
  operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7763
                                 SFUNC_GOT);
7764
  operands[0] = force_reg (SImode, operands[0]);
7765
 
7766
  emit_move_insn (r0, func);
7767
  emit_move_insn (r1, cookie_rtx);
7768
 
7769
  if (cookie & CALL_COOKIE_RET_TRAMP (1))
7770
    emit_call_insn (gen_call_pop_compact_rettramp
7771
                     (operands[0], operands[1], operands[2], operands[3]));
7772
  else
7773
    emit_call_insn (gen_call_pop_compact
7774
                     (operands[0], operands[1], operands[2], operands[3]));
7775
 
7776
  DONE;
7777
}")
7778
 
7779
(define_expand "call_value"
7780
  [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7781
                   (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7782
                                 (match_operand 2 "" "")))
7783
              (match_operand 3 "" "")
7784
              (use (reg:PSI FPSCR_REG))
7785
              (clobber (reg:SI PR_REG))])]
7786
  ""
7787
  "
7788
{
7789
  if (TARGET_SHMEDIA)
7790
    {
7791
      operands[1] = shmedia_prepare_call_address (operands[1], 0);
7792
      emit_call_insn (gen_call_value_media (operands[0], operands[1],
7793
                                            operands[2]));
7794
      DONE;
7795
    }
7796
  else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7797
    {
7798
      rtx cookie_rtx = operands[3];
7799
      long cookie = INTVAL (cookie_rtx);
7800
      rtx func = XEXP (operands[1], 0);
7801
      rtx r0, r1;
7802
 
7803
      if (flag_pic)
7804
        {
7805
          if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7806
            {
7807
              rtx reg = gen_reg_rtx (Pmode);
7808
 
7809
              emit_insn (gen_symGOTPLT2reg (reg, func));
7810
              func = reg;
7811
            }
7812
          else
7813
            func = legitimize_pic_address (func, Pmode, 0);
7814
        }
7815
 
7816
      r0 = gen_rtx_REG (SImode, R0_REG);
7817
      r1 = gen_rtx_REG (SImode, R1_REG);
7818
 
7819
      /* Since such a call function may use all call-clobbered
7820
         registers, we force a mode switch earlier, so that we don't
7821
         run out of registers when adjusting fpscr for the call.  */
7822
      emit_insn (gen_force_mode_for_call ());
7823
 
7824
      operands[1]
7825
        = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7826
                           SFUNC_GOT);
7827
      operands[1] = force_reg (SImode, operands[1]);
7828
 
7829
      emit_move_insn (r0, func);
7830
      emit_move_insn (r1, cookie_rtx);
7831
 
7832
      if (cookie & CALL_COOKIE_RET_TRAMP (1))
7833
        emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7834
                                                         operands[1],
7835
                                                         operands[2],
7836
                                                         operands[3]));
7837
      else
7838
        emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7839
                                                operands[2], operands[3]));
7840
 
7841
      DONE;
7842
    }
7843
  else if (TARGET_SHCOMPACT && flag_pic
7844
           && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7845
           && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7846
    {
7847
      rtx reg = gen_reg_rtx (Pmode);
7848
 
7849
      emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7850
      XEXP (operands[1], 0) = reg;
7851
    }
7852
  if (!flag_pic && TARGET_SH2A
7853
      && MEM_P (operands[1])
7854
      && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7855
    {
7856
      if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7857
        {
7858
          emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7859
                                 XEXP (operands[1], 0), operands[2]));
7860
          DONE;
7861
        }
7862
    }
7863
  if (flag_pic && TARGET_SH2
7864
      && MEM_P (operands[1])
7865
      && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7866
    {
7867
      emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7868
                                            operands[2]));
7869
      DONE;
7870
    }
7871
  else
7872
    operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7873
 
7874
  emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7875
  DONE;
7876
}")
7877
 
7878
(define_insn "sibcalli"
7879
  [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7880
         (match_operand 1 "" ""))
7881
   (use (reg:PSI FPSCR_REG))
7882
   (return)]
7883
  "TARGET_SH1"
7884
  "jmp  @%0%#"
7885
  [(set_attr "needs_delay_slot" "yes")
7886
   (set (attr "fp_mode")
7887
        (if_then_else (eq_attr "fpu_single" "yes")
7888
                      (const_string "single") (const_string "double")))
7889
   (set_attr "type" "jump_ind")])
7890
 
7891
(define_insn "sibcalli_pcrel"
7892
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7893
         (match_operand 1 "" ""))
7894
   (use (match_operand 2 "" ""))
7895
   (use (reg:PSI FPSCR_REG))
7896
   (return)]
7897
  "TARGET_SH2"
7898
  "braf %0\\n%O2:%#"
7899
  [(set_attr "needs_delay_slot" "yes")
7900
   (set (attr "fp_mode")
7901
        (if_then_else (eq_attr "fpu_single" "yes")
7902
                      (const_string "single") (const_string "double")))
7903
   (set_attr "type" "jump_ind")])
7904
 
7905
;; This uses an unspec to describe that the symbol_ref is very close.
7906
(define_insn "sibcalli_thunk"
7907
  [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7908
                             UNSPEC_THUNK))
7909
         (match_operand 1 "" ""))
7910
   (use (reg:PSI FPSCR_REG))
7911
   (return)]
7912
  "TARGET_SH1"
7913
  "bra  %O0"
7914
  [(set_attr "needs_delay_slot" "yes")
7915
   (set (attr "fp_mode")
7916
        (if_then_else (eq_attr "fpu_single" "yes")
7917
                      (const_string "single") (const_string "double")))
7918
   (set_attr "type" "jump")
7919
   (set_attr "length" "2")])
7920
 
7921
(define_insn_and_split "sibcall_pcrel"
7922
  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7923
         (match_operand 1 "" ""))
7924
   (use (reg:PSI FPSCR_REG))
7925
   (clobber (match_scratch:SI 2 "=k"))
7926
   (return)]
7927
  "TARGET_SH2"
7928
  "#"
7929
  "reload_completed"
7930
  [(const_int 0)]
7931
  "
7932
{
7933
  rtx lab = PATTERN (gen_call_site ());
7934
  rtx call_insn;
7935
 
7936
  emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7937
  call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7938
                                                  copy_rtx (lab)));
7939
  SIBLING_CALL_P (call_insn) = 1;
7940
  DONE;
7941
}"
7942
  [(set_attr "needs_delay_slot" "yes")
7943
   (set (attr "fp_mode")
7944
        (if_then_else (eq_attr "fpu_single" "yes")
7945
                      (const_string "single") (const_string "double")))
7946
   (set_attr "type" "jump_ind")])
7947
 
7948
(define_insn "sibcall_compact"
7949
  [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7950
         (match_operand 1 "" ""))
7951
   (return)
7952
   (use (match_operand:SI 2 "register_operand" "z,x"))
7953
   (use (reg:SI R1_REG))
7954
   (use (reg:PSI FPSCR_REG))
7955
   ;; We want to make sure the `x' above will only match MACH_REG
7956
   ;; because sibcall_epilogue may clobber MACL_REG.
7957
   (clobber (reg:SI MACL_REG))]
7958
  "TARGET_SHCOMPACT"
7959
  "@
7960
        jmp     @%0%#
7961
        jmp     @%0\\n  sts     %2, r0"
7962
  [(set_attr "needs_delay_slot" "yes,no")
7963
   (set_attr "length" "2,4")
7964
   (set (attr "fp_mode") (const_string "single"))
7965
   (set_attr "type" "jump_ind")])
7966
 
7967
(define_insn "sibcall_media"
7968
  [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7969
         (match_operand 1 "" ""))
7970
   (use (reg:SI PR_MEDIA_REG))
7971
   (return)]
7972
  "TARGET_SHMEDIA"
7973
  "blink        %0, r63"
7974
  [(set_attr "type" "jump_media")])
7975
 
7976
(define_expand "sibcall"
7977
  [(parallel
7978
    [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7979
           (match_operand 1 "" ""))
7980
     (match_operand 2 "" "")
7981
     (use (reg:PSI FPSCR_REG))
7982
     (return)])]
7983
  ""
7984
  "
7985
{
7986
  if (TARGET_SHMEDIA)
7987
    {
7988
      operands[0] = shmedia_prepare_call_address (operands[0], 1);
7989
      emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7990
      DONE;
7991
    }
7992
  else if (TARGET_SHCOMPACT && operands[2]
7993
           && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7994
    {
7995
      rtx cookie_rtx = operands[2];
7996
      long cookie = INTVAL (cookie_rtx);
7997
      rtx func = XEXP (operands[0], 0);
7998
      rtx mach, r1;
7999
 
8000
      if (flag_pic)
8001
        {
8002
          if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8003
            {
8004
              rtx reg = gen_reg_rtx (Pmode);
8005
 
8006
              emit_insn (gen_symGOT2reg (reg, func));
8007
              func = reg;
8008
            }
8009
          else
8010
            func = legitimize_pic_address (func, Pmode, 0);
8011
        }
8012
 
8013
      /* FIXME: if we could tell whether all argument registers are
8014
         already taken, we could decide whether to force the use of
8015
         MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8016
         simple way to tell.  We could use the CALL_COOKIE, but we
8017
         can't currently tell a register used for regular argument
8018
         passing from one that is unused.  If we leave it up to reload
8019
         to decide which register to use, it seems to always choose
8020
         R0_REG, which leaves no available registers in SIBCALL_REGS
8021
         to hold the address of the trampoline.  */
8022
      mach = gen_rtx_REG (SImode, MACH_REG);
8023
      r1 = gen_rtx_REG (SImode, R1_REG);
8024
 
8025
      /* Since such a call function may use all call-clobbered
8026
         registers, we force a mode switch earlier, so that we don't
8027
         run out of registers when adjusting fpscr for the call.  */
8028
      emit_insn (gen_force_mode_for_call ());
8029
 
8030
      operands[0]
8031
        = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8032
                           SFUNC_GOT);
8033
      operands[0] = force_reg (SImode, operands[0]);
8034
 
8035
      /* We don't need a return trampoline, since the callee will
8036
         return directly to the upper caller.  */
8037
      if (cookie & CALL_COOKIE_RET_TRAMP (1))
8038
        {
8039
          cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8040
          cookie_rtx = GEN_INT (cookie);
8041
        }
8042
 
8043
      emit_move_insn (mach, func);
8044
      emit_move_insn (r1, cookie_rtx);
8045
 
8046
      emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8047
      DONE;
8048
    }
8049
  else if (TARGET_SHCOMPACT && flag_pic
8050
           && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8051
           && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8052
    {
8053
      rtx reg = gen_reg_rtx (Pmode);
8054
 
8055
      emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8056
      XEXP (operands[0], 0) = reg;
8057
    }
8058
  if (flag_pic && TARGET_SH2
8059
      && MEM_P (operands[0])
8060
      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8061
      /* The PLT needs the PIC register, but the epilogue would have
8062
         to restore it, so we can only use PC-relative PIC calls for
8063
         static functions.  */
8064
      && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8065
    {
8066
      emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8067
      DONE;
8068
    }
8069
  else
8070
    operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8071
 
8072
  emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8073
  DONE;
8074
}")
8075
 
8076
(define_insn "sibcall_valuei"
8077
  [(set (match_operand 0 "" "=rf")
8078
        (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8079
              (match_operand 2 "" "")))
8080
   (use (reg:PSI FPSCR_REG))
8081
   (return)]
8082
  "TARGET_SH1"
8083
  "jmp  @%1%#"
8084
  [(set_attr "needs_delay_slot" "yes")
8085
   (set (attr "fp_mode")
8086
        (if_then_else (eq_attr "fpu_single" "yes")
8087
                      (const_string "single") (const_string "double")))
8088
   (set_attr "type" "jump_ind")])
8089
 
8090
(define_insn "sibcall_valuei_pcrel"
8091
  [(set (match_operand 0 "" "=rf")
8092
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8093
              (match_operand 2 "" "")))
8094
   (use (match_operand 3 "" ""))
8095
   (use (reg:PSI FPSCR_REG))
8096
   (return)]
8097
  "TARGET_SH2"
8098
  "braf %1\\n%O3:%#"
8099
  [(set_attr "needs_delay_slot" "yes")
8100
   (set (attr "fp_mode")
8101
        (if_then_else (eq_attr "fpu_single" "yes")
8102
                      (const_string "single") (const_string "double")))
8103
   (set_attr "type" "jump_ind")])
8104
 
8105
(define_insn_and_split "sibcall_value_pcrel"
8106
  [(set (match_operand 0 "" "=rf")
8107
        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8108
              (match_operand 2 "" "")))
8109
   (use (reg:PSI FPSCR_REG))
8110
   (clobber (match_scratch:SI 3 "=k"))
8111
   (return)]
8112
  "TARGET_SH2"
8113
  "#"
8114
  "reload_completed"
8115
  [(const_int 0)]
8116
  "
8117
{
8118
  rtx lab = PATTERN (gen_call_site ());
8119
  rtx call_insn;
8120
 
8121
  emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8122
  call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8123
                                                        operands[3],
8124
                                                        operands[2],
8125
                                                        copy_rtx (lab)));
8126
  SIBLING_CALL_P (call_insn) = 1;
8127
  DONE;
8128
}"
8129
  [(set_attr "needs_delay_slot" "yes")
8130
   (set (attr "fp_mode")
8131
        (if_then_else (eq_attr "fpu_single" "yes")
8132
                      (const_string "single") (const_string "double")))
8133
   (set_attr "type" "jump_ind")])
8134
 
8135
(define_insn "sibcall_value_compact"
8136
  [(set (match_operand 0 "" "=rf,rf")
8137
        (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8138
              (match_operand 2 "" "")))
8139
   (return)
8140
   (use (match_operand:SI 3 "register_operand" "z,x"))
8141
   (use (reg:SI R1_REG))
8142
   (use (reg:PSI FPSCR_REG))
8143
   ;; We want to make sure the `x' above will only match MACH_REG
8144
   ;; because sibcall_epilogue may clobber MACL_REG.
8145
   (clobber (reg:SI MACL_REG))]
8146
  "TARGET_SHCOMPACT"
8147
  "@
8148
        jmp     @%1%#
8149
        jmp     @%1\\n  sts     %3, r0"
8150
  [(set_attr "needs_delay_slot" "yes,no")
8151
   (set_attr "length" "2,4")
8152
   (set (attr "fp_mode") (const_string "single"))
8153
   (set_attr "type" "jump_ind")])
8154
 
8155
(define_insn "sibcall_value_media"
8156
  [(set (match_operand 0 "" "=rf")
8157
        (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8158
              (match_operand 2 "" "")))
8159
   (use (reg:SI PR_MEDIA_REG))
8160
   (return)]
8161
  "TARGET_SHMEDIA"
8162
  "blink        %1, r63"
8163
  [(set_attr "type" "jump_media")])
8164
 
8165
(define_expand "sibcall_value"
8166
  [(parallel
8167
    [(set (match_operand 0 "arith_reg_operand" "")
8168
          (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8169
                (match_operand 2 "" "")))
8170
     (match_operand 3 "" "")
8171
     (use (reg:PSI FPSCR_REG))
8172
     (return)])]
8173
  ""
8174
  "
8175
{
8176
  if (TARGET_SHMEDIA)
8177
    {
8178
      operands[1] = shmedia_prepare_call_address (operands[1], 1);
8179
      emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8180
                                               operands[2]));
8181
      DONE;
8182
    }
8183
  else if (TARGET_SHCOMPACT && operands[3]
8184
           && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8185
    {
8186
      rtx cookie_rtx = operands[3];
8187
      long cookie = INTVAL (cookie_rtx);
8188
      rtx func = XEXP (operands[1], 0);
8189
      rtx mach, r1;
8190
 
8191
      if (flag_pic)
8192
        {
8193
          if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8194
            {
8195
              rtx reg = gen_reg_rtx (Pmode);
8196
 
8197
              emit_insn (gen_symGOT2reg (reg, func));
8198
              func = reg;
8199
            }
8200
          else
8201
            func = legitimize_pic_address (func, Pmode, 0);
8202
        }
8203
 
8204
      /* FIXME: if we could tell whether all argument registers are
8205
         already taken, we could decide whether to force the use of
8206
         MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8207
         simple way to tell.  We could use the CALL_COOKIE, but we
8208
         can't currently tell a register used for regular argument
8209
         passing from one that is unused.  If we leave it up to reload
8210
         to decide which register to use, it seems to always choose
8211
         R0_REG, which leaves no available registers in SIBCALL_REGS
8212
         to hold the address of the trampoline.  */
8213
      mach = gen_rtx_REG (SImode, MACH_REG);
8214
      r1 = gen_rtx_REG (SImode, R1_REG);
8215
 
8216
      /* Since such a call function may use all call-clobbered
8217
         registers, we force a mode switch earlier, so that we don't
8218
         run out of registers when adjusting fpscr for the call.  */
8219
      emit_insn (gen_force_mode_for_call ());
8220
 
8221
      operands[1]
8222
        = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8223
                           SFUNC_GOT);
8224
      operands[1] = force_reg (SImode, operands[1]);
8225
 
8226
      /* We don't need a return trampoline, since the callee will
8227
         return directly to the upper caller.  */
8228
      if (cookie & CALL_COOKIE_RET_TRAMP (1))
8229
        {
8230
          cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8231
          cookie_rtx = GEN_INT (cookie);
8232
        }
8233
 
8234
      emit_move_insn (mach, func);
8235
      emit_move_insn (r1, cookie_rtx);
8236
 
8237
      emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8238
                                                 operands[2], mach));
8239
      DONE;
8240
    }
8241
  else if (TARGET_SHCOMPACT && flag_pic
8242
           && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8243
           && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8244
    {
8245
      rtx reg = gen_reg_rtx (Pmode);
8246
 
8247
      emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8248
      XEXP (operands[1], 0) = reg;
8249
    }
8250
  if (flag_pic && TARGET_SH2
8251
      && MEM_P (operands[1])
8252
      && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8253
      /* The PLT needs the PIC register, but the epilogue would have
8254
         to restore it, so we can only use PC-relative PIC calls for
8255
         static functions.  */
8256
      && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8257
    {
8258
      emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8259
                                               XEXP (operands[1], 0),
8260
                                               operands[2]));
8261
      DONE;
8262
    }
8263
  else
8264
    operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8265
 
8266
  emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8267
  DONE;
8268
}")
8269
 
8270
(define_insn "call_value_pop_compact"
8271
  [(set (match_operand 0 "" "=rf")
8272
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8273
              (match_operand 2 "" "")))
8274
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8275
                                 (match_operand 4 "immediate_operand" "n")))
8276
   (match_operand 3 "immediate_operand" "n")
8277
   (use (reg:SI R0_REG))
8278
   (use (reg:SI R1_REG))
8279
   (use (reg:PSI FPSCR_REG))
8280
   (clobber (reg:SI PR_REG))]
8281
  "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8282
  "jsr  @%1%#"
8283
  [(set_attr "type" "call")
8284
   (set (attr "fp_mode")
8285
        (if_then_else (eq_attr "fpu_single" "yes")
8286
                      (const_string "single") (const_string "double")))
8287
   (set_attr "needs_delay_slot" "yes")])
8288
 
8289
(define_insn "call_value_pop_compact_rettramp"
8290
  [(set (match_operand 0 "" "=rf")
8291
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8292
              (match_operand 2 "" "")))
8293
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8294
                                 (match_operand 4 "immediate_operand" "n")))
8295
   (match_operand 3 "immediate_operand" "n")
8296
   (use (reg:SI R0_REG))
8297
   (use (reg:SI R1_REG))
8298
   (use (reg:PSI FPSCR_REG))
8299
   (clobber (reg:SI R10_REG))
8300
   (clobber (reg:SI PR_REG))]
8301
  "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8302
  "jsr  @%1%#"
8303
  [(set_attr "type" "call")
8304
   (set (attr "fp_mode")
8305
        (if_then_else (eq_attr "fpu_single" "yes")
8306
                      (const_string "single") (const_string "double")))
8307
   (set_attr "needs_delay_slot" "yes")])
8308
 
8309
(define_expand "call_value_pop"
8310
  [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8311
                   (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8312
                                 (match_operand 2 "" "")))
8313
              (match_operand 3 "" "")
8314
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8315
                                            (match_operand 4 "" "")))])]
8316
  "TARGET_SHCOMPACT"
8317
  "
8318
{
8319
  rtx cookie_rtx;
8320
  long cookie;
8321
  rtx func;
8322
  rtx r0, r1;
8323
 
8324
  gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8325
  cookie_rtx = operands[3];
8326
  cookie = INTVAL (cookie_rtx);
8327
  func = XEXP (operands[1], 0);
8328
 
8329
  if (flag_pic)
8330
    {
8331
      if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8332
        {
8333
          rtx reg = gen_reg_rtx (Pmode);
8334
 
8335
          emit_insn (gen_symGOTPLT2reg (reg, func));
8336
          func = reg;
8337
        }
8338
      else
8339
        func = legitimize_pic_address (func, Pmode, 0);
8340
    }
8341
 
8342
  r0 = gen_rtx_REG (SImode, R0_REG);
8343
  r1 = gen_rtx_REG (SImode, R1_REG);
8344
 
8345
  /* Since such a call function may use all call-clobbered
8346
     registers, we force a mode switch earlier, so that we don't
8347
     run out of registers when adjusting fpscr for the call.  */
8348
  emit_insn (gen_force_mode_for_call ());
8349
 
8350
  operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8351
                                 SFUNC_GOT);
8352
  operands[1] = force_reg (SImode, operands[1]);
8353
 
8354
  emit_move_insn (r0, func);
8355
  emit_move_insn (r1, cookie_rtx);
8356
 
8357
  if (cookie & CALL_COOKIE_RET_TRAMP (1))
8358
    emit_call_insn (gen_call_value_pop_compact_rettramp
8359
                        (operands[0], operands[1], operands[2],
8360
                         operands[3], operands[4]));
8361
  else
8362
    emit_call_insn (gen_call_value_pop_compact
8363
                        (operands[0], operands[1], operands[2],
8364
                         operands[3], operands[4]));
8365
 
8366
  DONE;
8367
}")
8368
 
8369
(define_expand "sibcall_epilogue"
8370
  [(return)]
8371
  ""
8372
  "
8373
{
8374
  sh_expand_epilogue (1);
8375
  if (TARGET_SHCOMPACT)
8376
    {
8377
      rtx insn, set;
8378
 
8379
      /* If epilogue clobbers r0, preserve it in macl.  */
8380
      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8381
        if ((set = single_set (insn))
8382
            && REG_P (SET_DEST (set))
8383
            && REGNO (SET_DEST (set)) == R0_REG)
8384
          {
8385
            rtx r0 = gen_rtx_REG (SImode, R0_REG);
8386
            rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8387
 
8388
            /* We can't tell at this point whether the sibcall is a
8389
               sibcall_compact and, if it is, whether it uses r0 or
8390
               mach as operand 2, so let the instructions that
8391
               preserve r0 be optimized away if r0 turns out to be
8392
               dead.  */
8393
            emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8394
            emit_move_insn (r0, tmp);
8395
            break;
8396
          }
8397
    }
8398
  DONE;
8399
}")
8400
 
8401
(define_insn "indirect_jump_compact"
8402
  [(set (pc)
8403
        (match_operand:SI 0 "arith_reg_operand" "r"))]
8404
  "TARGET_SH1"
8405
  "jmp  @%0%#"
8406
  [(set_attr "needs_delay_slot" "yes")
8407
   (set_attr "type" "jump_ind")])
8408
 
8409
(define_expand "indirect_jump"
8410
  [(set (pc)
8411
        (match_operand 0 "register_operand" ""))]
8412
  ""
8413
  "
8414
{
8415
  if (GET_MODE (operands[0]) != Pmode)
8416
    operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8417
}")
8418
 
8419
;; The use of operand 1 / 2 helps us distinguish case table jumps
8420
;; which can be present in structured code from indirect jumps which can not
8421
;; be present in structured code.  This allows -fprofile-arcs to work.
8422
 
8423
;; For SH1 processors.
8424
(define_insn "casesi_jump_1"
8425
  [(set (pc)
8426
        (match_operand:SI 0 "register_operand" "r"))
8427
   (use (label_ref (match_operand 1 "" "")))]
8428
  "TARGET_SH1"
8429
  "jmp  @%0%#"
8430
  [(set_attr "needs_delay_slot" "yes")
8431
   (set_attr "type" "jump_ind")])
8432
 
8433
;; For all later processors.
8434
(define_insn "casesi_jump_2"
8435
  [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8436
                      (label_ref (match_operand 1 "" ""))))
8437
   (use (label_ref (match_operand 2 "" "")))]
8438
  "TARGET_SH2
8439
   && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8440
  "braf %0%#"
8441
  [(set_attr "needs_delay_slot" "yes")
8442
   (set_attr "type" "jump_ind")])
8443
 
8444
(define_insn "casesi_jump_media"
8445
  [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8446
   (use (label_ref (match_operand 1 "" "")))]
8447
  "TARGET_SHMEDIA"
8448
  "blink        %0, r63"
8449
  [(set_attr "type" "jump_media")])
8450
 
8451
;; Call subroutine returning any type.
8452
;; ??? This probably doesn't work.
8453
 
8454
(define_expand "untyped_call"
8455
  [(parallel [(call (match_operand 0 "" "")
8456
                    (const_int 0))
8457
              (match_operand 1 "" "")
8458
              (match_operand 2 "" "")])]
8459
  "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8460
  "
8461
{
8462
  int i;
8463
 
8464
  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8465
 
8466
  for (i = 0; i < XVECLEN (operands[2], 0); i++)
8467
    {
8468
      rtx set = XVECEXP (operands[2], 0, i);
8469
      emit_move_insn (SET_DEST (set), SET_SRC (set));
8470
    }
8471
 
8472
  /* The optimizer does not know that the call sets the function value
8473
     registers we stored in the result block.  We avoid problems by
8474
     claiming that all hard registers are used and clobbered at this
8475
     point.  */
8476
  emit_insn (gen_blockage ());
8477
 
8478
  DONE;
8479
}")
8480
 
8481
;; ------------------------------------------------------------------------
8482
;; Misc insns
8483
;; ------------------------------------------------------------------------
8484
 
8485
(define_insn "dect"
8486
  [(set (reg:SI T_REG)
8487
        (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8488
   (set (match_operand:SI 0 "arith_reg_dest" "=r")
8489
        (plus:SI (match_dup 1) (const_int -1)))]
8490
  "TARGET_SH2"
8491
  "dt   %0"
8492
  [(set_attr "type" "arith")])
8493
 
8494
(define_insn "nop"
8495
  [(const_int 0)]
8496
  ""
8497
  "nop")
8498
 
8499
;; Load address of a label. This is only generated by the casesi expand,
8500
;; and by machine_dependent_reorg (fixing up fp moves).
8501
;; This must use unspec, because this only works for labels that are
8502
;; within range,
8503
 
8504
(define_insn "mova"
8505
  [(set (reg:SI R0_REG)
8506
        (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8507
  "TARGET_SH1"
8508
  "mova %O0,r0"
8509
  [(set_attr "in_delay_slot" "no")
8510
   (set_attr "type" "arith")])
8511
 
8512
;; machine_dependent_reorg will make this a `mova'.
8513
(define_insn "mova_const"
8514
  [(set (reg:SI R0_REG)
8515
        (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8516
  "TARGET_SH1"
8517
  "#"
8518
  [(set_attr "in_delay_slot" "no")
8519
   (set_attr "type" "arith")])
8520
 
8521
(define_expand "GOTaddr2picreg"
8522
  [(set (reg:SI R0_REG)
8523
        (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8524
                   UNSPEC_MOVA))
8525
   (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8526
   (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8527
  "" "
8528
{
8529
  if (TARGET_VXWORKS_RTP)
8530
    {
8531
      rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8532
      rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8533
      emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8534
      DONE;
8535
    }
8536
 
8537
  operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8538
  operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8539
 
8540
  if (TARGET_SHMEDIA)
8541
    {
8542
      rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8543
      rtx pic = operands[0];
8544
      rtx lab = PATTERN (gen_call_site ());
8545
      rtx insn, equiv;
8546
 
8547
      equiv = operands[1];
8548
      operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8549
                                    UNSPEC_PCREL_SYMOFF);
8550
      operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8551
 
8552
      if (Pmode == SImode)
8553
        {
8554
          emit_insn (gen_movsi_const (pic, operands[1]));
8555
          emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8556
        }
8557
      else
8558
        {
8559
          emit_insn (gen_movdi_const (pic, operands[1]));
8560
          emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8561
        }
8562
 
8563
      insn = emit_move_insn (operands[0], tr);
8564
 
8565
      set_unique_reg_note (insn, REG_EQUAL, equiv);
8566
 
8567
      DONE;
8568
    }
8569
}
8570
")
8571
 
8572
;; A helper for GOTaddr2picreg to finish up the initialization of the
8573
;; PIC register.
8574
 
8575
(define_expand "vxworks_picreg"
8576
  [(set (reg:SI PIC_REG)
8577
        (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8578
   (set (reg:SI R0_REG)
8579
        (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8580
   (set (reg:SI PIC_REG)
8581
        (mem:SI (reg:SI PIC_REG)))
8582
   (set (reg:SI PIC_REG)
8583
        (mem:SI (plus:SI (reg:SI PIC_REG)
8584
                         (reg:SI R0_REG))))]
8585
  "TARGET_VXWORKS_RTP")
8586
 
8587
(define_insn "*ptb"
8588
  [(set (match_operand 0 "target_reg_operand" "=b")
8589
        (const (unspec [(match_operand 1 "" "Csy")]
8590
                             UNSPEC_DATALABEL)))]
8591
  "TARGET_SHMEDIA && flag_pic
8592
   && satisfies_constraint_Csy (operands[1])"
8593
  "ptb/u        datalabel %1, %0"
8594
  [(set_attr "type" "ptabs_media")
8595
   (set_attr "length" "*")])
8596
 
8597
(define_insn "ptrel_si"
8598
  [(set (match_operand:SI 0 "target_reg_operand" "=b")
8599
        (plus:SI (match_operand:SI 1 "register_operand" "r")
8600
              (pc)))
8601
   (match_operand:SI 2 "" "")]
8602
  "TARGET_SHMEDIA"
8603
  "%O2: ptrel/u %1, %0"
8604
  [(set_attr "type" "ptabs_media")])
8605
 
8606
(define_insn "ptrel_di"
8607
  [(set (match_operand:DI 0 "target_reg_operand" "=b")
8608
        (plus:DI (match_operand:DI 1 "register_operand" "r")
8609
              (pc)))
8610
   (match_operand:DI 2 "" "")]
8611
  "TARGET_SHMEDIA"
8612
  "%O2: ptrel/u %1, %0"
8613
  [(set_attr "type" "ptabs_media")])
8614
 
8615
(define_expand "builtin_setjmp_receiver"
8616
  [(match_operand 0 "" "")]
8617
  "flag_pic"
8618
  "
8619
{
8620
  emit_insn (gen_GOTaddr2picreg ());
8621
  DONE;
8622
}")
8623
 
8624
(define_expand "call_site"
8625
  [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8626
  "TARGET_SH1"
8627
  "
8628
{
8629
  static HOST_WIDE_INT i = 0;
8630
  operands[0] = GEN_INT (i);
8631
  i++;
8632
}")
8633
 
8634
;; op0 = op1 + r12 but hide it before reload completed.  See the comment
8635
;; in symGOT_load expand.
8636
 
8637
(define_insn_and_split "chk_guard_add"
8638
  [(set (match_operand:SI 0 "register_operand" "=&r")
8639
        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8640
                    (reg:SI PIC_REG)]
8641
                   UNSPEC_CHKADD))]
8642
  "TARGET_SH1"
8643
  "#"
8644
  "TARGET_SH1 && reload_completed"
8645
  [(set (match_dup 0) (reg:SI PIC_REG))
8646
   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
8647
  ""
8648
  [(set_attr "type" "arith")])
8649
 
8650
(define_expand "sym_label2reg"
8651
  [(set (match_operand:SI 0 "" "")
8652
        (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8653
                              (const (plus:SI (match_operand:SI 2 "" "")
8654
                                              (const_int 2)))]
8655
                             UNSPEC_SYMOFF)))]
8656
  "TARGET_SH1" "")
8657
 
8658
(define_expand "symGOT_load"
8659
  [(set (match_dup 2) (match_operand 1 "" ""))
8660
   (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8661
   (set (match_operand 0 "" "") (mem (match_dup 3)))]
8662
  ""
8663
  "
8664
{
8665
  rtx mem;
8666
 
8667
  operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8668
  operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8669
 
8670
  if (TARGET_SHMEDIA)
8671
    {
8672
      rtx reg = operands[2];
8673
 
8674
      if (Pmode == DImode)
8675
        {
8676
          if (flag_pic > 1)
8677
            emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8678
          else
8679
            emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8680
        }
8681
      else
8682
        {
8683
          if (flag_pic > 1)
8684
            emit_insn (gen_movsi_const (reg, operands[1]));
8685
          else
8686
            emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8687
        }
8688
    }
8689
  else
8690
    emit_move_insn (operands[2], operands[1]);
8691
 
8692
  /* When stack protector inserts codes after the result is set to
8693
     R0, @(rX, r12) will cause a spill failure for R0.  Use a unspec
8694
     insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8695
     when rX is a GOT address for the guard symbol.  Ugly but doesn't
8696
     matter because this is a rare situation.  */
8697
  if (!TARGET_SHMEDIA
8698
      && flag_stack_protect
8699
      && GET_CODE (operands[1]) == CONST
8700
      && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8701
      && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8702
      && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8703
                 \"__stack_chk_guard\") == 0)
8704
    emit_insn (gen_chk_guard_add (operands[3], operands[2]));
8705
  else
8706
    emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
8707
                                               gen_rtx_REG (Pmode, PIC_REG)));
8708
 
8709
  /* N.B. This is not constant for a GOTPLT relocation.  */
8710
  mem = gen_rtx_MEM (Pmode, operands[3]);
8711
  MEM_NOTRAP_P (mem) = 1;
8712
  /* ??? Should we have a special alias set for the GOT?  */
8713
  emit_move_insn (operands[0], mem);
8714
 
8715
  DONE;
8716
}")
8717
 
8718
(define_expand "sym2GOT"
8719
  [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8720
  ""
8721
  "")
8722
 
8723
(define_expand "symGOT2reg"
8724
  [(match_operand 0 "" "") (match_operand 1 "" "")]
8725
  ""
8726
  "
8727
{
8728
  rtx gotsym, insn;
8729
 
8730
  gotsym = gen_sym2GOT (operands[1]);
8731
  PUT_MODE (gotsym, Pmode);
8732
  insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8733
 
8734
  MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8735
 
8736
  DONE;
8737
}")
8738
 
8739
(define_expand "symGOTPLT2reg"
8740
  [(match_operand 0 "" "") (match_operand 1 "" "")]
8741
  ""
8742
  "
8743
{
8744
  rtx pltsym = gen_rtx_CONST (Pmode,
8745
                              gen_rtx_UNSPEC (Pmode,
8746
                                              gen_rtvec (1, operands[1]),
8747
                                              UNSPEC_GOTPLT));
8748
  emit_insn (gen_symGOT_load (operands[0], pltsym));
8749
  DONE;
8750
}")
8751
 
8752
(define_expand "sym2GOTOFF"
8753
  [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8754
  ""
8755
  "")
8756
 
8757
(define_expand "symGOTOFF2reg"
8758
  [(match_operand 0 "" "") (match_operand 1 "" "")]
8759
  ""
8760
  "
8761
{
8762
  rtx gotoffsym, insn;
8763
  rtx t = (!can_create_pseudo_p ()
8764
           ? operands[0]
8765
           : gen_reg_rtx (GET_MODE (operands[0])));
8766
 
8767
  gotoffsym = gen_sym2GOTOFF (operands[1]);
8768
  PUT_MODE (gotoffsym, Pmode);
8769
  emit_move_insn (t, gotoffsym);
8770
  insn = emit_move_insn (operands[0],
8771
                         gen_rtx_PLUS (Pmode, t,
8772
                                       gen_rtx_REG (Pmode, PIC_REG)));
8773
 
8774
  set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8775
 
8776
  DONE;
8777
}")
8778
 
8779
(define_expand "symPLT_label2reg"
8780
  [(set (match_operand:SI 0 "" "")
8781
        (const:SI
8782
         (unspec:SI
8783
          [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8784
           (const:SI (plus:SI (match_operand:SI 2 "" "")
8785
                              (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8786
   ;; Even though the PIC register is not really used by the call
8787
   ;; sequence in which this is expanded, the PLT code assumes the PIC
8788
   ;; register is set, so we must not skip its initialization.  Since
8789
   ;; we only use this expand as part of calling sequences, and never
8790
   ;; to take the address of a function, this is the best point to
8791
   ;; insert the (use).  Using the PLT to take the address of a
8792
   ;; function would be wrong, not only because the PLT entry could
8793
   ;; then be called from a function that doesn't initialize the PIC
8794
   ;; register to the proper GOT, but also because pointers to the
8795
   ;; same function might not compare equal, should they be set by
8796
   ;; different shared libraries.
8797
   (use (reg:SI PIC_REG))]
8798
  "TARGET_SH1"
8799
  "")
8800
 
8801
(define_expand "sym2PIC"
8802
  [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8803
  ""
8804
  "")
8805
 
8806
;; TLS code generation.
8807
;; ??? this should be a define_insn_and_split
8808
;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8809
;; 
8810
;; for details.
8811
 
8812
(define_insn "tls_global_dynamic"
8813
  [(set (match_operand:SI 0 "register_operand" "=&z")
8814
        (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8815
                                  UNSPEC_TLSGD))
8816
              (const_int 0)))
8817
   (use (reg:PSI FPSCR_REG))
8818
   (use (reg:SI PIC_REG))
8819
   (clobber (reg:SI PR_REG))
8820
   (clobber (scratch:SI))]
8821
  "TARGET_SH1"
8822
  "*
8823
{
8824
  return \"\\
8825
mov.l\\t1f,r4\\n\\
8826
\\tmova\\t2f,r0\\n\\
8827
\\tmov.l\\t2f,r1\\n\\
8828
\\tadd\\tr0,r1\\n\\
8829
\\tjsr\\t@r1\\n\\
8830
\\tadd\\tr12,r4\\n\\
8831
\\tbra\\t3f\\n\\
8832
\\tnop\\n\\
8833
\\t.align\\t2\\n\\
8834
1:\\t.long\\t%a1@TLSGD\\n\\
8835
2:\\t.long\\t__tls_get_addr@PLT\\n\\
8836
3:\";
8837
}"
8838
  [(set_attr "type" "tls_load")
8839
   (set_attr "length" "26")])
8840
 
8841
(define_insn "tls_local_dynamic"
8842
  [(set (match_operand:SI 0 "register_operand" "=&z")
8843
        (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8844
                                  UNSPEC_TLSLDM))
8845
              (const_int 0)))
8846
   (use (reg:PSI FPSCR_REG))
8847
   (use (reg:SI PIC_REG))
8848
   (clobber (reg:SI PR_REG))
8849
   (clobber (scratch:SI))]
8850
  "TARGET_SH1"
8851
  "*
8852
{
8853
  return \"\\
8854
mov.l\\t1f,r4\\n\\
8855
\\tmova\\t2f,r0\\n\\
8856
\\tmov.l\\t2f,r1\\n\\
8857
\\tadd\\tr0,r1\\n\\
8858
\\tjsr\\t@r1\\n\\
8859
\\tadd\\tr12,r4\\n\\
8860
\\tbra\\t3f\\n\\
8861
\\tnop\\n\\
8862
\\t.align\\t2\\n\\
8863
1:\\t.long\\t%a1@TLSLDM\\n\\
8864
2:\\t.long\\t__tls_get_addr@PLT\\n\\
8865
3:\";
8866
}"
8867
  [(set_attr "type" "tls_load")
8868
   (set_attr "length" "26")])
8869
 
8870
(define_expand "sym2DTPOFF"
8871
  [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8872
  ""
8873
  "")
8874
 
8875
(define_expand "symDTPOFF2reg"
8876
  [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8877
  ""
8878
  "
8879
{
8880
  rtx dtpoffsym;
8881
  rtx t = (!can_create_pseudo_p ()
8882
           ? operands[0]
8883
           : gen_reg_rtx (GET_MODE (operands[0])));
8884
 
8885
  dtpoffsym = gen_sym2DTPOFF (operands[1]);
8886
  PUT_MODE (dtpoffsym, Pmode);
8887
  emit_move_insn (t, dtpoffsym);
8888
  emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
8889
  DONE;
8890
}")
8891
 
8892
(define_expand "sym2GOTTPOFF"
8893
  [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8894
  ""
8895
  "")
8896
 
8897
(define_insn "tls_initial_exec"
8898
  [(set (match_operand:SI 0 "register_operand" "=&r")
8899
        (unspec:SI [(match_operand:SI 1 "" "")]
8900
                    UNSPEC_TLSIE))
8901
   (use (reg:SI GBR_REG))
8902
   (use (reg:SI PIC_REG))
8903
   (clobber (reg:SI R0_REG))]
8904
  ""
8905
  "*
8906
{
8907
  return \"\\
8908
mov.l\\t1f,r0\\n\\
8909
\\tstc\\tgbr,%0\\n\\
8910
\\tmov.l\\t@(r0,r12),r0\\n\\
8911
\\tbra\\t2f\\n\\
8912
\\tadd\\tr0,%0\\n\\
8913
\\t.align\\t2\\n\\
8914
1:\\t.long\\t%a1\\n\\
8915
2:\";
8916
}"
8917
  [(set_attr "type" "tls_load")
8918
   (set_attr "length" "16")])
8919
 
8920
(define_expand "sym2TPOFF"
8921
  [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8922
  ""
8923
  "")
8924
 
8925
(define_expand "symTPOFF2reg"
8926
  [(match_operand 0 "" "") (match_operand 1 "" "")]
8927
  ""
8928
  "
8929
{
8930
  rtx tpoffsym;
8931
 
8932
  tpoffsym = gen_sym2TPOFF (operands[1]);
8933
  PUT_MODE (tpoffsym, Pmode);
8934
  emit_move_insn (operands[0], tpoffsym);
8935
  DONE;
8936
}")
8937
 
8938
(define_insn "load_gbr"
8939
  [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8940
   (use (reg:SI GBR_REG))]
8941
  ""
8942
  "stc  gbr,%0"
8943
  [(set_attr "type" "tls_load")])
8944
 
8945
;; case instruction for switch statements.
8946
 
8947
;; Operand 0 is index
8948
;; operand 1 is the minimum bound
8949
;; operand 2 is the maximum bound - minimum bound + 1
8950
;; operand 3 is CODE_LABEL for the table;
8951
;; operand 4 is the CODE_LABEL to go to if index out of range.
8952
 
8953
(define_expand "casesi"
8954
  [(match_operand:SI 0 "arith_reg_operand" "")
8955
   (match_operand:SI 1 "arith_reg_operand" "")
8956
   (match_operand:SI 2 "arith_reg_operand" "")
8957
   (match_operand 3 "" "") (match_operand 4 "" "")]
8958
  ""
8959
  "
8960
{
8961
  rtx reg = gen_reg_rtx (SImode);
8962
  rtx reg2 = gen_reg_rtx (SImode);
8963
  if (TARGET_SHMEDIA)
8964
    {
8965
      rtx reg = gen_reg_rtx (DImode);
8966
      rtx reg2 = gen_reg_rtx (DImode);
8967
      rtx reg3 = gen_reg_rtx (Pmode);
8968
      rtx reg4 = gen_reg_rtx (Pmode);
8969
      rtx reg5 = gen_reg_rtx (Pmode);
8970
      rtx load, test;
8971
 
8972
      operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8973
      operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8974
      operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8975
 
8976
      test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8977
      emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8978
      emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8979
      test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8980
      emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8981
      emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8982
      emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8983
                                               (Pmode, operands[3])));
8984
      /* Messy: can we subreg to clean this up? */
8985
      if (Pmode == DImode)
8986
        load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8987
      else
8988
        load = gen_casesi_load_media (reg4,
8989
                                      gen_rtx_SUBREG (DImode, reg3, 0),
8990
                                      reg2, operands[3]);
8991
      PUT_MODE (SET_SRC (load), Pmode);
8992
      emit_insn (load);
8993
      /* ??? The following add could be eliminated if we used ptrel.  */
8994
      emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8995
      emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8996
      emit_barrier ();
8997
      DONE;
8998
    }
8999
  operands[1] = copy_to_mode_reg (SImode, operands[1]);
9000
  operands[2] = copy_to_mode_reg (SImode, operands[2]);
9001
  /* If optimizing, casesi_worker depends on the mode of the instruction
9002
     before label it 'uses' - operands[3].  */
9003
  emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9004
                           reg));
9005
  emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9006
  if (TARGET_SH2)
9007
    emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9008
  else
9009
    emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9010
  /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9011
     operands[3], but to lab.  We will fix this up in
9012
     machine_dependent_reorg.  */
9013
  emit_barrier ();
9014
  DONE;
9015
}")
9016
 
9017
(define_expand "casesi_0"
9018
  [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9019
   (set (match_dup 4) (minus:SI (match_dup 4)
9020
                                (match_operand:SI 1 "arith_operand" "")))
9021
   (set (reg:SI T_REG)
9022
        (gtu:SI (match_dup 4)
9023
                (match_operand:SI 2 "arith_reg_operand" "")))
9024
   (set (pc)
9025
        (if_then_else (ne (reg:SI T_REG)
9026
                          (const_int 0))
9027
                      (label_ref (match_operand 3 "" ""))
9028
                      (pc)))]
9029
  "TARGET_SH1"
9030
  "")
9031
 
9032
;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9033
;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9034
;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9035
 
9036
(define_insn "casesi_worker_0"
9037
  [(set (match_operand:SI 0 "register_operand" "=r,r")
9038
        (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9039
                 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9040
   (clobber (match_scratch:SI 3 "=X,1"))
9041
   (clobber (match_scratch:SI 4 "=&z,z"))]
9042
  "TARGET_SH1"
9043
  "#")
9044
 
9045
(define_split
9046
  [(set (match_operand:SI 0 "register_operand" "")
9047
        (unspec:SI [(match_operand:SI 1 "register_operand" "")
9048
                    (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9049
   (clobber (match_scratch:SI 3 ""))
9050
   (clobber (match_scratch:SI 4 ""))]
9051
  "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9052
  [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9053
   (parallel [(set (match_dup 0)
9054
              (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9055
                          (label_ref (match_dup 2))] UNSPEC_CASESI))
9056
              (clobber (match_dup 3))])
9057
   (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9058
  "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9059
 
9060
(define_split
9061
  [(set (match_operand:SI 0 "register_operand" "")
9062
        (unspec:SI [(match_operand:SI 1 "register_operand" "")
9063
                    (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9064
   (clobber (match_scratch:SI 3 ""))
9065
   (clobber (match_scratch:SI 4 ""))]
9066
  "TARGET_SH2 && reload_completed"
9067
  [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9068
   (parallel [(set (match_dup 0)
9069
              (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9070
                          (label_ref (match_dup 2))] UNSPEC_CASESI))
9071
              (clobber (match_dup 3))])]
9072
  "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9073
 
9074
(define_insn "casesi_worker_1"
9075
  [(set (match_operand:SI 0 "register_operand" "=r,r")
9076
        (unspec:SI [(reg:SI R0_REG)
9077
                    (match_operand:SI 1 "register_operand" "0,r")
9078
                    (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9079
   (clobber (match_scratch:SI 3 "=X,1"))]
9080
  "TARGET_SH1"
9081
  "*
9082
{
9083
  rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9084
 
9085
  gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9086
 
9087
  switch (GET_MODE (diff_vec))
9088
    {
9089
    case SImode:
9090
      return \"shll2    %1\;mov.l       @(r0,%1),%0\";
9091
    case HImode:
9092
      return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
9093
    case QImode:
9094
      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9095
        return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9096
      return \"mov.b    @(r0,%1),%0\";
9097
    default:
9098
      gcc_unreachable ();
9099
    }
9100
}"
9101
  [(set_attr "length" "4")])
9102
 
9103
(define_insn "casesi_worker_2"
9104
  [(set (match_operand:SI 0 "register_operand" "=r,r")
9105
        (unspec:SI [(reg:SI R0_REG)
9106
                    (match_operand:SI 1 "register_operand" "0,r")
9107
                    (label_ref (match_operand 2 "" ""))
9108
                    (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9109
   (clobber (match_operand:SI 4 "" "=X,1"))]
9110
  "TARGET_SH2 && reload_completed && flag_pic"
9111
  "*
9112
{
9113
  rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9114
  const char *load;
9115
 
9116
  gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9117
 
9118
  switch (GET_MODE (diff_vec))
9119
    {
9120
    case SImode:
9121
      output_asm_insn (\"shll2    %1\", operands);
9122
      load = \"mov.l    @(r0,%1),%0\"; break;
9123
    case HImode:
9124
      output_asm_insn (\"add    %1,%1\", operands);
9125
      load = \"mov.w    @(r0,%1),%0\"; break;
9126
    case QImode:
9127
      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9128
        load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9129
      else
9130
        load = \"mov.b  @(r0,%1),%0\";
9131
      break;
9132
    default:
9133
      gcc_unreachable ();
9134
    }
9135
  output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9136
  return load;
9137
}"
9138
  [(set_attr "length" "8")])
9139
 
9140
(define_insn "casesi_shift_media"
9141
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9142
        (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9143
                   (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9144
                    UNSPEC_CASESI)))]
9145
  "TARGET_SHMEDIA"
9146
  "*
9147
{
9148
  rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9149
 
9150
  gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9151
 
9152
  switch (GET_MODE (diff_vec))
9153
    {
9154
    case SImode:
9155
      return \"shlli    %1, 2, %0\";
9156
    case HImode:
9157
      return \"shlli    %1, 1, %0\";
9158
    case QImode:
9159
      if (rtx_equal_p (operands[0], operands[1]))
9160
        return \"\";
9161
      return \"add      %1, r63, %0\";
9162
    default:
9163
      gcc_unreachable ();
9164
    }
9165
}"
9166
  [(set_attr "type" "arith_media")])
9167
 
9168
(define_insn "casesi_load_media"
9169
  [(set (match_operand 0 "any_arith_reg_dest" "=r")
9170
        (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9171
                         (match_operand:DI 2 "arith_reg_operand" "r")
9172
                         (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9173
  "TARGET_SHMEDIA"
9174
  "*
9175
{
9176
  rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9177
 
9178
  gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9179
 
9180
  switch (GET_MODE (diff_vec))
9181
    {
9182
    case SImode:
9183
      return \"ldx.l    %1, %2, %0\";
9184
    case HImode:
9185
#if 0
9186
      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9187
        return \"ldx.uw %1, %2, %0\";
9188
#endif
9189
      return \"ldx.w    %1, %2, %0\";
9190
    case QImode:
9191
      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9192
        return \"ldx.ub %1, %2, %0\";
9193
      return \"ldx.b    %1, %2, %0\";
9194
    default:
9195
      gcc_unreachable ();
9196
    }
9197
}"
9198
  [(set_attr "type" "load_media")])
9199
 
9200
(define_expand "return"
9201
  [(return)]
9202
  "reload_completed && ! sh_need_epilogue ()"
9203
  "
9204
{
9205
  if (TARGET_SHMEDIA)
9206
    {
9207
      emit_jump_insn (gen_return_media ());
9208
      DONE;
9209
    }
9210
 
9211
  if (TARGET_SHCOMPACT
9212
      && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9213
    {
9214
      emit_jump_insn (gen_shcompact_return_tramp ());
9215
      DONE;
9216
    }
9217
}")
9218
 
9219
(define_insn "*return_i"
9220
  [(return)]
9221
  "TARGET_SH1 && ! (TARGET_SHCOMPACT
9222
                    && (crtl->args.info.call_cookie
9223
                        & CALL_COOKIE_RET_TRAMP (1)))
9224
   && reload_completed
9225
   && lookup_attribute (\"trap_exit\",
9226
                        DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9227
  "*
9228
  {
9229
    if (TARGET_SH2A && (dbr_sequence_length () == 0)
9230
                        && !current_function_interrupt)
9231
       return \"rts/n\";
9232
    else
9233
       return \"%@      %#\";
9234
  }"
9235
  [(set_attr "type" "return")
9236
   (set_attr "needs_delay_slot" "yes")])
9237
 
9238
;; trapa has no delay slot.
9239
(define_insn "*return_trapa"
9240
  [(return)]
9241
  "TARGET_SH1 && !TARGET_SHCOMPACT
9242
   && reload_completed"
9243
  "%@"
9244
  [(set_attr "type" "return")])
9245
 
9246
(define_expand "shcompact_return_tramp"
9247
  [(return)]
9248
  "TARGET_SHCOMPACT
9249
   && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9250
  "
9251
{
9252
  rtx reg = gen_rtx_REG (Pmode, R0_REG);
9253
 
9254
  function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9255
  emit_jump_insn (gen_shcompact_return_tramp_i ());
9256
  DONE;
9257
}")
9258
 
9259
(define_insn "shcompact_return_tramp_i"
9260
  [(parallel [(return) (use (reg:SI R0_REG))])]
9261
  "TARGET_SHCOMPACT
9262
   && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9263
  "jmp  @r0%#"
9264
  [(set_attr "type" "jump_ind")
9265
   (set_attr "needs_delay_slot" "yes")])
9266
 
9267
(define_insn "return_media_i"
9268
  [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9269
  "TARGET_SHMEDIA && reload_completed"
9270
  "blink        %0, r63"
9271
  [(set_attr "type" "jump_media")])
9272
 
9273
(define_insn "return_media_rte"
9274
  [(return)]
9275
  "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9276
  "rte"
9277
  [(set_attr "type" "jump_media")])
9278
 
9279
(define_expand "return_media"
9280
  [(return)]
9281
  "TARGET_SHMEDIA && reload_completed"
9282
  "
9283
{
9284
  int tr_regno = sh_media_register_for_return ();
9285
  rtx tr;
9286
 
9287
  if (current_function_interrupt)
9288
    {
9289
      emit_jump_insn (gen_return_media_rte ());
9290
      DONE;
9291
    }
9292
  if (tr_regno < 0)
9293
    {
9294
      rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9295
 
9296
      gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9297
      tr_regno = TR0_REG;
9298
      tr = gen_rtx_REG (Pmode, tr_regno);
9299
      emit_move_insn (tr, r18);
9300
    }
9301
  else
9302
    tr = gen_rtx_REG (Pmode, tr_regno);
9303
 
9304
  emit_jump_insn (gen_return_media_i (tr));
9305
  DONE;
9306
}")
9307
 
9308
(define_insn "shcompact_preserve_incoming_args"
9309
  [(set (match_operand:SI 0 "register_operand" "+r")
9310
        (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9311
  "TARGET_SHCOMPACT"
9312
  ""
9313
  [(set_attr "length" "0")])
9314
 
9315
(define_insn "shcompact_incoming_args"
9316
  [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9317
   (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9318
   (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9319
   (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9320
   (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9321
   (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9322
   (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9323
   (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9324
   (set (mem:BLK (reg:SI MACL_REG))
9325
        (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9326
   (use (reg:SI R0_REG))
9327
   (clobber (reg:SI R0_REG))
9328
   (clobber (reg:SI MACL_REG))
9329
   (clobber (reg:SI MACH_REG))
9330
   (clobber (reg:SI PR_REG))]
9331
  "TARGET_SHCOMPACT"
9332
  "jsr  @r0%#"
9333
  [(set_attr "needs_delay_slot" "yes")])
9334
 
9335
(define_insn "shmedia_save_restore_regs_compact"
9336
  [(set (reg:SI SP_REG)
9337
        (plus:SI (reg:SI SP_REG)
9338
                 (match_operand:SI 0 "immediate_operand" "i")))
9339
   (use (reg:SI R0_REG))
9340
   (clobber (reg:SI PR_REG))]
9341
  "TARGET_SHCOMPACT
9342
   && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9343
       || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9344
  "jsr @r0%#"
9345
  [(set_attr "needs_delay_slot" "yes")])
9346
 
9347
(define_expand "prologue"
9348
  [(const_int 0)]
9349
  ""
9350
  "sh_expand_prologue (); DONE;")
9351
 
9352
(define_expand "epilogue"
9353
  [(return)]
9354
  ""
9355
  "
9356
{
9357
  sh_expand_epilogue (0);
9358
  emit_jump_insn (gen_return ());
9359
  DONE;
9360
}")
9361
 
9362
(define_expand "eh_return"
9363
  [(use (match_operand 0 "register_operand" ""))]
9364
  ""
9365
{
9366
  rtx ra = operands[0];
9367
 
9368
  if (TARGET_SHMEDIA64)
9369
    emit_insn (gen_eh_set_ra_di (ra));
9370
  else
9371
    emit_insn (gen_eh_set_ra_si (ra));
9372
 
9373
  DONE;
9374
})
9375
 
9376
;; Clobber the return address on the stack.  We can't expand this
9377
;; until we know where it will be put in the stack frame.
9378
 
9379
(define_insn "eh_set_ra_si"
9380
  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9381
      UNSPECV_EH_RETURN)
9382
   (clobber (match_scratch:SI 1 "=&r"))]
9383
  "! TARGET_SHMEDIA64"
9384
  "#")
9385
 
9386
(define_insn "eh_set_ra_di"
9387
  [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9388
      UNSPECV_EH_RETURN)
9389
   (clobber (match_scratch:DI 1 "=&r"))]
9390
  "TARGET_SHMEDIA64"
9391
  "#")
9392
 
9393
(define_split
9394
  [(unspec_volatile [(match_operand 0 "register_operand" "")]
9395
      UNSPECV_EH_RETURN)
9396
   (clobber (match_scratch 1 ""))]
9397
  "reload_completed"
9398
  [(const_int 0)]
9399
  "
9400
{
9401
  sh_set_return_address (operands[0], operands[1]);
9402
  DONE;
9403
}")
9404
 
9405
(define_insn "blockage"
9406
  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9407
  ""
9408
  ""
9409
  [(set_attr "length" "0")])
9410
 
9411
;; Define movml instructions for SH2A target.  Currently they are
9412
;; used to push and pop all banked registers only.
9413
 
9414
(define_insn "movml_push_banked"
9415
  [(set (match_operand:SI 0 "register_operand" "=r")
9416
          (plus (match_dup 0) (const_int -32)))
9417
   (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9418
   (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9419
   (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9420
   (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9421
   (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9422
   (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9423
   (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9424
   (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9425
  "TARGET_SH2A && REGNO (operands[0]) == 15"
9426
  "movml.l\tr7,@-r15"
9427
  [(set_attr "in_delay_slot" "no")])
9428
 
9429
(define_insn "movml_pop_banked"
9430
  [(set (match_operand:SI 0 "register_operand" "=r")
9431
          (plus (match_dup 0) (const_int 32)))
9432
   (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9433
   (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9434
   (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9435
   (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9436
   (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9437
   (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9438
   (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9439
   (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9440
  "TARGET_SH2A && REGNO (operands[0]) == 15"
9441
  "movml.l\t@r15+,r7"
9442
  [(set_attr "in_delay_slot" "no")])
9443
 
9444
;; ------------------------------------------------------------------------
9445
;; Scc instructions
9446
;; ------------------------------------------------------------------------
9447
 
9448
(define_insn "movt"
9449
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9450
        (eq:SI (reg:SI T_REG) (const_int 1)))]
9451
  "TARGET_SH1"
9452
  "movt %0"
9453
  [(set_attr "type" "arith")])
9454
 
9455
(define_expand "cstore4_media"
9456
  [(set (match_operand:SI 0 "register_operand" "=r")
9457
        (match_operator:SI 1 "sh_float_comparison_operator"
9458
         [(match_operand 2 "logical_operand" "")
9459
          (match_operand 3 "cmp_operand" "")]))]
9460
  "TARGET_SHMEDIA"
9461
  "
9462
{
9463
  enum machine_mode mode = GET_MODE (operands[2]);
9464
  enum rtx_code code = GET_CODE (operands[1]);
9465
  bool invert, swap;
9466
  if (mode == VOIDmode)
9467
    mode = GET_MODE (operands[3]);
9468
  if (operands[2] == const0_rtx)
9469
    {
9470
      if (code == EQ || code == NE)
9471
        operands[2] = operands[3], operands[3] = const0_rtx;
9472
    }
9473
  else
9474
    operands[2] = force_reg (mode, operands[2]);
9475
  if (operands[3] != const0_rtx)
9476
    operands[3] = force_reg (mode, operands[3]);
9477
 
9478
  switch (code)
9479
    {
9480
    case GEU:
9481
    case GE:
9482
      swap = invert = !FLOAT_MODE_P (mode);
9483
      break;
9484
 
9485
    case LEU:
9486
    case LE:
9487
      swap = FLOAT_MODE_P (mode), invert = !swap;
9488
      break;
9489
 
9490
    case LTU:
9491
    case LT:
9492
      swap = true, invert = false;
9493
      break;
9494
 
9495
    case GTU:
9496
    case GT:
9497
    case EQ:
9498
    case UNORDERED:
9499
      swap = invert = false;
9500
      break;
9501
 
9502
    case NE:
9503
      swap = invert = true;
9504
      break;
9505
 
9506
    default:
9507
      gcc_unreachable ();
9508
  }
9509
 
9510
  if (swap)
9511
    {
9512
      rtx tem = operands[2];
9513
      operands[2] = operands[3];
9514
      operands[3] = tem;
9515
      code = swap_condition (code);
9516
    }
9517
 
9518
  if (invert)
9519
    {
9520
      rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9521
      code = reverse_condition (code);
9522
      operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9523
      emit_insn (gen_cstore4_media (tem, operands[1],
9524
                                    operands[2], operands[3]));
9525
      code = EQ;
9526
      operands[2] = tem;
9527
      operands[3] = const0_rtx;
9528
    }
9529
 
9530
  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9531
}")
9532
 
9533
(define_expand "cstoresi4"
9534
  [(set (match_operand:SI 0 "register_operand" "=r")
9535
        (match_operator:SI 1 "comparison_operator"
9536
         [(match_operand:SI 2 "cmpsi_operand" "")
9537
          (match_operand:SI 3 "arith_operand" "")]))]
9538
  "TARGET_SH1 || TARGET_SHMEDIA"
9539
  "if (TARGET_SHMEDIA)
9540
    {
9541
      emit_insn (gen_cstore4_media (operands[0], operands[1],
9542
                                    operands[2], operands[3]));
9543
      DONE;
9544
    }
9545
 
9546
   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9547
       && sh_expand_t_scc (operands))
9548
     DONE;
9549
 
9550
   if (! currently_expanding_to_rtl)
9551
     FAIL;
9552
 
9553
   sh_emit_compare_and_set (operands, SImode);
9554
   DONE;
9555
")
9556
 
9557
(define_expand "cstoredi4"
9558
  [(set (match_operand:SI 0 "register_operand" "=r")
9559
        (match_operator:SI 1 "comparison_operator"
9560
         [(match_operand:DI 2 "arith_operand" "")
9561
          (match_operand:DI 3 "arith_operand" "")]))]
9562
  "TARGET_SH2 || TARGET_SHMEDIA"
9563
  "if (TARGET_SHMEDIA)
9564
    {
9565
      emit_insn (gen_cstore4_media (operands[0], operands[1],
9566
                                    operands[2], operands[3]));
9567
      DONE;
9568
    }
9569
 
9570
   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9571
       && sh_expand_t_scc (operands))
9572
     DONE;
9573
 
9574
   if (! currently_expanding_to_rtl)
9575
     FAIL;
9576
 
9577
   sh_emit_compare_and_set (operands, DImode);
9578
   DONE;
9579
")
9580
 
9581
;; sne moves the complement of the T reg to DEST like this:
9582
;;      cmp/eq ...
9583
;;      mov    #-1,temp
9584
;;      negc   temp,dest
9585
;;   This is better than xoring compare result with 1 because it does
9586
;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9587
;;   loop.
9588
 
9589
(define_expand "movnegt"
9590
  [(set (match_dup 1) (const_int -1))
9591
   (parallel [(set (match_operand:SI 0 "" "")
9592
                   (neg:SI (plus:SI (reg:SI T_REG)
9593
                                    (match_dup 1))))
9594
              (set (reg:SI T_REG)
9595
                   (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9596
                          (const_int 0)))])]
9597
  ""
9598
  "
9599
{
9600
  operands[1] = gen_reg_rtx (SImode);
9601
}")
9602
 
9603
;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9604
;; This prevents a regression that occurred when we switched from xor to
9605
;; mov/neg for sne.
9606
 
9607
(define_split
9608
  [(set (match_operand:SI 0 "arith_reg_dest" "")
9609
        (plus:SI (reg:SI T_REG)
9610
                 (const_int -1)))]
9611
  "TARGET_SH1"
9612
  [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9613
   (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9614
  "")
9615
 
9616
(define_expand "cstoresf4"
9617
  [(set (match_operand:SI 0 "register_operand" "=r")
9618
        (match_operator:SI 1 "sh_float_comparison_operator"
9619
         [(match_operand:SF 2 "arith_operand" "")
9620
          (match_operand:SF 3 "arith_operand" "")]))]
9621
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9622
  "if (TARGET_SHMEDIA)
9623
     {
9624
       emit_insn (gen_cstore4_media (operands[0], operands[1],
9625
                                     operands[2], operands[3]));
9626
       DONE;
9627
     }
9628
 
9629
   if (! currently_expanding_to_rtl)
9630
     FAIL;
9631
 
9632
   sh_emit_compare_and_set (operands, SFmode);
9633
   DONE;
9634
")
9635
 
9636
(define_expand "cstoredf4"
9637
  [(set (match_operand:SI 0 "register_operand" "=r")
9638
        (match_operator:SI 1 "sh_float_comparison_operator"
9639
         [(match_operand:DF 2 "arith_operand" "")
9640
          (match_operand:DF 3 "arith_operand" "")]))]
9641
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9642
  "if (TARGET_SHMEDIA)
9643
     {
9644
       emit_insn (gen_cstore4_media (operands[0], operands[1],
9645
                                     operands[2], operands[3]));
9646
       DONE;
9647
     }
9648
 
9649
    if (! currently_expanding_to_rtl)
9650
      FAIL;
9651
 
9652
   sh_emit_compare_and_set (operands, DFmode);
9653
   DONE;
9654
")
9655
 
9656
;; -------------------------------------------------------------------------
9657
;; Instructions to cope with inline literal tables
9658
;; -------------------------------------------------------------------------
9659
 
9660
; 2 byte integer in line
9661
 
9662
(define_insn "consttable_2"
9663
 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9664
                    (match_operand 1 "" "")]
9665
                   UNSPECV_CONST2)]
9666
 ""
9667
 "*
9668
{
9669
  if (operands[1] != const0_rtx)
9670
    assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9671
  return \"\";
9672
}"
9673
 [(set_attr "length" "2")
9674
 (set_attr "in_delay_slot" "no")])
9675
 
9676
; 4 byte integer in line
9677
 
9678
(define_insn "consttable_4"
9679
 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9680
                    (match_operand 1 "" "")]
9681
                   UNSPECV_CONST4)]
9682
 ""
9683
 "*
9684
{
9685
  if (operands[1] != const0_rtx)
9686
    {
9687
      assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9688
      mark_symbol_refs_as_used (operands[0]);
9689
    }
9690
  return \"\";
9691
}"
9692
 [(set_attr "length" "4")
9693
  (set_attr "in_delay_slot" "no")])
9694
 
9695
; 8 byte integer in line
9696
 
9697
(define_insn "consttable_8"
9698
 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9699
                    (match_operand 1 "" "")]
9700
                   UNSPECV_CONST8)]
9701
 ""
9702
 "*
9703
{
9704
  if (operands[1] != const0_rtx)
9705
    assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9706
  return \"\";
9707
}"
9708
 [(set_attr "length" "8")
9709
  (set_attr "in_delay_slot" "no")])
9710
 
9711
; 4 byte floating point
9712
 
9713
(define_insn "consttable_sf"
9714
 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9715
                    (match_operand 1 "" "")]
9716
                   UNSPECV_CONST4)]
9717
 ""
9718
 "*
9719
{
9720
  if (operands[1] != const0_rtx)
9721
    {
9722
      REAL_VALUE_TYPE d;
9723
      REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9724
      assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9725
    }
9726
  return \"\";
9727
}"
9728
 [(set_attr "length" "4")
9729
  (set_attr "in_delay_slot" "no")])
9730
 
9731
; 8 byte floating point
9732
 
9733
(define_insn "consttable_df"
9734
 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9735
                    (match_operand 1 "" "")]
9736
                   UNSPECV_CONST8)]
9737
 ""
9738
 "*
9739
{
9740
  if (operands[1] != const0_rtx)
9741
    {
9742
      REAL_VALUE_TYPE d;
9743
      REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9744
      assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9745
    }
9746
  return \"\";
9747
}"
9748
 [(set_attr "length" "8")
9749
  (set_attr "in_delay_slot" "no")])
9750
 
9751
;; Alignment is needed for some constant tables; it may also be added for
9752
;; Instructions at the start of loops, or after unconditional branches.
9753
;; ??? We would get more accurate lengths if we did instruction
9754
;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9755
;; here is too conservative.
9756
 
9757
; align to a two byte boundary
9758
 
9759
(define_expand "align_2"
9760
 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9761
 ""
9762
 "")
9763
 
9764
; align to a four byte boundary
9765
;; align_4 and align_log are instructions for the starts of loops, or
9766
;; after unconditional branches, which may take up extra room.
9767
 
9768
(define_expand "align_4"
9769
 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9770
 ""
9771
 "")
9772
 
9773
; align to a cache line boundary
9774
 
9775
(define_insn "align_log"
9776
 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9777
 ""
9778
 ""
9779
 [(set_attr "length" "0")
9780
  (set_attr "in_delay_slot" "no")])
9781
 
9782
; emitted at the end of the literal table, used to emit the
9783
; 32bit branch labels if needed.
9784
 
9785
(define_insn "consttable_end"
9786
  [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9787
  ""
9788
  "* return output_jump_label_table ();"
9789
  [(set_attr "in_delay_slot" "no")])
9790
 
9791
; emitted at the end of the window in the literal table.
9792
 
9793
(define_insn "consttable_window_end"
9794
  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9795
  ""
9796
  ""
9797
  [(set_attr "length" "0")
9798
   (set_attr "in_delay_slot" "no")])
9799
 
9800
;; -------------------------------------------------------------------------
9801
;; Misc
9802
;; -------------------------------------------------------------------------
9803
 
9804
;; String/block move insn.
9805
 
9806
(define_expand "movmemsi"
9807
  [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9808
                   (mem:BLK (match_operand:BLK 1 "" "")))
9809
              (use (match_operand:SI 2 "nonmemory_operand" ""))
9810
              (use (match_operand:SI 3 "immediate_operand" ""))
9811
              (clobber (reg:SI PR_REG))
9812
              (clobber (reg:SI R4_REG))
9813
              (clobber (reg:SI R5_REG))
9814
              (clobber (reg:SI R0_REG))])]
9815
  "TARGET_SH1 && ! TARGET_SH5"
9816
  "
9817
{
9818
  if(expand_block_move (operands))
9819
     DONE;
9820
  else FAIL;
9821
}")
9822
 
9823
(define_insn "block_move_real"
9824
  [(parallel [(set (mem:BLK (reg:SI R4_REG))
9825
                   (mem:BLK (reg:SI R5_REG)))
9826
              (use (match_operand:SI 0 "arith_reg_operand" "r"))
9827
              (clobber (reg:SI PR_REG))
9828
              (clobber (reg:SI R0_REG))])]
9829
  "TARGET_SH1 && ! TARGET_HARD_SH4"
9830
  "jsr  @%0%#"
9831
  [(set_attr "type" "sfunc")
9832
   (set_attr "needs_delay_slot" "yes")])
9833
 
9834
(define_insn "block_lump_real"
9835
  [(parallel [(set (mem:BLK (reg:SI R4_REG))
9836
                   (mem:BLK (reg:SI R5_REG)))
9837
              (use (match_operand:SI 0 "arith_reg_operand" "r"))
9838
              (use (reg:SI R6_REG))
9839
              (clobber (reg:SI PR_REG))
9840
              (clobber (reg:SI T_REG))
9841
              (clobber (reg:SI R4_REG))
9842
              (clobber (reg:SI R5_REG))
9843
              (clobber (reg:SI R6_REG))
9844
              (clobber (reg:SI R0_REG))])]
9845
  "TARGET_SH1 && ! TARGET_HARD_SH4"
9846
  "jsr  @%0%#"
9847
  [(set_attr "type" "sfunc")
9848
   (set_attr "needs_delay_slot" "yes")])
9849
 
9850
(define_insn "block_move_real_i4"
9851
  [(parallel [(set (mem:BLK (reg:SI R4_REG))
9852
                   (mem:BLK (reg:SI R5_REG)))
9853
              (use (match_operand:SI 0 "arith_reg_operand" "r"))
9854
              (clobber (reg:SI PR_REG))
9855
              (clobber (reg:SI R0_REG))
9856
              (clobber (reg:SI R1_REG))
9857
              (clobber (reg:SI R2_REG))])]
9858
  "TARGET_HARD_SH4"
9859
  "jsr  @%0%#"
9860
  [(set_attr "type" "sfunc")
9861
   (set_attr "needs_delay_slot" "yes")])
9862
 
9863
(define_insn "block_lump_real_i4"
9864
  [(parallel [(set (mem:BLK (reg:SI R4_REG))
9865
                   (mem:BLK (reg:SI R5_REG)))
9866
              (use (match_operand:SI 0 "arith_reg_operand" "r"))
9867
              (use (reg:SI R6_REG))
9868
              (clobber (reg:SI PR_REG))
9869
              (clobber (reg:SI T_REG))
9870
              (clobber (reg:SI R4_REG))
9871
              (clobber (reg:SI R5_REG))
9872
              (clobber (reg:SI R6_REG))
9873
              (clobber (reg:SI R0_REG))
9874
              (clobber (reg:SI R1_REG))
9875
              (clobber (reg:SI R2_REG))
9876
              (clobber (reg:SI R3_REG))])]
9877
  "TARGET_HARD_SH4"
9878
  "jsr  @%0%#"
9879
  [(set_attr "type" "sfunc")
9880
   (set_attr "needs_delay_slot" "yes")])
9881
 
9882
;; -------------------------------------------------------------------------
9883
;; Floating point instructions.
9884
;; -------------------------------------------------------------------------
9885
 
9886
;; ??? All patterns should have a type attribute.
9887
 
9888
(define_expand "movpsi"
9889
  [(set (match_operand:PSI 0 "register_operand" "")
9890
        (match_operand:PSI 1 "general_movsrc_operand" ""))]
9891
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9892
  "")
9893
 
9894
;; The c / m alternative is a fake to guide reload to load directly into
9895
;; fpscr, since reload doesn't know how to use post-increment.
9896
;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9897
;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9898
;; predicate after reload.
9899
;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9900
;; like a mac -> gpr move.
9901
(define_insn "fpu_switch"
9902
  [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9903
        (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9904
  "TARGET_SH2E
9905
   && (! reload_completed
9906
       || true_regnum (operands[0]) != FPSCR_REG
9907
       || !MEM_P (operands[1])
9908
       || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9909
  "@
9910
        ! precision stays the same
9911
        lds.l   %1,fpscr
9912
        mov.l   %1,%0
9913
        #
9914
        lds     %1,fpscr
9915
        mov     %1,%0
9916
        mov.l   %1,%0
9917
        sts     fpscr,%0
9918
        sts.l   fpscr,%0"
9919
  [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9920
   (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9921
 
9922
(define_peephole2
9923
  [(set (reg:PSI FPSCR_REG)
9924
        (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9925
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9926
  [(const_int 0)]
9927
{
9928
  rtx fpscr, mem, new_insn;
9929
 
9930
  fpscr = SET_DEST (PATTERN (curr_insn));
9931
  mem = SET_SRC (PATTERN (curr_insn));
9932
  mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9933
 
9934
  new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9935
  add_reg_note (new_insn, REG_INC, operands[0]);
9936
  DONE;
9937
})
9938
 
9939
(define_split
9940
  [(set (reg:PSI FPSCR_REG)
9941
        (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9942
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9943
   && (flag_peephole2 ? epilogue_completed : reload_completed)"
9944
  [(const_int 0)]
9945
{
9946
  rtx fpscr, mem, new_insn;
9947
 
9948
  fpscr = SET_DEST (PATTERN (curr_insn));
9949
  mem = SET_SRC (PATTERN (curr_insn));
9950
  mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9951
 
9952
  new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9953
  add_reg_note (new_insn, REG_INC, operands[0]);
9954
 
9955
  if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9956
    emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9957
  DONE;
9958
})
9959
 
9960
;; ??? This uses the fp unit, but has no type indicating that.
9961
;; If we did that, this would either give a bogus latency or introduce
9962
;; a bogus FIFO constraint.
9963
;; Since this insn is currently only used for prologues/epilogues,
9964
;; it is probably best to claim no function unit, which matches the
9965
;; current setting.
9966
(define_insn "toggle_sz"
9967
  [(set (reg:PSI FPSCR_REG)
9968
        (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9969
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9970
  "fschg"
9971
  [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9972
 
9973
;; There's no way we can use it today, since optimize mode switching
9974
;; doesn't enable us to know from which mode we're switching to the
9975
;; mode it requests, to tell whether we can use a relative mode switch
9976
;; (like toggle_pr) or an absolute switch (like loading fpscr from
9977
;; memory).
9978
(define_insn "toggle_pr"
9979
  [(set (reg:PSI FPSCR_REG)
9980
        (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9981
  "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9982
  "fpchg"
9983
  [(set_attr "type" "fpscr_toggle")])
9984
 
9985
(define_expand "addsf3"
9986
  [(set (match_operand:SF 0 "arith_reg_operand" "")
9987
        (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9988
                 (match_operand:SF 2 "arith_reg_operand" "")))]
9989
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9990
  "
9991
{
9992
  if (TARGET_SH2E)
9993
    {
9994
      expand_sf_binop (&gen_addsf3_i, operands);
9995
      DONE;
9996
    }
9997
}")
9998
 
9999
(define_insn "*addsf3_media"
10000
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10001
        (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10002
                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10003
  "TARGET_SHMEDIA_FPU"
10004
  "fadd.s       %1, %2, %0"
10005
  [(set_attr "type" "fparith_media")])
10006
 
10007
(define_insn_and_split "unary_sf_op"
10008
  [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10009
        (vec_select:V2SF
10010
         (vec_concat:V2SF
10011
          (vec_select:SF
10012
           (match_dup 0)
10013
           (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10014
          (match_operator:SF 2 "unary_float_operator"
10015
            [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10016
                            (parallel [(match_operand 4
10017
                                        "const_int_operand" "n")]))]))
10018
         (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10019
  "TARGET_SHMEDIA_FPU"
10020
  "#"
10021
  "TARGET_SHMEDIA_FPU && reload_completed"
10022
  [(set (match_dup 5) (match_dup 6))]
10023
  "
10024
{
10025
  int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10026
  rtx op1 = gen_rtx_REG (SFmode,
10027
                         (true_regnum (operands[1])
10028
                          + (INTVAL (operands[4]) ^ endian)));
10029
 
10030
  operands[7] = gen_rtx_REG (SFmode,
10031
                             (true_regnum (operands[0])
10032
                              + (INTVAL (operands[3]) ^ endian)));
10033
  operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10034
}"
10035
  [(set_attr "type" "fparith_media")])
10036
 
10037
(define_insn_and_split "binary_sf_op0"
10038
  [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10039
        (vec_concat:V2SF
10040
          (match_operator:SF 3 "binary_float_operator"
10041
            [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10042
                            (parallel [(const_int 0)]))
10043
             (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10044
                            (parallel [(const_int 0)]))])
10045
          (vec_select:SF
10046
           (match_dup 0)
10047
           (parallel [(const_int 1)]))))]
10048
  "TARGET_SHMEDIA_FPU"
10049
  "#"
10050
  "&& reload_completed"
10051
  [(set (match_dup 4) (match_dup 5))]
10052
  "
10053
{
10054
  int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10055
  rtx op1 = gen_rtx_REG (SFmode,
10056
                         true_regnum (operands[1]) + endian);
10057
  rtx op2 = gen_rtx_REG (SFmode,
10058
                         true_regnum (operands[2]) + endian);
10059
 
10060
  operands[4] = gen_rtx_REG (SFmode,
10061
                             true_regnum (operands[0]) + endian);
10062
  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10063
}"
10064
  [(set_attr "type" "fparith_media")])
10065
 
10066
(define_insn_and_split "binary_sf_op1"
10067
  [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10068
        (vec_concat:V2SF
10069
          (vec_select:SF
10070
           (match_dup 0)
10071
           (parallel [(const_int 0)]))
10072
          (match_operator:SF 3 "binary_float_operator"
10073
            [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10074
                            (parallel [(const_int 1)]))
10075
             (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10076
                            (parallel [(const_int 1)]))])))]
10077
  "TARGET_SHMEDIA_FPU"
10078
  "#"
10079
  "&& reload_completed"
10080
  [(set (match_dup 4) (match_dup 5))]
10081
  "
10082
{
10083
  int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10084
  rtx op1 = gen_rtx_REG (SFmode,
10085
                         true_regnum (operands[1]) + (1 ^ endian));
10086
  rtx op2 = gen_rtx_REG (SFmode,
10087
                         true_regnum (operands[2]) + (1 ^ endian));
10088
 
10089
  operands[4] = gen_rtx_REG (SFmode,
10090
                             true_regnum (operands[0]) + (1 ^ endian));
10091
  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10092
}"
10093
  [(set_attr "type" "fparith_media")])
10094
 
10095
(define_insn "addsf3_i"
10096
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10097
        (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10098
                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10099
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10100
  "TARGET_SH2E"
10101
  "fadd %2,%0"
10102
  [(set_attr "type" "fp")
10103
   (set_attr "fp_mode" "single")])
10104
 
10105
(define_expand "subsf3"
10106
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10107
        (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10108
                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10109
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10110
  "
10111
{
10112
  if (TARGET_SH2E)
10113
    {
10114
      expand_sf_binop (&gen_subsf3_i, operands);
10115
      DONE;
10116
    }
10117
}")
10118
 
10119
(define_insn "*subsf3_media"
10120
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10121
        (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10122
                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10123
  "TARGET_SHMEDIA_FPU"
10124
  "fsub.s       %1, %2, %0"
10125
  [(set_attr "type" "fparith_media")])
10126
 
10127
(define_insn "subsf3_i"
10128
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10129
        (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10130
                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10131
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10132
  "TARGET_SH2E"
10133
  "fsub %2,%0"
10134
  [(set_attr "type" "fp")
10135
   (set_attr "fp_mode" "single")])
10136
 
10137
(define_expand "mulsf3"
10138
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10139
        (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10140
                 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10141
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10142
  "")
10143
 
10144
(define_insn "*mulsf3_media"
10145
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10146
        (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10147
                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10148
  "TARGET_SHMEDIA_FPU"
10149
  "fmul.s       %1, %2, %0"
10150
  [(set_attr "type" "fparith_media")])
10151
 
10152
;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10153
;; register in feeding fp instructions.  Thus, in order to generate fmac,
10154
;; we start out with a mulsf pattern that does not depend on fpscr.
10155
;; This is split after combine to introduce the dependency, in order to
10156
;; get mode switching and scheduling right.
10157
(define_insn_and_split "mulsf3_ie"
10158
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10159
        (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10160
                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10161
  "TARGET_SH2E"
10162
  "fmul %2,%0"
10163
  "TARGET_SH4 || TARGET_SH2A_SINGLE"
10164
  [(const_int 0)]
10165
  "
10166
{
10167
  emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10168
             get_fpscr_rtx ()));
10169
  DONE;
10170
}"
10171
  [(set_attr "type" "fp")])
10172
 
10173
(define_insn "mulsf3_i4"
10174
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10175
        (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10176
                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10177
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10178
  "TARGET_SH2E"
10179
  "fmul %2,%0"
10180
  [(set_attr "type" "fp")
10181
   (set_attr "fp_mode" "single")])
10182
 
10183
(define_insn "mac_media"
10184
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10185
        (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10186
                          (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10187
                 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10188
  "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10189
  "fmac.s %1, %2, %0"
10190
  [(set_attr "type" "fparith_media")])
10191
 
10192
(define_insn "*macsf3"
10193
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10194
        (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10195
                          (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10196
                 (match_operand:SF 3 "arith_reg_operand" "0")))
10197
   (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10198
  "TARGET_SH2E && TARGET_FMAC"
10199
  "fmac fr0,%2,%0"
10200
  [(set_attr "type" "fp")
10201
   (set_attr "fp_mode" "single")])
10202
 
10203
(define_expand "divsf3"
10204
  [(set (match_operand:SF 0 "arith_reg_operand" "")
10205
        (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10206
                (match_operand:SF 2 "arith_reg_operand" "")))]
10207
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10208
  "
10209
{
10210
  if (TARGET_SH2E)
10211
    {
10212
      expand_sf_binop (&gen_divsf3_i, operands);
10213
      DONE;
10214
    }
10215
}")
10216
 
10217
(define_insn "*divsf3_media"
10218
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10219
        (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10220
                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10221
  "TARGET_SHMEDIA_FPU"
10222
  "fdiv.s       %1, %2, %0"
10223
  [(set_attr "type" "fdiv_media")])
10224
 
10225
(define_insn "divsf3_i"
10226
  [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10227
        (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10228
                 (match_operand:SF 2 "arith_reg_operand" "f")))
10229
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10230
  "TARGET_SH2E"
10231
  "fdiv %2,%0"
10232
  [(set_attr "type" "fdiv")
10233
   (set_attr "fp_mode" "single")])
10234
 
10235
(define_insn "floatdisf2"
10236
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10237
        (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10238
  "TARGET_SHMEDIA_FPU"
10239
  "float.qs %1, %0"
10240
  [(set_attr "type" "fpconv_media")])
10241
 
10242
(define_expand "floatsisf2"
10243
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10244
        (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10245
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10246
  "
10247
{
10248
  if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10249
    {
10250
      emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10251
      DONE;
10252
    }
10253
}")
10254
 
10255
(define_insn "*floatsisf2_media"
10256
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10257
        (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10258
  "TARGET_SHMEDIA_FPU"
10259
  "float.ls     %1, %0"
10260
  [(set_attr "type" "fpconv_media")])
10261
 
10262
(define_insn "floatsisf2_i4"
10263
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10264
        (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10265
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10266
  "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10267
  "float        %1,%0"
10268
  [(set_attr "type" "fp")
10269
   (set_attr "fp_mode" "single")])
10270
 
10271
(define_insn "*floatsisf2_ie"
10272
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10273
        (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10274
  "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10275
  "float        %1,%0"
10276
  [(set_attr "type" "fp")])
10277
 
10278
(define_insn "fix_truncsfdi2"
10279
  [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10280
        (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10281
  "TARGET_SHMEDIA_FPU"
10282
  "ftrc.sq %1, %0"
10283
  [(set_attr "type" "fpconv_media")])
10284
 
10285
(define_expand "fix_truncsfsi2"
10286
  [(set (match_operand:SI 0 "fpul_operand" "=y")
10287
        (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10288
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10289
  "
10290
{
10291
  if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10292
    {
10293
      emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10294
      DONE;
10295
    }
10296
}")
10297
 
10298
(define_insn "*fix_truncsfsi2_media"
10299
  [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10300
        (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10301
  "TARGET_SHMEDIA_FPU"
10302
  "ftrc.sl      %1, %0"
10303
  [(set_attr "type" "fpconv_media")])
10304
 
10305
(define_insn "fix_truncsfsi2_i4"
10306
  [(set (match_operand:SI 0 "fpul_operand" "=y")
10307
        (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10308
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10309
  "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10310
  "ftrc %1,%0"
10311
  [(set_attr "type" "ftrc_s")
10312
   (set_attr "fp_mode" "single")])
10313
 
10314
;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10315
;; fix_truncsfsi2_i4.
10316
;; (define_insn "fix_truncsfsi2_i4_2"
10317
;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10318
;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10319
;;   (use (reg:PSI FPSCR_REG))
10320
;;   (clobber (reg:SI FPUL_REG))]
10321
;;  "TARGET_SH4"
10322
;;  "#"
10323
;;  [(set_attr "length" "4")
10324
;;   (set_attr "fp_mode" "single")])
10325
 
10326
;;(define_split
10327
;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10328
;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10329
;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10330
;;   (clobber (reg:SI FPUL_REG))]
10331
;;  "TARGET_SH4"
10332
;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10333
;;            (use (match_dup 2))])
10334
;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10335
 
10336
(define_insn "*fixsfsi"
10337
  [(set (match_operand:SI 0 "fpul_operand" "=y")
10338
        (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10339
  "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10340
  "ftrc %1,%0"
10341
  [(set_attr "type" "fp")])
10342
 
10343
(define_insn "cmpgtsf_t"
10344
  [(set (reg:SI T_REG)
10345
        (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10346
               (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10347
  "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10348
  "fcmp/gt      %1,%0"
10349
  [(set_attr "type" "fp_cmp")
10350
   (set_attr "fp_mode" "single")])
10351
 
10352
(define_insn "cmpeqsf_t"
10353
  [(set (reg:SI T_REG)
10354
        (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10355
               (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10356
  "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10357
  "fcmp/eq      %1,%0"
10358
  [(set_attr "type" "fp_cmp")
10359
   (set_attr "fp_mode" "single")])
10360
 
10361
(define_insn "ieee_ccmpeqsf_t"
10362
  [(set (reg:SI T_REG)
10363
        (ior:SI (reg:SI T_REG)
10364
                (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10365
                       (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10366
  "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10367
  "* return output_ieee_ccmpeq (insn, operands);"
10368
  [(set_attr "length" "4")])
10369
 
10370
 
10371
(define_insn "cmpgtsf_t_i4"
10372
  [(set (reg:SI T_REG)
10373
        (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10374
               (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10375
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10376
  "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10377
  "fcmp/gt      %1,%0"
10378
  [(set_attr "type" "fp_cmp")
10379
   (set_attr "fp_mode" "single")])
10380
 
10381
(define_insn "cmpeqsf_t_i4"
10382
  [(set (reg:SI T_REG)
10383
        (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10384
               (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10385
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10386
  "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10387
  "fcmp/eq      %1,%0"
10388
  [(set_attr "type" "fp_cmp")
10389
   (set_attr "fp_mode" "single")])
10390
 
10391
(define_insn "*ieee_ccmpeqsf_t_4"
10392
  [(set (reg:SI T_REG)
10393
        (ior:SI (reg:SI T_REG)
10394
                (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10395
                       (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10396
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10397
  "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10398
  "* return output_ieee_ccmpeq (insn, operands);"
10399
  [(set_attr "length" "4")
10400
   (set_attr "fp_mode" "single")])
10401
 
10402
(define_insn "cmpeqsf_media"
10403
  [(set (match_operand:SI 0 "register_operand" "=r")
10404
        (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10405
               (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10406
  "TARGET_SHMEDIA_FPU"
10407
  "fcmpeq.s     %1, %2, %0"
10408
  [(set_attr "type" "fcmp_media")])
10409
 
10410
(define_insn "cmpgtsf_media"
10411
  [(set (match_operand:SI 0 "register_operand" "=r")
10412
        (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10413
               (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10414
  "TARGET_SHMEDIA_FPU"
10415
  "fcmpgt.s     %1, %2, %0"
10416
  [(set_attr "type" "fcmp_media")])
10417
 
10418
(define_insn "cmpgesf_media"
10419
  [(set (match_operand:SI 0 "register_operand" "=r")
10420
        (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10421
               (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10422
  "TARGET_SHMEDIA_FPU"
10423
  "fcmpge.s     %1, %2, %0"
10424
  [(set_attr "type" "fcmp_media")])
10425
 
10426
(define_insn "cmpunsf_media"
10427
  [(set (match_operand:SI 0 "register_operand" "=r")
10428
        (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10429
                      (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10430
  "TARGET_SHMEDIA_FPU"
10431
  "fcmpun.s     %1, %2, %0"
10432
  [(set_attr "type" "fcmp_media")])
10433
 
10434
(define_expand "cbranchsf4"
10435
  [(set (pc)
10436
        (if_then_else (match_operator 0 "sh_float_comparison_operator"
10437
                       [(match_operand:SF 1 "arith_operand" "")
10438
                        (match_operand:SF 2 "arith_operand" "")])
10439
                      (match_operand 3 "" "")
10440
                      (pc)))]
10441
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10442
  "
10443
{
10444
  if (TARGET_SHMEDIA)
10445
    emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10446
                                          operands[3]));
10447
  else
10448
    sh_emit_compare_and_branch (operands, SFmode);
10449
  DONE;
10450
}")
10451
 
10452
(define_expand "negsf2"
10453
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10454
        (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10455
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10456
  "
10457
{
10458
  if (TARGET_SH2E)
10459
    {
10460
      expand_sf_unop (&gen_negsf2_i, operands);
10461
      DONE;
10462
    }
10463
}")
10464
 
10465
(define_insn "*negsf2_media"
10466
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10467
        (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10468
  "TARGET_SHMEDIA_FPU"
10469
  "fneg.s       %1, %0"
10470
  [(set_attr "type" "fmove_media")])
10471
 
10472
(define_insn "negsf2_i"
10473
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10474
        (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10475
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10476
  "TARGET_SH2E"
10477
  "fneg %0"
10478
  [(set_attr "type" "fmove")
10479
   (set_attr "fp_mode" "single")])
10480
 
10481
(define_expand "sqrtsf2"
10482
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10483
        (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10484
  "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10485
  "
10486
{
10487
  if (TARGET_SH3E)
10488
    {
10489
      expand_sf_unop (&gen_sqrtsf2_i, operands);
10490
      DONE;
10491
    }
10492
}")
10493
 
10494
(define_insn "*sqrtsf2_media"
10495
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10496
        (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10497
  "TARGET_SHMEDIA_FPU"
10498
  "fsqrt.s      %1, %0"
10499
  [(set_attr "type" "fdiv_media")])
10500
 
10501
(define_insn "sqrtsf2_i"
10502
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10503
        (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10504
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10505
  "TARGET_SH3E"
10506
  "fsqrt        %0"
10507
  [(set_attr "type" "fdiv")
10508
   (set_attr "fp_mode" "single")])
10509
 
10510
(define_insn "rsqrtsf2"
10511
  [(set (match_operand:SF 0 "register_operand" "=f")
10512
        (div:SF (match_operand:SF 1 "immediate_operand" "i")
10513
                (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10514
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10515
  "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10516
   && operands[1] == CONST1_RTX (SFmode)"
10517
  "fsrra        %0"
10518
  [(set_attr "type" "fsrra")
10519
   (set_attr "fp_mode" "single")])
10520
 
10521
(define_insn "fsca"
10522
  [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10523
        (vec_concat:V2SF
10524
         (unspec:SF [(mult:SF
10525
                      (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10526
                      (match_operand:SF 2 "immediate_operand" "i"))
10527
                    ] UNSPEC_FSINA)
10528
         (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10529
                    ] UNSPEC_FCOSA)))
10530
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10531
  "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10532
   && operands[2] == sh_fsca_int2sf ()"
10533
  "fsca fpul,%d0"
10534
  [(set_attr "type" "fsca")
10535
   (set_attr "fp_mode" "single")])
10536
 
10537
(define_expand "sinsf2"
10538
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
10539
        (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10540
                   UNSPEC_FSINA))]
10541
  "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10542
  "
10543
{
10544
  rtx scaled = gen_reg_rtx (SFmode);
10545
  rtx truncated = gen_reg_rtx (SImode);
10546
  rtx fsca = gen_reg_rtx (V2SFmode);
10547
  rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10548
 
10549
  emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10550
  emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10551
  emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10552
                          get_fpscr_rtx ()));
10553
  emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10554
  DONE;
10555
}")
10556
 
10557
(define_expand "cossf2"
10558
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
10559
        (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10560
                   UNSPEC_FCOSA))]
10561
  "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10562
  "
10563
{
10564
  rtx scaled = gen_reg_rtx (SFmode);
10565
  rtx truncated = gen_reg_rtx (SImode);
10566
  rtx fsca = gen_reg_rtx (V2SFmode);
10567
  rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10568
 
10569
  emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10570
  emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10571
  emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10572
                          get_fpscr_rtx ()));
10573
  emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10574
  DONE;
10575
}")
10576
 
10577
(define_expand "sindf2"
10578
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10579
        (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10580
                   UNSPEC_FSINA))]
10581
  "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10582
  "
10583
{
10584
  rtx scaled = gen_reg_rtx (DFmode);
10585
  rtx truncated = gen_reg_rtx (SImode);
10586
  rtx fsca = gen_reg_rtx (V2SFmode);
10587
  rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10588
  rtx sfresult = gen_reg_rtx (SFmode);
10589
 
10590
  emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10591
  emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10592
  emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10593
                          get_fpscr_rtx ()));
10594
  emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10595
  emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10596
  DONE;
10597
}")
10598
 
10599
(define_expand "cosdf2"
10600
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10601
        (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10602
                   UNSPEC_FCOSA))]
10603
  "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10604
  "
10605
{
10606
  rtx scaled = gen_reg_rtx (DFmode);
10607
  rtx truncated = gen_reg_rtx (SImode);
10608
  rtx fsca = gen_reg_rtx (V2SFmode);
10609
  rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10610
  rtx sfresult = gen_reg_rtx (SFmode);
10611
 
10612
  emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10613
  emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10614
  emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10615
                          get_fpscr_rtx ()));
10616
  emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10617
  emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10618
  DONE;
10619
}")
10620
 
10621
(define_expand "abssf2"
10622
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10623
        (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10624
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10625
  "
10626
{
10627
  if (TARGET_SH2E)
10628
    {
10629
      expand_sf_unop (&gen_abssf2_i, operands);
10630
      DONE;
10631
    }
10632
}")
10633
 
10634
(define_insn "*abssf2_media"
10635
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10636
        (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10637
  "TARGET_SHMEDIA_FPU"
10638
  "fabs.s       %1, %0"
10639
  [(set_attr "type" "fmove_media")])
10640
 
10641
(define_insn "abssf2_i"
10642
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10643
        (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10644
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10645
  "TARGET_SH2E"
10646
  "fabs %0"
10647
  [(set_attr "type" "fmove")
10648
   (set_attr "fp_mode" "single")])
10649
 
10650
(define_expand "adddf3"
10651
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10652
        (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10653
                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10654
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10655
  "
10656
{
10657
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10658
    {
10659
      expand_df_binop (&gen_adddf3_i, operands);
10660
      DONE;
10661
    }
10662
}")
10663
 
10664
(define_insn "*adddf3_media"
10665
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10666
        (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10667
                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10668
  "TARGET_SHMEDIA_FPU"
10669
  "fadd.d       %1, %2, %0"
10670
  [(set_attr "type" "dfparith_media")])
10671
 
10672
(define_insn "adddf3_i"
10673
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10674
        (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10675
                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10676
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10677
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10678
  "fadd %2,%0"
10679
  [(set_attr "type" "dfp_arith")
10680
   (set_attr "fp_mode" "double")])
10681
 
10682
(define_expand "subdf3"
10683
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10684
        (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10685
                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10686
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10687
  "
10688
{
10689
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10690
    {
10691
      expand_df_binop (&gen_subdf3_i, operands);
10692
      DONE;
10693
    }
10694
}")
10695
 
10696
(define_insn "*subdf3_media"
10697
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10698
        (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10699
                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10700
  "TARGET_SHMEDIA_FPU"
10701
  "fsub.d       %1, %2, %0"
10702
  [(set_attr "type" "dfparith_media")])
10703
 
10704
(define_insn "subdf3_i"
10705
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10706
        (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10707
                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10708
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10709
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10710
  "fsub %2,%0"
10711
  [(set_attr "type" "dfp_arith")
10712
   (set_attr "fp_mode" "double")])
10713
 
10714
(define_expand "muldf3"
10715
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10716
        (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10717
                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10718
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10719
  "
10720
{
10721
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10722
    {
10723
      expand_df_binop (&gen_muldf3_i, operands);
10724
      DONE;
10725
    }
10726
}")
10727
 
10728
(define_insn "*muldf3_media"
10729
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10730
        (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10731
                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10732
  "TARGET_SHMEDIA_FPU"
10733
  "fmul.d       %1, %2, %0"
10734
  [(set_attr "type" "dfmul_media")])
10735
 
10736
(define_insn "muldf3_i"
10737
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10738
        (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10739
                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10740
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10741
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10742
  "fmul %2,%0"
10743
  [(set_attr "type" "dfp_mul")
10744
   (set_attr "fp_mode" "double")])
10745
 
10746
(define_expand "divdf3"
10747
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10748
        (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10749
                (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10750
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10751
  "
10752
{
10753
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10754
    {
10755
      expand_df_binop (&gen_divdf3_i, operands);
10756
      DONE;
10757
    }
10758
}")
10759
 
10760
(define_insn "*divdf3_media"
10761
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10762
        (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10763
                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10764
  "TARGET_SHMEDIA_FPU"
10765
  "fdiv.d       %1, %2, %0"
10766
  [(set_attr "type" "dfdiv_media")])
10767
 
10768
(define_insn "divdf3_i"
10769
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10770
        (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10771
                (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10772
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10773
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10774
  "fdiv %2,%0"
10775
  [(set_attr "type" "dfdiv")
10776
   (set_attr "fp_mode" "double")])
10777
 
10778
(define_insn "floatdidf2"
10779
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10780
        (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10781
  "TARGET_SHMEDIA_FPU"
10782
  "float.qd     %1, %0"
10783
  [(set_attr "type" "dfpconv_media")])
10784
 
10785
(define_expand "floatsidf2"
10786
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10787
        (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10788
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10789
  "
10790
{
10791
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10792
    {
10793
      emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10794
                                      get_fpscr_rtx ()));
10795
      DONE;
10796
    }
10797
}")
10798
 
10799
(define_insn "*floatsidf2_media"
10800
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10801
        (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10802
  "TARGET_SHMEDIA_FPU"
10803
  "float.ld     %1, %0"
10804
  [(set_attr "type" "dfpconv_media")])
10805
 
10806
(define_insn "floatsidf2_i"
10807
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10808
        (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10809
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10810
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10811
  "float        %1,%0"
10812
  [(set_attr "type" "dfp_conv")
10813
   (set_attr "fp_mode" "double")])
10814
 
10815
(define_insn "fix_truncdfdi2"
10816
  [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10817
        (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10818
  "TARGET_SHMEDIA_FPU"
10819
  "ftrc.dq      %1, %0"
10820
  [(set_attr "type" "dfpconv_media")])
10821
 
10822
(define_expand "fix_truncdfsi2"
10823
  [(set (match_operand:SI 0 "fpul_operand" "")
10824
        (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10825
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10826
  "
10827
{
10828
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10829
    {
10830
      emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10831
                                          get_fpscr_rtx ()));
10832
      DONE;
10833
    }
10834
}")
10835
 
10836
(define_insn "*fix_truncdfsi2_media"
10837
  [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10838
        (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10839
  "TARGET_SHMEDIA_FPU"
10840
  "ftrc.dl      %1, %0"
10841
  [(set_attr "type" "dfpconv_media")])
10842
 
10843
(define_insn "fix_truncdfsi2_i"
10844
  [(set (match_operand:SI 0 "fpul_operand" "=y")
10845
        (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10846
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10847
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10848
  "ftrc %1,%0"
10849
  [(set_attr "type" "dfp_conv")
10850
   (set_attr "dfp_comp" "no")
10851
   (set_attr "fp_mode" "double")])
10852
 
10853
;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10854
;; fix_truncdfsi2_i.
10855
;; (define_insn "fix_truncdfsi2_i4"
10856
;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10857
;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10858
;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10859
;;    (clobber (reg:SI FPUL_REG))]
10860
;;   "TARGET_SH4"
10861
;;   "#"
10862
;;   [(set_attr "length" "4")
10863
;;    (set_attr "fp_mode" "double")])
10864
;;
10865
;; (define_split
10866
;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10867
;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10868
;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10869
;;    (clobber (reg:SI FPUL_REG))]
10870
;;   "TARGET_SH4"
10871
;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10872
;;            (use (match_dup 2))])
10873
;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10874
 
10875
(define_insn "cmpgtdf_t"
10876
  [(set (reg:SI T_REG)
10877
        (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10878
               (match_operand:DF 1 "arith_reg_operand" "f")))
10879
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10880
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10881
  "fcmp/gt      %1,%0"
10882
  [(set_attr "type" "dfp_cmp")
10883
   (set_attr "fp_mode" "double")])
10884
 
10885
(define_insn "cmpeqdf_t"
10886
  [(set (reg:SI T_REG)
10887
        (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10888
               (match_operand:DF 1 "arith_reg_operand" "f")))
10889
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10890
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10891
  "fcmp/eq      %1,%0"
10892
  [(set_attr "type" "dfp_cmp")
10893
   (set_attr "fp_mode" "double")])
10894
 
10895
(define_insn "*ieee_ccmpeqdf_t"
10896
  [(set (reg:SI T_REG)
10897
        (ior:SI (reg:SI T_REG)
10898
                (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10899
                       (match_operand:DF 1 "arith_reg_operand" "f"))))
10900
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10901
  "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10902
  "* return output_ieee_ccmpeq (insn, operands);"
10903
  [(set_attr "length" "4")
10904
   (set_attr "fp_mode" "double")])
10905
 
10906
(define_insn "cmpeqdf_media"
10907
  [(set (match_operand:SI 0 "register_operand" "=r")
10908
        (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10909
               (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10910
  "TARGET_SHMEDIA_FPU"
10911
  "fcmpeq.d     %1,%2,%0"
10912
  [(set_attr "type" "fcmp_media")])
10913
 
10914
(define_insn "cmpgtdf_media"
10915
  [(set (match_operand:SI 0 "register_operand" "=r")
10916
        (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10917
               (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10918
  "TARGET_SHMEDIA_FPU"
10919
  "fcmpgt.d     %1,%2,%0"
10920
  [(set_attr "type" "fcmp_media")])
10921
 
10922
(define_insn "cmpgedf_media"
10923
  [(set (match_operand:SI 0 "register_operand" "=r")
10924
        (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10925
               (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10926
  "TARGET_SHMEDIA_FPU"
10927
  "fcmpge.d     %1,%2,%0"
10928
  [(set_attr "type" "fcmp_media")])
10929
 
10930
(define_insn "cmpundf_media"
10931
  [(set (match_operand:SI 0 "register_operand" "=r")
10932
        (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10933
                      (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10934
  "TARGET_SHMEDIA_FPU"
10935
  "fcmpun.d     %1,%2,%0"
10936
  [(set_attr "type" "fcmp_media")])
10937
 
10938
(define_expand "cbranchdf4"
10939
  [(set (pc)
10940
        (if_then_else (match_operator 0 "sh_float_comparison_operator"
10941
                       [(match_operand:DF 1 "arith_operand" "")
10942
                        (match_operand:DF 2 "arith_operand" "")])
10943
                      (match_operand 3 "" "")
10944
                      (pc)))]
10945
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10946
  "
10947
{
10948
  if (TARGET_SHMEDIA)
10949
    emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10950
                                          operands[3]));
10951
  else
10952
    sh_emit_compare_and_branch (operands, DFmode);
10953
  DONE;
10954
}")
10955
 
10956
 
10957
(define_expand "negdf2"
10958
  [(set (match_operand:DF 0 "arith_reg_operand" "")
10959
        (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10960
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10961
  "
10962
{
10963
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10964
    {
10965
      expand_df_unop (&gen_negdf2_i, operands);
10966
      DONE;
10967
    }
10968
}")
10969
 
10970
(define_insn "*negdf2_media"
10971
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10972
        (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10973
  "TARGET_SHMEDIA_FPU"
10974
  "fneg.d       %1, %0"
10975
  [(set_attr "type" "fmove_media")])
10976
 
10977
(define_insn "negdf2_i"
10978
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10979
        (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10980
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10981
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10982
  "fneg %0"
10983
  [(set_attr "type" "fmove")
10984
   (set_attr "fp_mode" "double")])
10985
 
10986
(define_expand "sqrtdf2"
10987
  [(set (match_operand:DF 0 "arith_reg_operand" "")
10988
        (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10989
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10990
  "
10991
{
10992
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10993
    {
10994
      expand_df_unop (&gen_sqrtdf2_i, operands);
10995
      DONE;
10996
    }
10997
}")
10998
 
10999
(define_insn "*sqrtdf2_media"
11000
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11001
        (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11002
  "TARGET_SHMEDIA_FPU"
11003
  "fsqrt.d      %1, %0"
11004
  [(set_attr "type" "dfdiv_media")])
11005
 
11006
(define_insn "sqrtdf2_i"
11007
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11008
        (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11009
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11010
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11011
  "fsqrt        %0"
11012
  [(set_attr "type" "dfdiv")
11013
   (set_attr "fp_mode" "double")])
11014
 
11015
(define_expand "absdf2"
11016
  [(set (match_operand:DF 0 "arith_reg_operand" "")
11017
        (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11018
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11019
  "
11020
{
11021
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11022
    {
11023
      expand_df_unop (&gen_absdf2_i, operands);
11024
      DONE;
11025
    }
11026
}")
11027
 
11028
(define_insn "*absdf2_media"
11029
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11030
        (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11031
  "TARGET_SHMEDIA_FPU"
11032
  "fabs.d       %1, %0"
11033
  [(set_attr "type" "fmove_media")])
11034
 
11035
(define_insn "absdf2_i"
11036
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11037
        (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11038
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11039
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11040
  "fabs %0"
11041
  [(set_attr "type" "fmove")
11042
   (set_attr "fp_mode" "double")])
11043
 
11044
(define_expand "extendsfdf2"
11045
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11046
        (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11047
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11048
  "
11049
{
11050
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11051
    {
11052
      emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11053
                                        get_fpscr_rtx ()));
11054
      DONE;
11055
    }
11056
}")
11057
 
11058
(define_insn "*extendsfdf2_media"
11059
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11060
        (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11061
  "TARGET_SHMEDIA_FPU"
11062
  "fcnv.sd      %1, %0"
11063
  [(set_attr "type" "dfpconv_media")])
11064
 
11065
(define_insn "extendsfdf2_i4"
11066
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11067
        (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11068
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11069
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11070
  "fcnvsd  %1,%0"
11071
  [(set_attr "type" "fp")
11072
   (set_attr "fp_mode" "double")])
11073
 
11074
(define_expand "truncdfsf2"
11075
  [(set (match_operand:SF 0 "fpul_operand" "")
11076
        (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11077
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11078
  "
11079
{
11080
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11081
    {
11082
      emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11083
                                       get_fpscr_rtx ()));
11084
      DONE;
11085
    }
11086
}")
11087
 
11088
(define_insn "*truncdfsf2_media"
11089
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11090
        (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11091
  "TARGET_SHMEDIA_FPU"
11092
  "fcnv.ds      %1, %0"
11093
  [(set_attr "type" "dfpconv_media")])
11094
 
11095
(define_insn "truncdfsf2_i4"
11096
  [(set (match_operand:SF 0 "fpul_operand" "=y")
11097
        (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11098
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11099
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11100
  "fcnvds  %1,%0"
11101
  [(set_attr "type" "fp")
11102
   (set_attr "fp_mode" "double")])
11103
 
11104
;; Bit field extract patterns.  These give better code for packed bitfields,
11105
;; because they allow auto-increment addresses to be generated.
11106
 
11107
(define_expand "insv"
11108
  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11109
                         (match_operand:SI 1 "immediate_operand" "")
11110
                         (match_operand:SI 2 "immediate_operand" ""))
11111
        (match_operand:SI 3 "general_operand" ""))]
11112
  "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11113
  "
11114
{
11115
  rtx addr_target, orig_address, shift_reg, qi_val;
11116
  HOST_WIDE_INT bitsize, size, v = 0;
11117
  rtx x = operands[3];
11118
 
11119
  if (TARGET_SH2A && TARGET_BITOPS
11120
      && (satisfies_constraint_Sbw (operands[0])
11121
          || satisfies_constraint_Sbv (operands[0]))
11122
      && satisfies_constraint_M (operands[1])
11123
      && satisfies_constraint_K03 (operands[2]))
11124
    {
11125
      if (satisfies_constraint_N (operands[3]))
11126
        {
11127
          emit_insn (gen_bclr_m2a (operands[0], operands[2]));
11128
          DONE;
11129
        }
11130
      else if (satisfies_constraint_M (operands[3]))
11131
        {
11132
          emit_insn (gen_bset_m2a (operands[0], operands[2]));
11133
          DONE;
11134
        }
11135
      else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
11136
                && satisfies_constraint_M (operands[1]))
11137
        {
11138
          emit_insn (gen_bst_m2a (operands[0], operands[2]));
11139
          DONE;
11140
        }
11141
      else if (REG_P (operands[3])
11142
               && satisfies_constraint_M (operands[1]))
11143
        {
11144
          emit_insn (gen_bld_reg (operands[3], const0_rtx));
11145
          emit_insn (gen_bst_m2a (operands[0], operands[2]));
11146
          DONE;
11147
        }
11148
    }
11149
  /* ??? expmed doesn't care for non-register predicates.  */
11150
  if (! memory_operand (operands[0], VOIDmode)
11151
      || ! immediate_operand (operands[1], VOIDmode)
11152
      || ! immediate_operand (operands[2], VOIDmode)
11153
      || ! general_operand (x, VOIDmode))
11154
    FAIL;
11155
  /* If this isn't a 16 / 24 / 32 bit field, or if
11156
     it doesn't start on a byte boundary, then fail.  */
11157
  bitsize = INTVAL (operands[1]);
11158
  if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11159
      || (INTVAL (operands[2]) % 8) != 0)
11160
    FAIL;
11161
 
11162
  size = bitsize / 8;
11163
  orig_address = XEXP (operands[0], 0);
11164
  shift_reg = gen_reg_rtx (SImode);
11165
  if (CONST_INT_P (x))
11166
    {
11167
      v = INTVAL (x);
11168
      qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11169
    }
11170
  else
11171
    {
11172
      emit_insn (gen_movsi (shift_reg, operands[3]));
11173
      qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11174
    }
11175
  addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11176
 
11177
  operands[0] = replace_equiv_address (operands[0], addr_target);
11178
  emit_insn (gen_movqi (operands[0], qi_val));
11179
 
11180
  while (size -= 1)
11181
    {
11182
      if (CONST_INT_P (x))
11183
        qi_val
11184
          = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11185
      else
11186
        {
11187
          emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11188
          qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11189
        }
11190
      emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11191
      emit_insn (gen_movqi (operands[0], qi_val));
11192
    }
11193
 
11194
  DONE;
11195
}")
11196
 
11197
(define_insn "movua"
11198
  [(set (match_operand:SI 0 "register_operand" "=z")
11199
        (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11200
                   UNSPEC_MOVUA))]
11201
  "TARGET_SH4A_ARCH"
11202
  "movua.l      %1,%0"
11203
  [(set_attr "type" "movua")])
11204
 
11205
;; We shouldn't need this, but cse replaces increments with references
11206
;; to other regs before flow has a chance to create post_inc
11207
;; addressing modes, and only postreload's cse_move2add brings the
11208
;; increments back to a usable form.
11209
(define_peephole2
11210
  [(set (match_operand:SI 0 "register_operand" "")
11211
        (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11212
                         (const_int 32) (const_int 0)))
11213
   (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11214
  "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11215
  [(set (match_operand:SI 0 "register_operand" "")
11216
        (sign_extract:SI (mem:SI (post_inc:SI
11217
                                  (match_operand:SI 1 "register_operand" "")))
11218
                         (const_int 32) (const_int 0)))]
11219
  "")
11220
 
11221
(define_expand "extv"
11222
  [(set (match_operand:SI 0 "register_operand" "")
11223
        (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11224
                         (match_operand 2 "const_int_operand" "")
11225
                         (match_operand 3 "const_int_operand" "")))]
11226
  "TARGET_SH4A_ARCH || TARGET_SH2A"
11227
{
11228
  if (TARGET_SH2A && TARGET_BITOPS
11229
      && (satisfies_constraint_Sbw (operands[1])
11230
          || satisfies_constraint_Sbv (operands[1]))
11231
      && satisfies_constraint_M (operands[2])
11232
      && satisfies_constraint_K03 (operands[3]))
11233
   {
11234
      emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11235
      if (REGNO (operands[0]) != T_REG)
11236
        emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11237
      DONE;
11238
   }
11239
  if (TARGET_SH4A_ARCH
11240
      && INTVAL (operands[2]) == 32
11241
      && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11242
      && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11243
    {
11244
      rtx src = adjust_address (operands[1], BLKmode, 0);
11245
      set_mem_size (src, 4);
11246
      emit_insn (gen_movua (operands[0], src));
11247
      DONE;
11248
    }
11249
 
11250
  FAIL;
11251
})
11252
 
11253
(define_expand "extzv"
11254
  [(set (match_operand:SI 0 "register_operand" "")
11255
        (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11256
                         (match_operand 2 "const_int_operand" "")
11257
                         (match_operand 3 "const_int_operand" "")))]
11258
  "TARGET_SH4A_ARCH || TARGET_SH2A"
11259
{
11260
  if (TARGET_SH2A && TARGET_BITOPS
11261
      && (satisfies_constraint_Sbw (operands[1])
11262
          || satisfies_constraint_Sbv (operands[1]))
11263
      && satisfies_constraint_M (operands[2])
11264
      && satisfies_constraint_K03 (operands[3]))
11265
    {
11266
      emit_insn (gen_bld_m2a (operands[1], operands[3]));
11267
      if (REGNO (operands[0]) != T_REG)
11268
        emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11269
      DONE;
11270
    }
11271
  if (TARGET_SH4A_ARCH
11272
      && INTVAL (operands[2]) == 32
11273
      && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11274
      && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11275
    {
11276
      rtx src = adjust_address (operands[1], BLKmode, 0);
11277
      set_mem_size (src, 4);
11278
      emit_insn (gen_movua (operands[0], src));
11279
      DONE;
11280
    }
11281
 
11282
  FAIL;
11283
})
11284
 
11285
;; SH2A instructions for bitwise operations.
11286
 
11287
;; Clear a bit in a memory location.
11288
(define_insn "bclr_m2a"
11289
  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11290
        (and:QI
11291
            (not:QI (ashift:QI (const_int 1)
11292
                        (match_operand:QI 1 "const_int_operand" "K03,K03")))
11293
            (match_dup 0)))]
11294
  "TARGET_SH2A && TARGET_BITOPS"
11295
  "@
11296
        bclr.b\\t%1,%0
11297
        bclr.b\\t%1,@(0,%t0)"
11298
[(set_attr "length" "4,4")])
11299
 
11300
(define_insn "bclrmem_m2a"
11301
  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11302
        (and:QI (match_dup 0)
11303
                (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11304
  "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11305
  "@
11306
        bclr.b\\t%W1,%0
11307
        bclr.b\\t%W1,@(0,%t0)"
11308
  [(set_attr "length" "4,4")])
11309
 
11310
;; Set a bit in a memory location.
11311
(define_insn "bset_m2a"
11312
  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11313
        (ior:QI
11314
            (ashift:QI (const_int 1)
11315
                       (match_operand:QI 1 "const_int_operand" "K03,K03"))
11316
            (match_dup 0)))]
11317
  "TARGET_SH2A && TARGET_BITOPS"
11318
  "@
11319
        bset.b\\t%1,%0
11320
        bset.b\\t%1,@(0,%t0)"
11321
  [(set_attr "length" "4,4")])
11322
 
11323
(define_insn "bsetmem_m2a"
11324
  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11325
        (ior:QI (match_dup 0)
11326
                (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11327
  "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11328
  "@
11329
        bset.b\\t%V1,%0
11330
        bset.b\\t%V1,@(0,%t0)"
11331
  [(set_attr "length" "4,4")])
11332
 
11333
;;; Transfer the contents of the T bit to a specified bit of memory.
11334
(define_insn "bst_m2a"
11335
  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11336
        (if_then_else (eq (reg:SI T_REG) (const_int 0))
11337
            (and:QI
11338
                (not:QI (ashift:QI (const_int 1)
11339
                        (match_operand:QI 1 "const_int_operand" "K03,K03")))
11340
                (match_dup 0))
11341
            (ior:QI
11342
                (ashift:QI (const_int 1) (match_dup 1))
11343
                (match_dup 0))))]
11344
  "TARGET_SH2A && TARGET_BITOPS"
11345
  "@
11346
        bst.b\\t%1,%0
11347
        bst.b\\t%1,@(0,%t0)"
11348
  [(set_attr "length" "4")])
11349
 
11350
;; Store a specified bit of memory in the T bit.
11351
(define_insn "bld_m2a"
11352
  [(set (reg:SI T_REG)
11353
        (zero_extract:SI
11354
            (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11355
            (const_int 1)
11356
            (match_operand 1 "const_int_operand" "K03,K03")))]
11357
  "TARGET_SH2A && TARGET_BITOPS"
11358
  "@
11359
        bld.b\\t%1,%0
11360
        bld.b\\t%1,@(0,%t0)"
11361
  [(set_attr "length" "4,4")])
11362
 
11363
;; Store a specified bit of memory in the T bit.
11364
(define_insn "bldsign_m2a"
11365
  [(set (reg:SI T_REG)
11366
        (sign_extract:SI
11367
            (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11368
            (const_int 1)
11369
            (match_operand 1 "const_int_operand" "K03,K03")))]
11370
  "TARGET_SH2A && TARGET_BITOPS"
11371
  "@
11372
        bld.b\\t%1,%0
11373
        bld.b\\t%1,@(0,%t0)"
11374
  [(set_attr "length" "4,4")])
11375
 
11376
;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11377
(define_insn "bld_reg"
11378
  [(set (reg:SI T_REG)
11379
        (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11380
                         (const_int 1)
11381
                         (match_operand 1 "const_int_operand" "K03")))]
11382
  "TARGET_SH2A"
11383
  "bld\\t%1,%0")
11384
 
11385
(define_insn "*bld_regqi"
11386
  [(set (reg:SI T_REG)
11387
        (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11388
                         (const_int 1)
11389
                         (match_operand 1 "const_int_operand" "K03")))]
11390
  "TARGET_SH2A"
11391
  "bld\\t%1,%0")
11392
 
11393
;; Take logical and of a specified bit of memory with the T bit and
11394
;; store its result in the T bit.
11395
(define_insn "band_m2a"
11396
  [(set (reg:SI T_REG)
11397
        (and:SI (reg:SI T_REG)
11398
                (zero_extract:SI
11399
                    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11400
                    (const_int 1)
11401
                    (match_operand 1 "const_int_operand" "K03,K03"))))]
11402
  "TARGET_SH2A && TARGET_BITOPS"
11403
  "@
11404
        band.b\\t%1,%0
11405
        band.b\\t%1,@(0,%t0)"
11406
  [(set_attr "length" "4,4")])
11407
 
11408
(define_insn "bandreg_m2a"
11409
  [(set (match_operand:SI 0 "register_operand" "=r,r")
11410
        (and:SI (zero_extract:SI
11411
                    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11412
                    (const_int 1)
11413
                    (match_operand 2 "const_int_operand" "K03,K03"))
11414
                (match_operand:SI 3 "register_operand" "r,r")))]
11415
  "TARGET_SH2A && TARGET_BITOPS"
11416
  "@
11417
        band.b\\t%2,%1\;movt\\t%0
11418
        band.b\\t%2,@(0,%t1)\;movt\\t%0"
11419
  [(set_attr "length" "6,6")])
11420
 
11421
;; Take logical or of a specified bit of memory with the T bit and
11422
;; store its result in the T bit.
11423
(define_insn "bor_m2a"
11424
  [(set (reg:SI T_REG)
11425
        (ior:SI (reg:SI T_REG)
11426
                (zero_extract:SI
11427
                    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11428
                    (const_int 1)
11429
                    (match_operand 1 "const_int_operand" "K03,K03"))))]
11430
  "TARGET_SH2A && TARGET_BITOPS"
11431
  "@
11432
        bor.b\\t%1,%0
11433
        bor.b\\t%1,@(0,%t0)"
11434
  [(set_attr "length" "4,4")])
11435
 
11436
(define_insn "borreg_m2a"
11437
  [(set (match_operand:SI 0 "register_operand" "=r,r")
11438
        (ior:SI (zero_extract:SI
11439
                    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11440
                    (const_int 1)
11441
                    (match_operand 2 "const_int_operand" "K03,K03"))
11442
                (match_operand:SI 3 "register_operand" "=r,r")))]
11443
  "TARGET_SH2A && TARGET_BITOPS"
11444
  "@
11445
        bor.b\\t%2,%1\;movt\\t%0
11446
        bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11447
  [(set_attr "length" "6,6")])
11448
 
11449
;; Take exclusive or of a specified bit of memory with the T bit and
11450
;; store its result in the T bit.
11451
(define_insn "bxor_m2a"
11452
  [(set (reg:SI T_REG)
11453
        (xor:SI (reg:SI T_REG)
11454
                (zero_extract:SI
11455
                    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11456
                    (const_int 1)
11457
                    (match_operand 1 "const_int_operand" "K03,K03"))))]
11458
  "TARGET_SH2A && TARGET_BITOPS"
11459
  "@
11460
        bxor.b\\t%1,%0
11461
        bxor.b\\t%1,@(0,%t0)"
11462
  [(set_attr "length" "4,4")])
11463
 
11464
(define_insn "bxorreg_m2a"
11465
  [(set (match_operand:SI 0 "register_operand" "=r,r")
11466
        (xor:SI (zero_extract:SI
11467
                    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11468
                    (const_int 1)
11469
                    (match_operand 2 "const_int_operand" "K03,K03"))
11470
                (match_operand:SI 3 "register_operand" "=r,r")))]
11471
  "TARGET_SH2A && TARGET_BITOPS"
11472
  "@
11473
        bxor.b\\t%2,%1\;movt\\t%0
11474
        bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11475
  [(set_attr "length" "6,6")])
11476
 
11477
 
11478
;; -------------------------------------------------------------------------
11479
;; Peepholes
11480
;; -------------------------------------------------------------------------
11481
;; This matches cases where the bit in a memory location is set.
11482
(define_peephole2
11483
  [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11484
        (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11485
   (set (match_dup 0)
11486
        (ior:SI (match_dup 0)
11487
        (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11488
   (set (match_dup 1)
11489
        (match_operand 3 "arith_reg_operand" "r,r"))]
11490
  "TARGET_SH2A && TARGET_BITOPS
11491
   && satisfies_constraint_Pso (operands[2])
11492
   && REGNO (operands[0]) == REGNO (operands[3])"
11493
  [(set (match_dup 1)
11494
        (ior:QI (match_dup 1)
11495
                (match_dup 2)))]
11496
  "")
11497
 
11498
;; This matches cases where the bit in a memory location is cleared.
11499
(define_peephole2
11500
  [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11501
        (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11502
   (set (match_dup 0)
11503
        (and:SI (match_dup 0)
11504
        (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11505
   (set (match_dup 1)
11506
        (match_operand 3 "arith_reg_operand" "r,r"))]
11507
  "TARGET_SH2A && TARGET_BITOPS
11508
   && satisfies_constraint_Psz (operands[2])
11509
   && REGNO (operands[0]) == REGNO (operands[3])"
11510
  [(set (match_dup 1)
11511
        (and:QI (match_dup 1)
11512
                (match_dup 2)))]
11513
  "")
11514
 
11515
;; This matches cases where a stack pointer increment at the start of the
11516
;; epilogue combines with a stack slot read loading the return value.
11517
 
11518
(define_peephole
11519
  [(set (match_operand:SI 0 "arith_reg_operand" "")
11520
        (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11521
   (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11522
  "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11523
  "mov.l        @%1+,%0")
11524
 
11525
;; See the comment on the dt combiner pattern above.
11526
 
11527
(define_peephole
11528
  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11529
        (plus:SI (match_dup 0)
11530
                 (const_int -1)))
11531
   (set (reg:SI T_REG)
11532
        (eq:SI (match_dup 0)
11533
               (const_int 0)))]
11534
  "TARGET_SH2"
11535
  "dt   %0")
11536
 
11537
;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11538
;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11539
;; reload when the constant is too large for a reg+offset address.
11540
 
11541
;; ??? We would get much better code if this was done in reload.  This would
11542
;; require modifying find_reloads_address to recognize that if the constant
11543
;; is out-of-range for an immediate add, then we get better code by reloading
11544
;; the constant into a register than by reloading the sum into a register,
11545
;; since the former is one instruction shorter if the address does not need
11546
;; to be offsettable.  Unfortunately this does not work, because there is
11547
;; only one register, r0, that can be used as an index register.  This register
11548
;; is also the function return value register.  So, if we try to force reload
11549
;; to use double-reg addresses, then we end up with some instructions that
11550
;; need to use r0 twice.  The only way to fix this is to change the calling
11551
;; convention so that r0 is not used to return values.
11552
 
11553
(define_peephole
11554
  [(set (match_operand:SI 0 "register_operand" "=r")
11555
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11556
   (set (mem:SI (match_dup 0))
11557
        (match_operand:SI 2 "general_movsrc_operand" ""))]
11558
  "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11559
  "mov.l        %2,@(%0,%1)")
11560
 
11561
(define_peephole
11562
  [(set (match_operand:SI 0 "register_operand" "=r")
11563
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11564
   (set (match_operand:SI 2 "general_movdst_operand" "")
11565
        (mem:SI (match_dup 0)))]
11566
  "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11567
  "mov.l        @(%0,%1),%2")
11568
 
11569
(define_peephole
11570
  [(set (match_operand:SI 0 "register_operand" "=r")
11571
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11572
   (set (mem:HI (match_dup 0))
11573
        (match_operand:HI 2 "general_movsrc_operand" ""))]
11574
  "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11575
  "mov.w        %2,@(%0,%1)")
11576
 
11577
(define_peephole
11578
  [(set (match_operand:SI 0 "register_operand" "=r")
11579
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11580
   (set (match_operand:HI 2 "general_movdst_operand" "")
11581
        (mem:HI (match_dup 0)))]
11582
  "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11583
  "mov.w        @(%0,%1),%2")
11584
 
11585
(define_peephole
11586
  [(set (match_operand:SI 0 "register_operand" "=r")
11587
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11588
   (set (mem:QI (match_dup 0))
11589
        (match_operand:QI 2 "general_movsrc_operand" ""))]
11590
  "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11591
  "mov.b        %2,@(%0,%1)")
11592
 
11593
(define_peephole
11594
  [(set (match_operand:SI 0 "register_operand" "=r")
11595
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11596
   (set (match_operand:QI 2 "general_movdst_operand" "")
11597
        (mem:QI (match_dup 0)))]
11598
  "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11599
  "mov.b        @(%0,%1),%2")
11600
 
11601
(define_peephole
11602
  [(set (match_operand:SI 0 "register_operand" "=r")
11603
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11604
   (set (mem:SF (match_dup 0))
11605
        (match_operand:SF 2 "general_movsrc_operand" ""))]
11606
  "TARGET_SH1 && REGNO (operands[0]) == 0
11607
   && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11608
       || (GET_CODE (operands[2]) == SUBREG
11609
           && REGNO (SUBREG_REG (operands[2])) < 16))
11610
   && reg_unused_after (operands[0], insn)"
11611
  "mov.l        %2,@(%0,%1)")
11612
 
11613
(define_peephole
11614
  [(set (match_operand:SI 0 "register_operand" "=r")
11615
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11616
   (set (match_operand:SF 2 "general_movdst_operand" "")
11617
 
11618
        (mem:SF (match_dup 0)))]
11619
  "TARGET_SH1 && REGNO (operands[0]) == 0
11620
   && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11621
       || (GET_CODE (operands[2]) == SUBREG
11622
           && REGNO (SUBREG_REG (operands[2])) < 16))
11623
   && reg_unused_after (operands[0], insn)"
11624
  "mov.l        @(%0,%1),%2")
11625
 
11626
(define_peephole
11627
  [(set (match_operand:SI 0 "register_operand" "=r")
11628
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11629
   (set (mem:SF (match_dup 0))
11630
        (match_operand:SF 2 "general_movsrc_operand" ""))]
11631
  "TARGET_SH2E && REGNO (operands[0]) == 0
11632
   && ((REG_P (operands[2])
11633
        && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11634
       || (GET_CODE (operands[2]) == SUBREG
11635
           && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11636
   && reg_unused_after (operands[0], insn)"
11637
  "fmov{.s|}    %2,@(%0,%1)")
11638
 
11639
(define_peephole
11640
  [(set (match_operand:SI 0 "register_operand" "=r")
11641
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11642
   (set (match_operand:SF 2 "general_movdst_operand" "")
11643
 
11644
        (mem:SF (match_dup 0)))]
11645
  "TARGET_SH2E && REGNO (operands[0]) == 0
11646
   && ((REG_P (operands[2])
11647
        && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11648
       || (GET_CODE (operands[2]) == SUBREG
11649
           && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11650
   && reg_unused_after (operands[0], insn)"
11651
  "fmov{.s|}    @(%0,%1),%2")
11652
 
11653
;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11654
(define_insn "sp_switch_1"
11655
  [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11656
  "TARGET_SH1"
11657
  "*
11658
{
11659
  output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11660
  output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11661
  return \"mov r0,r15\";
11662
}"
11663
  [(set_attr "length" "10")])
11664
 
11665
;; Switch back to the original stack for interrupt functions with the
11666
;; sp_switch attribute.  */
11667
(define_insn "sp_switch_2"
11668
  [(const_int 2)]
11669
  "TARGET_SH1"
11670
  "mov.l @r15+,r15\;mov.l @r15+,r0"
11671
  [(set_attr "length" "4")])
11672
 
11673
;; Integer vector moves
11674
 
11675
(define_expand "movv8qi"
11676
  [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11677
        (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11678
  "TARGET_SHMEDIA"
11679
  "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11680
 
11681
(define_insn "movv8qi_i"
11682
  [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11683
        (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11684
  "TARGET_SHMEDIA
11685
   && (register_operand (operands[0], V8QImode)
11686
       || sh_register_operand (operands[1], V8QImode))"
11687
  "@
11688
        add     %1, r63, %0
11689
        movi    %1, %0
11690
        #
11691
        ld%M1.q %m1, %0
11692
        st%M0.q %m0, %N1"
11693
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11694
   (set_attr "length" "4,4,16,4,4")])
11695
 
11696
(define_split
11697
  [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11698
        (subreg:V8QI (const_int 0) 0))]
11699
  "TARGET_SHMEDIA"
11700
  [(set (match_dup 0)
11701
        (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11702
                            (const_int 0) (const_int 0) (const_int 0)
11703
                            (const_int 0) (const_int 0)]))])
11704
 
11705
(define_split
11706
  [(set (match_operand 0 "arith_reg_dest" "")
11707
        (match_operand 1 "sh_rep_vec" ""))]
11708
  "TARGET_SHMEDIA && reload_completed
11709
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
11710
   && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11711
   && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11712
   && (XVECEXP (operands[1], 0, 0) != const0_rtx
11713
       || XVECEXP (operands[1], 0, 1) != const0_rtx)
11714
   && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11715
       || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11716
  [(set (match_dup 0) (match_dup 1))
11717
   (match_dup 2)]
11718
  "
11719
{
11720
  int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11721
  rtx elt1 = XVECEXP (operands[1], 0, 1);
11722
 
11723
  if (unit_size > 2)
11724
    operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11725
  else
11726
    {
11727
      if (unit_size < 2)
11728
        operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11729
      operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11730
    }
11731
  operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11732
  operands[1] = XVECEXP (operands[1], 0, 0);
11733
  if (unit_size < 2)
11734
    {
11735
      if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11736
        operands[1]
11737
          = GEN_INT (TARGET_LITTLE_ENDIAN
11738
                     ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11739
                     : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11740
      else
11741
        {
11742
          operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11743
          operands[1]
11744
            = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11745
        }
11746
    }
11747
}")
11748
 
11749
(define_split
11750
  [(set (match_operand 0 "arith_reg_dest" "")
11751
        (match_operand 1 "sh_const_vec" ""))]
11752
  "TARGET_SHMEDIA && reload_completed
11753
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
11754
   && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11755
  [(set (match_dup 0) (match_dup 1))]
11756
  "
11757
{
11758
  rtx v = operands[1];
11759
  enum machine_mode new_mode
11760
    = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11761
 
11762
  operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11763
  operands[1]
11764
    = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11765
}")
11766
 
11767
(define_expand "movv2hi"
11768
  [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11769
        (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11770
  "TARGET_SHMEDIA"
11771
  "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11772
 
11773
(define_insn "movv2hi_i"
11774
  [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11775
        (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11776
  "TARGET_SHMEDIA
11777
   && (register_operand (operands[0], V2HImode)
11778
       || sh_register_operand (operands[1], V2HImode))"
11779
  "@
11780
        add.l   %1, r63, %0
11781
        movi    %1, %0
11782
        #
11783
        ld%M1.l %m1, %0
11784
        st%M0.l %m0, %N1"
11785
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11786
   (set_attr "length" "4,4,16,4,4")
11787
   (set (attr "highpart")
11788
        (cond [(match_test "sh_contains_memref_p (insn)")
11789
               (const_string "user")]
11790
              (const_string "ignore")))])
11791
 
11792
(define_expand "movv4hi"
11793
  [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11794
        (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11795
  "TARGET_SHMEDIA"
11796
  "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11797
 
11798
(define_insn "movv4hi_i"
11799
  [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11800
        (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11801
  "TARGET_SHMEDIA
11802
   && (register_operand (operands[0], V4HImode)
11803
       || sh_register_operand (operands[1], V4HImode))"
11804
  "@
11805
        add     %1, r63, %0
11806
        movi    %1, %0
11807
        #
11808
        ld%M1.q %m1, %0
11809
        st%M0.q %m0, %N1"
11810
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11811
   (set_attr "length" "4,4,16,4,4")
11812
   (set_attr "highpart" "depend")])
11813
 
11814
(define_expand "movv2si"
11815
  [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11816
        (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11817
  "TARGET_SHMEDIA"
11818
  "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11819
 
11820
(define_insn "movv2si_i"
11821
  [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11822
        (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11823
  "TARGET_SHMEDIA
11824
   && (register_operand (operands[0], V2SImode)
11825
       || sh_register_operand (operands[1], V2SImode))"
11826
  "@
11827
        add     %1, r63, %0
11828
        #
11829
        #
11830
        ld%M1.q %m1, %0
11831
        st%M0.q %m0, %N1"
11832
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11833
   (set_attr "length" "4,4,16,4,4")
11834
   (set_attr "highpart" "depend")])
11835
 
11836
;; Multimedia Intrinsics
11837
 
11838
(define_insn "absv2si2"
11839
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11840
        (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11841
  "TARGET_SHMEDIA"
11842
  "mabs.l       %1, %0"
11843
  [(set_attr "type" "mcmp_media")
11844
   (set_attr "highpart" "depend")])
11845
 
11846
(define_insn "absv4hi2"
11847
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11848
        (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11849
  "TARGET_SHMEDIA"
11850
  "mabs.w       %1, %0"
11851
  [(set_attr "type" "mcmp_media")
11852
   (set_attr "highpart" "depend")])
11853
 
11854
(define_insn "addv2si3"
11855
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11856
        (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11857
                   (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11858
  "TARGET_SHMEDIA"
11859
  "madd.l       %1, %2, %0"
11860
  [(set_attr "type" "arith_media")
11861
   (set_attr "highpart" "depend")])
11862
 
11863
(define_insn "addv4hi3"
11864
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11865
        (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11866
                   (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11867
  "TARGET_SHMEDIA"
11868
  "madd.w       %1, %2, %0"
11869
  [(set_attr "type" "arith_media")
11870
   (set_attr "highpart" "depend")])
11871
 
11872
(define_insn_and_split "addv2hi3"
11873
  [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11874
        (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11875
                   (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11876
  "TARGET_SHMEDIA"
11877
  "#"
11878
  "TARGET_SHMEDIA"
11879
  [(const_int 0)]
11880
  "
11881
{
11882
  rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11883
  rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11884
  rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11885
  rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11886
  rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11887
 
11888
  emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11889
  emit_insn (gen_truncdisi2 (si_dst, di_dst));
11890
  DONE;
11891
}"
11892
  [(set_attr "highpart" "must_split")])
11893
 
11894
(define_insn "ssaddv2si3"
11895
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11896
        (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11897
                      (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11898
  "TARGET_SHMEDIA"
11899
  "madds.l      %1, %2, %0"
11900
  [(set_attr "type" "mcmp_media")
11901
   (set_attr "highpart" "depend")])
11902
 
11903
(define_insn "usaddv8qi3"
11904
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11905
        (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11906
                      (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11907
  "TARGET_SHMEDIA"
11908
  "madds.ub     %1, %2, %0"
11909
  [(set_attr "type" "mcmp_media")
11910
   (set_attr "highpart" "depend")])
11911
 
11912
(define_insn "ssaddv4hi3"
11913
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11914
        (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11915
                      (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11916
  "TARGET_SHMEDIA"
11917
  "madds.w      %1, %2, %0"
11918
  [(set_attr "type" "mcmp_media")
11919
   (set_attr "highpart" "depend")])
11920
 
11921
(define_insn "negcmpeqv8qi"
11922
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11923
        (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11924
                           (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11925
  "TARGET_SHMEDIA"
11926
  "mcmpeq.b     %N1, %N2, %0"
11927
  [(set_attr "type" "mcmp_media")
11928
   (set_attr "highpart" "depend")])
11929
 
11930
(define_insn "negcmpeqv2si"
11931
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11932
        (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11933
                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11934
  "TARGET_SHMEDIA"
11935
  "mcmpeq.l     %N1, %N2, %0"
11936
  [(set_attr "type" "mcmp_media")
11937
   (set_attr "highpart" "depend")])
11938
 
11939
(define_insn "negcmpeqv4hi"
11940
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11941
        (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11942
                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11943
  "TARGET_SHMEDIA"
11944
  "mcmpeq.w     %N1, %N2, %0"
11945
  [(set_attr "type" "mcmp_media")
11946
   (set_attr "highpart" "depend")])
11947
 
11948
(define_insn "negcmpgtuv8qi"
11949
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11950
        (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11951
                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11952
  "TARGET_SHMEDIA"
11953
  "mcmpgt.ub    %N1, %N2, %0"
11954
  [(set_attr "type" "mcmp_media")
11955
   (set_attr "highpart" "depend")])
11956
 
11957
(define_insn "negcmpgtv2si"
11958
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11959
        (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11960
                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11961
  "TARGET_SHMEDIA"
11962
  "mcmpgt.l     %N1, %N2, %0"
11963
  [(set_attr "type" "mcmp_media")
11964
   (set_attr "highpart" "depend")])
11965
 
11966
(define_insn "negcmpgtv4hi"
11967
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11968
        (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11969
                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11970
  "TARGET_SHMEDIA"
11971
  "mcmpgt.w     %N1, %N2, %0"
11972
  [(set_attr "type" "mcmp_media")
11973
   (set_attr "highpart" "depend")])
11974
 
11975
(define_insn "mcmv"
11976
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11977
        (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11978
                        (match_operand:DI 2 "arith_reg_operand" "r"))
11979
                (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11980
                        (not:DI (match_dup 2)))))]
11981
  "TARGET_SHMEDIA"
11982
  "mcmv %N1, %2, %0"
11983
  [(set_attr "type" "arith_media")
11984
   (set_attr "highpart" "depend")])
11985
 
11986
(define_insn "mcnvs_lw"
11987
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11988
        (vec_concat:V4HI
11989
         (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11990
         (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11991
  "TARGET_SHMEDIA"
11992
  "mcnvs.lw     %N1, %N2, %0"
11993
  [(set_attr "type" "mcmp_media")])
11994
 
11995
(define_insn "mcnvs_wb"
11996
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11997
        (vec_concat:V8QI
11998
         (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11999
         (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12000
  "TARGET_SHMEDIA"
12001
  "mcnvs.wb     %N1, %N2, %0"
12002
  [(set_attr "type" "mcmp_media")])
12003
 
12004
(define_insn "mcnvs_wub"
12005
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12006
        (vec_concat:V8QI
12007
         (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12008
         (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12009
  "TARGET_SHMEDIA"
12010
  "mcnvs.wub    %N1, %N2, %0"
12011
  [(set_attr "type" "mcmp_media")])
12012
 
12013
(define_insn "mextr_rl"
12014
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12015
        (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12016
                             (match_operand:HI 3 "mextr_bit_offset" "i"))
12017
               (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12018
                          (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12019
  "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12020
  "*
12021
{
12022
  static char templ[21];
12023
 
12024
  sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12025
           (int) INTVAL (operands[3]) >> 3);
12026
  return templ;
12027
}"
12028
  [(set_attr "type" "arith_media")])
12029
 
12030
(define_insn "*mextr_lr"
12031
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12032
        (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12033
                           (match_operand:HI 3 "mextr_bit_offset" "i"))
12034
               (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12035
                            (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12036
  "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12037
  "*
12038
{
12039
  static char templ[21];
12040
 
12041
  sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12042
           (int) INTVAL (operands[4]) >> 3);
12043
  return templ;
12044
}"
12045
  [(set_attr "type" "arith_media")])
12046
 
12047
; mextrN can be modelled with vec_select / vec_concat, but the selection
12048
; vector then varies depending on endianness.
12049
(define_expand "mextr1"
12050
  [(match_operand:DI 0 "arith_reg_dest" "")
12051
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12052
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12053
  "TARGET_SHMEDIA"
12054
  "
12055
{
12056
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12057
                           GEN_INT (1 * 8), GEN_INT (7 * 8)));
12058
  DONE;
12059
}")
12060
 
12061
(define_expand "mextr2"
12062
  [(match_operand:DI 0 "arith_reg_dest" "")
12063
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12064
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12065
  "TARGET_SHMEDIA"
12066
  "
12067
{
12068
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12069
                           GEN_INT (2 * 8), GEN_INT (6 * 8)));
12070
  DONE;
12071
}")
12072
 
12073
(define_expand "mextr3"
12074
  [(match_operand:DI 0 "arith_reg_dest" "")
12075
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12076
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12077
  "TARGET_SHMEDIA"
12078
  "
12079
{
12080
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12081
                           GEN_INT (3 * 8), GEN_INT (5 * 8)));
12082
  DONE;
12083
}")
12084
 
12085
(define_expand "mextr4"
12086
  [(match_operand:DI 0 "arith_reg_dest" "")
12087
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12088
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12089
  "TARGET_SHMEDIA"
12090
  "
12091
{
12092
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12093
                           GEN_INT (4 * 8), GEN_INT (4 * 8)));
12094
  DONE;
12095
}")
12096
 
12097
(define_expand "mextr5"
12098
  [(match_operand:DI 0 "arith_reg_dest" "")
12099
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12100
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12101
  "TARGET_SHMEDIA"
12102
  "
12103
{
12104
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12105
                           GEN_INT (5 * 8), GEN_INT (3 * 8)));
12106
  DONE;
12107
}")
12108
 
12109
(define_expand "mextr6"
12110
  [(match_operand:DI 0 "arith_reg_dest" "")
12111
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12112
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12113
  "TARGET_SHMEDIA"
12114
  "
12115
{
12116
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12117
                           GEN_INT (6 * 8), GEN_INT (2 * 8)));
12118
  DONE;
12119
}")
12120
 
12121
(define_expand "mextr7"
12122
  [(match_operand:DI 0 "arith_reg_dest" "")
12123
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12124
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12125
  "TARGET_SHMEDIA"
12126
  "
12127
{
12128
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12129
                           GEN_INT (7 * 8), GEN_INT (1 * 8)));
12130
  DONE;
12131
}")
12132
 
12133
(define_expand "mmacfx_wl"
12134
  [(match_operand:V2SI 0 "arith_reg_dest" "")
12135
   (match_operand:V2HI 1 "extend_reg_operand" "")
12136
   (match_operand:V2HI 2 "extend_reg_operand" "")
12137
   (match_operand:V2SI 3 "arith_reg_operand" "")]
12138
  "TARGET_SHMEDIA"
12139
  "
12140
{
12141
  emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12142
                              operands[1], operands[2]));
12143
  DONE;
12144
}")
12145
 
12146
;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12147
;; is depend
12148
(define_insn "mmacfx_wl_i"
12149
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12150
        (ss_plus:V2SI
12151
         (match_operand:V2SI 1 "arith_reg_operand" "0")
12152
         (ss_truncate:V2SI
12153
          (ashift:V2DI
12154
           (sign_extend:V2DI
12155
            (mult:V2SI
12156
             (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12157
             (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12158
           (const_int 1)))))]
12159
  "TARGET_SHMEDIA"
12160
  "mmacfx.wl    %2, %3, %0"
12161
  [(set_attr "type" "mac_media")
12162
   (set_attr "highpart" "depend")])
12163
 
12164
(define_expand "mmacnfx_wl"
12165
  [(match_operand:V2SI 0 "arith_reg_dest" "")
12166
   (match_operand:V2HI 1 "extend_reg_operand" "")
12167
   (match_operand:V2HI 2 "extend_reg_operand" "")
12168
   (match_operand:V2SI 3 "arith_reg_operand" "")]
12169
  "TARGET_SHMEDIA"
12170
  "
12171
{
12172
  emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12173
                               operands[1], operands[2]));
12174
  DONE;
12175
}")
12176
 
12177
(define_insn "mmacnfx_wl_i"
12178
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12179
        (ss_minus:V2SI
12180
         (match_operand:V2SI 1 "arith_reg_operand" "0")
12181
         (ss_truncate:V2SI
12182
          (ashift:V2DI
12183
           (sign_extend:V2DI
12184
            (mult:V2SI
12185
             (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12186
             (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12187
           (const_int 1)))))]
12188
  "TARGET_SHMEDIA"
12189
  "mmacnfx.wl   %2, %3, %0"
12190
  [(set_attr "type" "mac_media")
12191
   (set_attr "highpart" "depend")])
12192
 
12193
(define_insn "mulv2si3"
12194
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12195
        (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12196
                   (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12197
  "TARGET_SHMEDIA"
12198
  "mmul.l       %1, %2, %0"
12199
  [(set_attr "type" "d2mpy_media")
12200
   (set_attr "highpart" "depend")])
12201
 
12202
(define_insn "mulv4hi3"
12203
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12204
        (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12205
                   (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12206
  "TARGET_SHMEDIA"
12207
  "mmul.w       %1, %2, %0"
12208
  [(set_attr "type" "dmpy_media")
12209
   (set_attr "highpart" "depend")])
12210
 
12211
(define_insn "mmulfx_l"
12212
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12213
        (ss_truncate:V2SI
12214
         (ashiftrt:V2DI
12215
          (mult:V2DI
12216
           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12217
           (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12218
          (const_int 31))))]
12219
  "TARGET_SHMEDIA"
12220
  "mmulfx.l     %1, %2, %0"
12221
  [(set_attr "type" "d2mpy_media")
12222
   (set_attr "highpart" "depend")])
12223
 
12224
(define_insn "mmulfx_w"
12225
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12226
        (ss_truncate:V4HI
12227
         (ashiftrt:V4SI
12228
          (mult:V4SI
12229
           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12230
           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12231
          (const_int 15))))]
12232
  "TARGET_SHMEDIA"
12233
  "mmulfx.w     %1, %2, %0"
12234
  [(set_attr "type" "dmpy_media")
12235
   (set_attr "highpart" "depend")])
12236
 
12237
(define_insn "mmulfxrp_w"
12238
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12239
        (ss_truncate:V4HI
12240
         (ashiftrt:V4SI
12241
          (plus:V4SI
12242
           (mult:V4SI
12243
            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12244
            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12245
           (const_int 16384))
12246
          (const_int 15))))]
12247
  "TARGET_SHMEDIA"
12248
  "mmulfxrp.w   %1, %2, %0"
12249
  [(set_attr "type" "dmpy_media")
12250
   (set_attr "highpart" "depend")])
12251
 
12252
 
12253
(define_expand "mmulhi_wl"
12254
  [(match_operand:V2SI 0 "arith_reg_dest" "")
12255
   (match_operand:V4HI 1 "arith_reg_operand" "")
12256
   (match_operand:V4HI 2 "arith_reg_operand" "")]
12257
  "TARGET_SHMEDIA"
12258
  "
12259
{
12260
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12261
             (operands[0], operands[1], operands[2]));
12262
  DONE;
12263
}")
12264
 
12265
(define_expand "mmullo_wl"
12266
  [(match_operand:V2SI 0 "arith_reg_dest" "")
12267
   (match_operand:V4HI 1 "arith_reg_operand" "")
12268
   (match_operand:V4HI 2 "arith_reg_operand" "")]
12269
  "TARGET_SHMEDIA"
12270
  "
12271
{
12272
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12273
             (operands[0], operands[1], operands[2]));
12274
  DONE;
12275
}")
12276
 
12277
(define_insn "mmul23_wl"
12278
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12279
        (vec_select:V2SI
12280
         (mult:V4SI
12281
          (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12282
          (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12283
         (parallel [(const_int 2) (const_int 3)])))]
12284
  "TARGET_SHMEDIA"
12285
  "* return (TARGET_LITTLE_ENDIAN
12286
             ? \"mmulhi.wl      %1, %2, %0\"
12287
             : \"mmullo.wl      %1, %2, %0\");"
12288
  [(set_attr "type" "dmpy_media")
12289
   (set (attr "highpart")
12290
        (cond [(eq_attr "endian" "big") (const_string "ignore")]
12291
         (const_string "user")))])
12292
 
12293
(define_insn "mmul01_wl"
12294
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12295
        (vec_select:V2SI
12296
         (mult:V4SI
12297
          (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12298
          (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12299
         (parallel [(const_int 0) (const_int 1)])))]
12300
  "TARGET_SHMEDIA"
12301
  "* return (TARGET_LITTLE_ENDIAN
12302
             ? \"mmullo.wl      %1, %2, %0\"
12303
             : \"mmulhi.wl      %1, %2, %0\");"
12304
  [(set_attr "type" "dmpy_media")
12305
   (set (attr "highpart")
12306
        (cond [(eq_attr "endian" "little") (const_string "ignore")]
12307
         (const_string "user")))])
12308
 
12309
 
12310
(define_expand "mmulsum_wq"
12311
  [(match_operand:DI 0 "arith_reg_dest" "")
12312
   (match_operand:V4HI 1 "arith_reg_operand" "")
12313
   (match_operand:V4HI 2 "arith_reg_operand" "")
12314
   (match_operand:DI 3 "arith_reg_operand" "")]
12315
  "TARGET_SHMEDIA"
12316
  "
12317
{
12318
  emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12319
                               operands[1], operands[2]));
12320
  DONE;
12321
}")
12322
 
12323
(define_insn "mmulsum_wq_i"
12324
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12325
        (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12326
         (plus:DI
12327
          (plus:DI
12328
           (vec_select:DI
12329
            (mult:V4DI
12330
             (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12331
             (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12332
            (parallel [(const_int 0)]))
12333
           (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12334
                                     (sign_extend:V4DI (match_dup 3)))
12335
                          (parallel [(const_int 1)])))
12336
          (plus:DI
12337
           (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12338
                                     (sign_extend:V4DI (match_dup 3)))
12339
                          (parallel [(const_int 2)]))
12340
           (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12341
                                     (sign_extend:V4DI (match_dup 3)))
12342
                          (parallel [(const_int 3)]))))))]
12343
  "TARGET_SHMEDIA"
12344
  "mmulsum.wq   %2, %3, %0"
12345
  [(set_attr "type" "mac_media")])
12346
 
12347
(define_expand "mperm_w"
12348
  [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12349
   (match_operand:V4HI 1 "arith_reg_operand" "r")
12350
   (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12351
  "TARGET_SHMEDIA"
12352
  "
12353
{
12354
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12355
             (operands[0], operands[1], operands[2]));
12356
  DONE;
12357
}")
12358
 
12359
; This use of vec_select isn't exactly correct according to rtl.texi
12360
; (because not constant), but it seems a straightforward extension.
12361
(define_insn "mperm_w_little"
12362
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12363
        (vec_select:V4HI
12364
         (match_operand:V4HI 1 "arith_reg_operand" "r")
12365
         (parallel
12366
          [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12367
                            (const_int 2) (const_int 0))
12368
           (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12369
           (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12370
           (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12371
  "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12372
  "mperm.w      %1, %N2, %0"
12373
  [(set_attr "type" "arith_media")])
12374
 
12375
(define_insn "mperm_w_big"
12376
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12377
        (vec_select:V4HI
12378
         (match_operand:V4HI 1 "arith_reg_operand" "r")
12379
         (parallel
12380
          [(zero_extract:QI (not:QI (match_operand:QI 2
12381
                                     "extend_reg_or_0_operand" "rZ"))
12382
                            (const_int 2) (const_int 0))
12383
           (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12384
           (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12385
           (zero_extract:QI (not:QI (match_dup 2))
12386
                            (const_int 2) (const_int 6))])))]
12387
  "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12388
  "mperm.w      %1, %N2, %0"
12389
  [(set_attr "type" "arith_media")])
12390
 
12391
(define_insn "mperm_w0"
12392
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12393
        (vec_duplicate:V4HI (truncate:HI (match_operand 1
12394
                                          "trunc_hi_operand" "r"))))]
12395
  "TARGET_SHMEDIA"
12396
  "mperm.w      %1, r63, %0"
12397
  [(set_attr "type" "arith_media")
12398
   (set_attr "highpart" "ignore")])
12399
 
12400
(define_expand "msad_ubq"
12401
  [(match_operand:DI 0 "arith_reg_dest" "")
12402
   (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12403
   (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12404
   (match_operand:DI 3 "arith_reg_operand" "")]
12405
  "TARGET_SHMEDIA"
12406
  "
12407
{
12408
  emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12409
                             operands[1], operands[2]));
12410
  DONE;
12411
}")
12412
 
12413
(define_insn "msad_ubq_i"
12414
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12415
        (plus:DI
12416
         (plus:DI
12417
          (plus:DI
12418
           (plus:DI
12419
            (match_operand:DI 1 "arith_reg_operand" "0")
12420
            (abs:DI (vec_select:DI
12421
                     (minus:V8DI
12422
                      (zero_extend:V8DI
12423
                       (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12424
                      (zero_extend:V8DI
12425
                       (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12426
                     (parallel [(const_int 0)]))))
12427
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12428
                                              (zero_extend:V8DI (match_dup 3)))
12429
                                  (parallel [(const_int 1)]))))
12430
          (plus:DI
12431
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12432
                                              (zero_extend:V8DI (match_dup 3)))
12433
                                  (parallel [(const_int 2)])))
12434
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12435
                                              (zero_extend:V8DI (match_dup 3)))
12436
                                  (parallel [(const_int 3)])))))
12437
         (plus:DI
12438
          (plus:DI
12439
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12440
                                              (zero_extend:V8DI (match_dup 3)))
12441
                                  (parallel [(const_int 4)])))
12442
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12443
                                              (zero_extend:V8DI (match_dup 3)))
12444
                                  (parallel [(const_int 5)]))))
12445
          (plus:DI
12446
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12447
                                              (zero_extend:V8DI (match_dup 3)))
12448
                                  (parallel [(const_int 6)])))
12449
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12450
                                              (zero_extend:V8DI (match_dup 3)))
12451
                                  (parallel [(const_int 7)])))))))]
12452
  "TARGET_SHMEDIA"
12453
  "msad.ubq     %N2, %N3, %0"
12454
  [(set_attr "type" "mac_media")])
12455
 
12456
(define_insn "mshalds_l"
12457
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12458
        (ss_truncate:V2SI
12459
         (ashift:V2DI
12460
          (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12461
          (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12462
                  (const_int 31)))))]
12463
  "TARGET_SHMEDIA"
12464
  "mshalds.l    %1, %2, %0"
12465
  [(set_attr "type" "mcmp_media")
12466
   (set_attr "highpart" "depend")])
12467
 
12468
(define_insn "mshalds_w"
12469
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12470
        (ss_truncate:V4HI
12471
         (ashift:V4SI
12472
          (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12473
          (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12474
                  (const_int 15)))))]
12475
  "TARGET_SHMEDIA"
12476
  "mshalds.w    %1, %2, %0"
12477
  [(set_attr "type" "mcmp_media")
12478
   (set_attr "highpart" "depend")])
12479
 
12480
(define_insn "ashrv2si3"
12481
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12482
        (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12483
                       (match_operand:DI 2 "arith_reg_operand" "r")))]
12484
  "TARGET_SHMEDIA"
12485
  "mshard.l     %1, %2, %0"
12486
  [(set_attr "type" "arith_media")
12487
   (set_attr "highpart" "depend")])
12488
 
12489
(define_insn "ashrv4hi3"
12490
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12491
        (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12492
                       (match_operand:DI 2 "arith_reg_operand" "r")))]
12493
  "TARGET_SHMEDIA"
12494
  "mshard.w     %1, %2, %0"
12495
  [(set_attr "type" "arith_media")
12496
   (set_attr "highpart" "depend")])
12497
 
12498
(define_insn "mshards_q"
12499
  [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12500
        (ss_truncate:HI
12501
         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12502
                      (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12503
  "TARGET_SHMEDIA"
12504
  "mshards.q    %1, %N2, %0"
12505
  [(set_attr "type" "mcmp_media")])
12506
 
12507
(define_expand "mshfhi_b"
12508
  [(match_operand:V8QI 0 "arith_reg_dest" "")
12509
   (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12510
   (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12511
  "TARGET_SHMEDIA"
12512
  "
12513
{
12514
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12515
             (operands[0], operands[1], operands[2]));
12516
  DONE;
12517
}")
12518
 
12519
(define_expand "mshflo_b"
12520
  [(match_operand:V8QI 0 "arith_reg_dest" "")
12521
   (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12522
   (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12523
  "TARGET_SHMEDIA"
12524
  "
12525
{
12526
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12527
             (operands[0], operands[1], operands[2]));
12528
  DONE;
12529
}")
12530
 
12531
(define_insn "mshf4_b"
12532
  [(set
12533
    (match_operand:V8QI 0 "arith_reg_dest" "=r")
12534
    (vec_select:V8QI
12535
     (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12536
                       (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12537
     (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12538
                (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12539
  "TARGET_SHMEDIA"
12540
  "* return (TARGET_LITTLE_ENDIAN
12541
             ? \"mshfhi.b       %N1, %N2, %0\"
12542
             : \"mshflo.b       %N1, %N2, %0\");"
12543
  [(set_attr "type" "arith_media")
12544
   (set (attr "highpart")
12545
        (cond [(eq_attr "endian" "big") (const_string "ignore")]
12546
         (const_string "user")))])
12547
 
12548
(define_insn "mshf0_b"
12549
  [(set
12550
    (match_operand:V8QI 0 "arith_reg_dest" "=r")
12551
    (vec_select:V8QI
12552
     (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12553
                       (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12554
     (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12555
                (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12556
  "TARGET_SHMEDIA"
12557
  "* return (TARGET_LITTLE_ENDIAN
12558
             ? \"mshflo.b       %N1, %N2, %0\"
12559
             : \"mshfhi.b       %N1, %N2, %0\");"
12560
  [(set_attr "type" "arith_media")
12561
   (set (attr "highpart")
12562
        (cond [(eq_attr "endian" "little") (const_string "ignore")]
12563
         (const_string "user")))])
12564
 
12565
(define_expand "mshfhi_l"
12566
  [(match_operand:V2SI 0 "arith_reg_dest" "")
12567
   (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12568
   (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12569
  "TARGET_SHMEDIA"
12570
  "
12571
{
12572
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12573
             (operands[0], operands[1], operands[2]));
12574
  DONE;
12575
}")
12576
 
12577
(define_expand "mshflo_l"
12578
  [(match_operand:V2SI 0 "arith_reg_dest" "")
12579
   (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12580
   (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12581
  "TARGET_SHMEDIA"
12582
  "
12583
{
12584
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12585
             (operands[0], operands[1], operands[2]));
12586
  DONE;
12587
}")
12588
 
12589
(define_insn "mshf4_l"
12590
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12591
        (vec_select:V2SI
12592
         (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12593
                          (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12594
         (parallel [(const_int 1) (const_int 3)])))]
12595
  "TARGET_SHMEDIA"
12596
  "* return (TARGET_LITTLE_ENDIAN
12597
             ? \"mshfhi.l       %N1, %N2, %0\"
12598
             : \"mshflo.l       %N1, %N2, %0\");"
12599
  [(set_attr "type" "arith_media")
12600
   (set (attr "highpart")
12601
        (cond [(eq_attr "endian" "big") (const_string "ignore")]
12602
         (const_string "user")))])
12603
 
12604
(define_insn "mshf0_l"
12605
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12606
        (vec_select:V2SI
12607
         (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12608
                          (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12609
         (parallel [(const_int 0) (const_int 2)])))]
12610
  "TARGET_SHMEDIA"
12611
  "* return (TARGET_LITTLE_ENDIAN
12612
             ? \"mshflo.l       %N1, %N2, %0\"
12613
             : \"mshfhi.l       %N1, %N2, %0\");"
12614
  [(set_attr "type" "arith_media")
12615
   (set (attr "highpart")
12616
        (cond [(eq_attr "endian" "little") (const_string "ignore")]
12617
         (const_string "user")))])
12618
 
12619
(define_expand "mshfhi_w"
12620
  [(match_operand:V4HI 0 "arith_reg_dest" "")
12621
   (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12622
   (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12623
  "TARGET_SHMEDIA"
12624
  "
12625
{
12626
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12627
             (operands[0], operands[1], operands[2]));
12628
  DONE;
12629
}")
12630
 
12631
(define_expand "mshflo_w"
12632
  [(match_operand:V4HI 0 "arith_reg_dest" "")
12633
   (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12634
   (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12635
  "TARGET_SHMEDIA"
12636
  "
12637
{
12638
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12639
             (operands[0], operands[1], operands[2]));
12640
  DONE;
12641
}")
12642
 
12643
(define_insn "mshf4_w"
12644
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12645
        (vec_select:V4HI
12646
         (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12647
                          (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12648
         (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12649
  "TARGET_SHMEDIA"
12650
  "* return (TARGET_LITTLE_ENDIAN
12651
             ? \"mshfhi.w       %N1, %N2, %0\"
12652
             : \"mshflo.w       %N1, %N2, %0\");"
12653
  [(set_attr "type" "arith_media")
12654
   (set (attr "highpart")
12655
        (cond [(eq_attr "endian" "big") (const_string "ignore")]
12656
         (const_string "user")))])
12657
 
12658
(define_insn "mshf0_w"
12659
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12660
        (vec_select:V4HI
12661
         (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12662
                          (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12663
         (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12664
  "TARGET_SHMEDIA"
12665
  "* return (TARGET_LITTLE_ENDIAN
12666
             ? \"mshflo.w       %N1, %N2, %0\"
12667
             : \"mshfhi.w       %N1, %N2, %0\");"
12668
  [(set_attr "type" "arith_media")
12669
   (set (attr "highpart")
12670
        (cond [(eq_attr "endian" "little") (const_string "ignore")]
12671
         (const_string "user")))])
12672
 
12673
(define_insn "mshflo_w_x"
12674
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12675
        (vec_select:V4HI
12676
         (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12677
                          (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12678
         (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12679
  "TARGET_SHMEDIA"
12680
  "mshflo.w     %N1, %N2, %0"
12681
  [(set_attr "type" "arith_media")
12682
   (set_attr "highpart" "ignore")])
12683
 
12684
;; These are useful to expand ANDs and as combiner patterns.
12685
(define_insn_and_split "mshfhi_l_di"
12686
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12687
        (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12688
                             (const_int 32))
12689
                (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12690
                        (const_int -4294967296))))]
12691
  "TARGET_SHMEDIA"
12692
  "@
12693
        mshfhi.l        %N1, %N2, %0
12694
        #"
12695
  "TARGET_SHMEDIA && reload_completed
12696
   && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12697
  [(set (match_dup 3) (match_dup 4))
12698
   (set (match_dup 5) (match_dup 6))]
12699
  "
12700
{
12701
  operands[3] = gen_lowpart (SImode, operands[0]);
12702
  operands[4] = gen_highpart (SImode, operands[1]);
12703
  operands[5] = gen_highpart (SImode, operands[0]);
12704
  operands[6] = gen_highpart (SImode, operands[2]);
12705
}"
12706
  [(set_attr "type" "arith_media")])
12707
 
12708
(define_insn "*mshfhi_l_di_rev"
12709
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12710
        (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12711
                        (const_int -4294967296))
12712
                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12713
                             (const_int 32))))]
12714
  "TARGET_SHMEDIA"
12715
  "mshfhi.l     %N2, %N1, %0"
12716
  [(set_attr "type" "arith_media")])
12717
 
12718
(define_split
12719
  [(set (match_operand:DI 0 "arith_reg_dest" "")
12720
        (ior:DI (zero_extend:DI (match_operand:SI 1
12721
                                              "extend_reg_or_0_operand" ""))
12722
                (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12723
                        (const_int -4294967296))))
12724
   (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12725
  "TARGET_SHMEDIA"
12726
  [(const_int 0)]
12727
  "
12728
{
12729
  emit_insn (gen_ashldi3_media (operands[3],
12730
                                simplify_gen_subreg (DImode, operands[1],
12731
                                                     SImode, 0),
12732
                                GEN_INT (32)));
12733
  emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12734
  DONE;
12735
}")
12736
 
12737
(define_insn "mshflo_l_di"
12738
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12739
        (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12740
                        (const_int 4294967295))
12741
                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12742
                           (const_int 32))))]
12743
 
12744
  "TARGET_SHMEDIA"
12745
  "mshflo.l     %N1, %N2, %0"
12746
  [(set_attr "type" "arith_media")
12747
   (set_attr "highpart" "ignore")])
12748
 
12749
(define_insn "*mshflo_l_di_rev"
12750
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12751
        (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12752
                           (const_int 32))
12753
                (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12754
                        (const_int 4294967295))))]
12755
 
12756
  "TARGET_SHMEDIA"
12757
  "mshflo.l     %N2, %N1, %0"
12758
  [(set_attr "type" "arith_media")
12759
   (set_attr "highpart" "ignore")])
12760
 
12761
;; Combiner pattern for trampoline initialization.
12762
(define_insn_and_split "*double_shori"
12763
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12764
        (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12765
                           (const_int 32))
12766
                (match_operand:DI 2 "const_int_operand" "n")))]
12767
  "TARGET_SHMEDIA
12768
   && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12769
  "#"
12770
  "rtx_equal_p (operands[0], operands[1])"
12771
  [(const_int 0)]
12772
  "
12773
{
12774
  HOST_WIDE_INT v = INTVAL (operands[2]);
12775
 
12776
  emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12777
  emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12778
  DONE;
12779
}"
12780
  [(set_attr "highpart" "ignore")])
12781
 
12782
 
12783
(define_insn "*mshflo_l_di_x"
12784
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12785
        (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12786
                                 "rZ"))
12787
                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12788
                           (const_int 32))))]
12789
 
12790
  "TARGET_SHMEDIA"
12791
  "mshflo.l     %N1, %N2, %0"
12792
  [(set_attr "type" "arith_media")
12793
   (set_attr "highpart" "ignore")])
12794
 
12795
(define_insn_and_split "concat_v2sf"
12796
  [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12797
;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12798
        (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12799
                         (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12800
 
12801
  "TARGET_SHMEDIA"
12802
  "@
12803
        mshflo.l        %N1, %N2, %0
12804
        #
12805
        #"
12806
  "TARGET_SHMEDIA && reload_completed
12807
   && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12808
  [(set (match_dup 3) (match_dup 1))
12809
   (set (match_dup 4) (match_dup 2))]
12810
  "
12811
{
12812
  operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12813
  operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12814
}"
12815
  [(set_attr "type" "arith_media")
12816
   (set_attr "highpart" "ignore")])
12817
 
12818
(define_insn "*mshflo_l_di_x_rev"
12819
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12820
        (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12821
                           (const_int 32))
12822
                (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12823
 
12824
  "TARGET_SHMEDIA"
12825
  "mshflo.l     %N2, %N1, %0"
12826
  [(set_attr "type" "arith_media")
12827
   (set_attr "highpart" "ignore")])
12828
 
12829
(define_insn "ashlv2si3"
12830
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12831
        (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12832
                     (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12833
  "TARGET_SHMEDIA"
12834
  "mshlld.l     %1, %2, %0"
12835
  [(set_attr "type" "arith_media")
12836
   (set_attr "highpart" "depend")])
12837
 
12838
(define_split
12839
  [(set (match_operand 0 "any_register_operand" "")
12840
        (match_operator 3 "shift_operator"
12841
          [(match_operand 1 "any_register_operand" "")
12842
           (match_operand 2 "shift_count_reg_operand" "")]))]
12843
  "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12844
  [(set (match_dup 0) (match_dup 3))]
12845
  "
12846
{
12847
  rtx count = operands[2];
12848
  enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12849
 
12850
  while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12851
         || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12852
         || GET_CODE (count) == TRUNCATE)
12853
    count = XEXP (count, 0);
12854
  inner_mode = GET_MODE (count);
12855
  count = simplify_gen_subreg (outer_mode, count, inner_mode,
12856
                               subreg_lowpart_offset (outer_mode, inner_mode));
12857
  operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12858
                                operands[1], count);
12859
}")
12860
 
12861
(define_insn "ashlv4hi3"
12862
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12863
        (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12864
                     (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12865
  "TARGET_SHMEDIA"
12866
  "mshlld.w     %1, %2, %0"
12867
  [(set_attr "type" "arith_media")
12868
   (set_attr "highpart" "depend")])
12869
 
12870
(define_insn "lshrv2si3"
12871
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12872
        (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12873
                     (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12874
  "TARGET_SHMEDIA"
12875
  "mshlrd.l     %1, %2, %0"
12876
  [(set_attr "type" "arith_media")
12877
   (set_attr "highpart" "depend")])
12878
 
12879
(define_insn "lshrv4hi3"
12880
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12881
        (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12882
                       (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12883
  "TARGET_SHMEDIA"
12884
  "mshlrd.w     %1, %2, %0"
12885
  [(set_attr "type" "arith_media")
12886
   (set_attr "highpart" "depend")])
12887
 
12888
(define_insn "subv2si3"
12889
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12890
        (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12891
                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12892
  "TARGET_SHMEDIA"
12893
  "msub.l       %N1, %2, %0"
12894
  [(set_attr "type" "arith_media")
12895
   (set_attr "highpart" "depend")])
12896
 
12897
(define_insn "subv4hi3"
12898
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12899
        (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12900
                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12901
  "TARGET_SHMEDIA"
12902
  "msub.w       %N1, %2, %0"
12903
  [(set_attr "type" "arith_media")
12904
   (set_attr "highpart" "depend")])
12905
 
12906
(define_insn_and_split "subv2hi3"
12907
  [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12908
        (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12909
                   (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12910
  "TARGET_SHMEDIA"
12911
  "#"
12912
  "TARGET_SHMEDIA"
12913
  [(const_int 0)]
12914
  "
12915
{
12916
  rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12917
  rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12918
  rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12919
  rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12920
  rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12921
 
12922
  emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12923
  emit_insn (gen_truncdisi2 (si_dst, di_dst));
12924
  DONE;
12925
}"
12926
  [(set_attr "highpart" "must_split")])
12927
 
12928
(define_insn "sssubv2si3"
12929
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12930
        (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12931
                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12932
  "TARGET_SHMEDIA"
12933
  "msubs.l      %N1, %2, %0"
12934
  [(set_attr "type" "mcmp_media")
12935
   (set_attr "highpart" "depend")])
12936
 
12937
(define_insn "ussubv8qi3"
12938
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12939
        (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12940
                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12941
  "TARGET_SHMEDIA"
12942
  "msubs.ub     %N1, %2, %0"
12943
  [(set_attr "type" "mcmp_media")
12944
   (set_attr "highpart" "depend")])
12945
 
12946
(define_insn "sssubv4hi3"
12947
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12948
        (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12949
                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12950
  "TARGET_SHMEDIA"
12951
  "msubs.w      %N1, %2, %0"
12952
  [(set_attr "type" "mcmp_media")
12953
   (set_attr "highpart" "depend")])
12954
 
12955
;; Floating Point Intrinsics
12956
 
12957
(define_insn "fcosa_s"
12958
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12959
        (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12960
                   UNSPEC_FCOSA))]
12961
  "TARGET_SHMEDIA"
12962
  "fcosa.s      %1, %0"
12963
  [(set_attr "type" "atrans_media")])
12964
 
12965
(define_insn "fsina_s"
12966
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12967
        (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12968
                   UNSPEC_FSINA))]
12969
  "TARGET_SHMEDIA"
12970
  "fsina.s      %1, %0"
12971
  [(set_attr "type" "atrans_media")])
12972
 
12973
(define_insn "fipr"
12974
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12975
        (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12976
                                                    "fp_arith_reg_operand" "f")
12977
                                                   (match_operand:V4SF 2
12978
                                                    "fp_arith_reg_operand" "f"))
12979
                                         (parallel [(const_int 0)]))
12980
                          (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12981
                                         (parallel [(const_int 1)])))
12982
                 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12983
                                         (parallel [(const_int 2)]))
12984
                          (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12985
                                         (parallel [(const_int 3)])))))]
12986
  "TARGET_SHMEDIA"
12987
  "fipr.s       %1, %2, %0"
12988
  [(set_attr "type" "fparith_media")])
12989
 
12990
(define_insn "fsrra_s"
12991
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12992
        (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12993
                   UNSPEC_FSRRA))]
12994
  "TARGET_SHMEDIA"
12995
  "fsrra.s      %1, %0"
12996
  [(set_attr "type" "atrans_media")])
12997
 
12998
(define_insn "ftrv"
12999
  [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13000
        (plus:V4SF
13001
         (plus:V4SF
13002
          (mult:V4SF
13003
           (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13004
                            (parallel [(const_int 0) (const_int 5)
13005
                                       (const_int 10) (const_int 15)]))
13006
           (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13007
          (mult:V4SF
13008
           (vec_select:V4SF (match_dup 1)
13009
                            (parallel [(const_int 4) (const_int 9)
13010
                                       (const_int 14) (const_int 3)]))
13011
           (vec_select:V4SF (match_dup 2)
13012
                            (parallel [(const_int 1) (const_int 2)
13013
                                       (const_int 3) (const_int 0)]))))
13014
         (plus:V4SF
13015
          (mult:V4SF
13016
           (vec_select:V4SF (match_dup 1)
13017
                            (parallel [(const_int 8) (const_int 13)
13018
                                       (const_int 2) (const_int 7)]))
13019
           (vec_select:V4SF (match_dup 2)
13020
                            (parallel [(const_int 2) (const_int 3)
13021
                                       (const_int 0) (const_int 1)])))
13022
          (mult:V4SF
13023
           (vec_select:V4SF (match_dup 1)
13024
                            (parallel [(const_int 12) (const_int 1)
13025
                                       (const_int 6) (const_int 11)]))
13026
           (vec_select:V4SF (match_dup 2)
13027
                            (parallel [(const_int 3) (const_int 0)
13028
                                       (const_int 1) (const_int 2)]))))))]
13029
  "TARGET_SHMEDIA"
13030
  "ftrv.s %1, %2, %0"
13031
  [(set_attr "type" "fparith_media")])
13032
 
13033
(define_insn "ldhi_l"
13034
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13035
        (zero_extract:SI
13036
         (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13037
                                  (const_int 3))
13038
                          (const_int -3)))
13039
         (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13040
         (const_int 0)))]
13041
  "TARGET_SHMEDIA32"
13042
  "ldhi.l       %U1, %0"
13043
  [(set_attr "type" "load_media")])
13044
 
13045
(define_insn "ldhi_q"
13046
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13047
        (zero_extract:DI
13048
         (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13049
                                  (const_int 7))
13050
                          (const_int -7)))
13051
         (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13052
         (const_int 0)))]
13053
  "TARGET_SHMEDIA32"
13054
  "ldhi.q       %U1, %0"
13055
  [(set_attr "type" "load_media")])
13056
 
13057
(define_insn_and_split "*ldhi_q_comb0"
13058
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13059
        (zero_extract:DI
13060
         (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13061
                                            "register_operand" "r")
13062
                                           (match_operand:SI 2
13063
                                            "ua_offset" "I06"))
13064
                                  (const_int 7))
13065
                          (const_int -7)))
13066
         (plus:SI (and:SI (match_dup 1) (const_int 7))
13067
                  (const_int 1))
13068
         (const_int 0)))]
13069
  "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13070
  "#"
13071
  ""
13072
  [(pc)]
13073
  "emit_insn (gen_ldhi_q (operands[0],
13074
                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
13075
   DONE;")
13076
 
13077
 
13078
(define_insn_and_split "*ldhi_q_comb1"
13079
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13080
        (zero_extract:DI
13081
         (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13082
                                            "register_operand" "r")
13083
                                           (match_operand:SI 2
13084
                                            "ua_offset" "I06"))
13085
                                  (const_int 7))
13086
                          (const_int -7)))
13087
         (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
13088
                                                   "ua_offset" "I06"))
13089
                          (const_int 7))
13090
                  (const_int 1))
13091
         (const_int 0)))]
13092
  "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13093
   && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13094
  "#"
13095
  ""
13096
  [(pc)]
13097
  "emit_insn (gen_ldhi_q (operands[0],
13098
                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
13099
   DONE;")
13100
 
13101
 
13102
(define_insn "ldlo_l"
13103
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13104
        (zero_extract:SI
13105
         (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13106
                         (const_int -4)))
13107
         (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13108
         (and:SI (match_dup 1) (const_int 3))))]
13109
  "TARGET_SHMEDIA32"
13110
  "ldlo.l       %U1, %0"
13111
  [(set_attr "type" "load_media")])
13112
 
13113
(define_insn "ldlo_q"
13114
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13115
        (zero_extract:DI
13116
         (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13117
                         (const_int -8)))
13118
         (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13119
         (and:SI (match_dup 1) (const_int 7))))]
13120
  "TARGET_SHMEDIA32"
13121
  "ldlo.q       %U1, %0"
13122
  [(set_attr "type" "load_media")])
13123
 
13124
(define_insn_and_split "*ldlo_q_comb0"
13125
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13126
        (zero_extract:DI
13127
         (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13128
                                  (match_operand:SI 2 "ua_offset" "I06"))
13129
                         (const_int -8)))
13130
         (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13131
         (and:SI (match_dup 1) (const_int 7))))]
13132
  "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13133
  "#"
13134
  ""
13135
  [(pc)]
13136
  "emit_insn (gen_ldlo_q (operands[0],
13137
                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
13138
   DONE;")
13139
 
13140
(define_insn_and_split "*ldlo_q_comb1"
13141
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13142
        (zero_extract:DI
13143
         (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13144
                                  (match_operand:SI 2 "ua_offset" "I06"))
13145
                         (const_int -8)))
13146
         (minus:SI (const_int 8)
13147
                   (and:SI (plus:SI (match_dup 1)
13148
                                    (match_operand:SI 3 "ua_offset" "I06"))
13149
                           (const_int 7)))
13150
         (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13151
  "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13152
   && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13153
  "#"
13154
  ""
13155
  [(pc)]
13156
  "emit_insn (gen_ldlo_q (operands[0],
13157
                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
13158
   DONE;")
13159
 
13160
(define_insn "sthi_l"
13161
  [(set (zero_extract:SI
13162
         (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13163
                                  (const_int 3))
13164
                          (const_int -3)))
13165
         (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13166
         (const_int 0))
13167
        (match_operand:SI 1 "arith_reg_operand" "r"))]
13168
  "TARGET_SHMEDIA32"
13169
  "sthi.l       %U0, %1"
13170
  [(set_attr "type" "ustore_media")])
13171
 
13172
;; All unaligned stores are considered to be 'narrow' because they typically
13173
;; operate on less that a quadword, and when they operate on a full quadword,
13174
;; the vanilla store high / store low sequence will cause a stall if not
13175
;; scheduled apart.
13176
(define_insn "sthi_q"
13177
  [(set (zero_extract:DI
13178
         (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13179
                                  (const_int 7))
13180
                          (const_int -7)))
13181
         (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13182
         (const_int 0))
13183
        (match_operand:DI 1 "arith_reg_operand" "r"))]
13184
  "TARGET_SHMEDIA32"
13185
  "sthi.q       %U0, %1"
13186
  [(set_attr "type" "ustore_media")])
13187
 
13188
(define_insn_and_split "*sthi_q_comb0"
13189
  [(set (zero_extract:DI
13190
         (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13191
                                            "register_operand" "r")
13192
                                           (match_operand:SI 1 "ua_offset"
13193
                                            "I06"))
13194
                                  (const_int 7))
13195
                          (const_int -7)))
13196
         (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13197
         (const_int 0))
13198
        (match_operand:DI 2 "arith_reg_operand" "r"))]
13199
  "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13200
  "#"
13201
  ""
13202
  [(pc)]
13203
  "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13204
                          operands[2]));
13205
   DONE;")
13206
 
13207
(define_insn_and_split "*sthi_q_comb1"
13208
  [(set (zero_extract:DI
13209
         (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13210
                                            "register_operand" "r")
13211
                                           (match_operand:SI 1 "ua_offset"
13212
                                            "I06"))
13213
                                  (const_int 7))
13214
                          (const_int -7)))
13215
         (plus:SI (and:SI (plus:SI (match_dup 0)
13216
                                   (match_operand:SI 2 "ua_offset" "I06"))
13217
                          (const_int 7))
13218
                  (const_int 1))
13219
         (const_int 0))
13220
        (match_operand:DI 3 "arith_reg_operand" "r"))]
13221
  "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13222
   && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13223
  "#"
13224
  ""
13225
  [(pc)]
13226
  "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13227
                          operands[3]));
13228
   DONE;")
13229
 
13230
;; This is highpart user because the address is used as full 64 bit.
13231
(define_insn "stlo_l"
13232
  [(set (zero_extract:SI
13233
         (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13234
                         (const_int -4)))
13235
         (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13236
         (and:SI (match_dup 0) (const_int 3)))
13237
        (match_operand:SI 1 "arith_reg_operand" "r"))]
13238
  "TARGET_SHMEDIA32"
13239
  "stlo.l       %U0, %1"
13240
  [(set_attr "type" "ustore_media")])
13241
 
13242
(define_insn "stlo_q"
13243
  [(set (zero_extract:DI
13244
         (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13245
                         (const_int -8)))
13246
         (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13247
         (and:SI (match_dup 0) (const_int 7)))
13248
        (match_operand:DI 1 "arith_reg_operand" "r"))]
13249
  "TARGET_SHMEDIA32"
13250
  "stlo.q       %U0, %1"
13251
  [(set_attr "type" "ustore_media")])
13252
 
13253
(define_insn_and_split "*stlo_q_comb0"
13254
  [(set (zero_extract:DI
13255
         (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13256
                                  (match_operand:SI 1 "ua_offset" "I06"))
13257
                         (const_int -8)))
13258
         (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13259
         (and:SI (match_dup 0) (const_int 7)))
13260
        (match_operand:DI 2 "arith_reg_operand" "r"))]
13261
  "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13262
  "#"
13263
  ""
13264
  [(pc)]
13265
  "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13266
                          operands[2]));
13267
   DONE;")
13268
 
13269
(define_insn_and_split "*stlo_q_comb1"
13270
  [(set (zero_extract:DI
13271
         (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13272
                                  (match_operand:SI 1 "ua_offset" "I06"))
13273
                         (const_int -8)))
13274
         (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13275
                                                  (match_operand:SI 2
13276
                                                   "ua_offset" "I06"))
13277
                                         (const_int 7)))
13278
         (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13279
        (match_operand:DI 3 "arith_reg_operand" "r"))]
13280
  "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13281
  "#"
13282
  ""
13283
  [(pc)]
13284
  "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13285
                          operands[3]));
13286
   DONE;")
13287
 
13288
(define_insn "ldhi_l64"
13289
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13290
        (zero_extract:SI
13291
         (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13292
                                  (const_int 3))
13293
                          (const_int -3)))
13294
         (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13295
         (const_int 0)))]
13296
  "TARGET_SHMEDIA64"
13297
  "ldhi.l       %U1, %0"
13298
  [(set_attr "type" "load_media")])
13299
 
13300
(define_insn "ldhi_q64"
13301
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13302
        (zero_extract:DI
13303
         (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13304
                                  (const_int 7))
13305
                          (const_int -7)))
13306
         (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13307
         (const_int 0)))]
13308
  "TARGET_SHMEDIA64"
13309
  "ldhi.q       %U1, %0"
13310
  [(set_attr "type" "load_media")])
13311
 
13312
(define_insn "ldlo_l64"
13313
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13314
        (zero_extract:SI
13315
         (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13316
                         (const_int -4)))
13317
         (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13318
         (and:DI (match_dup 1) (const_int 3))))]
13319
  "TARGET_SHMEDIA64"
13320
  "ldlo.l       %U1, %0"
13321
  [(set_attr "type" "load_media")])
13322
 
13323
(define_insn "ldlo_q64"
13324
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13325
        (zero_extract:DI
13326
         (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13327
                         (const_int -8)))
13328
         (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13329
         (and:DI (match_dup 1) (const_int 7))))]
13330
  "TARGET_SHMEDIA64"
13331
  "ldlo.q       %U1, %0"
13332
  [(set_attr "type" "load_media")])
13333
 
13334
(define_insn "sthi_l64"
13335
  [(set (zero_extract:SI
13336
         (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13337
                                  (const_int 3))
13338
                          (const_int -3)))
13339
         (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13340
         (const_int 0))
13341
        (match_operand:SI 1 "arith_reg_operand" "r"))]
13342
  "TARGET_SHMEDIA64"
13343
  "sthi.l       %U0, %1"
13344
  [(set_attr "type" "ustore_media")])
13345
 
13346
(define_insn "sthi_q64"
13347
  [(set (zero_extract:DI
13348
         (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13349
                                  (const_int 7))
13350
                          (const_int -7)))
13351
         (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13352
         (const_int 0))
13353
        (match_operand:DI 1 "arith_reg_operand" "r"))]
13354
  "TARGET_SHMEDIA64"
13355
  "sthi.q       %U0, %1"
13356
  [(set_attr "type" "ustore_media")])
13357
 
13358
(define_insn "stlo_l64"
13359
  [(set (zero_extract:SI
13360
         (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13361
                         (const_int -4)))
13362
         (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13363
         (and:DI (match_dup 0) (const_int 3)))
13364
        (match_operand:SI 1 "arith_reg_operand" "r"))]
13365
  "TARGET_SHMEDIA64"
13366
  "stlo.l       %U0, %1"
13367
  [(set_attr "type" "ustore_media")])
13368
 
13369
(define_insn "stlo_q64"
13370
  [(set (zero_extract:DI
13371
         (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13372
                         (const_int -8)))
13373
         (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13374
         (and:DI (match_dup 0) (const_int 7)))
13375
        (match_operand:DI 1 "arith_reg_operand" "r"))]
13376
  "TARGET_SHMEDIA64"
13377
  "stlo.q       %U0, %1"
13378
  [(set_attr "type" "ustore_media")])
13379
 
13380
(define_insn "nsb"
13381
  [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13382
        (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13383
                   UNSPEC_NSB))]
13384
  "TARGET_SHMEDIA"
13385
  "nsb  %1, %0"
13386
  [(set_attr "type" "arith_media")])
13387
 
13388
(define_insn "nsbsi"
13389
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13390
        (zero_extend:SI
13391
         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13392
                    UNSPEC_NSB)))]
13393
  "TARGET_SHMEDIA"
13394
  "nsb  %1, %0"
13395
  [(set_attr "type" "arith_media")])
13396
 
13397
(define_insn "nsbdi"
13398
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13399
        (zero_extend:DI
13400
         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13401
                    UNSPEC_NSB)))]
13402
  "TARGET_SHMEDIA"
13403
  "nsb  %1, %0"
13404
  [(set_attr "type" "arith_media")])
13405
 
13406
(define_expand "ffsdi2"
13407
  [(set (match_operand:DI 0 "arith_reg_dest" "")
13408
        (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13409
  "TARGET_SHMEDIA"
13410
  "
13411
{
13412
  rtx scratch = gen_reg_rtx (DImode);
13413
  rtx last;
13414
 
13415
  emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13416
  emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13417
  emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13418
  emit_insn (gen_nsbdi (scratch, scratch));
13419
  emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13420
  emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13421
  last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13422
  set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13423
 
13424
  DONE;
13425
}")
13426
 
13427
(define_expand "ffssi2"
13428
  [(set (match_operand:SI 0 "arith_reg_dest" "")
13429
        (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13430
  "TARGET_SHMEDIA"
13431
  "
13432
{
13433
  rtx scratch = gen_reg_rtx (SImode);
13434
  rtx discratch = gen_reg_rtx (DImode);
13435
  rtx last;
13436
 
13437
  emit_insn (gen_adddi3 (discratch,
13438
                         simplify_gen_subreg (DImode, operands[1], SImode, 0),
13439
                         constm1_rtx));
13440
  emit_insn (gen_andcdi3 (discratch,
13441
                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13442
                          discratch));
13443
  emit_insn (gen_nsbsi (scratch, discratch));
13444
  last = emit_insn (gen_subsi3 (operands[0],
13445
                                force_reg (SImode, GEN_INT (63)), scratch));
13446
  set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13447
 
13448
  DONE;
13449
}")
13450
 
13451
(define_insn "byterev"
13452
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13453
        (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13454
                         (parallel [(const_int 7) (const_int 6) (const_int 5)
13455
                                    (const_int 4) (const_int 3) (const_int 2)
13456
                                    (const_int 1) (const_int 0)])))]
13457
  "TARGET_SHMEDIA"
13458
  "byterev      %1, %0"
13459
  [(set_attr "type" "arith_media")])
13460
 
13461
(define_insn "*prefetch_media"
13462
  [(prefetch (match_operand:QI 0 "address_operand" "p")
13463
             (match_operand:SI 1 "const_int_operand" "n")
13464
             (match_operand:SI 2 "const_int_operand" "n"))]
13465
  "TARGET_SHMEDIA"
13466
  "*
13467
{
13468
  operands[0] = gen_rtx_MEM (QImode, operands[0]);
13469
  output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13470
  return \"\";
13471
}"
13472
  [(set_attr "type" "other")])
13473
 
13474
(define_insn "*prefetch_i4"
13475
  [(prefetch (match_operand:SI 0 "register_operand" "r")
13476
             (match_operand:SI 1 "const_int_operand" "n")
13477
             (match_operand:SI 2 "const_int_operand" "n"))]
13478
  "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13479
  "*
13480
{
13481
  return \"pref @%0\";
13482
}"
13483
  [(set_attr "type" "other")])
13484
 
13485
;; In user mode, the "pref" instruction will raise a RADDERR exception
13486
;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
13487
;; implementation of __builtin_prefetch for VxWorks RTPs.
13488
(define_expand "prefetch"
13489
  [(prefetch (match_operand 0 "address_operand" "p")
13490
             (match_operand:SI 1 "const_int_operand" "n")
13491
             (match_operand:SI 2 "const_int_operand" "n"))]
13492
  "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13493
   && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13494
  "
13495
{
13496
  if (GET_MODE (operands[0]) != Pmode
13497
      || !CONST_INT_P (operands[1])
13498
      || !CONST_INT_P (operands[2]))
13499
    FAIL;
13500
  if (! TARGET_SHMEDIA)
13501
    operands[0] = force_reg (Pmode, operands[0]);
13502
}")
13503
 
13504
(define_insn "prefetch_m2a"
13505
  [(prefetch (match_operand:SI 0 "register_operand" "r")
13506
             (match_operand:SI 1 "const_int_operand" "n")
13507
             (match_operand:SI 2 "const_int_operand" "n"))]
13508
  "TARGET_SH2A"
13509
  "pref\\t@%0"
13510
  [(set_attr "type" "other")])
13511
 
13512
(define_insn "alloco_i"
13513
  [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13514
        (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13515
  "TARGET_SHMEDIA32"
13516
  "*
13517
{
13518
  rtx xops[2];
13519
 
13520
  if (GET_CODE (operands[0]) == PLUS)
13521
    {
13522
      xops[0] = XEXP (operands[0], 0);
13523
      xops[1] = XEXP (operands[0], 1);
13524
    }
13525
  else
13526
    {
13527
      xops[0] = operands[0];
13528
      xops[1] = const0_rtx;
13529
    }
13530
  output_asm_insn (\"alloco   %0, %1\", xops);
13531
  return \"\";
13532
}"
13533
  [(set_attr "type" "other")])
13534
 
13535
(define_split
13536
  [(set (match_operand 0 "any_register_operand" "")
13537
        (match_operand 1 "" ""))]
13538
  "TARGET_SHMEDIA && reload_completed"
13539
  [(set (match_dup 0) (match_dup 1))]
13540
  "
13541
{
13542
  int n_changes = 0;
13543
 
13544
  for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13545
  if (!n_changes)
13546
    FAIL;
13547
}")
13548
 
13549
; Stack Protector Patterns
13550
 
13551
(define_expand "stack_protect_set"
13552
  [(set (match_operand 0 "memory_operand" "")
13553
        (match_operand 1 "memory_operand" ""))]
13554
  ""
13555
{
13556
  if (TARGET_SHMEDIA)
13557
    {
13558
      if (TARGET_SHMEDIA64)
13559
        emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13560
      else
13561
        emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13562
    }
13563
  else
13564
    emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13565
 
13566
  DONE;
13567
})
13568
 
13569
(define_insn "stack_protect_set_si"
13570
  [(set (match_operand:SI 0 "memory_operand" "=m")
13571
        (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13572
   (set (match_scratch:SI 2 "=&r") (const_int 0))]
13573
  "!TARGET_SHMEDIA"
13574
  "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13575
  [(set_attr "type" "other")
13576
   (set_attr "length" "6")])
13577
 
13578
(define_insn "stack_protect_set_si_media"
13579
  [(set (match_operand:SI 0 "memory_operand" "=m")
13580
        (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13581
   (set (match_scratch:SI 2 "=&r") (const_int 0))]
13582
  "TARGET_SHMEDIA"
13583
  "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13584
  [(set_attr "type" "other")
13585
   (set_attr "length" "12")])
13586
 
13587
(define_insn "stack_protect_set_di_media"
13588
  [(set (match_operand:DI 0 "memory_operand" "=m")
13589
        (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13590
   (set (match_scratch:DI 2 "=&r") (const_int 0))]
13591
  "TARGET_SHMEDIA64"
13592
  "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13593
  [(set_attr "type" "other")
13594
   (set_attr "length" "12")])
13595
 
13596
(define_expand "stack_protect_test"
13597
  [(match_operand 0 "memory_operand" "")
13598
   (match_operand 1 "memory_operand" "")
13599
   (match_operand 2 "" "")]
13600
  ""
13601
{
13602
  if (TARGET_SHMEDIA)
13603
    {
13604
      rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13605
      rtx test;
13606
 
13607
      test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13608
      if (TARGET_SHMEDIA64)
13609
        {
13610
          emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13611
                                                      operands[1]));
13612
          emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13613
        }
13614
      else
13615
        {
13616
          emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13617
                                                      operands[1]));
13618
          emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13619
        }
13620
    }
13621
  else
13622
    {
13623
      emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13624
      emit_jump_insn (gen_branch_true (operands[2]));
13625
    }
13626
 
13627
  DONE;
13628
})
13629
 
13630
(define_insn "stack_protect_test_si"
13631
  [(set (reg:SI T_REG)
13632
        (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13633
                    (match_operand:SI 1 "memory_operand" "m")]
13634
                   UNSPEC_SP_TEST))
13635
  (set (match_scratch:SI 2 "=&r") (const_int 0))
13636
  (set (match_scratch:SI 3 "=&r") (const_int 0))]
13637
  "!TARGET_SHMEDIA"
13638
  "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13639
  [(set_attr "type" "other")
13640
   (set_attr "length" "10")])
13641
 
13642
(define_insn "stack_protect_test_si_media"
13643
  [(set (match_operand:SI 0 "register_operand" "=&r")
13644
        (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13645
                    (match_operand:SI 2 "memory_operand" "m")]
13646
                   UNSPEC_SP_TEST))
13647
  (set (match_scratch:SI 3 "=&r") (const_int 0))]
13648
  "TARGET_SHMEDIA"
13649
  "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13650
  [(set_attr "type" "other")
13651
   (set_attr "length" "16")])
13652
 
13653
(define_insn "stack_protect_test_di_media"
13654
  [(set (match_operand:DI 0 "register_operand" "=&r")
13655
        (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13656
                    (match_operand:DI 2 "memory_operand" "m")]
13657
                   UNSPEC_SP_TEST))
13658
  (set (match_scratch:DI 3 "=&r") (const_int 0))]
13659
  "TARGET_SHMEDIA64"
13660
  "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13661
  [(set_attr "type" "other")
13662
   (set_attr "length" "16")])
13663
 
13664
(include "sync.md")

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.