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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [sh/] [sh.md] - Blame information for rev 298

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

Line No. Rev Author Line
1 282 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 Free Software Foundation, Inc.
4
;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5
;;  Improved by Jim Wilson (wilson@cygnus.com).
6
 
7
;; This file is part of GCC.
8
 
9
;; GCC is free software; you can redistribute it and/or modify
10
;; it under the terms of the GNU General Public License as published by
11
;; the Free Software Foundation; either version 3, or (at your option)
12
;; any later version.
13
 
14
;; GCC is distributed in the hope that it will be useful,
15
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
;; GNU General Public License for more details.
18
 
19
;; You should have received a copy of the GNU General Public License
20
;; along with GCC; see the file COPYING3.  If not see
21
;; .
22
 
23
 
24
;; ??? Should prepend a * to all pattern names which are not used.
25
;; This will make the compiler smaller, and rebuilds after changes faster.
26
 
27
;; ??? Should be enhanced to include support for many more GNU superoptimizer
28
;; sequences.  Especially the sequences for arithmetic right shifts.
29
 
30
;; ??? Should check all DImode patterns for consistency and usefulness.
31
 
32
;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
33
;; way to generate them.
34
 
35
;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
36
;; for a str* inline function.
37
 
38
;; BSR is not generated by the compiler proper, but when relaxing, it
39
;; generates .uses pseudo-ops that allow linker relaxation to create
40
;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
41
 
42
;; Special constraints for SH machine description:
43
;;
44
;;    t -- T
45
;;    x -- mac
46
;;    l -- pr
47
;;    z -- r0
48
;;
49
;; Special formats used for outputting SH instructions:
50
;;
51
;;   %.  --  print a .s if insn needs delay slot
52
;;   %@  --  print rte/rts if is/isn't an interrupt function
53
;;   %#  --  output a nop if there is nothing to put in the delay slot
54
;;   %O  --  print a constant without the #
55
;;   %R  --  print the lsw reg of a double
56
;;   %S  --  print the msw reg of a double
57
;;   %T  --  print next word of a double REG or MEM
58
;;
59
;; Special predicates:
60
;;
61
;;  arith_operand          -- operand is valid source for arithmetic op
62
;;  arith_reg_operand      -- operand is valid register for arithmetic op
63
;;  general_movdst_operand -- operand is valid move destination
64
;;  general_movsrc_operand -- operand is valid move source
65
;;  logical_operand        -- operand is valid source for logical op
66
 
67
;; -------------------------------------------------------------------------
68
;; Constants
69
;; -------------------------------------------------------------------------
70
 
71
(define_constants [
72
  (AP_REG       145)
73
  (PR_REG       146)
74
  (T_REG        147)
75
  (GBR_REG      144)
76
  (MACH_REG     148)
77
  (MACL_REG     149)
78
  (FPUL_REG     150)
79
  (RAP_REG      152)
80
 
81
  (FPSCR_REG    151)
82
 
83
  (PIC_REG      12)
84
  (FP_REG       14)
85
  (SP_REG       15)
86
 
87
  (PR_MEDIA_REG 18)
88
  (T_MEDIA_REG  19)
89
 
90
  (R0_REG       0)
91
  (R1_REG       1)
92
  (R2_REG       2)
93
  (R3_REG       3)
94
  (R4_REG       4)
95
  (R5_REG       5)
96
  (R6_REG       6)
97
  (R7_REG       7)
98
  (R8_REG       8)
99
  (R9_REG       9)
100
  (R10_REG      10)
101
  (R20_REG      20)
102
  (R21_REG      21)
103
  (R22_REG      22)
104
  (R23_REG      23)
105
 
106
  (DR0_REG      64)
107
  (DR2_REG      66)
108
  (DR4_REG      68)
109
  (FR23_REG     87)
110
 
111
  (TR0_REG      128)
112
  (TR1_REG      129)
113
  (TR2_REG      130)
114
 
115
  (XD0_REG      136)
116
 
117
  ;; These are used with unspec.
118
  (UNSPEC_COMPACT_ARGS  0)
119
  (UNSPEC_MOVA          1)
120
  (UNSPEC_CASESI        2)
121
  (UNSPEC_DATALABEL     3)
122
  (UNSPEC_BBR           4)
123
  (UNSPEC_SFUNC         5)
124
  (UNSPEC_PIC           6)
125
  (UNSPEC_GOT           7)
126
  (UNSPEC_GOTOFF        8)
127
  (UNSPEC_PLT           9)
128
  (UNSPEC_CALLER        10)
129
  (UNSPEC_GOTPLT        11)
130
  (UNSPEC_ICACHE        12)
131
  (UNSPEC_INIT_TRAMP    13)
132
  (UNSPEC_FCOSA         14)
133
  (UNSPEC_FSRRA         15)
134
  (UNSPEC_FSINA         16)
135
  (UNSPEC_NSB           17)
136
  (UNSPEC_ALLOCO        18)
137
  (UNSPEC_TLSGD         20)
138
  (UNSPEC_TLSLDM        21)
139
  (UNSPEC_TLSIE         22)
140
  (UNSPEC_DTPOFF        23)
141
  (UNSPEC_GOTTPOFF      24)
142
  (UNSPEC_TPOFF         25)
143
  (UNSPEC_RA            26)
144
  (UNSPEC_DIV_INV_M0    30)
145
  (UNSPEC_DIV_INV_M1    31)
146
  (UNSPEC_DIV_INV_M2    32)
147
  (UNSPEC_DIV_INV_M3    33)
148
  (UNSPEC_DIV_INV20     34)
149
  (UNSPEC_DIV_INV_TABLE 37)
150
  (UNSPEC_ASHIFTRT      35)
151
  (UNSPEC_THUNK         36)
152
  (UNSPEC_SP_SET        40)
153
  (UNSPEC_SP_TEST       41)
154
  (UNSPEC_MOVUA         42)
155
 
156
  ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
157
  ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
158
  (UNSPEC_EXTRACT_S16   43)
159
  (UNSPEC_EXTRACT_U16   44)
160
 
161
  ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
162
  (UNSPEC_SYMOFF        45)
163
 
164
  ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
165
  (UNSPEC_PCREL_SYMOFF  46)
166
 
167
  ;; These are used with unspec_volatile.
168
  (UNSPECV_BLOCKAGE     0)
169
  (UNSPECV_ALIGN        1)
170
  (UNSPECV_CONST2       2)
171
  (UNSPECV_CONST4       4)
172
  (UNSPECV_CONST8       6)
173
  (UNSPECV_WINDOW_END   10)
174
  (UNSPECV_CONST_END    11)
175
  (UNSPECV_EH_RETURN    12)
176
])
177
 
178
;; -------------------------------------------------------------------------
179
;; Attributes
180
;; -------------------------------------------------------------------------
181
 
182
;; Target CPU.
183
 
184
(define_attr "cpu"
185
 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
186
  (const (symbol_ref "sh_cpu_attr")))
187
 
188
(define_attr "endian" "big,little"
189
 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
190
                      (const_string "little") (const_string "big"))))
191
 
192
;; Indicate if the default fpu mode is single precision.
193
(define_attr "fpu_single" "yes,no"
194
  (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
195
                         (const_string "yes") (const_string "no"))))
196
 
197
(define_attr "fmovd" "yes,no"
198
  (const (if_then_else (symbol_ref "TARGET_FMOVD")
199
                       (const_string "yes") (const_string "no"))))
200
;; pipeline model
201
(define_attr "pipe_model" "sh1,sh4,sh5media"
202
  (const
203
   (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
204
          (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
205
         (const_string "sh1"))))
206
 
207
;; cbranch      conditional branch instructions
208
;; jump         unconditional jumps
209
;; arith        ordinary arithmetic
210
;; arith3       a compound insn that behaves similarly to a sequence of
211
;;              three insns of type arith
212
;; arith3b      like above, but might end with a redirected branch
213
;; load         from memory
214
;; load_si      Likewise, SImode variant for general register.
215
;; fload        Likewise, but load to fp register.
216
;; store        to memory
217
;; fstore       floating point register to memory
218
;; move         general purpose register to register
219
;; movi8        8-bit immediate to general purpose register
220
;; mt_group     other sh4 mt instructions
221
;; fmove        register to register, floating point
222
;; smpy         word precision integer multiply
223
;; dmpy         longword or doublelongword precision integer multiply
224
;; return       rts
225
;; pload        load of pr reg, which can't be put into delay slot of rts
226
;; prset        copy register to pr reg, ditto
227
;; pstore       store of pr reg, which can't be put into delay slot of jsr
228
;; prget        copy pr to register, ditto
229
;; pcload       pc relative load of constant value
230
;; pcfload      Likewise, but load to fp register.
231
;; pcload_si    Likewise, SImode variant for general register.
232
;; rte          return from exception
233
;; sfunc        special function call with known used registers
234
;; call         function call
235
;; fp           floating point
236
;; fpscr_toggle toggle a bit in the fpscr
237
;; fdiv         floating point divide (or square root)
238
;; gp_fpul      move from general purpose register to fpul
239
;; fpul_gp      move from fpul to general purpose register
240
;; mac_gp       move from mac[lh] to general purpose register
241
;; gp_mac       move from general purpose register to mac[lh]
242
;; mac_mem      move from mac[lh] to memory
243
;; mem_mac      move from memory to mac[lh]
244
;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
245
;; ftrc_s       fix_truncsfsi2_i4
246
;; dfdiv        double precision floating point divide (or square root)
247
;; cwb          ic_invalidate_line_i
248
;; movua        SH4a unaligned load
249
;; fsrra        square root reciprocal approximate
250
;; fsca         sine and cosine approximate
251
;; tls_load     load TLS related address
252
;; arith_media  SHmedia arithmetic, logical, and shift instructions
253
;; cbranch_media SHmedia conditional branch instructions
254
;; cmp_media    SHmedia compare instructions
255
;; dfdiv_media  SHmedia double precision divide and square root
256
;; dfmul_media  SHmedia double precision multiply instruction
257
;; dfparith_media SHmedia double precision floating point arithmetic
258
;; dfpconv_media SHmedia double precision floating point conversions
259
;; dmpy_media   SHmedia longword multiply
260
;; fcmp_media   SHmedia floating point compare instructions
261
;; fdiv_media   SHmedia single precision divide and square root
262
;; fload_media  SHmedia floating point register load instructions
263
;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
264
;; fparith_media SHmedia single precision floating point arithmetic
265
;; fpconv_media SHmedia single precision floating point conversions
266
;; fstore_media SHmedia floating point register store instructions
267
;; gettr_media  SHmedia gettr instruction
268
;; invalidate_line_media SHmedia invalidate_line sequence
269
;; jump_media   SHmedia unconditional branch instructions
270
;; load_media   SHmedia general register load instructions
271
;; pt_media     SHmedia pt instruction (expanded by assembler)
272
;; ptabs_media  SHmedia ptabs instruction
273
;; store_media  SHmedia general register store instructions
274
;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
275
;; mac_media    SHmedia mac-style fixed point operations
276
;; d2mpy_media  SHmedia: two 32-bit integer multiplies
277
;; atrans_media SHmedia approximate transcendental functions
278
;; ustore_media SHmedia unaligned stores
279
;; nil          no-op move, will be deleted.
280
 
281
(define_attr "type"
282
 "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"
283
  (const_string "other"))
284
 
285
;; We define a new attribute namely "insn_class".We use
286
;; this for the DFA based pipeline description.
287
;;
288
;; mt_group      SH4 "mt" group instructions.
289
;;
290
;; ex_group      SH4 "ex" group instructions.
291
;;
292
;; ls_group      SH4 "ls" group instructions.
293
;;
294
 
295
(define_attr "insn_class"
296
  "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
297
  (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
298
         (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
299
         (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
300
         (eq_attr "type" "cbranch,jump") (const_string "br_group")
301
         (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
302
           (const_string "fe_group")
303
         (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")]
304
        (const_string "none")))
305
;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
306
;; so these do not belong in an insn group, although they are modeled
307
;; with their own define_insn_reservations.
308
 
309
;; Indicate what precision must be selected in fpscr for this insn, if any.
310
 
311
(define_attr "fp_mode" "single,double,none" (const_string "none"))
312
 
313
;; Indicate if the fpu mode is set by this instruction
314
;; "unknown" must have the value as "none" in fp_mode, and means
315
;; that the instruction/abi has left the processor in an unknown
316
;; state.
317
;; "none" means that nothing has changed and no mode is set.
318
;; This attribute is only used for the Renesas ABI.
319
(define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
320
 
321
; If a conditional branch destination is within -252..258 bytes away
322
; from the instruction it can be 2 bytes long.  Something in the
323
; range -4090..4100 bytes can be 6 bytes long.  All other conditional
324
; branches are initially assumed to be 16 bytes long.
325
; In machine_dependent_reorg, we split all branches that are longer than
326
; 2 bytes.
327
 
328
;; The maximum range used for SImode constant pool entries is 1018.  A final
329
;; instruction can add 8 bytes while only being 4 bytes in size, thus we
330
;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
331
;; instruction around the pool table, 2 bytes of alignment before the table,
332
;; and 30 bytes of alignment after the table.  That gives a maximum total
333
;; pool size of 1058 bytes.
334
;; Worst case code/pool content size ratio is 1:2 (using asms).
335
;; Thus, in the worst case, there is one instruction in front of a maximum
336
;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
337
;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
338
;; If we have a forward branch, the initial table will be put after the
339
;; unconditional branch.
340
;;
341
;; ??? We could do much better by keeping track of the actual pcloads within
342
;; the branch range and in the pcload range in front of the branch range.
343
 
344
;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
345
;; inside an le.
346
(define_attr "short_cbranch_p" "no,yes"
347
  (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
348
         (const_string "no")
349
         (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
350
         (const_string "yes")
351
         (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
352
         (const_string "no")
353
         (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
354
         (const_string "yes")
355
         ] (const_string "no")))
356
 
357
(define_attr "med_branch_p" "no,yes"
358
  (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
359
              (const_int 1988))
360
         (const_string "yes")
361
         (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
362
         (const_string "no")
363
         (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
364
              (const_int 8186))
365
         (const_string "yes")
366
         ] (const_string "no")))
367
 
368
(define_attr "med_cbranch_p" "no,yes"
369
  (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
370
              (const_int 1986))
371
         (const_string "yes")
372
         (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
373
         (const_string "no")
374
         (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
375
               (const_int 8184))
376
         (const_string "yes")
377
         ] (const_string "no")))
378
 
379
(define_attr "braf_branch_p" "no,yes"
380
  (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
381
         (const_string "no")
382
         (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
383
              (const_int 20660))
384
         (const_string "yes")
385
         (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
386
         (const_string "no")
387
         (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
388
              (const_int 65530))
389
         (const_string "yes")
390
         ] (const_string "no")))
391
 
392
(define_attr "braf_cbranch_p" "no,yes"
393
  (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
394
         (const_string "no")
395
         (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
396
              (const_int 20658))
397
         (const_string "yes")
398
         (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
399
         (const_string "no")
400
         (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
401
              (const_int 65528))
402
         (const_string "yes")
403
         ] (const_string "no")))
404
 
405
; An unconditional jump in the range -4092..4098 can be 2 bytes long.
406
; For wider ranges, we need a combination of a code and a data part.
407
; If we can get a scratch register for a long range jump, the code
408
; part can be 4 bytes long; otherwise, it must be 8 bytes long.
409
; If the jump is in the range -32764..32770, the data part can be 2 bytes
410
; long; otherwise, it must be 6 bytes long.
411
 
412
; All other instructions are two bytes long by default.
413
 
414
;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
415
;; but getattrtab doesn't understand this.
416
(define_attr "length" ""
417
  (cond [(eq_attr "type" "cbranch")
418
         (cond [(eq_attr "short_cbranch_p" "yes")
419
                (const_int 2)
420
                (eq_attr "med_cbranch_p" "yes")
421
                (const_int 6)
422
                (eq_attr "braf_cbranch_p" "yes")
423
                (const_int 12)
424
;; ??? using pc is not computed transitively.
425
                (ne (match_dup 0) (match_dup 0))
426
                (const_int 14)
427
                (ne (symbol_ref ("flag_pic")) (const_int 0))
428
                (const_int 24)
429
                ] (const_int 16))
430
         (eq_attr "type" "jump")
431
         (cond [(eq_attr "med_branch_p" "yes")
432
                (const_int 2)
433
                (and (ne (symbol_ref "prev_nonnote_insn (insn)")
434
                         (const_int 0))
435
                     (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
436
                              (symbol_ref "INSN"))
437
                          (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
438
                              (symbol_ref "code_for_indirect_jump_scratch"))))
439
                (cond [(eq_attr "braf_branch_p" "yes")
440
                       (const_int 6)
441
                       (eq (symbol_ref "flag_pic") (const_int 0))
442
                       (const_int 10)
443
                       (ne (symbol_ref "TARGET_SH2") (const_int 0))
444
                       (const_int 10)] (const_int 18))
445
                (eq_attr "braf_branch_p" "yes")
446
                (const_int 10)
447
;; ??? using pc is not computed transitively.
448
                (ne (match_dup 0) (match_dup 0))
449
                (const_int 12)
450
                (ne (symbol_ref ("flag_pic")) (const_int 0))
451
                (const_int 22)
452
                ] (const_int 14))
453
         (eq_attr "type" "pt_media")
454
         (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
455
                       (const_int 20) (const_int 12))
456
         (and (eq_attr "type" "jump_media")
457
              (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
458
         (const_int 8)
459
         ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
460
                         (const_int 4)
461
                         (const_int 2))))
462
 
463
;; DFA descriptions for the pipelines
464
 
465
(include "sh1.md")
466
(include "shmedia.md")
467
(include "sh4.md")
468
 
469
(include "predicates.md")
470
(include "constraints.md")
471
 
472
;; Definitions for filling delay slots
473
 
474
(define_attr "needs_delay_slot" "yes,no" (const_string "no"))
475
 
476
(define_attr "banked" "yes,no"
477
        (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
478
                   (const_int 1))
479
               (const_string "yes")]
480
              (const_string "no")))
481
 
482
;; ??? This should be (nil) instead of (const_int 0)
483
(define_attr "hit_stack" "yes,no"
484
        (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
485
                   (const_int 0))
486
               (const_string "no")]
487
              (const_string "yes")))
488
 
489
(define_attr "interrupt_function" "no,yes"
490
  (const (symbol_ref "current_function_interrupt")))
491
 
492
(define_attr "in_delay_slot" "yes,no"
493
  (cond [(eq_attr "type" "cbranch") (const_string "no")
494
         (eq_attr "type" "pcload,pcload_si") (const_string "no")
495
         (eq_attr "needs_delay_slot" "yes") (const_string "no")
496
         (eq_attr "length" "2") (const_string "yes")
497
         ] (const_string "no")))
498
 
499
(define_attr "cond_delay_slot" "yes,no"
500
  (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
501
         ] (const_string "no")))
502
 
503
(define_attr "is_sfunc" ""
504
  (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
505
 
506
(define_attr "is_mac_media" ""
507
  (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
508
 
509
(define_attr "branch_zero" "yes,no"
510
  (cond [(eq_attr "type" "!cbranch") (const_string "no")
511
         (ne (symbol_ref "(next_active_insn (insn)\
512
                           == (prev_active_insn\
513
                               (XEXP (SET_SRC (PATTERN (insn)), 1))))\
514
                          && get_attr_length (next_active_insn (insn)) == 2")
515
             (const_int 0))
516
         (const_string "yes")]
517
        (const_string "no")))
518
 
519
;; SH4 Double-precision computation with double-precision result -
520
;; the two halves are ready at different times.
521
(define_attr "dfp_comp" "yes,no"
522
  (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
523
        (const_string "no")))
524
 
525
;; Insns for which the latency of a preceding fp insn is decreased by one.
526
(define_attr "late_fp_use" "yes,no" (const_string "no"))
527
;; And feeding insns for which this relevant.
528
(define_attr "any_fp_comp" "yes,no"
529
  (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
530
         (const_string "yes")]
531
        (const_string "no")))
532
 
533
(define_attr "any_int_load" "yes,no"
534
  (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
535
         (const_string "yes")]
536
        (const_string "no")))
537
 
538
(define_attr "highpart" "user, ignore, extend, depend, must_split"
539
  (const_string "user"))
540
 
541
(define_delay
542
  (eq_attr "needs_delay_slot" "yes")
543
  [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
544
 
545
;; On the SH and SH2, the rte instruction reads the return pc from the stack,
546
;; and thus we can't put a pop instruction in its delay slot.
547
;; ??? On the SH3, the rte instruction does not use the stack, so a pop
548
;; instruction can go in the delay slot.
549
 
550
;; Since a normal return (rts) implicitly uses the PR register,
551
;; we can't allow PR register loads in an rts delay slot.
552
 
553
(define_delay
554
  (eq_attr "type" "return")
555
  [(and (eq_attr "in_delay_slot" "yes")
556
        (ior (and (eq_attr "interrupt_function" "no")
557
                  (eq_attr "type" "!pload,prset"))
558
             (and (eq_attr "interrupt_function" "yes")
559
                  (ior
560
                   (eq (symbol_ref "TARGET_SH3") (const_int 0))
561
                   (eq_attr "hit_stack" "no")
562
                   (eq_attr "banked" "no"))))) (nil) (nil)])
563
 
564
;; Since a call implicitly uses the PR register, we can't allow
565
;; a PR register store in a jsr delay slot.
566
 
567
(define_delay
568
  (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
569
  [(and (eq_attr "in_delay_slot" "yes")
570
        (eq_attr "type" "!pstore,prget")) (nil) (nil)])
571
 
572
;; Say that we have annulled true branches, since this gives smaller and
573
;; faster code when branches are predicted as not taken.
574
 
575
;; ??? The non-annulled condition should really be "in_delay_slot",
576
;; but insns that can be filled in non-annulled get priority over insns
577
;; that can only be filled in anulled.
578
 
579
(define_delay
580
  (and (eq_attr "type" "cbranch")
581
       (ne (symbol_ref "TARGET_SH2") (const_int 0)))
582
  ;; SH2e has a hardware bug that pretty much prohibits the use of
583
  ;; annuled delay slots.
584
  [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
585
                                          (not (eq_attr "cpu" "sh2e"))) (nil)])
586
 
587
;; -------------------------------------------------------------------------
588
;; SImode signed integer comparisons
589
;; -------------------------------------------------------------------------
590
 
591
(define_insn ""
592
  [(set (reg:SI T_REG)
593
        (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
594
                       (match_operand:SI 1 "logical_operand" "K08,r"))
595
               (const_int 0)))]
596
  "TARGET_SH1"
597
  "tst  %1,%0"
598
  [(set_attr "type" "mt_group")])
599
 
600
;; ??? Perhaps should only accept reg/constant if the register is reg 0.
601
;; That would still allow reload to create cmpi instructions, but would
602
;; perhaps allow forcing the constant into a register when that is better.
603
;; Probably should use r0 for mem/imm compares, but force constant into a
604
;; register for pseudo/imm compares.
605
 
606
(define_insn "cmpeqsi_t"
607
  [(set (reg:SI T_REG)
608
        (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
609
               (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
610
  "TARGET_SH1"
611
  "@
612
        tst     %0,%0
613
        cmp/eq  %1,%0
614
        cmp/eq  %1,%0"
615
   [(set_attr "type" "mt_group")])
616
 
617
(define_insn "cmpgtsi_t"
618
  [(set (reg:SI T_REG)
619
        (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
620
               (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
621
  "TARGET_SH1"
622
  "@
623
        cmp/gt  %1,%0
624
        cmp/pl  %0"
625
   [(set_attr "type" "mt_group")])
626
 
627
(define_insn "cmpgesi_t"
628
  [(set (reg:SI T_REG)
629
        (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
630
               (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
631
  "TARGET_SH1"
632
  "@
633
        cmp/ge  %1,%0
634
        cmp/pz  %0"
635
   [(set_attr "type" "mt_group")])
636
 
637
;; -------------------------------------------------------------------------
638
;; SImode compare and branch
639
;; -------------------------------------------------------------------------
640
 
641
(define_expand "cbranchsi4"
642
  [(set (pc)
643
        (if_then_else (match_operator 0 "comparison_operator"
644
                        [(match_operand:SI 1 "arith_operand" "")
645
                         (match_operand:SI 2 "arith_operand" "")])
646
                      (label_ref (match_operand 3 "" ""))
647
                      (pc)))
648
   (clobber (reg:SI T_REG))]
649
  ""
650
  "if (TARGET_SHMEDIA)
651
      emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
652
                                             operands[2], operands[3]));
653
   else if (TARGET_CBRANCHDI4)
654
     expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
655
   else
656
     sh_emit_compare_and_branch (operands, SImode);
657
   DONE;")
658
 
659
;; -------------------------------------------------------------------------
660
;; SImode unsigned integer comparisons
661
;; -------------------------------------------------------------------------
662
 
663
(define_insn_and_split "cmpgeusi_t"
664
  [(set (reg:SI T_REG)
665
        (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
666
                (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
667
  "TARGET_SH1"
668
  "cmp/hs       %1,%0"
669
  "&& operands[1] == CONST0_RTX (SImode)"
670
  [(pc)]
671
  "
672
{
673
  emit_insn (gen_sett ());
674
  DONE;
675
}"
676
   [(set_attr "type" "mt_group")])
677
 
678
(define_insn "cmpgtusi_t"
679
  [(set (reg:SI T_REG)
680
        (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
681
                (match_operand:SI 1 "arith_reg_operand" "r")))]
682
  "TARGET_SH1"
683
  "cmp/hi       %1,%0"
684
   [(set_attr "type" "mt_group")])
685
 
686
 
687
;; -------------------------------------------------------------------------
688
;; DImode compare and branch
689
;; -------------------------------------------------------------------------
690
 
691
 
692
;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
693
;; Therefore, we aim to have a set of three branches that go straight to the
694
;; destination, i.e. only one of them is taken at any one time.
695
;; This mechanism should also be slightly better for the sh4-200.
696
 
697
(define_expand "cbranchdi4"
698
  [(set (pc)
699
        (if_then_else (match_operator 0 "comparison_operator"
700
                        [(match_operand:DI 1 "arith_operand" "")
701
                         (match_operand:DI 2 "arith_operand" "")])
702
                      (label_ref (match_operand 3 "" ""))
703
                      (pc)))
704
   (clobber (match_dup 4))
705
   (clobber (reg:SI T_REG))]
706
  "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
707
  "
708
{
709
  enum rtx_code comparison;
710
 
711
  if (TARGET_SHMEDIA)
712
    {
713
      emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
714
                                             operands[2], operands[3]));
715
      DONE;
716
    }
717
 
718
  else if (!TARGET_CBRANCHDI4)
719
    {
720
      sh_emit_compare_and_branch (operands, DImode);
721
      DONE;
722
    }
723
 
724
  else
725
    {
726
      if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
727
        DONE;
728
 
729
      comparison = prepare_cbranch_operands (operands, DImode,
730
                                             LAST_AND_UNUSED_RTX_CODE);
731
      if (comparison != GET_CODE (operands[0]))
732
        operands[0]
733
          = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
734
       operands[4] = gen_rtx_SCRATCH (SImode);
735
    }
736
}")
737
 
738
(define_insn_and_split "cbranchdi4_i"
739
  [(set (pc)
740
        (if_then_else (match_operator 0 "comparison_operator"
741
                        [(match_operand:DI 1 "arith_operand" "r,r")
742
                         (match_operand:DI 2 "arith_operand" "rN,I08")])
743
                      (label_ref (match_operand 3 "" ""))
744
                      (pc)))
745
   (clobber (match_scratch:SI 4 "=X,&r"))
746
   (clobber (reg:SI T_REG))]
747
  "TARGET_CBRANCHDI4"
748
  "#"
749
  "&& reload_completed"
750
  [(pc)]
751
  "
752
{
753
  if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
754
    FAIL;
755
  DONE;
756
}")
757
 
758
;; -------------------------------------------------------------------------
759
;; DImode signed integer comparisons
760
;; -------------------------------------------------------------------------
761
 
762
(define_insn ""
763
  [(set (reg:SI T_REG)
764
        (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
765
                       (match_operand:DI 1 "arith_operand" "r"))
766
               (const_int 0)))]
767
  "TARGET_SH1"
768
  "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
769
                                 insn, operands);"
770
  [(set_attr "length" "6")
771
   (set_attr "type" "arith3b")])
772
 
773
(define_insn "cmpeqdi_t"
774
  [(set (reg:SI T_REG)
775
        (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
776
               (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
777
  "TARGET_SH1"
778
  "@
779
        tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
780
        cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
781
  [(set_attr "length" "6")
782
   (set_attr "type" "arith3b")])
783
 
784
(define_split
785
  [(set (reg:SI T_REG)
786
        (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
787
               (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
788
;; If we applied this split when not optimizing, it would only be
789
;; applied during the machine-dependent reorg, when no new basic blocks
790
;; may be created.
791
  "TARGET_SH1 && reload_completed && optimize"
792
  [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
793
   (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
794
                           (label_ref (match_dup 6))
795
                           (pc)))
796
   (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
797
   (match_dup 6)]
798
  "
799
{
800
  operands[2]
801
    = gen_rtx_REG (SImode,
802
                   true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
803
  operands[3]
804
    = (operands[1] == const0_rtx
805
       ? const0_rtx
806
       : gen_rtx_REG (SImode,
807
                      true_regnum (operands[1])
808
                      + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
809
  operands[4] = gen_lowpart (SImode, operands[0]);
810
  operands[5] = gen_lowpart (SImode, operands[1]);
811
  operands[6] = gen_label_rtx ();
812
}")
813
 
814
(define_insn "cmpgtdi_t"
815
  [(set (reg:SI T_REG)
816
        (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
817
               (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
818
  "TARGET_SH2"
819
  "@
820
        cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
821
        tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
822
  [(set_attr "length" "8")
823
   (set_attr "type" "arith3")])
824
 
825
(define_insn "cmpgedi_t"
826
  [(set (reg:SI T_REG)
827
        (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
828
               (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
829
  "TARGET_SH2"
830
  "@
831
        cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
832
        cmp/pz\\t%S0"
833
  [(set_attr "length" "8,2")
834
   (set_attr "type" "arith3,mt_group")])
835
 
836
;; -------------------------------------------------------------------------
837
;; DImode unsigned integer comparisons
838
;; -------------------------------------------------------------------------
839
 
840
(define_insn "cmpgeudi_t"
841
  [(set (reg:SI T_REG)
842
        (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
843
                (match_operand:DI 1 "arith_reg_operand" "r")))]
844
  "TARGET_SH2"
845
  "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
846
  [(set_attr "length" "8")
847
   (set_attr "type" "arith3")])
848
 
849
(define_insn "cmpgtudi_t"
850
  [(set (reg:SI T_REG)
851
        (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
852
                (match_operand:DI 1 "arith_reg_operand" "r")))]
853
  "TARGET_SH2"
854
  "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
855
  [(set_attr "length" "8")
856
   (set_attr "type" "arith3")])
857
 
858
(define_insn "cmpeqsi_media"
859
  [(set (match_operand:SI 0 "register_operand" "=r")
860
        (eq:SI (match_operand:SI 1 "logical_operand" "%r")
861
               (match_operand:SI 2 "cmp_operand" "Nr")))]
862
  "TARGET_SHMEDIA"
863
  "cmpeq        %1, %N2, %0"
864
  [(set_attr "type" "cmp_media")])
865
 
866
(define_insn "cmpeqdi_media"
867
  [(set (match_operand:SI 0 "register_operand" "=r")
868
        (eq:SI (match_operand:DI 1 "register_operand" "%r")
869
               (match_operand:DI 2 "cmp_operand" "Nr")))]
870
  "TARGET_SHMEDIA"
871
  "cmpeq        %1, %N2, %0"
872
  [(set_attr "type" "cmp_media")])
873
 
874
(define_insn "cmpgtsi_media"
875
  [(set (match_operand:SI 0 "register_operand" "=r")
876
        (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
877
               (match_operand:SI 2 "cmp_operand" "rN")))]
878
  "TARGET_SHMEDIA"
879
  "cmpgt        %N1, %N2, %0"
880
  [(set_attr "type" "cmp_media")])
881
 
882
(define_insn "cmpgtdi_media"
883
  [(set (match_operand:SI 0 "register_operand" "=r")
884
        (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
885
               (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
886
  "TARGET_SHMEDIA"
887
  "cmpgt        %N1, %N2, %0"
888
  [(set_attr "type" "cmp_media")])
889
 
890
(define_insn "cmpgtusi_media"
891
  [(set (match_operand:SI 0 "register_operand" "=r")
892
        (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
893
                (match_operand:SI 2 "cmp_operand" "rN")))]
894
  "TARGET_SHMEDIA"
895
  "cmpgtu       %N1, %N2, %0"
896
  [(set_attr "type" "cmp_media")])
897
 
898
(define_insn "cmpgtudi_media"
899
  [(set (match_operand:SI 0 "register_operand" "=r")
900
        (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
901
                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
902
  "TARGET_SHMEDIA"
903
  "cmpgtu       %N1, %N2, %0"
904
  [(set_attr "type" "cmp_media")])
905
 
906
; These two patterns are for combine.
907
(define_insn "*cmpne0sisi_media"
908
  [(set (match_operand:SI 0 "register_operand" "=r")
909
        (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
910
  "TARGET_SHMEDIA"
911
  "cmpgtu       %1,r63,%0"
912
  [(set_attr "type" "cmp_media")])
913
 
914
;; -------------------------------------------------------------------------
915
;; Conditional move instructions
916
;; -------------------------------------------------------------------------
917
 
918
;; The insn names may seem reversed, but note that cmveq performs the move
919
;; if op1 == 0, and cmvne does it if op1 != 0.
920
 
921
(define_insn "movdicc_false"
922
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
923
        (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
924
                             (const_int 0))
925
         (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
926
         (match_operand:DI 3 "arith_reg_operand" "0")))]
927
  "TARGET_SHMEDIA"
928
  "cmveq        %1, %N2, %0"
929
  [(set_attr "type" "arith_media")])
930
 
931
(define_insn "movdicc_true"
932
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
933
        (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
934
                             (const_int 0))
935
         (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
936
         (match_operand:DI 3 "arith_reg_operand" "0")))]
937
  "TARGET_SHMEDIA"
938
  "cmvne        %1, %N2, %0"
939
  [(set_attr "type" "arith_media")])
940
 
941
(define_peephole2
942
  [(set (match_operand:DI 0 "arith_reg_dest" "")
943
        (if_then_else:DI (match_operator 3 "equality_comparison_operator"
944
                           [(match_operand:DI 1 "arith_reg_operand" "")
945
                            (const_int 0)])
946
         (match_operand:DI 2 "arith_reg_dest" "")
947
         (match_dup 0)))
948
   (set (match_dup 2) (match_dup 0))]
949
  "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
950
  [(set (match_dup 2)
951
        (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
952
  "
953
{
954
  operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
955
                                VOIDmode, operands[1], CONST0_RTX (DImode));
956
}")
957
 
958
(define_peephole2
959
  [(set (match_operand:DI 0 "general_movdst_operand" "")
960
        (match_operand:DI 1 "arith_reg_or_0_operand" ""))
961
   (set (match_operand:DI 2 "arith_reg_dest" "")
962
        (if_then_else:DI (match_operator 4 "equality_comparison_operator"
963
                           [(match_operand:DI 3 "arith_reg_operand" "")
964
                            (const_int 0)])
965
         (match_dup 0)
966
         (match_dup 2)))]
967
  "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
968
  [(set (match_dup 2)
969
        (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
970
  "")
971
 
972
(define_expand "movdicc"
973
  [(set (match_operand:DI 0 "register_operand" "")
974
        (if_then_else:DI (match_operand 1 "comparison_operator" "")
975
                         (match_operand:DI 2 "register_operand" "")
976
                         (match_operand:DI 3 "register_operand" "")))]
977
  "TARGET_SHMEDIA"
978
  "
979
{
980
  if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
981
      && GET_MODE (XEXP (operands[1], 0)) == DImode
982
      && XEXP (operands[1], 1) == const0_rtx)
983
    ;
984
  else
985
    {
986
      if (!can_create_pseudo_p ())
987
        FAIL;
988
 
989
      operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
990
                                              GET_CODE (operands[1]),
991
                                              XEXP (operands[1], 0),
992
                                              XEXP (operands[1], 1));
993
      if (!operands[1])
994
        FAIL;
995
    }
996
}")
997
 
998
;; Add SImode variants for cmveq / cmvne to compensate for not promoting
999
;; SImode to DImode.
1000
(define_insn "movsicc_false"
1001
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1002
        (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1003
                          (const_int 0))
1004
         (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1005
         (match_operand:SI 3 "arith_reg_operand" "0")))]
1006
  "TARGET_SHMEDIA"
1007
  "cmveq        %1, %N2, %0"
1008
  [(set_attr "type" "arith_media")])
1009
 
1010
(define_insn "movsicc_true"
1011
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1012
        (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1013
                          (const_int 0))
1014
         (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1015
         (match_operand:SI 3 "arith_reg_operand" "0")))]
1016
  "TARGET_SHMEDIA"
1017
  "cmvne        %1, %N2, %0"
1018
  [(set_attr "type" "arith_media")])
1019
 
1020
(define_peephole2
1021
  [(set (match_operand:SI 0 "arith_reg_dest" "")
1022
        (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1023
                           [(match_operand:SI 1 "arith_reg_operand" "")
1024
                            (const_int 0)])
1025
         (match_operand:SI 2 "arith_reg_dest" "")
1026
         (match_dup 0)))
1027
   (set (match_dup 2) (match_dup 0))]
1028
  "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1029
  [(set (match_dup 2)
1030
        (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1031
  "
1032
{
1033
  operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1034
                                VOIDmode, operands[1], CONST0_RTX (SImode));
1035
}")
1036
 
1037
(define_peephole2
1038
  [(set (match_operand:SI 0 "general_movdst_operand" "")
1039
        (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1040
   (set (match_operand:SI 2 "arith_reg_dest" "")
1041
        (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1042
                           [(match_operand:SI 3 "arith_reg_operand" "")
1043
                            (const_int 0)])
1044
         (match_dup 0)
1045
         (match_dup 2)))]
1046
  "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1047
   && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1048
  [(set (match_dup 2)
1049
        (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1050
  "
1051
{
1052
  replace_rtx (operands[4], operands[0], operands[1]);
1053
}")
1054
 
1055
(define_peephole2
1056
  [(set (match_operand 0 "any_register_operand" "")
1057
        (match_operand 1 "any_register_operand" ""))
1058
   (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1059
   (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1060
  "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1061
    <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1062
   && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1063
   && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1064
   && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1065
   && ! reg_overlap_mentioned_p (operands[0], operands[3])
1066
   && ! reg_overlap_mentioned_p (operands[2], operands[0])
1067
   && ! reg_overlap_mentioned_p (operands[0], operands[1])
1068
   && (REGNO_REG_CLASS (REGNO (operands[0]))
1069
       == REGNO_REG_CLASS (REGNO (operands[2])))
1070
   && (REGNO_REG_CLASS (REGNO (operands[1]))
1071
       == REGNO_REG_CLASS (REGNO (operands[0])))"
1072
  [(set (match_dup 0) (match_dup 3))
1073
   (set (match_dup 4) (match_dup 5))]
1074
  "
1075
{
1076
  rtx set1, set2, insn2;
1077
  rtx replacements[4];
1078
 
1079
  /* We want to replace occurrences of operands[0] with operands[1] and
1080
     operands[2] with operands[0] in operands[4]/operands[5].
1081
     Doing just two replace_rtx calls naively would result in the second
1082
     replacement undoing all that the first did if operands[1] and operands[2]
1083
     are identical, so we must do this simultaneously.  */
1084
  replacements[0] = operands[0];
1085
  replacements[1] = operands[1];
1086
  replacements[2] = operands[2];
1087
  replacements[3] = operands[0];
1088
  if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1089
      || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1090
      || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1091
    FAIL;
1092
 
1093
  operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1094
  replace_n_hard_rtx (operands[4], replacements, 2, 1);
1095
  operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1096
  /* The operands array is aliased to recog_data.operand, which gets
1097
     clobbered by extract_insn, so finish with it now.  */
1098
  set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1099
  set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1100
  /* ??? The last insn might be a jump insn, but the generic peephole2 code
1101
     always uses emit_insn.  */
1102
  /* Check that we don't violate matching constraints or earlyclobbers.  */
1103
  extract_insn (emit_insn (set1));
1104
  if (! constrain_operands (1))
1105
    goto failure;
1106
  insn2 = emit (set2);
1107
  if (GET_CODE (insn2) == BARRIER)
1108
    goto failure;
1109
  extract_insn (insn2);
1110
  if (! constrain_operands (1))
1111
    {
1112
      rtx tmp;
1113
    failure:
1114
      tmp = replacements[0];
1115
      replacements[0] = replacements[1];
1116
      replacements[1] = tmp;
1117
      tmp = replacements[2];
1118
      replacements[2] = replacements[3];
1119
      replacements[3] = tmp;
1120
      replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1121
      replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1122
      replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1123
      FAIL;
1124
    }
1125
  DONE;
1126
}")
1127
 
1128
;; The register allocator is rather clumsy in handling multi-way conditional
1129
;; moves, so allow the combiner to make them, and we split them up after
1130
;; reload.  */
1131
(define_insn_and_split "*movsicc_umin"
1132
  [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1133
        (umin:SI (if_then_else:SI
1134
                   (eq (match_operand:SI 1 "arith_reg_operand" "r")
1135
                       (const_int 0))
1136
                   (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1137
                   (match_operand:SI 3 "register_operand" "0"))
1138
                 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1139
   (clobber (match_scratch:SI 5 "=&r"))]
1140
  "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1141
  "#"
1142
  "TARGET_SHMEDIA && reload_completed"
1143
  [(pc)]
1144
  "
1145
{
1146
  emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1147
                                operands[3]));
1148
  emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1149
  emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1150
                                operands[0]));
1151
  DONE;
1152
}")
1153
 
1154
(define_insn "*movsicc_t_false"
1155
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1156
        (if_then_else (eq (reg:SI T_REG) (const_int 0))
1157
                      (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1158
                      (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1159
  "TARGET_PRETEND_CMOVE
1160
   && (arith_reg_operand (operands[1], SImode)
1161
       || (immediate_operand (operands[1], SImode)
1162
           && satisfies_constraint_I08 (operands[1])))"
1163
  "bt 0f\;mov %1,%0\\n0:"
1164
  [(set_attr "type" "mt_group,arith") ;; poor approximation
1165
   (set_attr "length" "4")])
1166
 
1167
(define_insn "*movsicc_t_true"
1168
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1169
        (if_then_else (ne (reg:SI T_REG) (const_int 0))
1170
                      (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1171
                      (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1172
  "TARGET_PRETEND_CMOVE
1173
   && (arith_reg_operand (operands[1], SImode)
1174
       || (immediate_operand (operands[1], SImode)
1175
           && satisfies_constraint_I08 (operands[1])))"
1176
  "bf 0f\;mov %1,%0\\n0:"
1177
  [(set_attr "type" "mt_group,arith") ;; poor approximation
1178
   (set_attr "length" "4")])
1179
 
1180
(define_expand "movsicc"
1181
  [(set (match_operand:SI 0 "arith_reg_dest" "")
1182
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
1183
                         (match_operand:SI 2 "arith_reg_or_0_operand" "")
1184
                         (match_operand:SI 3 "arith_reg_operand" "")))]
1185
  "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1186
  "
1187
{
1188
  if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1189
      && GET_MODE (XEXP (operands[1], 0)) == SImode
1190
      && (TARGET_SHMEDIA
1191
          || (REG_P (XEXP (operands[1], 0))
1192
              && REGNO (XEXP (operands[1], 0)) == T_REG))
1193
      && XEXP (operands[1], 1) == const0_rtx)
1194
    ;
1195
 
1196
  else if (TARGET_PRETEND_CMOVE)
1197
    {
1198
      enum rtx_code code = GET_CODE (operands[1]);
1199
      enum rtx_code new_code = code;
1200
      rtx op0 = XEXP (operands[1], 0);
1201
      rtx op1 = XEXP (operands[1], 1);
1202
 
1203
      if (! currently_expanding_to_rtl)
1204
        FAIL;
1205
      switch (code)
1206
        {
1207
        case LT: case LE: case LEU: case LTU:
1208
          if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1209
            break;
1210
        case NE:
1211
          new_code = reverse_condition (code);
1212
          break;
1213
        case EQ: case GT: case GE: case GEU: case GTU:
1214
          break;
1215
        default:
1216
          FAIL;
1217
        }
1218
      sh_emit_scc_to_t (new_code, op0, op1);
1219
      operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1220
                                    gen_rtx_REG (SImode, T_REG), const0_rtx);
1221
    }
1222
  else
1223
    {
1224
      if (!can_create_pseudo_p ())
1225
        FAIL;
1226
 
1227
      operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1228
                                              GET_CODE (operands[1]),
1229
                                              XEXP (operands[1], 0),
1230
                                              XEXP (operands[1], 1));
1231
      if (!operands[1])
1232
        FAIL;
1233
    }
1234
}")
1235
 
1236
(define_expand "movqicc"
1237
  [(set (match_operand:QI 0 "register_operand" "")
1238
        (if_then_else:QI (match_operand 1 "comparison_operator" "")
1239
                         (match_operand:QI 2 "register_operand" "")
1240
                         (match_operand:QI 3 "register_operand" "")))]
1241
  "TARGET_SHMEDIA"
1242
  "
1243
{
1244
  operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1245
  operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1246
  operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1247
  emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1248
  DONE;
1249
}")
1250
 
1251
;; -------------------------------------------------------------------------
1252
;; Addition instructions
1253
;; -------------------------------------------------------------------------
1254
 
1255
(define_expand "adddi3"
1256
  [(set (match_operand:DI 0 "arith_reg_operand" "")
1257
        (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1258
                 (match_operand:DI 2 "arith_operand" "")))]
1259
  ""
1260
  "
1261
{
1262
  if (TARGET_SH1)
1263
    {
1264
      if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1265
        FAIL;
1266
      operands[2] = force_reg (DImode, operands[2]);
1267
      emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1268
      DONE;
1269
    }
1270
}")
1271
 
1272
(define_insn "*adddi3_media"
1273
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1274
        (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1275
                 (match_operand:DI 2 "arith_operand" "r,I10")))]
1276
  "TARGET_SHMEDIA"
1277
  "@
1278
        add     %1, %2, %0
1279
        addi    %1, %2, %0"
1280
  [(set_attr "type" "arith_media")])
1281
 
1282
(define_insn "*adddisi3_media"
1283
  [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1284
        (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1285
                 (match_operand:DI 2 "arith_operand" "r,I10")))]
1286
  "TARGET_SHMEDIA"
1287
  "@
1288
        add.l   %1, %2, %0
1289
        addi.l  %1, %2, %0"
1290
  [(set_attr "type" "arith_media")
1291
   (set_attr "highpart" "ignore")])
1292
 
1293
(define_insn "adddi3z_media"
1294
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1295
        (zero_extend:DI
1296
         (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1297
                  (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1298
  "TARGET_SHMEDIA"
1299
  "addz.l       %1, %N2, %0"
1300
  [(set_attr "type" "arith_media")
1301
   (set_attr "highpart" "ignore")])
1302
 
1303
(define_insn "adddi3_compact"
1304
  [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1305
        (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1306
                 (match_operand:DI 2 "arith_reg_operand" "r")))
1307
   (clobber (reg:SI T_REG))]
1308
  "TARGET_SH1"
1309
  "#"
1310
  [(set_attr "length" "6")])
1311
 
1312
(define_split
1313
  [(set (match_operand:DI 0 "arith_reg_dest" "")
1314
        (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1315
                 (match_operand:DI 2 "arith_reg_operand" "")))
1316
   (clobber (reg:SI T_REG))]
1317
  "TARGET_SH1 && reload_completed"
1318
  [(const_int 0)]
1319
  "
1320
{
1321
  rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1322
  high0 = gen_rtx_REG (SImode,
1323
                       true_regnum (operands[0])
1324
                       + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1325
  high2 = gen_rtx_REG (SImode,
1326
                       true_regnum (operands[2])
1327
                       + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1328
  emit_insn (gen_clrt ());
1329
  emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1330
  emit_insn (gen_addc1 (high0, high0, high2));
1331
  DONE;
1332
}")
1333
 
1334
(define_insn "addc"
1335
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1336
        (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1337
                          (match_operand:SI 2 "arith_reg_operand" "r"))
1338
                 (reg:SI T_REG)))
1339
   (set (reg:SI T_REG)
1340
        (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1341
  "TARGET_SH1"
1342
  "addc %2,%0"
1343
  [(set_attr "type" "arith")])
1344
 
1345
(define_insn "addc1"
1346
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1347
        (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1348
                          (match_operand:SI 2 "arith_reg_operand" "r"))
1349
                 (reg:SI T_REG)))
1350
   (clobber (reg:SI T_REG))]
1351
  "TARGET_SH1"
1352
  "addc %2,%0"
1353
  [(set_attr "type" "arith")])
1354
 
1355
(define_expand "addsi3"
1356
  [(set (match_operand:SI 0 "arith_reg_operand" "")
1357
        (plus:SI (match_operand:SI 1 "arith_operand" "")
1358
                 (match_operand:SI 2 "arith_operand" "")))]
1359
  ""
1360
  "
1361
{
1362
  if (TARGET_SHMEDIA)
1363
    operands[1] = force_reg (SImode, operands[1]);
1364
}")
1365
 
1366
(define_insn "addsi3_media"
1367
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1368
        (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1369
                 (match_operand:SI 2 "arith_operand" "r,I10")))]
1370
  "TARGET_SHMEDIA"
1371
  "@
1372
        add.l   %1, %2, %0
1373
        addi.l  %1, %2, %0"
1374
  [(set_attr "type" "arith_media")
1375
   (set_attr "highpart" "ignore")])
1376
 
1377
(define_insn "addsidi3_media"
1378
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1379
        (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1380
                                  "%r,r")
1381
                                 (match_operand:SI 2 "arith_operand"
1382
                                  "r,I10"))))]
1383
  "TARGET_SHMEDIA"
1384
  "@
1385
        add.l   %1, %2, %0
1386
        addi.l  %1, %2, %0"
1387
  [(set_attr "type" "arith_media")
1388
   (set_attr "highpart" "ignore")])
1389
 
1390
(define_insn "*addsi3_compact"
1391
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1392
        (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1393
                 (match_operand:SI 2 "arith_operand" "rI08")))]
1394
  "TARGET_SH1"
1395
  "add  %2,%0"
1396
  [(set_attr "type" "arith")])
1397
 
1398
;; -------------------------------------------------------------------------
1399
;; Subtraction instructions
1400
;; -------------------------------------------------------------------------
1401
 
1402
(define_expand "subdi3"
1403
  [(set (match_operand:DI 0 "arith_reg_operand" "")
1404
        (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1405
                  (match_operand:DI 2 "arith_reg_operand" "")))]
1406
  ""
1407
  "
1408
{
1409
  if (TARGET_SH1)
1410
    {
1411
      operands[1] = force_reg (DImode, operands[1]);
1412
      emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1413
      DONE;
1414
    }
1415
}")
1416
 
1417
(define_insn "*subdi3_media"
1418
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1419
        (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1420
                  (match_operand:DI 2 "arith_reg_operand" "r")))]
1421
  "TARGET_SHMEDIA"
1422
  "sub  %N1, %2, %0"
1423
  [(set_attr "type" "arith_media")])
1424
 
1425
(define_insn "subdisi3_media"
1426
  [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1427
        (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1428
                  (match_operand:DI 2 "arith_reg_operand" "r")))]
1429
  "TARGET_SHMEDIA"
1430
  "sub.l        %N1, %2, %0"
1431
  [(set_attr "type" "arith_media")
1432
   (set_attr "highpart" "ignore")])
1433
 
1434
(define_insn "subdi3_compact"
1435
  [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1436
        (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1437
                 (match_operand:DI 2 "arith_reg_operand" "r")))
1438
   (clobber (reg:SI T_REG))]
1439
  "TARGET_SH1"
1440
  "#"
1441
  [(set_attr "length" "6")])
1442
 
1443
(define_split
1444
  [(set (match_operand:DI 0 "arith_reg_dest" "")
1445
        (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1446
                  (match_operand:DI 2 "arith_reg_operand" "")))
1447
   (clobber (reg:SI T_REG))]
1448
  "TARGET_SH1 && reload_completed"
1449
  [(const_int 0)]
1450
  "
1451
{
1452
  rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1453
  high0 = gen_rtx_REG (SImode,
1454
                       true_regnum (operands[0])
1455
                       + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1456
  high2 = gen_rtx_REG (SImode,
1457
                       true_regnum (operands[2])
1458
                       + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1459
  emit_insn (gen_clrt ());
1460
  emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1461
  emit_insn (gen_subc1 (high0, high0, high2));
1462
  DONE;
1463
}")
1464
 
1465
(define_insn "subc"
1466
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1467
        (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1468
                            (match_operand:SI 2 "arith_reg_operand" "r"))
1469
                  (reg:SI T_REG)))
1470
   (set (reg:SI T_REG)
1471
        (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1472
                          (reg:SI T_REG))
1473
                (match_dup 1)))]
1474
  "TARGET_SH1"
1475
  "subc %2,%0"
1476
  [(set_attr "type" "arith")])
1477
 
1478
(define_insn "subc1"
1479
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1480
        (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1481
                            (match_operand:SI 2 "arith_reg_operand" "r"))
1482
                  (reg:SI T_REG)))
1483
   (clobber (reg:SI T_REG))]
1484
  "TARGET_SH1"
1485
  "subc %2,%0"
1486
  [(set_attr "type" "arith")])
1487
 
1488
;; life_analysis thinks rn is live before subc rn,rn, so make a special
1489
;; pattern for this case.  This helps multimedia applications that compute
1490
;; the sum of absolute differences.
1491
(define_insn "mov_neg_si_t"
1492
  [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1493
  "TARGET_SH1"
1494
  "subc %0,%0"
1495
  [(set_attr "type" "arith")])
1496
 
1497
(define_insn "*subsi3_internal"
1498
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1499
        (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1500
                  (match_operand:SI 2 "arith_reg_operand" "r")))]
1501
  "TARGET_SH1"
1502
  "sub  %2,%0"
1503
  [(set_attr "type" "arith")])
1504
 
1505
(define_insn_and_split "*subsi3_media"
1506
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1507
        (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1508
                  (match_operand:SI 2 "extend_reg_operand" "r")))]
1509
  "TARGET_SHMEDIA
1510
   && (operands[1] != constm1_rtx
1511
       || (GET_CODE (operands[2]) != TRUNCATE
1512
           && GET_CODE (operands[2]) != SUBREG))"
1513
  "sub.l        %N1, %2, %0"
1514
  "operands[1] == constm1_rtx"
1515
  [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1516
  ""
1517
  [(set_attr "type" "arith_media")
1518
   (set_attr "highpart" "ignore")])
1519
 
1520
(define_split
1521
  [(set (match_operand:SI 0 "arith_reg_dest" "")
1522
        (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1523
                                                       "general_extend_operand"
1524
                                                       "") 0)) 0)))]
1525
  "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1526
  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1527
   (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1528
  "")
1529
 
1530
(define_split
1531
  [(set (match_operand:SI 0 "arith_reg_dest" "")
1532
        (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1533
                                                       "general_extend_operand"
1534
                                                       "") 0)) 3)))]
1535
  "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1536
  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1537
   (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1538
  "")
1539
;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1540
;; will sometimes save one instruction.  Otherwise we might get
1541
;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1542
;; are the same.
1543
 
1544
(define_expand "subsi3"
1545
  [(set (match_operand:SI 0 "arith_reg_operand" "")
1546
        (minus:SI (match_operand:SI 1 "arith_operand" "")
1547
                  (match_operand:SI 2 "arith_reg_operand" "")))]
1548
  ""
1549
  "
1550
{
1551
  if (TARGET_SH1 && CONST_INT_P (operands[1]))
1552
    {
1553
      emit_insn (gen_negsi2 (operands[0], operands[2]));
1554
      emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1555
      DONE;
1556
    }
1557
  if (TARGET_SHMEDIA)
1558
    {
1559
      if (!can_create_pseudo_p ()
1560
          && ! arith_reg_or_0_operand (operands[1], SImode))
1561
        FAIL;
1562
      if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1563
        operands[1] = force_reg (SImode, operands[1]);
1564
    }
1565
}")
1566
 
1567
;; -------------------------------------------------------------------------
1568
;; Division instructions
1569
;; -------------------------------------------------------------------------
1570
 
1571
;; We take advantage of the library routines which don't clobber as many
1572
;; registers as a normal function call would.
1573
 
1574
;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1575
;; also has an effect on the register that holds the address of the sfunc.
1576
;; To make this work, we have an extra dummy insn that shows the use
1577
;; of this register for reorg.
1578
 
1579
(define_insn "use_sfunc_addr"
1580
  [(set (reg:SI PR_REG)
1581
        (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1582
  "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1583
  ""
1584
  [(set_attr "length" "0")])
1585
 
1586
(define_insn "udivsi3_sh2a"
1587
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1588
        (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1589
                (match_operand:SI 2 "arith_reg_operand" "z")))]
1590
  "TARGET_SH2A"
1591
  "divu %2,%1"
1592
  [(set_attr "type" "arith")
1593
   (set_attr "in_delay_slot" "no")])
1594
 
1595
;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1596
;; hard register 0.  If we used hard register 0, then the next instruction
1597
;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1598
;; gets allocated to a stack slot that needs its address reloaded, then
1599
;; there is nothing to prevent reload from using r0 to reload the address.
1600
;; This reload would clobber the value in r0 we are trying to store.
1601
;; If we let reload allocate r0, then this problem can never happen.
1602
 
1603
(define_insn "udivsi3_i1"
1604
  [(set (match_operand:SI 0 "register_operand" "=z")
1605
        (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1606
   (clobber (reg:SI T_REG))
1607
   (clobber (reg:SI PR_REG))
1608
   (clobber (reg:SI R4_REG))
1609
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1610
  "TARGET_SH1 && ! TARGET_SH4"
1611
  "jsr  @%1%#"
1612
  [(set_attr "type" "sfunc")
1613
   (set_attr "needs_delay_slot" "yes")])
1614
 
1615
; Since shmedia-nofpu code could be linked against shcompact code, and
1616
; the udivsi3 libcall has the same name, we must consider all registers
1617
; clobbered that are in the union of the registers clobbered by the
1618
; shmedia and the shcompact implementation.  Note, if the shcompact
1619
; implementation actually used shcompact code, we'd need to clobber
1620
; also r23 and fr23.
1621
(define_insn "udivsi3_i1_media"
1622
  [(set (match_operand:SI 0 "register_operand" "=z")
1623
        (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1624
   (clobber (reg:SI T_MEDIA_REG))
1625
   (clobber (reg:SI PR_MEDIA_REG))
1626
   (clobber (reg:SI R20_REG))
1627
   (clobber (reg:SI R21_REG))
1628
   (clobber (reg:SI R22_REG))
1629
   (clobber (reg:DI TR0_REG))
1630
   (clobber (reg:DI TR1_REG))
1631
   (clobber (reg:DI TR2_REG))
1632
   (use (match_operand 1 "target_reg_operand" "b"))]
1633
  "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1634
  "blink        %1, r18"
1635
  [(set_attr "type" "sfunc")
1636
   (set_attr "needs_delay_slot" "yes")])
1637
 
1638
(define_expand "udivsi3_i4_media"
1639
  [(set (match_dup 3)
1640
        (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1641
   (set (match_dup 4)
1642
        (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1643
   (set (match_dup 5) (float:DF (match_dup 3)))
1644
   (set (match_dup 6) (float:DF (match_dup 4)))
1645
   (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1646
   (set (match_dup 8) (fix:DI (match_dup 7)))
1647
   (set (match_operand:SI 0 "register_operand" "")
1648
        (truncate:SI (match_dup 8)))]
1649
  "TARGET_SHMEDIA_FPU"
1650
  "
1651
{
1652
  operands[3] = gen_reg_rtx (DImode);
1653
  operands[4] = gen_reg_rtx (DImode);
1654
  operands[5] = gen_reg_rtx (DFmode);
1655
  operands[6] = gen_reg_rtx (DFmode);
1656
  operands[7] = gen_reg_rtx (DFmode);
1657
  operands[8] = gen_reg_rtx (DImode);
1658
}")
1659
 
1660
(define_insn "udivsi3_i4"
1661
  [(set (match_operand:SI 0 "register_operand" "=y")
1662
        (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1663
   (clobber (reg:SI T_REG))
1664
   (clobber (reg:SI PR_REG))
1665
   (clobber (reg:DF DR0_REG))
1666
   (clobber (reg:DF DR2_REG))
1667
   (clobber (reg:DF DR4_REG))
1668
   (clobber (reg:SI R0_REG))
1669
   (clobber (reg:SI R1_REG))
1670
   (clobber (reg:SI R4_REG))
1671
   (clobber (reg:SI R5_REG))
1672
   (use (reg:PSI FPSCR_REG))
1673
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1674
  "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1675
  "jsr  @%1%#"
1676
  [(set_attr "type" "sfunc")
1677
   (set_attr "fp_mode" "double")
1678
   (set_attr "needs_delay_slot" "yes")])
1679
 
1680
(define_insn "udivsi3_i4_single"
1681
  [(set (match_operand:SI 0 "register_operand" "=y")
1682
        (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1683
   (clobber (reg:SI T_REG))
1684
   (clobber (reg:SI PR_REG))
1685
   (clobber (reg:DF DR0_REG))
1686
   (clobber (reg:DF DR2_REG))
1687
   (clobber (reg:DF DR4_REG))
1688
   (clobber (reg:SI R0_REG))
1689
   (clobber (reg:SI R1_REG))
1690
   (clobber (reg:SI R4_REG))
1691
   (clobber (reg:SI R5_REG))
1692
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1693
  "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1694
  "jsr  @%1%#"
1695
  [(set_attr "type" "sfunc")
1696
   (set_attr "needs_delay_slot" "yes")])
1697
 
1698
(define_insn "udivsi3_i4_int"
1699
  [(set (match_operand:SI 0 "register_operand" "=z")
1700
        (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1701
   (clobber (reg:SI T_REG))
1702
   (clobber (reg:SI R1_REG))
1703
   (clobber (reg:SI PR_REG))
1704
   (clobber (reg:SI MACH_REG))
1705
   (clobber (reg:SI MACL_REG))
1706
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1707
  "TARGET_SH1"
1708
  "jsr  @%1%#"
1709
  [(set_attr "type" "sfunc")
1710
   (set_attr "needs_delay_slot" "yes")])
1711
 
1712
 
1713
(define_expand "udivsi3"
1714
  [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1715
   (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1716
   (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1717
   (parallel [(set (match_operand:SI 0 "register_operand" "")
1718
                   (udiv:SI (reg:SI R4_REG)
1719
                            (reg:SI R5_REG)))
1720
              (clobber (reg:SI T_REG))
1721
              (clobber (reg:SI PR_REG))
1722
              (clobber (reg:SI R4_REG))
1723
              (use (match_dup 3))])]
1724
  ""
1725
  "
1726
{
1727
  rtx last;
1728
 
1729
  operands[3] = gen_reg_rtx (Pmode);
1730
  /* Emit the move of the address to a pseudo outside of the libcall.  */
1731
  if (TARGET_DIVIDE_CALL_TABLE)
1732
    {
1733
      /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1734
         that causes problems when the divide code is supposed to come from a
1735
         separate library.  Division by zero is undefined, so dividing 1 can be
1736
         implemented by comparing with the divisor.  */
1737
      if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1738
        {
1739
          rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1740
          emit_insn (gen_cstoresi4 (operands[0], test,
1741
                                    operands[1], operands[2]));
1742
          DONE;
1743
        }
1744
      else if (operands[2] == const0_rtx)
1745
        {
1746
          emit_move_insn (operands[0], operands[2]);
1747
          DONE;
1748
        }
1749
      function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1750
      last = gen_udivsi3_i4_int (operands[0], operands[3]);
1751
    }
1752
  else if (TARGET_DIVIDE_CALL_FP)
1753
    {
1754
      function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1755
      if (TARGET_FPU_SINGLE)
1756
        last = gen_udivsi3_i4_single (operands[0], operands[3]);
1757
      else
1758
        last = gen_udivsi3_i4 (operands[0], operands[3]);
1759
    }
1760
  else if (TARGET_SHMEDIA_FPU)
1761
    {
1762
      operands[1] = force_reg (SImode, operands[1]);
1763
      operands[2] = force_reg (SImode, operands[2]);
1764
      emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1765
      DONE;
1766
    }
1767
  else if (TARGET_SH2A)
1768
    {
1769
      operands[1] = force_reg (SImode, operands[1]);
1770
      operands[2] = force_reg (SImode, operands[2]);
1771
      emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1772
      DONE;
1773
    }
1774
  else if (TARGET_SH5)
1775
    {
1776
      function_symbol (operands[3],
1777
                       TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1778
                       SFUNC_STATIC);
1779
 
1780
      if (TARGET_SHMEDIA)
1781
        last = gen_udivsi3_i1_media (operands[0], operands[3]);
1782
      else if (TARGET_FPU_ANY)
1783
        last = gen_udivsi3_i4_single (operands[0], operands[3]);
1784
      else
1785
        last = gen_udivsi3_i1 (operands[0], operands[3]);
1786
    }
1787
  else
1788
    {
1789
      function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1790
      last = gen_udivsi3_i1 (operands[0], operands[3]);
1791
    }
1792
  emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1793
  emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1794
  emit_insn (last);
1795
  DONE;
1796
}")
1797
 
1798
(define_insn "divsi3_sh2a"
1799
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1800
        (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1801
                (match_operand:SI 2 "arith_reg_operand" "z")))]
1802
  "TARGET_SH2A"
1803
  "divs %2,%1"
1804
  [(set_attr "type" "arith")
1805
   (set_attr "in_delay_slot" "no")])
1806
 
1807
(define_insn "divsi3_i1"
1808
  [(set (match_operand:SI 0 "register_operand" "=z")
1809
        (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1810
   (clobber (reg:SI T_REG))
1811
   (clobber (reg:SI PR_REG))
1812
   (clobber (reg:SI R1_REG))
1813
   (clobber (reg:SI R2_REG))
1814
   (clobber (reg:SI R3_REG))
1815
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1816
  "TARGET_SH1 && ! TARGET_SH4"
1817
  "jsr  @%1%#"
1818
  [(set_attr "type" "sfunc")
1819
   (set_attr "needs_delay_slot" "yes")])
1820
 
1821
(define_insn "divsi3_i1_media"
1822
  [(set (match_operand:SI 0 "register_operand" "=z")
1823
        (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1824
   (clobber (reg:SI T_MEDIA_REG))
1825
   (clobber (reg:SI PR_MEDIA_REG))
1826
   (clobber (reg:SI R1_REG))
1827
   (clobber (reg:SI R20_REG))
1828
   (clobber (reg:SI R21_REG))
1829
   (clobber (reg:SI TR0_REG))
1830
   (use (match_operand 1 "target_reg_operand" "b"))]
1831
  "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1832
  "blink        %1, r18"
1833
  [(set_attr "type" "sfunc")])
1834
 
1835
(define_insn "divsi3_media_2"
1836
  [(set (match_operand:SI 0 "register_operand" "=z")
1837
        (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1838
   (clobber (reg:SI T_MEDIA_REG))
1839
   (clobber (reg:SI PR_MEDIA_REG))
1840
   (clobber (reg:SI R1_REG))
1841
   (clobber (reg:SI R21_REG))
1842
   (clobber (reg:SI TR0_REG))
1843
   (use (reg:SI R20_REG))
1844
   (use (match_operand 1 "target_reg_operand" "b"))]
1845
  "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1846
  "blink        %1, r18"
1847
  [(set_attr "type" "sfunc")])
1848
 
1849
;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1850
;; hard reg clobbers and data dependencies that we need when we want
1851
;; to rematerialize the division into a call.
1852
(define_insn_and_split "divsi_inv_call"
1853
  [(set (match_operand:SI 0 "register_operand" "=r")
1854
        (div:SI (match_operand:SI 1 "register_operand" "r")
1855
                (match_operand:SI 2 "register_operand" "r")))
1856
   (clobber (reg:SI R4_REG))
1857
   (clobber (reg:SI R5_REG))
1858
   (clobber (reg:SI T_MEDIA_REG))
1859
   (clobber (reg:SI PR_MEDIA_REG))
1860
   (clobber (reg:SI R1_REG))
1861
   (clobber (reg:SI R21_REG))
1862
   (clobber (reg:SI TR0_REG))
1863
   (clobber (reg:SI R20_REG))
1864
   (use (match_operand:SI 3 "register_operand" "r"))]
1865
  "TARGET_SHMEDIA"
1866
  "#"
1867
  "&& (high_life_started || reload_completed)"
1868
  [(set (match_dup 0) (match_dup 3))]
1869
  ""
1870
  [(set_attr "highpart" "must_split")])
1871
 
1872
;; This is the combiner pattern for -mdiv=inv:call .
1873
(define_insn_and_split "*divsi_inv_call_combine"
1874
  [(set (match_operand:SI 0 "register_operand" "=z")
1875
        (div:SI (match_operand:SI 1 "register_operand" "r")
1876
                (match_operand:SI 2 "register_operand" "r")))
1877
   (clobber (reg:SI R4_REG))
1878
   (clobber (reg:SI R5_REG))
1879
   (clobber (reg:SI T_MEDIA_REG))
1880
   (clobber (reg:SI PR_MEDIA_REG))
1881
   (clobber (reg:SI R1_REG))
1882
   (clobber (reg:SI R21_REG))
1883
   (clobber (reg:SI TR0_REG))
1884
   (clobber (reg:SI R20_REG))
1885
   (use (unspec:SI [(match_dup 1)
1886
                    (match_operand:SI 3 "" "")
1887
                    (unspec:SI [(match_operand:SI 4 "" "")
1888
                                (match_dup 3)
1889
                                (match_operand:DI 5 "" "")]
1890
                     UNSPEC_DIV_INV_M2)
1891
                    (match_operand:DI 6 "" "")
1892
                    (const_int 0)
1893
                    (const_int 0)]
1894
         UNSPEC_DIV_INV_M3))]
1895
  "TARGET_SHMEDIA"
1896
  "#"
1897
  "&& (high_life_started || reload_completed)"
1898
  [(pc)]
1899
  "
1900
{
1901
  const char *name = sh_divsi3_libfunc;
1902
  enum sh_function_kind kind = SFUNC_GOT;
1903
  rtx sym;
1904
 
1905
  emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1906
  emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1907
  while (TARGET_DIVIDE_INV_CALL2)
1908
    {
1909
      rtx x = operands[3];
1910
 
1911
      if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1912
        break;
1913
      x = XVECEXP (x, 0, 0);
1914
      name = \"__sdivsi3_2\";
1915
      kind = SFUNC_STATIC;
1916
      emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1917
      break;
1918
    }
1919
  sym = function_symbol (NULL, name, kind);
1920
  emit_insn (gen_divsi3_media_2 (operands[0], sym));
1921
  DONE;
1922
}"
1923
  [(set_attr "highpart" "must_split")])
1924
 
1925
(define_expand "divsi3_i4_media"
1926
  [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1927
   (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1928
   (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1929
   (set (match_operand:SI 0 "register_operand" "=r")
1930
        (fix:SI (match_dup 5)))]
1931
  "TARGET_SHMEDIA_FPU"
1932
  "
1933
{
1934
  operands[3] = gen_reg_rtx (DFmode);
1935
  operands[4] = gen_reg_rtx (DFmode);
1936
  operands[5] = gen_reg_rtx (DFmode);
1937
}")
1938
 
1939
(define_insn "divsi3_i4"
1940
  [(set (match_operand:SI 0 "register_operand" "=y")
1941
        (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1942
   (clobber (reg:SI PR_REG))
1943
   (clobber (reg:DF DR0_REG))
1944
   (clobber (reg:DF DR2_REG))
1945
   (use (reg:PSI FPSCR_REG))
1946
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1947
  "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1948
  "jsr  @%1%#"
1949
  [(set_attr "type" "sfunc")
1950
   (set_attr "fp_mode" "double")
1951
   (set_attr "needs_delay_slot" "yes")])
1952
 
1953
(define_insn "divsi3_i4_single"
1954
  [(set (match_operand:SI 0 "register_operand" "=y")
1955
        (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1956
   (clobber (reg:SI PR_REG))
1957
   (clobber (reg:DF DR0_REG))
1958
   (clobber (reg:DF DR2_REG))
1959
   (clobber (reg:SI R2_REG))
1960
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1961
  "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1962
  "jsr  @%1%#"
1963
  [(set_attr "type" "sfunc")
1964
   (set_attr "needs_delay_slot" "yes")])
1965
 
1966
(define_insn "divsi3_i4_int"
1967
  [(set (match_operand:SI 0 "register_operand" "=z")
1968
        (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1969
   (clobber (reg:SI T_REG))
1970
   (clobber (reg:SI PR_REG))
1971
   (clobber (reg:SI R1_REG))
1972
   (clobber (reg:SI MACH_REG))
1973
   (clobber (reg:SI MACL_REG))
1974
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1975
  "TARGET_SH1"
1976
  "jsr  @%1%#"
1977
  [(set_attr "type" "sfunc")
1978
   (set_attr "needs_delay_slot" "yes")])
1979
 
1980
(define_expand "divsi3"
1981
  [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1982
   (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1983
   (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1984
   (parallel [(set (match_operand:SI 0 "register_operand" "")
1985
                   (div:SI (reg:SI R4_REG)
1986
                           (reg:SI R5_REG)))
1987
              (clobber (reg:SI T_REG))
1988
              (clobber (reg:SI PR_REG))
1989
              (clobber (reg:SI R1_REG))
1990
              (clobber (reg:SI R2_REG))
1991
              (clobber (reg:SI R3_REG))
1992
              (use (match_dup 3))])]
1993
  ""
1994
  "
1995
{
1996
  rtx last;
1997
 
1998
  operands[3] = gen_reg_rtx (Pmode);
1999
  /* Emit the move of the address to a pseudo outside of the libcall.  */
2000
  if (TARGET_DIVIDE_CALL_TABLE)
2001
    {
2002
      function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2003
      last = gen_divsi3_i4_int (operands[0], operands[3]);
2004
    }
2005
  else if (TARGET_DIVIDE_CALL_FP)
2006
    {
2007
      function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2008
      if (TARGET_FPU_SINGLE)
2009
        last = gen_divsi3_i4_single (operands[0], operands[3]);
2010
      else
2011
        last = gen_divsi3_i4 (operands[0], operands[3]);
2012
    }
2013
  else if (TARGET_SH2A)
2014
    {
2015
      operands[1] = force_reg (SImode, operands[1]);
2016
      operands[2] = force_reg (SImode, operands[2]);
2017
      emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2018
      DONE;
2019
    }
2020
  else if (TARGET_DIVIDE_INV)
2021
    {
2022
      rtx dividend = operands[1];
2023
      rtx divisor = operands[2];
2024
      rtx tab_base;
2025
      rtx nsb_res = gen_reg_rtx (DImode);
2026
      rtx norm64 = gen_reg_rtx (DImode);
2027
      rtx tab_ix = gen_reg_rtx (DImode);
2028
      rtx norm32 = gen_reg_rtx (SImode);
2029
      rtx i92 = force_reg (DImode, GEN_INT (92));
2030
      rtx scratch0a = gen_reg_rtx (DImode);
2031
      rtx scratch0b = gen_reg_rtx (DImode);
2032
      rtx inv0 = gen_reg_rtx (SImode);
2033
      rtx scratch1a = gen_reg_rtx (DImode);
2034
      rtx scratch1b = gen_reg_rtx (DImode);
2035
      rtx shift = gen_reg_rtx (DImode);
2036
      rtx i2p27, i43;
2037
      rtx inv1 = gen_reg_rtx (SImode);
2038
      rtx scratch2a = gen_reg_rtx (DImode);
2039
      rtx scratch2b = gen_reg_rtx (SImode);
2040
      rtx inv2 = gen_reg_rtx (SImode);
2041
      rtx scratch3a = gen_reg_rtx (DImode);
2042
      rtx scratch3b = gen_reg_rtx (DImode);
2043
      rtx scratch3c = gen_reg_rtx (DImode);
2044
      rtx scratch3d = gen_reg_rtx (SImode);
2045
      rtx scratch3e = gen_reg_rtx (DImode);
2046
      rtx result = gen_reg_rtx (SImode);
2047
 
2048
      if (! arith_reg_or_0_operand (dividend, SImode))
2049
        dividend = force_reg (SImode, dividend);
2050
      if (! arith_reg_operand (divisor, SImode))
2051
        divisor = force_reg (SImode, divisor);
2052
      if (flag_pic && Pmode != DImode)
2053
        {
2054
          tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2055
          tab_base = gen_datalabel_ref (tab_base);
2056
          tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2057
        }
2058
      else
2059
        {
2060
          tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2061
          tab_base = gen_datalabel_ref (tab_base);
2062
          tab_base = force_reg (DImode, tab_base);
2063
        }
2064
      if (TARGET_DIVIDE_INV20U)
2065
        i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2066
      else
2067
        i2p27 = GEN_INT (0);
2068
      if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2069
        i43 = force_reg (DImode, GEN_INT (43));
2070
      else
2071
        i43 = GEN_INT (0);
2072
      emit_insn (gen_nsbdi (nsb_res,
2073
                            simplify_gen_subreg (DImode, divisor, SImode, 0)));
2074
      emit_insn (gen_ashldi3_media (norm64,
2075
                                    gen_rtx_SUBREG (DImode, divisor, 0),
2076
                                    nsb_res));
2077
      emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2078
      emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2079
      emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2080
                                   inv0, scratch0a, scratch0b,
2081
                                   scratch1a, scratch1b));
2082
      emit_insn (gen_subdi3 (shift, i92, nsb_res));
2083
      emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2084
                                   scratch2a));
2085
      emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2086
                                   i2p27, i43,
2087
                                   scratch3a, scratch3b, scratch3c,
2088
                                   scratch2a, scratch2b, scratch3d, scratch3e));
2089
      if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2090
        emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2091
      else if (TARGET_DIVIDE_INV_FP)
2092
        emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2093
                                     gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2094
                                     gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2095
                                     gen_reg_rtx (DFmode)));
2096
      else
2097
        emit_move_insn (operands[0], result);
2098
      DONE;
2099
    }
2100
  else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2101
    {
2102
      operands[1] = force_reg (SImode, operands[1]);
2103
      operands[2] = force_reg (SImode, operands[2]);
2104
      emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2105
      DONE;
2106
    }
2107
  else if (TARGET_SH5)
2108
    {
2109
      if (TARGET_DIVIDE_CALL2)
2110
        {
2111
          rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2112
          tab_base = gen_datalabel_ref (tab_base);
2113
          emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2114
        }
2115
      if (TARGET_FPU_ANY && TARGET_SH1)
2116
        function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2117
      else if (TARGET_DIVIDE_CALL2)
2118
        function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2119
      else
2120
        function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2121
 
2122
      if (TARGET_SHMEDIA)
2123
        last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2124
                (operands[0], operands[3]));
2125
      else if (TARGET_FPU_ANY)
2126
        last = gen_divsi3_i4_single (operands[0], operands[3]);
2127
      else
2128
        last = gen_divsi3_i1 (operands[0], operands[3]);
2129
    }
2130
  else
2131
    {
2132
      function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2133
      last = gen_divsi3_i1 (operands[0], operands[3]);
2134
    }
2135
  emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2136
  emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2137
  emit_insn (last);
2138
  DONE;
2139
}")
2140
 
2141
;; operands: scratch, tab_base, tab_ix
2142
;; These are unspecs because we could generate an indexed addressing mode
2143
;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2144
;; confuse reload.  See PR27117.
2145
 
2146
(define_insn "divsi_inv_qitable"
2147
  [(set (match_operand:DI 0 "register_operand" "=r")
2148
        (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2149
                                    (match_operand:DI 2 "register_operand" "r")]
2150
                         UNSPEC_DIV_INV_TABLE)))]
2151
  "TARGET_SHMEDIA"
2152
  "@
2153
        ldx.ub  %1, %2, %0"
2154
  [(set_attr "type" "load_media")
2155
   (set_attr "highpart" "user")])
2156
 
2157
;; operands: scratch, tab_base, tab_ix
2158
(define_insn "divsi_inv_hitable"
2159
  [(set (match_operand:DI 0 "register_operand" "=r")
2160
        (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2161
                                    (match_operand:DI 2 "register_operand" "r")]
2162
                         UNSPEC_DIV_INV_TABLE)))]
2163
  "TARGET_SHMEDIA"
2164
  "@
2165
        ldx.w   %1, %2, %0"
2166
  [(set_attr "type" "load_media")
2167
   (set_attr "highpart" "user")])
2168
 
2169
;; operands: inv0, tab_base, tab_ix, norm32
2170
;; scratch equiv in sdivsi3_2: r19, r21
2171
(define_expand "divsi_inv_m0"
2172
  [(set (match_operand:SI 0 "register_operand" "=r")
2173
        (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2174
                    (match_operand:DI 2 "register_operand" "r")
2175
                    (match_operand:SI 3 "register_operand" "r")]
2176
         UNSPEC_DIV_INV_M0))
2177
   (clobber (match_operand:DI 4 "register_operand" "=r"))
2178
   (clobber (match_operand:DI 5 "register_operand" "=r"))]
2179
  "TARGET_SHMEDIA"
2180
  "
2181
{
2182
/*
2183
tab_base: r20
2184
tab_ix: r21
2185
norm32: r25
2186
 ldx.ub r20, r21, r19 // u0.8
2187
 shlli r21, 1, r21
2188
 muls.l r25, r19, r19 // s2.38
2189
 ldx.w r20, r21, r21  // s2.14
2190
 shari r19, 24, r19   // truncate to s2.14
2191
 sub r21, r19, r19    // some 11 bit inverse in s1.14
2192
*/
2193
 
2194
  rtx inv0 = operands[0];
2195
  rtx tab_base = operands[1];
2196
  rtx tab_ix = operands[2];
2197
  rtx norm32 = operands[3];
2198
  rtx scratch0 = operands[4];
2199
  rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2200
  rtx scratch1 = operands[5];
2201
 
2202
  emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2203
  emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2204
  emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2205
  emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2206
  emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2207
  emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2208
  DONE;
2209
}")
2210
 
2211
;; operands: inv1, tab_base, tab_ix, norm32
2212
(define_insn_and_split "divsi_inv_m1"
2213
  [(set (match_operand:SI 0 "register_operand" "=r")
2214
        (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2215
                    (match_operand:DI 2 "register_operand" "r")
2216
                    (match_operand:SI 3 "register_operand" "r")]
2217
         UNSPEC_DIV_INV_M1))
2218
   (clobber (match_operand:SI 4 "register_operand" "=r"))
2219
   (clobber (match_operand:DI 5 "register_operand" "=r"))
2220
   (clobber (match_operand:DI 6 "register_operand" "=r"))
2221
   (clobber (match_operand:DI 7 "register_operand" "=r"))
2222
   (clobber (match_operand:DI 8 "register_operand" "=r"))]
2223
  "TARGET_SHMEDIA"
2224
  "#"
2225
  "&& !can_create_pseudo_p ()"
2226
  [(pc)]
2227
  "
2228
{
2229
/* inv0: r19
2230
 muls.l r19, r19, r18 // u0.28
2231
 muls.l r25, r18, r18 // s2.58
2232
 shlli r19, 45, r0    // multiply by two and convert to s2.58
2233
 sub r0, r18, r18
2234
 shari r18, 28, r18   // some 18 bit inverse in s1.30
2235
*/
2236
 
2237
  rtx inv1 = operands[0];
2238
  rtx tab_base = operands[1];
2239
  rtx tab_ix = operands[2];
2240
  rtx norm32 = operands[3];
2241
  rtx inv0 = operands[4];
2242
  rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2243
  rtx scratch0a = operands[5];
2244
  rtx scratch0b = operands[6];
2245
  rtx scratch0 = operands[7];
2246
  rtx scratch1 = operands[8];
2247
  rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2248
 
2249
  emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2250
                               scratch0a, scratch0b));
2251
  emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2252
  emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2253
  emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2254
  emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2255
  emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2256
  DONE;
2257
}")
2258
 
2259
;; operands: inv2, norm32, inv1, i92
2260
(define_insn_and_split "divsi_inv_m2"
2261
  [(set (match_operand:SI 0 "register_operand" "=r")
2262
        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2263
                    (match_operand:SI 2 "register_operand" "r")
2264
                    (match_operand:DI 3 "register_operand" "r")]
2265
         UNSPEC_DIV_INV_M2))
2266
   (clobber (match_operand:DI 4 "register_operand" "=r"))]
2267
  "TARGET_SHMEDIA"
2268
  "#"
2269
  "&& !can_create_pseudo_p ()"
2270
  [(pc)]
2271
  "
2272
{
2273
/*
2274
 muls.l r18, r25, r0  // s2.60
2275
 shari r0, 16, r0     // s-16.44
2276
  sub
2277
 muls.l r0, r18, r19  // s-16.74
2278
 shari r19, 30, r19   // s-16.44
2279
*/
2280
  rtx inv2 = operands[0];
2281
  rtx norm32 = operands[1];
2282
  rtx inv1 = operands[2];
2283
  rtx i92 = operands[3];
2284
  rtx scratch0 = operands[4];
2285
  rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2286
 
2287
  emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2288
  emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2289
  emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2290
  emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2291
  emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2292
  DONE;
2293
}")
2294
 
2295
(define_insn_and_split "divsi_inv_m3"
2296
  [(set (match_operand:SI 0 "register_operand" "=r")
2297
        (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2298
                    (match_operand:SI 2 "register_operand" "r")
2299
                    (match_operand:SI 3 "register_operand" "r")
2300
                    (match_operand:DI 4 "register_operand" "r")
2301
                    (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2302
                    (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2303
         UNSPEC_DIV_INV_M3))
2304
   (clobber (match_operand:DI 7 "register_operand" "=r"))
2305
   (clobber (match_operand:DI 8 "register_operand" "=r"))
2306
   (clobber (match_operand:DI 9 "register_operand" "=r"))
2307
   (clobber (match_operand:DI 10 "register_operand" "=r"))
2308
   (clobber (match_operand:SI 11 "register_operand" "=r"))
2309
   (clobber (match_operand:SI 12 "register_operand" "=r"))
2310
   (clobber (match_operand:DI 13 "register_operand" "=r"))]
2311
  "TARGET_SHMEDIA"
2312
  "#"
2313
  "&& !can_create_pseudo_p ()"
2314
  [(pc)]
2315
  "
2316
{
2317
/*
2318
  r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2319
  r0: scratch0  r19: scratch1 r21: scratch2
2320
 
2321
  muls.l r18, r4, r25 // s32.30
2322
 muls.l r19, r4, r19  // s15.30
2323
 shari r25, 63, r21
2324
  shari r19, 14, r19  // s18.-14
2325
 sub r25, r19, r0
2326
 shard r0, r1, r0
2327
 sub r0, r21, r0
2328
*/
2329
 
2330
  rtx result = operands[0];
2331
  rtx dividend = operands[1];
2332
  rtx inv1 = operands[2];
2333
  rtx inv2 = operands[3];
2334
  rtx shift = operands[4];
2335
  rtx scratch0 = operands[7];
2336
  rtx scratch1 = operands[8];
2337
  rtx scratch2 = operands[9];
2338
 
2339
  if (satisfies_constraint_N (dividend))
2340
    {
2341
      emit_move_insn (result, dividend);
2342
      DONE;
2343
    }
2344
 
2345
  emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2346
  emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2347
  emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2348
  emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2349
  emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2350
  emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2351
  emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2352
  DONE;
2353
}")
2354
 
2355
;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2356
;; inv1: tab_base, tab_ix, norm32
2357
;; inv2: norm32, inv1, i92
2358
(define_insn_and_split "divsi_inv_m1_3"
2359
  [(set (match_operand:SI 0 "register_operand" "=r")
2360
        (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2361
                    (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2362
                                (match_operand:DI 3 "register_operand" "r")
2363
                                (match_operand:SI 4 "register_operand" "r")]
2364
                     UNSPEC_DIV_INV_M1)
2365
                    (unspec:SI [(match_dup 4)
2366
                                (unspec:SI [(match_dup 2)
2367
                                            (match_dup 3)
2368
                                            (match_dup 4)] UNSPEC_DIV_INV_M1)
2369
                                (match_operand:SI 5 "" "")]
2370
                     UNSPEC_DIV_INV_M2)
2371
                    (match_operand:DI 6 "register_operand" "r")
2372
                    (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2373
                    (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2374
         UNSPEC_DIV_INV_M3))
2375
   (clobber (match_operand:DI 9 "register_operand" "=r"))
2376
   (clobber (match_operand:DI 10 "register_operand" "=r"))
2377
   (clobber (match_operand:DI 11 "register_operand" "=r"))
2378
   (clobber (match_operand:DI 12 "register_operand" "=r"))
2379
   (clobber (match_operand:SI 13 "register_operand" "=r"))
2380
   (clobber (match_operand:SI 14 "register_operand" "=r"))
2381
   (clobber (match_operand:DI 15 "register_operand" "=r"))]
2382
  "TARGET_SHMEDIA
2383
   && (TARGET_DIVIDE_INV_MINLAT
2384
       || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2385
  "#"
2386
  "&& !can_create_pseudo_p ()"
2387
  [(pc)]
2388
  "
2389
{
2390
  rtx result = operands[0];
2391
  rtx dividend = operands[1];
2392
  rtx tab_base = operands[2];
2393
  rtx tab_ix = operands[3];
2394
  rtx norm32 = operands[4];
2395
  /* rtx i92 = operands[5]; */
2396
  rtx shift = operands[6];
2397
  rtx i2p27 = operands[7];
2398
  rtx i43 = operands[8];
2399
  rtx scratch0 = operands[9];
2400
  rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2401
  rtx scratch1 = operands[10];
2402
  rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2403
  rtx scratch2 = operands[11];
2404
  rtx scratch3 = operands[12];
2405
  rtx scratch4 = operands[13];
2406
  rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2407
  rtx scratch5 = operands[14];
2408
  rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2409
  rtx scratch6 = operands[15];
2410
 
2411
  emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2412
                               scratch0, scratch1));
2413
  /* inv0 == scratch4 */
2414
  if (! TARGET_DIVIDE_INV20U)
2415
    {
2416
      emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2417
      i2p27 = scratch0;
2418
      emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2419
    }
2420
  else
2421
    {
2422
      emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2423
      emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2424
    }
2425
  emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2426
  emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2427
  emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2428
  /* inv1 == scratch4 */
2429
 
2430
  if (TARGET_DIVIDE_INV_MINLAT)
2431
    {
2432
      emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2433
      emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2434
      emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2435
      emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2436
      emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2437
      emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2438
      emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2439
      emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2440
      emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2441
      emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2442
      emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2443
    }
2444
  else
2445
    {
2446
      rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2447
      /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2448
      emit_insn (gen_nsbdi (scratch6,
2449
                            simplify_gen_subreg (DImode, dividend, SImode, 0)));
2450
      emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2451
      emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2452
      emit_insn (gen_divsi_inv20 (scratch2,
2453
                                  norm32, scratch4, dividend,
2454
                                  scratch6, scratch3, i43,
2455
                                  /* scratch0 may be shared with i2p27.  */
2456
                                  scratch0, scratch1, scratch5,
2457
                                  label, label, i2p27));
2458
    }
2459
  emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2460
  emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2461
  DONE;
2462
}")
2463
 
2464
(define_insn "divsi_inv20"
2465
  [(set (match_operand:DI 0 "register_operand" "=&r")
2466
        (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2467
                    (match_operand:SI 2 "register_operand" "r")
2468
                    (match_operand:SI 3 "register_operand" "r")
2469
                    (match_operand:DI 4 "register_operand" "r")
2470
                    (match_operand:DI 5 "register_operand" "r")
2471
                    (match_operand:DI 6 "register_operand" "r")
2472
                    (match_operand:DI 12 "register_operand" "r")
2473
                    (match_operand 10 "target_operand" "b")
2474
                    (match_operand 11 "immediate_operand" "i")]
2475
         UNSPEC_DIV_INV20))
2476
   (clobber (match_operand:DI 7 "register_operand" "=&r"))
2477
   (clobber (match_operand:DI 8 "register_operand" "=&r"))
2478
   (clobber (match_operand:SI 9 "register_operand" "=r"))]
2479
  "TARGET_SHMEDIA
2480
   && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2481
  "*
2482
{
2483
/* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2484
             %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2485
             %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2486
             %10 label (tr), %11 label (imm)
2487
 
2488
 muls.l inv1, norm32, scratch0  // s2.60
2489
  muls.l inv1, dividend, result // s32.30
2490
  xor i2p27, result_sign, round_scratch
2491
 bge/u dividend_nsb, i43, tr.. (label)
2492
 shari scratch0, 16, scratch0   // s-16.44
2493
 muls.l sratch0_si, inv1, scratch0 // s-16.74
2494
  sub result, round_scratch, result
2495
  shari dividend, 14, scratch1   // s19.-14
2496
 shari scratch0, 30, scratch0   // s-16.44
2497
 muls.l scratch0, scratch1, round_scratch // s15.30
2498
label:
2499
 sub result, round_scratch, result */
2500
 
2501
  int likely = TARGET_DIVIDE_INV20L;
2502
 
2503
  if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2504
  output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2505
  output_asm_insn (likely
2506
                   ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2507
                   : \"bge/u\t%4, %6, %10\", operands);
2508
  output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2509
  if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2510
  output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2511
  return (likely
2512
          ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2513
          : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2514
}")
2515
 
2516
(define_insn_and_split "divsi_inv_fp"
2517
  [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2518
        (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2519
                (match_operand:SI 2 "register_operand" "rf")))
2520
   (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2521
   (clobber (match_operand:SI 4 "register_operand" "=r"))
2522
   (clobber (match_operand:SI 5 "register_operand" "=r"))
2523
   (clobber (match_operand:DF 6 "register_operand" "=r"))
2524
   (clobber (match_operand:DF 7 "register_operand" "=r"))
2525
   (clobber (match_operand:DF 8 "register_operand" "=r"))]
2526
  "TARGET_SHMEDIA_FPU"
2527
  "#"
2528
  "&& (high_life_started || reload_completed)"
2529
  [(set (match_dup 0) (match_dup 3))]
2530
  ""
2531
  [(set_attr "highpart" "must_split")])
2532
 
2533
;; If a matching group of divide-by-inverse instructions is in the same
2534
;; basic block after gcse & loop optimizations, we want to transform them
2535
;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2536
(define_insn_and_split "*divsi_inv_fp_combine"
2537
  [(set (match_operand:SI 0 "register_operand" "=f")
2538
        (div:SI (match_operand:SI 1 "register_operand" "f")
2539
                (match_operand:SI 2 "register_operand" "f")))
2540
   (use (unspec:SI [(match_dup 1)
2541
                    (match_operand:SI 3 "" "")
2542
                    (unspec:SI [(match_operand:SI 4 "" "")
2543
                                (match_dup 3)
2544
                                (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2545
                    (match_operand:DI 6 "" "")
2546
                    (const_int 0)
2547
                    (const_int 0)] UNSPEC_DIV_INV_M3))
2548
   (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2549
   (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2550
   (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2551
   (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2552
   (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2553
  "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2554
  "#"
2555
  "&& 1"
2556
  [(set (match_dup 9) (float:DF (match_dup 1)))
2557
   (set (match_dup 10) (float:DF (match_dup 2)))
2558
   (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2559
   (set (match_dup 8)
2560
        (fix:SI (match_dup 11)))
2561
   (set (match_dup 0) (match_dup 8))]
2562
  "
2563
{
2564
  if (! fp_arith_reg_operand (operands[1], SImode))
2565
    {
2566
      emit_move_insn (operands[7], operands[1]);
2567
      operands[1] = operands[7];
2568
    }
2569
  if (! fp_arith_reg_operand (operands[2], SImode))
2570
    {
2571
      emit_move_insn (operands[8], operands[2]);
2572
      operands[2] = operands[8];
2573
    }
2574
}"
2575
  [(set_attr "highpart" "must_split")])
2576
 
2577
;; -------------------------------------------------------------------------
2578
;; Multiplication instructions
2579
;; -------------------------------------------------------------------------
2580
 
2581
(define_insn "umulhisi3_i"
2582
  [(set (reg:SI MACL_REG)
2583
        (mult:SI (zero_extend:SI
2584
                  (match_operand:HI 0 "arith_reg_operand" "r"))
2585
                 (zero_extend:SI
2586
                  (match_operand:HI 1 "arith_reg_operand" "r"))))]
2587
  "TARGET_SH1"
2588
  "mulu.w       %1,%0"
2589
  [(set_attr "type" "smpy")])
2590
 
2591
(define_insn "mulhisi3_i"
2592
  [(set (reg:SI MACL_REG)
2593
        (mult:SI (sign_extend:SI
2594
                  (match_operand:HI 0 "arith_reg_operand" "r"))
2595
                 (sign_extend:SI
2596
                  (match_operand:HI 1 "arith_reg_operand" "r"))))]
2597
  "TARGET_SH1"
2598
  "muls.w       %1,%0"
2599
  [(set_attr "type" "smpy")])
2600
 
2601
(define_expand "mulhisi3"
2602
  [(set (reg:SI MACL_REG)
2603
        (mult:SI (sign_extend:SI
2604
                  (match_operand:HI 1 "arith_reg_operand" ""))
2605
                 (sign_extend:SI
2606
                  (match_operand:HI 2 "arith_reg_operand" ""))))
2607
   (set (match_operand:SI 0 "arith_reg_operand" "")
2608
        (reg:SI MACL_REG))]
2609
  "TARGET_SH1"
2610
  "
2611
{
2612
  rtx insn, macl;
2613
 
2614
  macl = gen_rtx_REG (SImode, MACL_REG);
2615
  start_sequence ();
2616
  emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2617
  insn = get_insns ();
2618
  end_sequence ();
2619
  /* expand_binop can't find a suitable code in umul_widen_optab to
2620
     make a REG_EQUAL note from, so make one here.
2621
     See also smulsi3_highpart.
2622
     ??? Alternatively, we could put this at the calling site of expand_binop,
2623
     i.e. expand_expr.  */
2624
  /* Use emit_libcall_block for loop invariant code motion and to make
2625
     a REG_EQUAL note.  */
2626
  emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2627
 
2628
  DONE;
2629
}")
2630
 
2631
(define_expand "umulhisi3"
2632
  [(set (reg:SI MACL_REG)
2633
        (mult:SI (zero_extend:SI
2634
                  (match_operand:HI 1 "arith_reg_operand" ""))
2635
                 (zero_extend:SI
2636
                  (match_operand:HI 2 "arith_reg_operand" ""))))
2637
   (set (match_operand:SI 0 "arith_reg_operand" "")
2638
        (reg:SI MACL_REG))]
2639
  "TARGET_SH1"
2640
  "
2641
{
2642
  rtx insn, macl;
2643
 
2644
  macl = gen_rtx_REG (SImode, MACL_REG);
2645
  start_sequence ();
2646
  emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2647
  insn = get_insns ();
2648
  end_sequence ();
2649
  /* expand_binop can't find a suitable code in umul_widen_optab to
2650
     make a REG_EQUAL note from, so make one here.
2651
     See also smulsi3_highpart.
2652
     ??? Alternatively, we could put this at the calling site of expand_binop,
2653
     i.e. expand_expr.  */
2654
  /* Use emit_libcall_block for loop invariant code motion and to make
2655
     a REG_EQUAL note.  */
2656
  emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2657
 
2658
  DONE;
2659
}")
2660
 
2661
;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2662
;; a call to a routine which clobbers known registers.
2663
 
2664
(define_insn ""
2665
  [(set (match_operand:SI 1 "register_operand" "=z")
2666
        (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2667
   (clobber (reg:SI MACL_REG))
2668
   (clobber (reg:SI T_REG))
2669
   (clobber (reg:SI PR_REG))
2670
   (clobber (reg:SI R3_REG))
2671
   (clobber (reg:SI R2_REG))
2672
   (clobber (reg:SI R1_REG))
2673
   (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2674
  "TARGET_SH1"
2675
  "jsr  @%0%#"
2676
  [(set_attr "type" "sfunc")
2677
   (set_attr "needs_delay_slot" "yes")])
2678
 
2679
(define_expand "mulsi3_call"
2680
  [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2681
   (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2682
   (parallel[(set (match_operand:SI 0 "register_operand" "")
2683
                  (mult:SI (reg:SI R4_REG)
2684
                           (reg:SI R5_REG)))
2685
             (clobber (reg:SI MACL_REG))
2686
             (clobber (reg:SI T_REG))
2687
             (clobber (reg:SI PR_REG))
2688
             (clobber (reg:SI R3_REG))
2689
             (clobber (reg:SI R2_REG))
2690
             (clobber (reg:SI R1_REG))
2691
             (use (match_operand:SI 3 "register_operand" ""))])]
2692
  "TARGET_SH1"
2693
  "")
2694
 
2695
(define_insn "mul_r"
2696
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2697
        (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2698
                 (match_operand:SI 2 "arith_reg_operand" "z")))]
2699
  "TARGET_SH2A"
2700
  "mulr %2,%0"
2701
  [(set_attr "type" "dmpy")])
2702
 
2703
(define_insn "mul_l"
2704
  [(set (reg:SI MACL_REG)
2705
        (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2706
                 (match_operand:SI 1 "arith_reg_operand" "r")))]
2707
  "TARGET_SH2"
2708
  "mul.l        %1,%0"
2709
  [(set_attr "type" "dmpy")])
2710
 
2711
(define_expand "mulsi3"
2712
  [(set (reg:SI MACL_REG)
2713
        (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2714
                  (match_operand:SI 2 "arith_reg_operand" "")))
2715
   (set (match_operand:SI 0 "arith_reg_operand" "")
2716
        (reg:SI MACL_REG))]
2717
  "TARGET_SH1"
2718
  "
2719
{
2720
  if (!TARGET_SH2)
2721
    {
2722
      /* The address must be set outside the libcall,
2723
         since it goes into a pseudo.  */
2724
      rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2725
      rtx addr = force_reg (SImode, sym);
2726
      rtx insns = gen_mulsi3_call (operands[0], operands[1],
2727
                                   operands[2], addr);
2728
      emit_insn (insns);
2729
    }
2730
  else
2731
    {
2732
      rtx macl = gen_rtx_REG (SImode, MACL_REG);
2733
 
2734
      emit_insn (gen_mul_l (operands[1], operands[2]));
2735
      /* consec_sets_giv can only recognize the first insn that sets a
2736
         giv as the giv insn.  So we must tag this also with a REG_EQUAL
2737
         note.  */
2738
      emit_insn (gen_movsi_i ((operands[0]), macl));
2739
    }
2740
  DONE;
2741
}")
2742
 
2743
(define_insn "mulsidi3_i"
2744
  [(set (reg:SI MACH_REG)
2745
        (truncate:SI
2746
         (lshiftrt:DI
2747
          (mult:DI
2748
           (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2749
           (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2750
          (const_int 32))))
2751
   (set (reg:SI MACL_REG)
2752
        (mult:SI (match_dup 0)
2753
                 (match_dup 1)))]
2754
  "TARGET_SH2"
2755
  "dmuls.l      %1,%0"
2756
  [(set_attr "type" "dmpy")])
2757
 
2758
(define_expand "mulsidi3"
2759
  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2760
        (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2761
                 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2762
  "TARGET_SH2 || TARGET_SHMEDIA"
2763
  "
2764
{
2765
  if (TARGET_SH2)
2766
    {
2767
       emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2768
                                        operands[2]));
2769
       DONE;
2770
    }
2771
}")
2772
 
2773
(define_insn "mulsidi3_media"
2774
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2775
        (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2776
                 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2777
  "TARGET_SHMEDIA"
2778
  "muls.l       %1, %2, %0"
2779
  [(set_attr "type" "dmpy_media")
2780
   (set_attr "highpart" "ignore")])
2781
 
2782
(define_insn "mulsidi3_compact"
2783
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2784
        (mult:DI
2785
         (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2786
         (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2787
   (clobber (reg:SI MACH_REG))
2788
   (clobber (reg:SI MACL_REG))]
2789
  "TARGET_SH2"
2790
  "#")
2791
 
2792
(define_split
2793
  [(set (match_operand:DI 0 "arith_reg_dest" "")
2794
        (mult:DI
2795
         (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2796
         (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2797
   (clobber (reg:SI MACH_REG))
2798
   (clobber (reg:SI MACL_REG))]
2799
  "TARGET_SH2"
2800
  [(const_int 0)]
2801
  "
2802
{
2803
  rtx low_dst = gen_lowpart (SImode, operands[0]);
2804
  rtx high_dst = gen_highpart (SImode, operands[0]);
2805
 
2806
  emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2807
 
2808
  emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2809
  emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2810
  /* We need something to tag the possible REG_EQUAL notes on to.  */
2811
  emit_move_insn (operands[0], operands[0]);
2812
  DONE;
2813
}")
2814
 
2815
(define_insn "umulsidi3_i"
2816
  [(set (reg:SI MACH_REG)
2817
        (truncate:SI
2818
         (lshiftrt:DI
2819
          (mult:DI
2820
           (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2821
           (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2822
          (const_int 32))))
2823
   (set (reg:SI MACL_REG)
2824
        (mult:SI (match_dup 0)
2825
                 (match_dup 1)))]
2826
  "TARGET_SH2"
2827
  "dmulu.l      %1,%0"
2828
  [(set_attr "type" "dmpy")])
2829
 
2830
(define_expand "umulsidi3"
2831
  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2832
        (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2833
                 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2834
  "TARGET_SH2 || TARGET_SHMEDIA"
2835
  "
2836
{
2837
  if (TARGET_SH2)
2838
    {
2839
       emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2840
                                         operands[2]));
2841
       DONE;
2842
    }
2843
}")
2844
 
2845
(define_insn "umulsidi3_media"
2846
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2847
        (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2848
                 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2849
  "TARGET_SHMEDIA"
2850
  "mulu.l       %1, %2, %0"
2851
  [(set_attr "type" "dmpy_media")
2852
   (set_attr "highpart" "ignore")])
2853
 
2854
(define_insn "umulsidi3_compact"
2855
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2856
        (mult:DI
2857
         (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2858
         (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2859
   (clobber (reg:SI MACH_REG))
2860
   (clobber (reg:SI MACL_REG))]
2861
  "TARGET_SH2"
2862
  "#")
2863
 
2864
(define_split
2865
  [(set (match_operand:DI 0 "arith_reg_dest" "")
2866
        (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2867
                 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2868
   (clobber (reg:SI MACH_REG))
2869
   (clobber (reg:SI MACL_REG))]
2870
  "TARGET_SH2"
2871
  [(const_int 0)]
2872
  "
2873
{
2874
  rtx low_dst = gen_lowpart (SImode, operands[0]);
2875
  rtx high_dst = gen_highpart (SImode, operands[0]);
2876
 
2877
  emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2878
 
2879
  emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2880
  emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2881
  /* We need something to tag the possible REG_EQUAL notes on to.  */
2882
  emit_move_insn (operands[0], operands[0]);
2883
  DONE;
2884
}")
2885
 
2886
(define_insn "smulsi3_highpart_i"
2887
  [(set (reg:SI MACH_REG)
2888
        (truncate:SI
2889
         (lshiftrt:DI
2890
          (mult:DI
2891
           (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2892
           (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2893
          (const_int 32))))
2894
   (clobber (reg:SI MACL_REG))]
2895
  "TARGET_SH2"
2896
  "dmuls.l      %1,%0"
2897
  [(set_attr "type" "dmpy")])
2898
 
2899
(define_expand "smulsi3_highpart"
2900
  [(parallel
2901
    [(set (reg:SI MACH_REG)
2902
          (truncate:SI
2903
           (lshiftrt:DI
2904
            (mult:DI
2905
             (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2906
             (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2907
            (const_int 32))))
2908
    (clobber (reg:SI MACL_REG))])
2909
   (set (match_operand:SI 0 "arith_reg_operand" "")
2910
        (reg:SI MACH_REG))]
2911
  "TARGET_SH2"
2912
  "
2913
{
2914
  rtx insn, mach;
2915
 
2916
  mach = gen_rtx_REG (SImode, MACH_REG);
2917
  start_sequence ();
2918
  emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2919
  insn = get_insns ();
2920
  end_sequence ();
2921
  /* expand_binop can't find a suitable code in mul_highpart_optab to
2922
     make a REG_EQUAL note from, so make one here.
2923
     See also {,u}mulhisi.
2924
     ??? Alternatively, we could put this at the calling site of expand_binop,
2925
     i.e. expand_mult_highpart.  */
2926
  /* Use emit_libcall_block for loop invariant code motion and to make
2927
     a REG_EQUAL note.  */
2928
  emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2929
 
2930
  DONE;
2931
}")
2932
 
2933
(define_insn "umulsi3_highpart_i"
2934
  [(set (reg:SI MACH_REG)
2935
        (truncate:SI
2936
         (lshiftrt:DI
2937
          (mult:DI
2938
           (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2939
           (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2940
          (const_int 32))))
2941
   (clobber (reg:SI MACL_REG))]
2942
  "TARGET_SH2"
2943
  "dmulu.l      %1,%0"
2944
  [(set_attr "type" "dmpy")])
2945
 
2946
(define_expand "umulsi3_highpart"
2947
  [(parallel
2948
    [(set (reg:SI MACH_REG)
2949
          (truncate:SI
2950
           (lshiftrt:DI
2951
            (mult:DI
2952
             (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2953
             (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2954
            (const_int 32))))
2955
    (clobber (reg:SI MACL_REG))])
2956
   (set (match_operand:SI 0 "arith_reg_operand" "")
2957
        (reg:SI MACH_REG))]
2958
  "TARGET_SH2"
2959
  "
2960
{
2961
  rtx insn, mach;
2962
 
2963
  mach = gen_rtx_REG (SImode, MACH_REG);
2964
  start_sequence ();
2965
  emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2966
  insn = get_insns ();
2967
  end_sequence ();
2968
  /* Use emit_libcall_block for loop invariant code motion and to make
2969
     a REG_EQUAL note.  */
2970
  emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2971
 
2972
  DONE;
2973
}")
2974
 
2975
(define_insn_and_split "muldi3"
2976
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2977
        (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2978
                 (match_operand:DI 2 "arith_reg_operand" "r")))
2979
   (clobber (match_scratch:DI 3 "=&r"))
2980
   (clobber (match_scratch:DI 4 "=r"))]
2981
  "TARGET_SHMEDIA"
2982
  "#"
2983
  "reload_completed"
2984
  [(const_int 0)]
2985
  "
2986
{
2987
  rtx op3_v2si, op2_v2si;
2988
 
2989
  op3_v2si = operands[3];
2990
  if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2991
    {
2992
      op3_v2si = XEXP (op3_v2si, 0);
2993
      op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2994
    }
2995
  op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2996
  op2_v2si = operands[2];
2997
  if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2998
    {
2999
      op2_v2si = XEXP (op2_v2si, 0);
3000
      op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3001
    }
3002
  op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3003
  emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3004
  emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3005
  emit_insn (gen_umulsidi3_media (operands[4],
3006
                                 sh_gen_truncate (SImode, operands[1], 0),
3007
                                 sh_gen_truncate (SImode, operands[2], 0)));
3008
  emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3009
  emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3010
  emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3011
  emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3012
  DONE;
3013
}")
3014
 
3015
 
3016
;; -------------------------------------------------------------------------
3017
;; Logical operations
3018
;; -------------------------------------------------------------------------
3019
 
3020
(define_insn "*andsi3_compact"
3021
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3022
        (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3023
                (match_operand:SI 2 "logical_operand" "r,K08")))]
3024
  "TARGET_SH1"
3025
  "and  %2,%0"
3026
  [(set_attr "type" "arith")])
3027
 
3028
(define_insn "*andsi3_media"
3029
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3030
        (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3031
                (match_operand:SI 2 "logical_operand" "r,I10")))]
3032
  "TARGET_SHMEDIA"
3033
  "@
3034
        and     %1, %2, %0
3035
        andi    %1, %2, %0"
3036
  [(set_attr "type" "arith_media")])
3037
 
3038
(define_insn "*andsi3_bclr"
3039
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3040
        (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3041
                (match_operand:SI 2 "const_int_operand" "Psz")))]
3042
  "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3043
  "bclr\\t%W2,%0"
3044
  [(set_attr "type" "arith")])
3045
 
3046
;; If the constant is 255, then emit an extu.b instruction instead of an
3047
;; and, since that will give better code.
3048
 
3049
(define_expand "andsi3"
3050
  [(set (match_operand:SI 0 "arith_reg_operand" "")
3051
        (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3052
                (match_operand:SI 2 "logical_operand" "")))]
3053
  ""
3054
  "
3055
{
3056
  if (TARGET_SH1
3057
      && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3058
    {
3059
      emit_insn (gen_zero_extendqisi2 (operands[0],
3060
                                       gen_lowpart (QImode, operands[1])));
3061
      DONE;
3062
    }
3063
}")
3064
 
3065
(define_insn_and_split "anddi3"
3066
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3067
        (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3068
                (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3069
  "TARGET_SHMEDIA"
3070
  "@
3071
        and     %1, %2, %0
3072
        andi    %1, %2, %0
3073
        #"
3074
  "reload_completed
3075
   && ! logical_operand (operands[2], DImode)"
3076
  [(const_int 0)]
3077
  "
3078
{
3079
  if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3080
    emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3081
  else
3082
    emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3083
  DONE;
3084
}"
3085
  [(set_attr "type" "arith_media")])
3086
 
3087
(define_insn "andcsi3"
3088
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3089
        (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3090
                (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3091
  "TARGET_SHMEDIA"
3092
  "andc %1,%2,%0"
3093
  [(set_attr "type" "arith_media")])
3094
 
3095
(define_insn "andcdi3"
3096
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3097
        (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3098
                (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3099
  "TARGET_SHMEDIA"
3100
  "andc %1,%2,%0"
3101
  [(set_attr "type" "arith_media")])
3102
 
3103
(define_expand "iorsi3"
3104
  [(set (match_operand:SI 0 "arith_reg_operand" "")
3105
        (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3106
                (match_operand:SI 2 "logical_operand" "")))]
3107
  ""
3108
  "")
3109
 
3110
(define_insn "*iorsi3_compact"
3111
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3112
        (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3113
                (match_operand:SI 2 "logical_operand" "r,K08")))]
3114
  "TARGET_SH1
3115
   && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3116
  "or   %2,%0"
3117
  [(set_attr "type" "arith")])
3118
 
3119
(define_insn "*iorsi3_media"
3120
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3121
        (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3122
                (match_operand:SI 2 "logical_operand" "r,I10")))]
3123
  "TARGET_SHMEDIA"
3124
  "@
3125
        or      %1, %2, %0
3126
        ori     %1, %2, %0"
3127
  [(set_attr "type" "arith_media")])
3128
 
3129
(define_insn "*iorsi3_bset"
3130
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3131
        (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3132
        (match_operand:SI 2 "const_int_operand" "Pso")))]
3133
  "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3134
  "bset\\t%V2,%0"
3135
  [(set_attr "type" "arith")])
3136
 
3137
(define_insn "iordi3"
3138
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3139
        (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3140
                (match_operand:DI 2 "logical_operand" "r,I10")))]
3141
  "TARGET_SHMEDIA"
3142
  "@
3143
        or      %1, %2, %0
3144
        ori     %1, %2, %0"
3145
  [(set_attr "type" "arith_media")])
3146
 
3147
(define_insn_and_split "*logical_sidi3"
3148
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3149
        (sign_extend:DI (match_operator:SI 3 "logical_operator"
3150
                          [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3151
                           (match_operand:SI 2 "logical_operand" "r,I10")])))]
3152
  "TARGET_SHMEDIA"
3153
  "#"
3154
  "&& reload_completed"
3155
  [(set (match_dup 0) (match_dup 3))]
3156
  "
3157
{
3158
  operands[3]
3159
    = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3160
                      simplify_gen_subreg (DImode, operands[1], SImode, 0),
3161
                      simplify_gen_subreg (DImode, operands[2], SImode, 0));
3162
}")
3163
 
3164
(define_insn_and_split "*logical_sidisi3"
3165
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3166
        (truncate:SI (sign_extend:DI
3167
                        (match_operator:SI 3 "logical_operator"
3168
                          [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3169
                           (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3170
  "TARGET_SHMEDIA"
3171
  "#"
3172
  "&& 1"
3173
  [(set (match_dup 0) (match_dup 3))])
3174
 
3175
(define_insn_and_split "*logical_sidi3_2"
3176
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3177
        (sign_extend:DI (truncate:SI (sign_extend:DI
3178
                        (match_operator:SI 3 "logical_operator"
3179
                          [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3180
                           (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3181
  "TARGET_SHMEDIA"
3182
  "#"
3183
  "&& 1"
3184
  [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3185
 
3186
(define_expand "xorsi3"
3187
  [(set (match_operand:SI 0 "arith_reg_operand" "")
3188
        (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3189
                (match_operand:SI 2 "xor_operand" "")))]
3190
  ""
3191
  "")
3192
 
3193
(define_insn "*xorsi3_compact"
3194
  [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3195
        (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3196
                (match_operand:SI 2 "logical_operand" "K08,r")))]
3197
  "TARGET_SH1"
3198
  "xor  %2,%0"
3199
  [(set_attr "type" "arith")])
3200
 
3201
(define_insn "*xorsi3_media"
3202
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3203
        (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3204
                (match_operand:SI 2 "xor_operand" "r,I06")))]
3205
  "TARGET_SHMEDIA"
3206
  "@
3207
        xor     %1, %2, %0
3208
        xori    %1, %2, %0"
3209
  [(set_attr "type" "arith_media")])
3210
 
3211
;; Store the complements of the T bit in a register.
3212
(define_insn "xorsi3_movrt"
3213
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3214
        (xor:SI (reg:SI T_REG)
3215
                (const_int 1)))]
3216
  "TARGET_SH2A"
3217
  "movrt\\t%0"
3218
  [(set_attr "type" "arith")])
3219
 
3220
(define_insn "xordi3"
3221
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3222
        (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3223
                (match_operand:DI 2 "xor_operand" "r,I06")))]
3224
  "TARGET_SHMEDIA"
3225
  "@
3226
        xor     %1, %2, %0
3227
        xori    %1, %2, %0"
3228
  [(set_attr "type" "arith_media")])
3229
 
3230
;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3231
;; converts 2 * sign extend -> logical op into logical op -> sign extend
3232
(define_split
3233
  [(set (match_operand:DI 0 "arith_reg_dest" "")
3234
        (sign_extend:DI (match_operator 4 "binary_logical_operator"
3235
                          [(match_operand 1 "any_register_operand" "")
3236
                           (match_operand 2 "any_register_operand" "")])))]
3237
  "TARGET_SHMEDIA"
3238
  [(set (match_dup 5) (match_dup 4))
3239
   (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3240
"
3241
{
3242
  enum machine_mode inmode = GET_MODE (operands[1]);
3243
  int offset = 0;
3244
 
3245
  if (GET_CODE (operands[0]) == SUBREG)
3246
    {
3247
      offset = SUBREG_BYTE (operands[0]);
3248
      operands[0] = SUBREG_REG (operands[0]);
3249
    }
3250
  gcc_assert (REG_P (operands[0]));
3251
  if (! TARGET_LITTLE_ENDIAN)
3252
    offset += 8 - GET_MODE_SIZE (inmode);
3253
  operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3254
}")
3255
 
3256
;; -------------------------------------------------------------------------
3257
;; Shifts and rotates
3258
;; -------------------------------------------------------------------------
3259
 
3260
(define_expand "rotldi3"
3261
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3262
        (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3263
                   (match_operand:HI 2 "mextr_bit_offset" "i")))]
3264
  "TARGET_SHMEDIA"
3265
  "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3266
 
3267
(define_insn "rotldi3_mextr"
3268
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3269
        (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3270
                   (match_operand:HI 2 "mextr_bit_offset" "i")))]
3271
  "TARGET_SHMEDIA"
3272
  "*
3273
{
3274
  static char templ[16];
3275
 
3276
  sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3277
           8 - (int) (INTVAL (operands[2]) >> 3));
3278
  return templ;
3279
}"
3280
  [(set_attr "type" "arith_media")])
3281
 
3282
(define_expand "rotrdi3"
3283
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3284
        (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3285
                     (match_operand:HI 2 "mextr_bit_offset" "i")))]
3286
  "TARGET_SHMEDIA"
3287
  "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3288
 
3289
(define_insn "rotrdi3_mextr"
3290
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3291
        (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3292
                     (match_operand:HI 2 "mextr_bit_offset" "i")))]
3293
  "TARGET_SHMEDIA"
3294
  "*
3295
{
3296
  static char templ[16];
3297
 
3298
  sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3299
  return templ;
3300
}"
3301
  [(set_attr "type" "arith_media")])
3302
 
3303
(define_split
3304
  [(set (match_operand:DI 0 "arith_reg_dest" "")
3305
        (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3306
                                         "ua_address_operand" "")))
3307
                (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3308
                           (const_int 8))))
3309
   (clobber (match_operand:DI 3 "register_operand" ""))]
3310
  "TARGET_SHMEDIA"
3311
  [(match_dup 4) (match_dup 5)]
3312
  "
3313
{
3314
  operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3315
                 (operands[3], operands[1]));
3316
  operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3317
                              GEN_INT (56), GEN_INT (8));
3318
}")
3319
 
3320
(define_insn "rotlsi3_1"
3321
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3322
        (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3323
                   (const_int 1)))
3324
   (set (reg:SI T_REG)
3325
        (lshiftrt:SI (match_dup 1) (const_int 31)))]
3326
  "TARGET_SH1"
3327
  "rotl %0"
3328
  [(set_attr "type" "arith")])
3329
 
3330
(define_insn "rotlsi3_31"
3331
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3332
        (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3333
                   (const_int 31)))
3334
   (clobber (reg:SI T_REG))]
3335
  "TARGET_SH1"
3336
  "rotr %0"
3337
  [(set_attr "type" "arith")])
3338
 
3339
(define_insn "rotlsi3_16"
3340
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3341
        (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3342
                   (const_int 16)))]
3343
  "TARGET_SH1"
3344
  "swap.w       %1,%0"
3345
  [(set_attr "type" "arith")])
3346
 
3347
(define_expand "rotlsi3"
3348
  [(set (match_operand:SI 0 "arith_reg_dest" "")
3349
        (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3350
                   (match_operand:SI 2 "immediate_operand" "")))]
3351
  "TARGET_SH1"
3352
  "
3353
{
3354
  static const char rot_tab[] = {
3355
    000, 000, 000, 000, 000, 000, 010, 001,
3356
    001, 001, 011, 013, 003, 003, 003, 003,
3357
    003, 003, 003, 003, 003, 013, 012, 002,
3358
    002, 002, 010, 000, 000, 000, 000, 000,
3359
  };
3360
 
3361
  int count, choice;
3362
 
3363
  if (!CONST_INT_P (operands[2]))
3364
    FAIL;
3365
  count = INTVAL (operands[2]);
3366
  choice = rot_tab[count];
3367
  if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3368
    FAIL;
3369
  choice &= 7;
3370
  switch (choice)
3371
    {
3372
    case 0:
3373
      emit_move_insn (operands[0], operands[1]);
3374
      count -= (count & 16) * 2;
3375
      break;
3376
    case 3:
3377
     emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3378
     count -= 16;
3379
     break;
3380
    case 1:
3381
    case 2:
3382
      {
3383
        rtx parts[2];
3384
        parts[0] = gen_reg_rtx (SImode);
3385
        parts[1] = gen_reg_rtx (SImode);
3386
        emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3387
        emit_move_insn (parts[choice-1], operands[1]);
3388
        emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3389
        emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3390
        emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3391
        count = (count & ~16) - 8;
3392
      }
3393
    }
3394
 
3395
  for (; count > 0; count--)
3396
    emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3397
  for (; count < 0; count++)
3398
    emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3399
 
3400
  DONE;
3401
}")
3402
 
3403
(define_insn "*rotlhi3_8"
3404
  [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3405
        (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3406
                   (const_int 8)))]
3407
  "TARGET_SH1"
3408
  "swap.b       %1,%0"
3409
  [(set_attr "type" "arith")])
3410
 
3411
(define_expand "rotlhi3"
3412
  [(set (match_operand:HI 0 "arith_reg_operand" "")
3413
        (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3414
                   (match_operand:HI 2 "immediate_operand" "")))]
3415
  "TARGET_SH1"
3416
  "
3417
{
3418
  if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3419
    FAIL;
3420
}")
3421
 
3422
;;
3423
;; shift left
3424
 
3425
(define_insn "ashlsi3_sh2a"
3426
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3427
        (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3428
                   (match_operand:SI 2 "arith_reg_operand" "r")))]
3429
  "TARGET_SH2A"
3430
  "shad %2,%0"
3431
  [(set_attr "type" "arith")
3432
   (set_attr "length" "4")])
3433
 
3434
;; This pattern is used by init_expmed for computing the costs of shift
3435
;; insns.
3436
 
3437
(define_insn_and_split "ashlsi3_std"
3438
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3439
        (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3440
                   (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3441
   (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3442
  "TARGET_SH3
3443
   || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3444
  "@
3445
   shld %2,%0
3446
   add  %0,%0
3447
   shll%O2      %0
3448
   #"
3449
  "TARGET_SH3
3450
   && reload_completed
3451
   && CONST_INT_P (operands[2])
3452
   && ! satisfies_constraint_P27 (operands[2])"
3453
  [(set (match_dup 3) (match_dup 2))
3454
   (parallel
3455
    [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3456
     (clobber (match_dup 4))])]
3457
  "operands[4] = gen_rtx_SCRATCH (SImode);"
3458
  [(set_attr "length" "*,*,*,4")
3459
   (set_attr "type" "dyn_shift,arith,arith,arith")])
3460
 
3461
(define_insn "ashlhi3_k"
3462
  [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3463
        (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3464
                   (match_operand:HI 2 "const_int_operand" "M,P27")))]
3465
  "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3466
  "@
3467
        add     %0,%0
3468
        shll%O2 %0"
3469
  [(set_attr "type" "arith")])
3470
 
3471
(define_insn "ashlsi3_n"
3472
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3473
        (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3474
                   (match_operand:SI 2 "const_int_operand" "n")))
3475
   (clobber (reg:SI T_REG))]
3476
  "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3477
  "#"
3478
  [(set (attr "length")
3479
        (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3480
               (const_string "2")
3481
               (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3482
               (const_string "4")
3483
               (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3484
               (const_string "6")]
3485
              (const_string "8")))
3486
   (set_attr "type" "arith")])
3487
 
3488
(define_split
3489
  [(set (match_operand:SI 0 "arith_reg_dest" "")
3490
        (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3491
                   (match_operand:SI 2 "const_int_operand" "")))
3492
   (clobber (reg:SI T_REG))]
3493
  "TARGET_SH1 && reload_completed"
3494
  [(use (reg:SI R0_REG))]
3495
  "
3496
{
3497
  gen_shifty_op (ASHIFT, operands);
3498
  DONE;
3499
}")
3500
 
3501
(define_insn "ashlsi3_media"
3502
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3503
        (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3504
                   (match_operand:SI 2 "shift_count_operand" "r,n")))]
3505
  "TARGET_SHMEDIA"
3506
  "@
3507
        shlld.l %1, %2, %0
3508
        shlli.l %1, %2, %0"
3509
  [(set_attr "type" "arith_media")
3510
   (set_attr "highpart" "ignore")])
3511
 
3512
(define_expand "ashlsi3"
3513
  [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3514
                   (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3515
                              (match_operand:SI 2 "nonmemory_operand" "")))
3516
              (clobber (reg:SI T_REG))])]
3517
  ""
3518
  "
3519
{
3520
  if (TARGET_SHMEDIA)
3521
    {
3522
      emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3523
      DONE;
3524
    }
3525
  if (CONST_INT_P (operands[2])
3526
      && sh_dynamicalize_shift_p (operands[2]))
3527
    operands[2] = force_reg (SImode, operands[2]);
3528
  if (TARGET_SH3)
3529
    {
3530
      emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3531
      DONE;
3532
    }
3533
  if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3534
    FAIL;
3535
}")
3536
 
3537
(define_insn "*ashlhi3_n"
3538
  [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3539
        (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3540
                   (match_operand:HI 2 "const_int_operand" "n")))
3541
   (clobber (reg:SI T_REG))]
3542
  "TARGET_SH1"
3543
  "#"
3544
  [(set (attr "length")
3545
        (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3546
               (const_string "2")
3547
               (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3548
               (const_string "4")]
3549
              (const_string "6")))
3550
   (set_attr "type" "arith")])
3551
 
3552
(define_expand "ashlhi3"
3553
  [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3554
                   (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3555
                              (match_operand:SI 2 "nonmemory_operand" "")))
3556
              (clobber (reg:SI T_REG))])]
3557
  "TARGET_SH1"
3558
  "
3559
{
3560
  if (!CONST_INT_P (operands[2]))
3561
    FAIL;
3562
  /* It may be possible to call gen_ashlhi3 directly with more generic
3563
     operands.  Make sure operands[1] is a HImode register here.  */
3564
  if (!arith_reg_operand (operands[1], HImode))
3565
    operands[1] = copy_to_mode_reg (HImode, operands[1]);
3566
}")
3567
 
3568
(define_split
3569
  [(set (match_operand:HI 0 "arith_reg_dest" "")
3570
        (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3571
                   (match_operand:HI 2 "const_int_operand" "")))
3572
   (clobber (reg:SI T_REG))]
3573
  "TARGET_SH1 && reload_completed"
3574
  [(use (reg:SI R0_REG))]
3575
  "
3576
{
3577
  gen_shifty_hi_op (ASHIFT, operands);
3578
  DONE;
3579
}")
3580
 
3581
;
3582
; arithmetic shift right
3583
;
3584
 
3585
(define_insn "ashrsi3_sh2a"
3586
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3587
        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3588
                   (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3589
  "TARGET_SH2A"
3590
  "shad %2,%0"
3591
  [(set_attr "type" "dyn_shift")
3592
   (set_attr "length" "4")])
3593
 
3594
(define_insn "ashrsi3_k"
3595
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3596
        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3597
                     (match_operand:SI 2 "const_int_operand" "M")))
3598
   (clobber (reg:SI T_REG))]
3599
  "TARGET_SH1 && INTVAL (operands[2]) == 1"
3600
  "shar %0"
3601
  [(set_attr "type" "arith")])
3602
 
3603
;; We can't do HImode right shifts correctly unless we start out with an
3604
;; explicit zero / sign extension; doing that would result in worse overall
3605
;; code, so just let the machine independent code widen the mode.
3606
;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3607
 
3608
 
3609
;; ??? This should be a define expand.
3610
 
3611
(define_insn "ashrsi2_16"
3612
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3613
        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3614
                     (const_int 16)))]
3615
  "TARGET_SH1"
3616
  "#"
3617
  [(set_attr "length" "4")])
3618
 
3619
(define_split
3620
  [(set (match_operand:SI 0 "arith_reg_dest" "")
3621
        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3622
                     (const_int 16)))]
3623
  "TARGET_SH1"
3624
  [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3625
   (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3626
  "operands[2] = gen_lowpart (HImode, operands[0]);")
3627
 
3628
;; ??? This should be a define expand.
3629
 
3630
(define_insn "ashrsi2_31"
3631
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3632
        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3633
                     (const_int 31)))
3634
   (clobber (reg:SI T_REG))]
3635
  "TARGET_SH1"
3636
  "#"
3637
  [(set_attr "length" "4")])
3638
 
3639
(define_split
3640
  [(set (match_operand:SI 0 "arith_reg_dest" "")
3641
        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3642
                     (const_int 31)))
3643
   (clobber (reg:SI T_REG))]
3644
  "TARGET_SH1"
3645
  [(const_int 0)]
3646
  "
3647
{
3648
  emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3649
  emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3650
  DONE;
3651
}")
3652
 
3653
(define_peephole2
3654
  [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3655
   (set (reg:SI T_REG)
3656
        (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3657
  "TARGET_SH1
3658
   && peep2_reg_dead_p (2, operands[0])
3659
   && peep2_reg_dead_p (2, operands[1])"
3660
  [(const_int 0)]
3661
  "
3662
{
3663
  emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3664
  DONE;
3665
}")
3666
 
3667
(define_insn "ashlsi_c"
3668
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3669
        (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3670
   (set (reg:SI T_REG)
3671
        (lt:SI (match_dup 1) (const_int 0)))]
3672
  "TARGET_SH1"
3673
  "shll %0"
3674
  [(set_attr "type" "arith")])
3675
 
3676
(define_insn "*ashlsi_c_void"
3677
  [(set (reg:SI T_REG)
3678
        (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3679
   (clobber (match_scratch:SI 1 "=0"))]
3680
  "TARGET_SH1 && cse_not_expected"
3681
  "shll %0"
3682
  [(set_attr "type" "arith")])
3683
 
3684
(define_insn "ashrsi3_d"
3685
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3686
        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3687
                     (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3688
  "TARGET_SH3"
3689
  "shad %2,%0"
3690
  [(set_attr "type" "dyn_shift")])
3691
 
3692
(define_insn "ashrsi3_n"
3693
  [(set (reg:SI R4_REG)
3694
        (ashiftrt:SI (reg:SI R4_REG)
3695
                     (match_operand:SI 0 "const_int_operand" "i")))
3696
   (clobber (reg:SI T_REG))
3697
   (clobber (reg:SI PR_REG))
3698
   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3699
  "TARGET_SH1"
3700
  "jsr  @%1%#"
3701
  [(set_attr "type" "sfunc")
3702
   (set_attr "needs_delay_slot" "yes")])
3703
 
3704
(define_insn "ashrsi3_media"
3705
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3706
        (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3707
                     (match_operand:SI 2 "shift_count_operand" "r,n")))]
3708
  "TARGET_SHMEDIA"
3709
  "@
3710
        shard.l %1, %2, %0
3711
        shari.l %1, %2, %0"
3712
  [(set_attr "type" "arith_media")
3713
   (set_attr "highpart" "ignore")])
3714
 
3715
(define_expand "ashrsi3"
3716
  [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3717
                   (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3718
                                (match_operand:SI 2 "nonmemory_operand" "")))
3719
              (clobber (reg:SI T_REG))])]
3720
  ""
3721
  "
3722
{
3723
  if (TARGET_SHMEDIA)
3724
    {
3725
      emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3726
      DONE;
3727
    }
3728
  if (expand_ashiftrt (operands))
3729
    DONE;
3730
  else
3731
    FAIL;
3732
}")
3733
 
3734
;; logical shift right
3735
 
3736
(define_insn "lshrsi3_sh2a"
3737
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3738
        (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3739
                     (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3740
  "TARGET_SH2A"
3741
  "shld %2,%0"
3742
  [(set_attr "type" "dyn_shift")
3743
   (set_attr "length" "4")])
3744
 
3745
(define_insn "lshrsi3_d"
3746
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3747
        (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3748
                     (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3749
  "TARGET_SH3"
3750
  "shld %2,%0"
3751
  [(set_attr "type" "dyn_shift")])
3752
 
3753
;;  Only the single bit shift clobbers the T bit.
3754
 
3755
(define_insn "lshrsi3_m"
3756
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3757
        (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3758
                     (match_operand:SI 2 "const_int_operand" "M")))
3759
   (clobber (reg:SI T_REG))]
3760
  "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3761
  "shlr %0"
3762
  [(set_attr "type" "arith")])
3763
 
3764
(define_insn "lshrsi3_k"
3765
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3766
        (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3767
                     (match_operand:SI 2 "const_int_operand" "P27")))]
3768
  "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3769
   && ! satisfies_constraint_M (operands[2])"
3770
  "shlr%O2      %0"
3771
  [(set_attr "type" "arith")])
3772
 
3773
(define_insn "lshrsi3_n"
3774
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3775
        (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3776
                     (match_operand:SI 2 "const_int_operand" "n")))
3777
   (clobber (reg:SI T_REG))]
3778
  "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3779
  "#"
3780
  [(set (attr "length")
3781
        (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3782
               (const_string "2")
3783
               (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3784
               (const_string "4")
3785
               (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3786
               (const_string "6")]
3787
              (const_string "8")))
3788
   (set_attr "type" "arith")])
3789
 
3790
(define_split
3791
  [(set (match_operand:SI 0 "arith_reg_dest" "")
3792
        (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3793
                     (match_operand:SI 2 "const_int_operand" "")))
3794
   (clobber (reg:SI T_REG))]
3795
  "TARGET_SH1 && reload_completed"
3796
  [(use (reg:SI R0_REG))]
3797
  "
3798
{
3799
  gen_shifty_op (LSHIFTRT, operands);
3800
  DONE;
3801
}")
3802
 
3803
(define_insn "lshrsi3_media"
3804
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3805
        (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3806
                     (match_operand:SI 2 "shift_count_operand" "r,n")))]
3807
  "TARGET_SHMEDIA"
3808
  "@
3809
        shlrd.l %1, %2, %0
3810
        shlri.l %1, %2, %0"
3811
  [(set_attr "type" "arith_media")
3812
   (set_attr "highpart" "ignore")])
3813
 
3814
(define_expand "lshrsi3"
3815
  [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3816
                   (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3817
                                (match_operand:SI 2 "nonmemory_operand" "")))
3818
              (clobber (reg:SI T_REG))])]
3819
  ""
3820
  "
3821
{
3822
  if (TARGET_SHMEDIA)
3823
    {
3824
      emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3825
      DONE;
3826
    }
3827
  if (CONST_INT_P (operands[2])
3828
      && sh_dynamicalize_shift_p (operands[2]))
3829
    operands[2] = force_reg (SImode, operands[2]);
3830
  if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3831
    {
3832
      rtx count = copy_to_mode_reg (SImode, operands[2]);
3833
      emit_insn (gen_negsi2 (count, count));
3834
      emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3835
      DONE;
3836
    }
3837
  if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3838
    FAIL;
3839
}")
3840
 
3841
;; ??? This should be a define expand.
3842
 
3843
(define_insn "ashldi3_k"
3844
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3845
        (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3846
                   (const_int 1)))
3847
   (clobber (reg:SI T_REG))]
3848
  "TARGET_SH1"
3849
  "shll %R0\;rotcl      %S0"
3850
  [(set_attr "length" "4")
3851
   (set_attr "type" "arith")])
3852
 
3853
;; Expander for DImode shift left with SImode operations.
3854
 
3855
(define_expand "ashldi3_std"
3856
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3857
        (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3858
                   (match_operand:DI 2 "const_int_operand" "n")))]
3859
  "TARGET_SH1 && INTVAL (operands[2]) < 32"
3860
  "
3861
{
3862
  int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3863
  int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3864
  rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3865
  rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3866
  rtx dst = gen_reg_rtx (DImode);
3867
  rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3868
  rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3869
  rtx tmp0, tmp1;
3870
 
3871
  tmp0 = gen_reg_rtx (SImode);
3872
  tmp1 = gen_reg_rtx (SImode);
3873
  emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3874
  emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
3875
  emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
3876
  emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3877
  emit_move_insn (operands[0], dst);
3878
  DONE;
3879
}")
3880
 
3881
(define_insn "ashldi3_media"
3882
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3883
        (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3884
                   (match_operand:DI 2 "shift_count_operand" "r,n")))]
3885
  "TARGET_SHMEDIA"
3886
  "@
3887
        shlld   %1, %2, %0
3888
        shlli   %1, %2, %0"
3889
  [(set_attr "type" "arith_media")])
3890
 
3891
(define_insn "*ashldisi3_media"
3892
  [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3893
        (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3894
                   (match_operand:DI 2 "const_int_operand" "n")))]
3895
  "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3896
  "shlli.l      %1, %2, %0"
3897
  [(set_attr "type" "arith_media")
3898
   (set_attr "highpart" "ignore")])
3899
 
3900
(define_expand "ashldi3"
3901
  [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3902
                   (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3903
                              (match_operand:DI 2 "immediate_operand" "")))
3904
              (clobber (reg:SI T_REG))])]
3905
  ""
3906
  "
3907
{
3908
  if (TARGET_SHMEDIA)
3909
    {
3910
      emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3911
      DONE;
3912
    }
3913
  if (CONST_INT_P (operands[2])
3914
      && INTVAL (operands[2]) == 1)
3915
    {
3916
      emit_insn (gen_ashldi3_k (operands[0], operands[1]));
3917
      DONE;
3918
    }
3919
  else if (CONST_INT_P (operands[2])
3920
      && INTVAL (operands[2]) < 32)
3921
    {
3922
      emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
3923
      DONE;
3924
    }
3925
  else
3926
    FAIL;
3927
}")
3928
 
3929
;; ??? This should be a define expand.
3930
 
3931
(define_insn "lshrdi3_k"
3932
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3933
        (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3934
                     (const_int 1)))
3935
   (clobber (reg:SI T_REG))]
3936
  "TARGET_SH1"
3937
  "shlr %S0\;rotcr      %R0"
3938
  [(set_attr "length" "4")
3939
   (set_attr "type" "arith")])
3940
 
3941
(define_insn "lshrdi3_media"
3942
  [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3943
        (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3944
                     (match_operand:DI 2 "shift_count_operand" "r,n")))]
3945
  "TARGET_SHMEDIA
3946
   && (arith_reg_dest (operands[0], DImode)
3947
       || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
3948
  "@
3949
        shlrd   %1, %2, %0
3950
        shlri   %1, %2, %0"
3951
  [(set_attr "type" "arith_media")])
3952
 
3953
(define_insn "*lshrdisi3_media"
3954
  [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3955
        (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3956
                     (match_operand:DI 2 "const_int_operand" "n")))]
3957
  "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3958
  "shlri.l      %1, %2, %0"
3959
  [(set_attr "type" "arith_media")
3960
   (set_attr "highpart" "ignore")])
3961
 
3962
(define_expand "lshrdi3"
3963
  [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3964
                   (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3965
                               (match_operand:DI 2 "immediate_operand" "")))
3966
             (clobber (reg:SI T_REG))])]
3967
  ""
3968
  "
3969
{
3970
  if (TARGET_SHMEDIA)
3971
    {
3972
      emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3973
      DONE;
3974
    }
3975
  if (!CONST_INT_P (operands[2])
3976
      || INTVAL (operands[2]) != 1)
3977
    FAIL;
3978
}")
3979
 
3980
;; ??? This should be a define expand.
3981
 
3982
(define_insn "ashrdi3_k"
3983
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3984
        (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3985
                     (const_int 1)))
3986
   (clobber (reg:SI T_REG))]
3987
  "TARGET_SH1"
3988
  "shar %S0\;rotcr      %R0"
3989
  [(set_attr "length" "4")
3990
   (set_attr "type" "arith")])
3991
 
3992
(define_insn "ashrdi3_media"
3993
  [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3994
        (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3995
                     (match_operand:DI 2 "shift_count_operand" "r,n")))]
3996
  "TARGET_SHMEDIA
3997
   && (arith_reg_dest (operands[0], DImode)
3998
       || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
3999
  "@
4000
        shard   %1, %2, %0
4001
        shari   %1, %2, %0"
4002
  [(set_attr "type" "arith_media")])
4003
 
4004
(define_insn "*ashrdisi3_media"
4005
  [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4006
        (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4007
                     (match_operand:DI 2 "const_int_operand" "n")))]
4008
  "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4009
  "shari.l      %1, %2, %0"
4010
  [(set_attr "type" "arith_media")
4011
   (set_attr "highpart" "ignore")])
4012
 
4013
(define_insn "ashrdisi3_media_high"
4014
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4015
        (truncate:SI
4016
           (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4017
                        (match_operand:DI 2 "const_int_operand" "n"))))]
4018
  "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4019
  "shari        %1, %2, %0"
4020
  [(set_attr "type" "arith_media")])
4021
 
4022
(define_insn "ashrdisi3_media_opaque"
4023
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4024
        (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4025
                    (match_operand:DI 2 "const_int_operand" "n")]
4026
         UNSPEC_ASHIFTRT))]
4027
  "TARGET_SHMEDIA"
4028
  "shari        %1, %2, %0"
4029
  [(set_attr "type" "arith_media")])
4030
 
4031
(define_expand "ashrdi3"
4032
  [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4033
                   (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4034
                                (match_operand:DI 2 "immediate_operand" "")))
4035
              (clobber (reg:SI T_REG))])]
4036
  ""
4037
  "
4038
{
4039
  if (TARGET_SHMEDIA)
4040
    {
4041
      emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4042
      DONE;
4043
    }
4044
  if (!CONST_INT_P (operands[2])
4045
      || INTVAL (operands[2]) != 1)
4046
    FAIL;
4047
}")
4048
 
4049
;; combined left/right shift
4050
 
4051
(define_split
4052
  [(set (match_operand:SI 0 "register_operand" "")
4053
        (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4054
                           (match_operand:SI 2 "const_int_operand" ""))
4055
                (match_operand:SI 3 "const_int_operand" "")))]
4056
  "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4057
  [(use (reg:SI R0_REG))]
4058
  "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4059
   DONE;")
4060
 
4061
(define_split
4062
  [(set (match_operand:SI 0 "register_operand" "")
4063
        (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4064
                           (match_operand:SI 2 "const_int_operand" ""))
4065
                (match_operand:SI 3 "const_int_operand" "")))
4066
   (clobber (reg:SI T_REG))]
4067
  "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4068
  [(use (reg:SI R0_REG))]
4069
  "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4070
   DONE;")
4071
 
4072
(define_insn ""
4073
  [(set (match_operand:SI 0 "register_operand" "=r")
4074
        (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4075
                           (match_operand:SI 2 "const_int_operand" "n"))
4076
                (match_operand:SI 3 "const_int_operand" "n")))
4077
   (clobber (reg:SI T_REG))]
4078
  "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4079
 "#"
4080
  [(set (attr "length")
4081
        (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4082
               (const_string "4")
4083
               (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4084
               (const_string "6")
4085
               (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4086
               (const_string "8")
4087
               (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4088
               (const_string "10")
4089
               (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4090
               (const_string "12")
4091
               (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4092
               (const_string "14")
4093
               (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4094
               (const_string "16")]
4095
              (const_string "18")))
4096
   (set_attr "type" "arith")])
4097
 
4098
(define_insn ""
4099
  [(set (match_operand:SI 0 "register_operand" "=z")
4100
        (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4101
                           (match_operand:SI 2 "const_int_operand" "n"))
4102
                (match_operand:SI 3 "const_int_operand" "n")))
4103
   (clobber (reg:SI T_REG))]
4104
  "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4105
 "#"
4106
  [(set (attr "length")
4107
        (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4108
               (const_string "4")
4109
               (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4110
               (const_string "6")
4111
               (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4112
               (const_string "8")]
4113
              (const_string "10")))
4114
   (set_attr "type" "arith")])
4115
 
4116
;; shift left / and combination with a scratch register: The combine pass
4117
;; does not accept the individual instructions, even though they are
4118
;; cheap.  But it needs a precise description so that it is usable after
4119
;; reload.
4120
(define_insn "and_shl_scratch"
4121
  [(set (match_operand:SI 0 "register_operand" "=r,&r")
4122
        (lshiftrt:SI
4123
         (ashift:SI
4124
          (and:SI
4125
           (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4126
                        (match_operand:SI 2 "const_int_operand" "N,n"))
4127
           (match_operand:SI 3 "" "0,r"))
4128
          (match_operand:SI 4 "const_int_operand" "n,n"))
4129
         (match_operand:SI 5 "const_int_operand" "n,n")))
4130
   (clobber (reg:SI T_REG))]
4131
  "TARGET_SH1"
4132
  "#"
4133
  [(set (attr "length")
4134
        (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4135
               (const_string "4")
4136
               (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4137
               (const_string "6")
4138
               (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4139
               (const_string "8")
4140
               (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4141
               (const_string "10")]
4142
              (const_string "12")))
4143
   (set_attr "type" "arith")])
4144
 
4145
(define_split
4146
  [(set (match_operand:SI 0 "register_operand" "")
4147
        (lshiftrt:SI
4148
         (ashift:SI
4149
          (and:SI
4150
           (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4151
                        (match_operand:SI 2 "const_int_operand" ""))
4152
           (match_operand:SI 3 "register_operand" ""))
4153
          (match_operand:SI 4 "const_int_operand" ""))
4154
         (match_operand:SI 5 "const_int_operand" "")))
4155
   (clobber (reg:SI T_REG))]
4156
  "TARGET_SH1"
4157
  [(use (reg:SI R0_REG))]
4158
  "
4159
{
4160
  rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4161
 
4162
  if (INTVAL (operands[2]))
4163
    {
4164
      gen_shifty_op (LSHIFTRT, operands);
4165
    }
4166
  emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4167
  operands[2] = operands[4];
4168
  gen_shifty_op (ASHIFT, operands);
4169
  if (INTVAL (operands[5]))
4170
    {
4171
      operands[2] = operands[5];
4172
      gen_shifty_op (LSHIFTRT, operands);
4173
    }
4174
  DONE;
4175
}")
4176
 
4177
;; signed left/right shift combination.
4178
(define_split
4179
  [(set (match_operand:SI 0 "register_operand" "")
4180
        (sign_extract:SI
4181
         (ashift:SI (match_operand:SI 1 "register_operand" "")
4182
                    (match_operand:SI 2 "const_int_operand" ""))
4183
         (match_operand:SI 3 "const_int_operand" "")
4184
         (const_int 0)))
4185
   (clobber (reg:SI T_REG))]
4186
  "TARGET_SH1"
4187
  [(use (reg:SI R0_REG))]
4188
  "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4189
   DONE;")
4190
 
4191
(define_insn "shl_sext_ext"
4192
  [(set (match_operand:SI 0 "register_operand" "=r")
4193
        (sign_extract:SI
4194
         (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
         (const_int 0)))
4198
   (clobber (reg:SI T_REG))]
4199
  "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4200
  "#"
4201
  [(set (attr "length")
4202
        (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4203
               (const_string "2")
4204
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4205
               (const_string "4")
4206
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4207
               (const_string "6")
4208
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4209
               (const_string "8")
4210
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4211
               (const_string "10")
4212
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4213
               (const_string "12")
4214
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4215
               (const_string "14")
4216
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4217
               (const_string "16")]
4218
              (const_string "18")))
4219
    (set_attr "type" "arith")])
4220
 
4221
(define_insn "shl_sext_sub"
4222
  [(set (match_operand:SI 0 "register_operand" "=z")
4223
        (sign_extract:SI
4224
         (ashift:SI (match_operand:SI 1 "register_operand" "0")
4225
                    (match_operand:SI 2 "const_int_operand" "n"))
4226
         (match_operand:SI 3 "const_int_operand" "n")
4227
         (const_int 0)))
4228
   (clobber (reg:SI T_REG))]
4229
  "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4230
  "#"
4231
  [(set (attr "length")
4232
        (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4233
               (const_string "6")
4234
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4235
               (const_string "8")
4236
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4237
               (const_string "10")
4238
               (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4239
               (const_string "12")]
4240
              (const_string "14")))
4241
    (set_attr "type" "arith")])
4242
 
4243
;; These patterns are found in expansions of DImode shifts by 16, and
4244
;; allow the xtrct instruction to be generated from C source.
4245
 
4246
(define_insn "xtrct_left"
4247
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4248
        (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4249
                           (const_int 16))
4250
                (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4251
                             (const_int 16))))]
4252
  "TARGET_SH1"
4253
  "xtrct        %1,%0"
4254
  [(set_attr "type" "arith")])
4255
 
4256
(define_insn "xtrct_right"
4257
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4258
        (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4259
                             (const_int 16))
4260
                (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4261
                           (const_int 16))))]
4262
  "TARGET_SH1"
4263
  "xtrct        %2,%0"
4264
  [(set_attr "type" "arith")])
4265
 
4266
;; -------------------------------------------------------------------------
4267
;; Unary arithmetic
4268
;; -------------------------------------------------------------------------
4269
 
4270
(define_insn "negc"
4271
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4272
        (neg:SI (plus:SI (reg:SI T_REG)
4273
                         (match_operand:SI 1 "arith_reg_operand" "r"))))
4274
   (set (reg:SI T_REG)
4275
        (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4276
               (const_int 0)))]
4277
  "TARGET_SH1"
4278
  "negc %1,%0"
4279
  [(set_attr "type" "arith")])
4280
 
4281
(define_insn "*negdi_media"
4282
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4283
        (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4284
  "TARGET_SHMEDIA"
4285
  "sub  r63, %1, %0"
4286
  [(set_attr "type" "arith_media")])
4287
 
4288
(define_expand "negdi2"
4289
  [(set (match_operand:DI 0 "arith_reg_operand" "")
4290
        (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4291
  ""
4292
  "
4293
{
4294
  if (TARGET_SH1)
4295
    {
4296
      int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4297
      int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4298
 
4299
      rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4300
      rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4301
 
4302
      rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4303
      rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4304
 
4305
      emit_insn (gen_clrt ());
4306
      emit_insn (gen_negc (low_dst, low_src));
4307
      emit_insn (gen_negc (high_dst, high_src));
4308
      DONE;
4309
    }
4310
}")
4311
 
4312
(define_insn "negsi2"
4313
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4314
        (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4315
  "TARGET_SH1"
4316
  "neg  %1,%0"
4317
  [(set_attr "type" "arith")])
4318
 
4319
(define_insn "one_cmplsi2"
4320
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4321
        (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4322
  "TARGET_SH1"
4323
  "not  %1,%0"
4324
  [(set_attr "type" "arith")])
4325
 
4326
(define_expand "one_cmpldi2"
4327
  [(set (match_operand:DI 0 "arith_reg_dest" "")
4328
        (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4329
                (const_int -1)))]
4330
  "TARGET_SHMEDIA" "")
4331
 
4332
/* The SH4 202 can do zero-offset branches without pipeline stalls.
4333
   This can be used as some kind of conditional execution, which is useful
4334
   for abs.  */
4335
(define_split
4336
  [(set (match_operand:SI 0 "arith_reg_dest" "")
4337
        (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4338
                         (match_operand:SI 1 "arith_reg_operand" ""))
4339
                 (reg:SI T_REG)))]
4340
  "TARGET_HARD_SH4"
4341
  [(const_int 0)]
4342
  "emit_insn (gen_movsi_i (operands[0], operands[1]));
4343
   emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4344
   DONE;")
4345
 
4346
(define_insn "cneg"
4347
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4348
        (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4349
                      (match_operand:SI 1 "arith_reg_operand" "0")
4350
                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4351
  "TARGET_HARD_SH4"
4352
  "bf 0f\;neg %2,%0\\n0:"
4353
  [(set_attr "type" "arith") ;; poor approximation
4354
   (set_attr "length" "4")])
4355
 
4356
 
4357
;; -------------------------------------------------------------------------
4358
;; Zero extension instructions
4359
;; -------------------------------------------------------------------------
4360
 
4361
(define_insn "zero_extendsidi2"
4362
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4363
        (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4364
  "TARGET_SHMEDIA"
4365
  "addz.l       %1, r63, %0"
4366
  [(set_attr "type" "arith_media")
4367
   (set_attr "highpart" "extend")])
4368
 
4369
(define_insn "zero_extendhidi2"
4370
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4371
        (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4372
  "TARGET_SHMEDIA"
4373
  "@
4374
        #
4375
        ld%M1.uw        %m1, %0"
4376
  [(set_attr "type" "*,load_media")
4377
   (set (attr "highpart")
4378
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4379
               (const_string "user")]
4380
              (const_string "ignore")))])
4381
 
4382
(define_split
4383
  [(set (match_operand:DI 0 "register_operand" "")
4384
        (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4385
  "TARGET_SHMEDIA && reload_completed"
4386
  [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4387
   (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4388
  "
4389
{
4390
  if (GET_CODE (operands[1]) == TRUNCATE)
4391
    operands[1] = XEXP (operands[1], 0);
4392
}")
4393
 
4394
;; ??? when a truncated input to a zero_extend is reloaded, reload will
4395
;; reload the entire truncate expression.
4396
(define_insn_and_split "*loaddi_trunc"
4397
  [(set (match_operand 0 "any_register_operand" "=r")
4398
        (truncate (match_operand:DI 1 "memory_operand" "m")))]
4399
  "TARGET_SHMEDIA && reload_completed"
4400
  "#"
4401
  "TARGET_SHMEDIA && reload_completed"
4402
  [(set (match_dup 0) (match_dup 1))]
4403
  "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4404
 
4405
(define_insn "zero_extendqidi2"
4406
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4407
        (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4408
  "TARGET_SHMEDIA"
4409
  "@
4410
        andi    %1, 255, %0
4411
        ld%M1.ub        %m1, %0"
4412
  [(set_attr "type" "arith_media,load_media")
4413
   (set (attr "highpart")
4414
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4415
               (const_string "user")]
4416
              (const_string "ignore")))])
4417
 
4418
(define_expand "zero_extendhisi2"
4419
  [(set (match_operand:SI 0 "arith_reg_operand" "")
4420
        (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4421
  ""
4422
  "
4423
{
4424
  if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4425
    operands[1] = copy_to_mode_reg (HImode, operands[1]);
4426
}")
4427
 
4428
(define_insn "*zero_extendhisi2_compact"
4429
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4430
        (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4431
  "TARGET_SH1"
4432
  "extu.w       %1,%0"
4433
  [(set_attr "type" "arith")])
4434
 
4435
(define_insn "*zero_extendhisi2_media"
4436
  [(set (match_operand:SI 0 "register_operand" "=r,r")
4437
        (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4438
  "TARGET_SHMEDIA"
4439
  "@
4440
        #
4441
        ld%M1.uw        %m1, %0"
4442
  [(set_attr "type" "arith_media,load_media")
4443
   (set (attr "highpart")
4444
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4445
               (const_string "user")]
4446
              (const_string "ignore")))])
4447
 
4448
(define_split
4449
  [(set (match_operand:SI 0 "register_operand" "")
4450
        (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4451
  "TARGET_SHMEDIA && reload_completed"
4452
  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4453
   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4454
  "
4455
{
4456
  rtx op1 = operands[1];
4457
 
4458
  if (GET_CODE (op1) == TRUNCATE)
4459
    op1 = XEXP (op1, 0);
4460
  operands[2]
4461
    = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4462
                           subreg_lowpart_offset (SImode, GET_MODE (op1)));
4463
}")
4464
 
4465
(define_expand "zero_extendqisi2"
4466
  [(set (match_operand:SI 0 "arith_reg_operand" "")
4467
        (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4468
  ""
4469
  "
4470
{
4471
  if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4472
    operands[1] = copy_to_mode_reg (QImode, operands[1]);
4473
}")
4474
 
4475
(define_insn "*zero_extendqisi2_compact"
4476
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4477
        (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4478
  "TARGET_SH1"
4479
  "extu.b       %1,%0"
4480
  [(set_attr "type" "arith")])
4481
 
4482
(define_insn "*zero_extendqisi2_media"
4483
  [(set (match_operand:SI 0 "register_operand" "=r,r")
4484
        (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4485
  "TARGET_SHMEDIA"
4486
  "@
4487
        andi    %1, 255, %0
4488
        ld%M1.ub        %m1, %0"
4489
  [(set_attr "type" "arith_media,load_media")
4490
   (set (attr "highpart")
4491
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4492
               (const_string "user")]
4493
              (const_string "ignore")))])
4494
 
4495
(define_insn "zero_extendqihi2"
4496
  [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4497
        (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4498
  "TARGET_SH1"
4499
  "extu.b       %1,%0"
4500
  [(set_attr "type" "arith")])
4501
 
4502
;; -------------------------------------------------------------------------
4503
;; Sign extension instructions
4504
;; -------------------------------------------------------------------------
4505
 
4506
;; ??? This should be a define expand.
4507
;; ??? Or perhaps it should be dropped?
4508
 
4509
;; convert_move generates good code for SH[1-4].
4510
(define_insn "extendsidi2"
4511
  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4512
        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4513
  "TARGET_SHMEDIA"
4514
  "@
4515
        add.l   %1, r63, %0
4516
        ld%M1.l %m1, %0
4517
        fmov.sl %1, %0"
4518
  [(set_attr "type" "arith_media,load_media,fpconv_media")
4519
   (set (attr "highpart")
4520
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4521
               (const_string "user")]
4522
              (const_string "extend")))])
4523
 
4524
(define_insn "extendhidi2"
4525
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4526
        (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4527
  "TARGET_SHMEDIA"
4528
  "@
4529
        #
4530
        ld%M1.w %m1, %0"
4531
  [(set_attr "type" "*,load_media")
4532
   (set (attr "highpart")
4533
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4534
               (const_string "user")]
4535
              (const_string "ignore")))])
4536
 
4537
(define_split
4538
  [(set (match_operand:DI 0 "register_operand" "")
4539
        (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4540
  "TARGET_SHMEDIA && reload_completed"
4541
  [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4542
   (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4543
  "
4544
{
4545
  if (GET_CODE (operands[1]) == TRUNCATE)
4546
    operands[1] = XEXP (operands[1], 0);
4547
}")
4548
 
4549
(define_insn "extendqidi2"
4550
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4551
        (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4552
  "TARGET_SHMEDIA"
4553
  "@
4554
        #
4555
        ld%M1.b %m1, %0"
4556
  [(set_attr "type" "*,load_media")
4557
   (set (attr "highpart")
4558
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4559
               (const_string "user")]
4560
              (const_string "ignore")))])
4561
 
4562
(define_split
4563
  [(set (match_operand:DI 0 "register_operand" "")
4564
        (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4565
  "TARGET_SHMEDIA && reload_completed"
4566
  [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4567
   (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4568
  "
4569
{
4570
  if (GET_CODE (operands[1]) == TRUNCATE)
4571
    operands[1] = XEXP (operands[1], 0);
4572
}")
4573
 
4574
(define_expand "extendhisi2"
4575
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4576
        (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4577
  ""
4578
  "")
4579
 
4580
(define_insn "*extendhisi2_compact"
4581
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4582
        (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4583
  "TARGET_SH1"
4584
  "@
4585
        exts.w  %1,%0
4586
        mov.w   %1,%0"
4587
  [(set_attr "type" "arith,load")])
4588
 
4589
(define_insn "*extendhisi2_media"
4590
  [(set (match_operand:SI 0 "register_operand" "=r,r")
4591
        (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4592
  "TARGET_SHMEDIA"
4593
  "@
4594
        #
4595
        ld%M1.w %m1, %0"
4596
  [(set_attr "type" "arith_media,load_media")
4597
   (set (attr "highpart")
4598
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4599
               (const_string "user")]
4600
              (const_string "ignore")))])
4601
 
4602
(define_split
4603
  [(set (match_operand:SI 0 "register_operand" "")
4604
        (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4605
  "TARGET_SHMEDIA && reload_completed"
4606
  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4607
   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4608
  "
4609
{
4610
  rtx op1 = operands[1];
4611
  if (GET_CODE (op1) == TRUNCATE)
4612
    op1 = XEXP (op1, 0);
4613
  operands[2]
4614
    = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4615
                           subreg_lowpart_offset (SImode, GET_MODE (op1)));
4616
}")
4617
 
4618
(define_expand "extendqisi2"
4619
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4620
        (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4621
  ""
4622
  "")
4623
 
4624
(define_insn "*extendqisi2_compact"
4625
  [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4626
        (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4627
  "TARGET_SH1"
4628
  "@
4629
        exts.b  %1,%0
4630
        mov.b   %1,%0"
4631
  [(set_attr "type" "arith,load")
4632
   (set_attr_alternative "length"
4633
     [(const_int 2)
4634
       (if_then_else
4635
        (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4636
        (const_int 4) (const_int 2))])])
4637
 
4638
(define_insn "*extendqisi2_media"
4639
  [(set (match_operand:SI 0 "register_operand" "=r,r")
4640
        (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4641
  "TARGET_SHMEDIA"
4642
  "@
4643
        #
4644
        ld%M1.b %m1, %0"
4645
  [(set_attr "type" "arith_media,load_media")
4646
   (set (attr "highpart")
4647
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4648
               (const_string "user")]
4649
              (const_string "ignore")))])
4650
 
4651
(define_split
4652
  [(set (match_operand:SI 0 "register_operand" "")
4653
        (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4654
  "TARGET_SHMEDIA && reload_completed"
4655
  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4656
   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4657
   "
4658
{
4659
  rtx op1 = operands[1];
4660
  if (GET_CODE (op1) == TRUNCATE)
4661
    op1 = XEXP (op1, 0);
4662
  operands[2]
4663
    = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4664
                           subreg_lowpart_offset (SImode, GET_MODE (op1)));
4665
}")
4666
 
4667
(define_insn "extendqihi2"
4668
  [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4669
        (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4670
  "TARGET_SH1"
4671
  "@
4672
        exts.b  %1,%0
4673
        mov.b   %1,%0"
4674
  [(set_attr "type" "arith,load")
4675
   (set_attr_alternative "length"
4676
     [(const_int 2)
4677
       (if_then_else
4678
        (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4679
        (const_int 4) (const_int 2))])])
4680
 
4681
/* It would seem useful to combine the truncXi patterns into the movXi
4682
   patterns, but unary operators are ignored when matching constraints,
4683
   so we need separate patterns.  */
4684
(define_insn "truncdisi2"
4685
  [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4686
        (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4687
  "TARGET_SHMEDIA"
4688
  "@
4689
        add.l   %1, r63, %0
4690
        st%M0.l %m0, %1
4691
        fst%M0.s        %m0, %T1
4692
        fmov.ls %1, %0
4693
        fmov.sl %T1, %0
4694
        fmov.s  %T1, %0"
4695
  [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4696
   (set (attr "highpart")
4697
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4698
               (const_string "user")]
4699
              (const_string "extend")))])
4700
 
4701
(define_insn "truncdihi2"
4702
  [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4703
        (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4704
  "TARGET_SHMEDIA"
4705
  "@
4706
        shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4707
        st%M0.w %m0, %1"
4708
  [(set_attr "type"   "arith_media,store_media")
4709
   (set_attr "length" "8,4")
4710
   (set (attr "highpart")
4711
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4712
               (const_string "user")]
4713
              (const_string "extend")))])
4714
 
4715
; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4716
; Because we use zero extension, we can't provide signed QImode compares
4717
; using a simple compare or conditional branch insn.
4718
(define_insn "truncdiqi2"
4719
  [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4720
        (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4721
  "TARGET_SHMEDIA"
4722
  "@
4723
        andi    %1, 255, %0
4724
        st%M0.b %m0, %1"
4725
  [(set_attr "type"   "arith_media,store")
4726
   (set (attr "highpart")
4727
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4728
               (const_string "user")]
4729
              (const_string "extend")))])
4730
;; -------------------------------------------------------------------------
4731
;; Move instructions
4732
;; -------------------------------------------------------------------------
4733
 
4734
;; define push and pop so it is easy for sh.c
4735
;; We can't use push and pop on SHcompact because the stack must always
4736
;; be 8-byte aligned.
4737
 
4738
(define_expand "push"
4739
  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4740
        (match_operand:SI 0 "register_operand" "r,l,x"))]
4741
  "TARGET_SH1 && ! TARGET_SH5"
4742
  "")
4743
 
4744
(define_expand "pop"
4745
  [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4746
        (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4747
  "TARGET_SH1 && ! TARGET_SH5"
4748
  "")
4749
 
4750
(define_expand "push_e"
4751
  [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4752
                   (match_operand:SF 0 "" ""))
4753
              (use (reg:PSI FPSCR_REG))
4754
              (clobber (scratch:SI))])]
4755
  "TARGET_SH1 && ! TARGET_SH5"
4756
  "")
4757
 
4758
(define_insn "push_fpul"
4759
  [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4760
  "TARGET_SH2E && ! TARGET_SH5"
4761
  "sts.l        fpul,@-r15"
4762
  [(set_attr "type" "fstore")
4763
   (set_attr "late_fp_use" "yes")
4764
   (set_attr "hit_stack" "yes")])
4765
 
4766
;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4767
;; so use that.
4768
(define_expand "push_4"
4769
  [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4770
                   (match_operand:DF 0 "" ""))
4771
              (use (reg:PSI FPSCR_REG))
4772
              (clobber (scratch:SI))])]
4773
  "TARGET_SH1 && ! TARGET_SH5"
4774
  "")
4775
 
4776
(define_expand "pop_e"
4777
  [(parallel [(set (match_operand:SF 0 "" "")
4778
              (mem:SF (post_inc:SI (reg:SI SP_REG))))
4779
              (use (reg:PSI FPSCR_REG))
4780
              (clobber (scratch:SI))])]
4781
  "TARGET_SH1 && ! TARGET_SH5"
4782
  "")
4783
 
4784
(define_insn "pop_fpul"
4785
  [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4786
  "TARGET_SH2E && ! TARGET_SH5"
4787
  "lds.l        @r15+,fpul"
4788
  [(set_attr "type" "load")
4789
   (set_attr "hit_stack" "yes")])
4790
 
4791
(define_expand "pop_4"
4792
  [(parallel [(set (match_operand:DF 0 "" "")
4793
                   (mem:DF (post_inc:SI (reg:SI SP_REG))))
4794
              (use (reg:PSI FPSCR_REG))
4795
              (clobber (scratch:SI))])]
4796
  "TARGET_SH1 && ! TARGET_SH5"
4797
  "")
4798
 
4799
(define_expand "push_fpscr"
4800
  [(const_int 0)]
4801
  "TARGET_SH2E"
4802
  "
4803
{
4804
  rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4805
                                                 gen_rtx_PRE_DEC (Pmode,
4806
                                                          stack_pointer_rtx)),
4807
                                        get_fpscr_rtx ()));
4808
  add_reg_note (insn, REG_INC, stack_pointer_rtx);
4809
  DONE;
4810
}")
4811
 
4812
(define_expand "pop_fpscr"
4813
  [(const_int 0)]
4814
  "TARGET_SH2E"
4815
  "
4816
{
4817
  rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4818
                                        gen_frame_mem (PSImode,
4819
                                                 gen_rtx_POST_INC (Pmode,
4820
                                                          stack_pointer_rtx))));
4821
  add_reg_note (insn, REG_INC, stack_pointer_rtx);
4822
  DONE;
4823
}")
4824
 
4825
;; These two patterns can happen as the result of optimization, when
4826
;; comparisons get simplified to a move of zero or 1 into the T reg.
4827
;; They don't disappear completely, because the T reg is a fixed hard reg.
4828
 
4829
(define_insn "clrt"
4830
  [(set (reg:SI T_REG) (const_int 0))]
4831
  "TARGET_SH1"
4832
  "clrt")
4833
 
4834
(define_insn "sett"
4835
  [(set (reg:SI T_REG) (const_int 1))]
4836
  "TARGET_SH1"
4837
  "sett")
4838
 
4839
;; t/r must come after r/r, lest reload will try to reload stuff like
4840
;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4841
;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4842
(define_insn "movsi_i"
4843
  [(set (match_operand:SI 0 "general_movdst_operand"
4844
            "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4845
        (match_operand:SI 1 "general_movsrc_operand"
4846
         "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4847
  "TARGET_SH1
4848
   && ! TARGET_SH2E
4849
   && ! TARGET_SH2A
4850
   && (register_operand (operands[0], SImode)
4851
       || register_operand (operands[1], SImode))"
4852
  "@
4853
        mov.l   %1,%0
4854
        mov     %1,%0
4855
        mov     %1,%0
4856
        cmp/pl  %1
4857
        mov.l   %1,%0
4858
        sts     %1,%0
4859
        sts     %1,%0
4860
        movt    %0
4861
        mov.l   %1,%0
4862
        sts.l   %1,%0
4863
        sts.l   %1,%0
4864
        lds     %1,%0
4865
        lds     %1,%0
4866
        lds.l   %1,%0
4867
        lds.l   %1,%0
4868
        fake    %1,%0"
4869
  [(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")
4870
   (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4871
 
4872
;; t/r must come after r/r, lest reload will try to reload stuff like
4873
;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4874
;; ??? This allows moves from macl to fpul to be recognized, but these moves
4875
;; will require a reload.
4876
;; ??? We can't include f/f because we need the proper FPSCR setting when
4877
;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4878
(define_insn "movsi_ie"
4879
  [(set (match_operand:SI 0 "general_movdst_operand"
4880
            "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4881
        (match_operand:SI 1 "general_movsrc_operand"
4882
         "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4883
  "(TARGET_SH2E || TARGET_SH2A)
4884
   && (register_operand (operands[0], SImode)
4885
       || register_operand (operands[1], SImode))"
4886
  "@
4887
        mov.l   %1,%0
4888
        mov     %1,%0
4889
        mov     %1,%0
4890
        movi20  %1,%0
4891
        movi20s %1,%0
4892
        cmp/pl  %1
4893
        mov.l   %1,%0
4894
        sts     %1,%0
4895
        sts     %1,%0
4896
        movt    %0
4897
        mov.l   %1,%0
4898
        sts.l   %1,%0
4899
        sts.l   %1,%0
4900
        lds     %1,%0
4901
        lds     %1,%0
4902
        lds.l   %1,%0
4903
        lds.l   %1,%0
4904
        lds.l   %1,%0
4905
        sts.l   %1,%0
4906
        fake    %1,%0
4907
        lds     %1,%0
4908
        sts     %1,%0
4909
        fsts    fpul,%0
4910
        flds    %1,fpul
4911
        fmov    %1,%0
4912
        ! move optimized away"
4913
  [(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")
4914
   (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4915
   (set_attr_alternative "length"
4916
     [(const_int 2)
4917
      (const_int 2)
4918
      (const_int 2)
4919
      (const_int 4)
4920
      (const_int 4)
4921
      (const_int 2)
4922
      (if_then_else
4923
        (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4924
        (const_int 4) (const_int 2))
4925
      (const_int 2)
4926
      (const_int 2)
4927
      (const_int 2)
4928
      (if_then_else
4929
        (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4930
        (const_int 4) (const_int 2))
4931
      (const_int 2)
4932
      (const_int 2)
4933
      (const_int 2)
4934
      (const_int 2)
4935
      (const_int 2)
4936
      (const_int 2)
4937
      (const_int 2)
4938
      (const_int 2)
4939
      (const_int 2)
4940
      (const_int 2)
4941
      (const_int 2)
4942
      (const_int 2)
4943
      (const_int 2)
4944
      (const_int 2)
4945
      (const_int 0)])])
4946
 
4947
(define_insn "movsi_i_lowpart"
4948
  [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
4949
        (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
4950
   "TARGET_SH1
4951
    && (register_operand (operands[0], SImode)
4952
        || register_operand (operands[1], SImode))"
4953
  "@
4954
        mov.l   %1,%0
4955
        mov     %1,%0
4956
        mov     %1,%0
4957
        mov.l   %1,%0
4958
        sts     %1,%0
4959
        sts     %1,%0
4960
        movt    %0
4961
        mov.l   %1,%0
4962
        fake    %1,%0"
4963
  [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
4964
 
4965
(define_insn_and_split "load_ra"
4966
  [(set (match_operand:SI 0 "general_movdst_operand" "")
4967
        (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4968
  "TARGET_SH1"
4969
  "#"
4970
  "&& ! currently_expanding_to_rtl"
4971
  [(set (match_dup 0) (match_dup 1))]
4972
  "
4973
{
4974
  if (TARGET_SHCOMPACT && crtl->saves_all_registers)
4975
    operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4976
}")
4977
 
4978
;; The '?'s in the following constraints may not reflect the time taken
4979
;; to perform the move. They are there to discourage the use of floating-
4980
;; point registers for storing integer values.
4981
(define_insn "*movsi_media"
4982
  [(set (match_operand:SI 0 "general_movdst_operand"
4983
                "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4984
        (match_operand:SI 1 "general_movsrc_operand"
4985
         "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4986
  "TARGET_SHMEDIA_FPU
4987
   && (register_operand (operands[0], SImode)
4988
       || sh_register_operand (operands[1], SImode)
4989
       || GET_CODE (operands[1]) == TRUNCATE)"
4990
  "@
4991
        add.l   %1, r63, %0
4992
        movi    %1, %0
4993
        #
4994
        ld%M1.l %m1, %0
4995
        st%M0.l %m0, %N1
4996
        fld%M1.s        %m1, %0
4997
        fst%M0.s        %m0, %1
4998
        fmov.ls %N1, %0
4999
        fmov.sl %1, %0
5000
        fmov.s  %1, %0
5001
        ptabs   %1, %0
5002
        gettr   %1, %0
5003
        pt      %1, %0"
5004
  [(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")
5005
   (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5006
   (set (attr "highpart")
5007
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5008
               (const_string "user")]
5009
              (const_string "ignore")))])
5010
 
5011
(define_insn "*movsi_media_nofpu"
5012
  [(set (match_operand:SI 0 "general_movdst_operand"
5013
                "=r,r,r,r,m,*b,r,*b")
5014
        (match_operand:SI 1 "general_movsrc_operand"
5015
         "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5016
  "TARGET_SHMEDIA
5017
   && (register_operand (operands[0], SImode)
5018
       || sh_register_operand (operands[1], SImode)
5019
       || GET_CODE (operands[1]) == TRUNCATE)"
5020
  "@
5021
        add.l   %1, r63, %0
5022
        movi    %1, %0
5023
        #
5024
        ld%M1.l %m1, %0
5025
        st%M0.l %m0, %N1
5026
        ptabs   %1, %0
5027
        gettr   %1, %0
5028
        pt      %1, %0"
5029
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5030
   (set_attr "length" "4,4,8,4,4,4,4,12")
5031
   (set (attr "highpart")
5032
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5033
               (const_string "user")]
5034
              (const_string "ignore")))])
5035
 
5036
(define_expand "movsi_const"
5037
  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5038
        (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5039
                              (const_int 16)] UNSPEC_EXTRACT_S16)))
5040
   (set (match_dup 0)
5041
        (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5042
                (const:SI (unspec:SI [(match_dup 1)
5043
                                      (const_int 0)] UNSPEC_EXTRACT_U16))))]
5044
  "TARGET_SHMEDIA && reload_completed
5045
   && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5046
  "
5047
{
5048
  if (GET_CODE (operands[1]) == LABEL_REF
5049
      && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5050
    LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5051
  else if (GOTOFF_P (operands[1]))
5052
    {
5053
      rtx unspec = XEXP (operands[1], 0);
5054
 
5055
      if (! UNSPEC_GOTOFF_P (unspec))
5056
        {
5057
          unspec = XEXP (unspec, 0);
5058
          if (! UNSPEC_GOTOFF_P (unspec))
5059
            abort ();
5060
        }
5061
      if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5062
          && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5063
        LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5064
    }
5065
}")
5066
 
5067
(define_expand "movsi_const_16bit"
5068
  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5069
        (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5070
                              (const_int 0)] UNSPEC_EXTRACT_S16)))]
5071
  "TARGET_SHMEDIA && flag_pic && reload_completed
5072
   && GET_CODE (operands[1]) == SYMBOL_REF"
5073
  "")
5074
 
5075
(define_split
5076
  [(set (match_operand:SI 0 "arith_reg_dest" "")
5077
        (match_operand:SI 1 "immediate_operand" ""))]
5078
  "TARGET_SHMEDIA && reload_completed
5079
   && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5080
  [(const_int 0)]
5081
  "
5082
{
5083
  rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5084
 
5085
  set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5086
 
5087
  DONE;
5088
}")
5089
 
5090
(define_split
5091
  [(set (match_operand:SI 0 "register_operand" "")
5092
        (match_operand:SI 1 "immediate_operand" ""))]
5093
  "TARGET_SHMEDIA && reload_completed
5094
   && ((CONST_INT_P (operands[1])
5095
        && ! satisfies_constraint_I16 (operands[1]))
5096
       || GET_CODE (operands[1]) == CONST_DOUBLE)"
5097
  [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5098
 
5099
(define_expand "movsi"
5100
  [(set (match_operand:SI 0 "general_movdst_operand" "")
5101
        (match_operand:SI 1 "general_movsrc_operand" ""))]
5102
  ""
5103
  "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5104
 
5105
(define_expand "ic_invalidate_line"
5106
  [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5107
                                (match_dup 1)] UNSPEC_ICACHE)
5108
              (clobber (scratch:SI))])]
5109
  "TARGET_HARD_SH4 || TARGET_SH5"
5110
  "
5111
{
5112
  if (TARGET_SHMEDIA)
5113
    {
5114
      emit_insn (gen_ic_invalidate_line_media (operands[0]));
5115
      DONE;
5116
    }
5117
  else if (TARGET_SHCOMPACT)
5118
    {
5119
      operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5120
      operands[1] = force_reg (Pmode, operands[1]);
5121
      emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5122
      DONE;
5123
    }
5124
  else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5125
    {
5126
      emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5127
      DONE;
5128
    }
5129
  operands[0] = force_reg (Pmode, operands[0]);
5130
  operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5131
                                                               Pmode)));
5132
}")
5133
 
5134
;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5135
;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5136
;; the requirement *1*00 for associative address writes.  The alignment of
5137
;; %0 implies that its least significant bit is cleared,
5138
;; thus we clear the V bit of a matching entry if there is one.
5139
(define_insn "ic_invalidate_line_i"
5140
  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5141
                     (match_operand:SI 1 "register_operand" "r")]
5142
                     UNSPEC_ICACHE)
5143
   (clobber (match_scratch:SI 2 "=&r"))]
5144
  "TARGET_HARD_SH4"
5145
  "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5146
  [(set_attr "length" "8")
5147
   (set_attr "type" "cwb")])
5148
 
5149
(define_insn "ic_invalidate_line_sh4a"
5150
  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5151
                    UNSPEC_ICACHE)]
5152
  "TARGET_SH4A_ARCH || TARGET_SH4_300"
5153
  "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5154
  [(set_attr "length" "16")
5155
   (set_attr "type" "cwb")])
5156
 
5157
;; ??? could make arg 0 an offsettable memory operand to allow to save
5158
;; an add in the code that calculates the address.
5159
(define_insn "ic_invalidate_line_media"
5160
  [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5161
                    UNSPEC_ICACHE)]
5162
  "TARGET_SHMEDIA"
5163
  "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5164
  [(set_attr "length" "16")
5165
   (set_attr "type" "invalidate_line_media")])
5166
 
5167
(define_insn "ic_invalidate_line_compact"
5168
  [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5169
                     (match_operand:SI 1 "register_operand" "r")]
5170
                    UNSPEC_ICACHE)
5171
   (clobber (reg:SI PR_REG))]
5172
  "TARGET_SHCOMPACT"
5173
  "jsr @%1%#"
5174
  [(set_attr "type" "sfunc")
5175
   (set_attr "needs_delay_slot" "yes")])
5176
 
5177
(define_expand "initialize_trampoline"
5178
  [(match_operand:SI 0 "" "")
5179
   (match_operand:SI 1 "" "")
5180
   (match_operand:SI 2 "" "")]
5181
  "TARGET_SHCOMPACT"
5182
  "
5183
{
5184
  rtx sfun, tramp;
5185
 
5186
  tramp = force_reg (Pmode, operands[0]);
5187
  sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5188
                                            SFUNC_STATIC));
5189
  emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5190
  emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5191
 
5192
  emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5193
  DONE;
5194
}")
5195
 
5196
(define_insn "initialize_trampoline_compact"
5197
  [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5198
                     (match_operand:SI 1 "register_operand" "r")
5199
                     (reg:SI R2_REG) (reg:SI R3_REG)]
5200
                    UNSPEC_INIT_TRAMP)
5201
 
5202
   (clobber (reg:SI PR_REG))]
5203
  "TARGET_SHCOMPACT"
5204
  "jsr @%1%#"
5205
  [(set_attr "type" "sfunc")
5206
   (set_attr "needs_delay_slot" "yes")])
5207
 
5208
(define_insn "movqi_i"
5209
  [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5210
        (match_operand:QI 1 "general_movsrc_operand"  "r,i,m,r,t,l,r"))]
5211
  "TARGET_SH1
5212
   && (arith_reg_operand (operands[0], QImode)
5213
       || arith_reg_operand (operands[1], QImode))"
5214
  "@
5215
        mov     %1,%0
5216
        mov     %1,%0
5217
        mov.b   %1,%0
5218
        mov.b   %1,%0
5219
        movt    %0
5220
        sts     %1,%0
5221
        lds     %1,%0"
5222
 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5223
  (set_attr_alternative "length"
5224
     [(const_int 2)
5225
      (const_int 2)
5226
      (if_then_else
5227
        (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5228
        (const_int 4) (const_int 2))
5229
      (if_then_else
5230
        (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5231
        (const_int 4) (const_int 2))
5232
      (const_int 2)
5233
      (const_int 2)
5234
      (const_int 2)])])
5235
 
5236
(define_insn "*movqi_media"
5237
  [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5238
        (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5239
  "TARGET_SHMEDIA
5240
   && (arith_reg_operand (operands[0], QImode)
5241
       || extend_reg_or_0_operand (operands[1], QImode))"
5242
  "@
5243
        add.l   %1, r63, %0
5244
        movi    %1, %0
5245
        ld%M1.ub        %m1, %0
5246
        st%M0.b %m0, %N1"
5247
  [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5248
   (set (attr "highpart")
5249
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5250
               (const_string "user")]
5251
              (const_string "ignore")))])
5252
 
5253
(define_expand "movqi"
5254
  [(set (match_operand:QI 0 "general_operand" "")
5255
        (match_operand:QI 1 "general_operand"  ""))]
5256
  ""
5257
  "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5258
 
5259
(define_expand "reload_inqi"
5260
  [(set (match_operand:SI 2 "" "=&r")
5261
        (match_operand:QI 1 "inqhi_operand" ""))
5262
   (set (match_operand:QI 0 "arith_reg_operand" "=r")
5263
        (truncate:QI (match_dup 3)))]
5264
  "TARGET_SHMEDIA"
5265
  "
5266
{
5267
  rtx inner = XEXP (operands[1], 0);
5268
  int regno = REGNO (inner);
5269
 
5270
  regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5271
  operands[1] = gen_rtx_REG (SImode, regno);
5272
  operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5273
}")
5274
 
5275
/* When storing r0, we have to avoid reg+reg addressing.  */
5276
(define_insn "movhi_i"
5277
  [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5278
        (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5279
  "TARGET_SH1
5280
   && (arith_reg_operand (operands[0], HImode)
5281
       || arith_reg_operand (operands[1], HImode))
5282
   && (!MEM_P (operands[0])
5283
       || GET_CODE (XEXP (operands[0], 0)) != PLUS
5284
       || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5285
       || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5286
  "@
5287
        mov.w   %1,%0
5288
        mov     %1,%0
5289
        mov.w   %1,%0
5290
        movt    %0
5291
        mov.w   %1,%0
5292
        sts     %1,%0
5293
        lds     %1,%0
5294
        fake    %1,%0"
5295
  [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5296
 
5297
(define_insn "*movhi_media"
5298
  [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5299
        (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5300
  "TARGET_SHMEDIA
5301
   && (arith_reg_operand (operands[0], HImode)
5302
       || arith_reg_or_0_operand (operands[1], HImode))"
5303
  "@
5304
        add.l   %1, r63, %0
5305
        movi    %1, %0
5306
        #
5307
        ld%M1.w %m1, %0
5308
        st%M0.w %m0, %N1"
5309
  [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5310
   (set (attr "highpart")
5311
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5312
               (const_string "user")]
5313
              (const_string "ignore")))])
5314
 
5315
(define_split
5316
  [(set (match_operand:HI 0 "register_operand" "")
5317
        (match_operand:HI 1 "immediate_operand" ""))]
5318
  "TARGET_SHMEDIA && reload_completed
5319
   && ! satisfies_constraint_I16 (operands[1])"
5320
  [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5321
 
5322
(define_expand "movhi"
5323
  [(set (match_operand:HI 0 "general_movdst_operand" "")
5324
        (match_operand:HI 1 "general_movsrc_operand"  ""))]
5325
  ""
5326
  "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5327
 
5328
(define_expand "reload_inhi"
5329
  [(set (match_operand:SI 2 "" "=&r")
5330
        (match_operand:HI 1 "inqhi_operand" ""))
5331
   (set (match_operand:HI 0 "arith_reg_operand" "=r")
5332
        (truncate:HI (match_dup 3)))]
5333
  "TARGET_SHMEDIA"
5334
  "
5335
{
5336
  rtx inner = XEXP (operands[1], 0);
5337
  int regno = REGNO (inner);
5338
 
5339
  regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5340
  operands[1] = gen_rtx_REG (SImode, regno);
5341
  operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5342
}")
5343
 
5344
;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5345
;; compiled with -m2 -ml -O3 -funroll-loops
5346
(define_insn "*movdi_i"
5347
  [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5348
        (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5349
  "TARGET_SH1
5350
   && (arith_reg_operand (operands[0], DImode)
5351
       || arith_reg_operand (operands[1], DImode))"
5352
  "* return output_movedouble (insn, operands, DImode);"
5353
  [(set_attr "length" "4")
5354
   (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5355
 
5356
;; If the output is a register and the input is memory or a register, we have
5357
;; to be careful and see which word needs to be loaded first.
5358
 
5359
(define_split
5360
  [(set (match_operand:DI 0 "general_movdst_operand" "")
5361
        (match_operand:DI 1 "general_movsrc_operand" ""))]
5362
  "TARGET_SH1 && reload_completed"
5363
  [(set (match_dup 2) (match_dup 3))
5364
   (set (match_dup 4) (match_dup 5))]
5365
  "
5366
{
5367
  int regno;
5368
 
5369
  if ((MEM_P (operands[0])
5370
       && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5371
      || (MEM_P (operands[1])
5372
          && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5373
    FAIL;
5374
 
5375
  switch (GET_CODE (operands[0]))
5376
    {
5377
    case REG:
5378
      regno = REGNO (operands[0]);
5379
      break;
5380
    case SUBREG:
5381
      regno = subreg_regno (operands[0]);
5382
      break;
5383
    case MEM:
5384
      regno = -1;
5385
      break;
5386
    default:
5387
      gcc_unreachable ();
5388
    }
5389
 
5390
  if (regno == -1
5391
      || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5392
    {
5393
      operands[2] = operand_subword (operands[0], 0, 0, DImode);
5394
      operands[3] = operand_subword (operands[1], 0, 0, DImode);
5395
      operands[4] = operand_subword (operands[0], 1, 0, DImode);
5396
      operands[5] = operand_subword (operands[1], 1, 0, DImode);
5397
    }
5398
  else
5399
    {
5400
      operands[2] = operand_subword (operands[0], 1, 0, DImode);
5401
      operands[3] = operand_subword (operands[1], 1, 0, DImode);
5402
      operands[4] = operand_subword (operands[0], 0, 0, DImode);
5403
      operands[5] = operand_subword (operands[1], 0, 0, DImode);
5404
    }
5405
 
5406
  if (operands[2] == 0 || operands[3] == 0
5407
      || operands[4] == 0 || operands[5] == 0)
5408
    FAIL;
5409
}")
5410
 
5411
;; The '?'s in the following constraints may not reflect the time taken
5412
;; to perform the move. They are there to discourage the use of floating-
5413
;; point registers for storing integer values.
5414
(define_insn "*movdi_media"
5415
  [(set (match_operand:DI 0 "general_movdst_operand"
5416
                 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5417
        (match_operand:DI 1 "general_movsrc_operand"
5418
         "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5419
  "TARGET_SHMEDIA_FPU
5420
   && (register_operand (operands[0], DImode)
5421
       || sh_register_operand (operands[1], DImode))"
5422
  "@
5423
        add     %1, r63, %0
5424
        movi    %1, %0
5425
        #
5426
        ld%M1.q %m1, %0
5427
        st%M0.q %m0, %N1
5428
        fld%M1.d        %m1, %0
5429
        fst%M0.d        %m0, %1
5430
        fmov.qd %N1, %0
5431
        fmov.dq %1, %0
5432
        fmov.d  %1, %0
5433
        ptabs   %1, %0
5434
        gettr   %1, %0
5435
        pt      %1, %0"
5436
  [(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")
5437
   (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5438
 
5439
(define_insn "*movdi_media_nofpu"
5440
  [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5441
        (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5442
  "TARGET_SHMEDIA
5443
   && (register_operand (operands[0], DImode)
5444
       || sh_register_operand (operands[1], DImode))"
5445
  "@
5446
        add     %1, r63, %0
5447
        movi    %1, %0
5448
        #
5449
        ld%M1.q %m1, %0
5450
        st%M0.q %m0, %N1
5451
        ptabs   %1, %0
5452
        gettr   %1, %0
5453
        pt      %1, %0"
5454
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5455
   (set_attr "length" "4,4,16,4,4,4,4,*")])
5456
 
5457
(define_insn "*movdi_media_I16"
5458
  [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5459
        (match_operand:DI 1 "const_int_operand" "I16"))]
5460
  "TARGET_SHMEDIA && reload_completed"
5461
  "movi %1, %0"
5462
  [(set_attr "type" "arith_media")
5463
   (set_attr "length" "4")])
5464
 
5465
(define_split
5466
  [(set (match_operand:DI 0 "arith_reg_dest" "")
5467
        (match_operand:DI 1 "immediate_operand" ""))]
5468
  "TARGET_SHMEDIA && reload_completed
5469
   && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5470
  [(set (match_dup 0) (match_dup 1))]
5471
  "
5472
{
5473
  rtx insn;
5474
 
5475
  if (TARGET_SHMEDIA64)
5476
    insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5477
  else
5478
    insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5479
 
5480
  set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5481
 
5482
  DONE;
5483
}")
5484
 
5485
(define_expand "movdi_const"
5486
  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5487
        (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5488
                              (const_int 48)] UNSPEC_EXTRACT_S16)))
5489
   (set (match_dup 0)
5490
        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5491
                (const:DI (unspec:DI [(match_dup 1)
5492
                                      (const_int 32)] UNSPEC_EXTRACT_U16))))
5493
   (set (match_dup 0)
5494
        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5495
                (const:DI (unspec:DI [(match_dup 1)
5496
                                      (const_int 16)] UNSPEC_EXTRACT_U16))))
5497
   (set (match_dup 0)
5498
        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5499
                (const:DI (unspec:DI [(match_dup 1)
5500
                                      (const_int 0)] UNSPEC_EXTRACT_U16))))]
5501
  "TARGET_SHMEDIA64 && reload_completed
5502
   && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5503
  "
5504
{
5505
  sh_mark_label (operands[1], 4);
5506
}")
5507
 
5508
(define_expand "movdi_const_32bit"
5509
  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5510
        (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5511
                              (const_int 16)] UNSPEC_EXTRACT_S16)))
5512
   (set (match_dup 0)
5513
        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5514
                (const:DI (unspec:DI [(match_dup 1)
5515
                                      (const_int 0)] UNSPEC_EXTRACT_U16))))]
5516
  "TARGET_SHMEDIA32 && reload_completed
5517
   && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5518
  "
5519
{
5520
  sh_mark_label (operands[1], 2);
5521
}")
5522
 
5523
(define_expand "movdi_const_16bit"
5524
  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5525
        (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5526
                              (const_int 0)] UNSPEC_EXTRACT_S16)))]
5527
  "TARGET_SHMEDIA && flag_pic && reload_completed
5528
   && GET_CODE (operands[1]) == SYMBOL_REF"
5529
  "")
5530
 
5531
(define_split
5532
  [(set (match_operand:DI 0 "ext_dest_operand" "")
5533
        (match_operand:DI 1 "immediate_operand" ""))]
5534
  "TARGET_SHMEDIA && reload_completed
5535
   && CONST_INT_P (operands[1])
5536
   && ! satisfies_constraint_I16 (operands[1])"
5537
  [(set (match_dup 0) (match_dup 2))
5538
   (match_dup 1)]
5539
  "
5540
{
5541
  unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5542
  unsigned HOST_WIDE_INT low = val;
5543
  unsigned HOST_WIDE_INT high = val;
5544
  unsigned HOST_WIDE_INT sign;
5545
  unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5546
 
5547
  /* Zero-extend the 16 least-significant bits.  */
5548
  low &= 0xffff;
5549
 
5550
  /* Arithmetic shift right the word by 16 bits.  */
5551
  high >>= 16;
5552
  if (GET_CODE (operands[0]) == SUBREG
5553
      && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5554
    {
5555
      high &= 0xffff;
5556
      high ^= 0x8000;
5557
      high -= 0x8000;
5558
    }
5559
  else
5560
    {
5561
      sign = 1;
5562
      sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5563
      high ^= sign;
5564
      high -= sign;
5565
    }
5566
  do
5567
    {
5568
      /* If we can't generate the constant with a two-insn movi / shori
5569
         sequence, try some other strategies.  */
5570
      if (! CONST_OK_FOR_I16 (high))
5571
        {
5572
          /* Try constant load / left shift.  We know VAL != 0.  */
5573
          val2 = val ^ (val-1);
5574
          if (val2 > 0x1ffff)
5575
            {
5576
              int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5577
 
5578
              if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5579
                  || (! CONST_OK_FOR_I16 (high >> 16)
5580
                      && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5581
                {
5582
                  val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5583
                  operands[1] = gen_ashldi3_media (operands[0], operands[0],
5584
                                                   GEN_INT (trailing_zeroes));
5585
                  break;
5586
                }
5587
            }
5588
          /* Try constant load / right shift.  */
5589
          val2 = (val >> 15) + 1;
5590
          if (val2 == (val2 & -val2))
5591
            {
5592
              int shift = 49 - exact_log2 (val2);
5593
 
5594
              val2 = trunc_int_for_mode (val << shift, DImode);
5595
              if (CONST_OK_FOR_I16 (val2))
5596
                {
5597
                  operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5598
                                                   GEN_INT (shift));
5599
                  break;
5600
                }
5601
            }
5602
          /* Try mperm.w .  */
5603
          val2 = val & 0xffff;
5604
          if ((val >> 16 & 0xffff) == val2
5605
              && (val >> 32 & 0xffff) == val2
5606
              && (val >> 48 & 0xffff) == val2)
5607
            {
5608
              val2 = (HOST_WIDE_INT) val >> 48;
5609
              operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5610
              operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5611
              break;
5612
            }
5613
          /* Try movi / mshflo.l  */
5614
          val2 = (HOST_WIDE_INT) val >> 32;
5615
          if (val2 == ((unsigned HOST_WIDE_INT)
5616
                        trunc_int_for_mode (val, SImode)))
5617
            {
5618
              operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5619
                                             operands[0]);
5620
              break;
5621
            }
5622
          /* Try movi / mshflo.l w/ r63.  */
5623
          val2 = val + ((HOST_WIDE_INT) -1 << 32);
5624
          if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5625
            {
5626
              operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5627
                                             const0_rtx);
5628
              break;
5629
            }
5630
        }
5631
      val2 = high;
5632
      operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5633
    }
5634
  while (0);
5635
  operands[2] = GEN_INT (val2);
5636
}")
5637
 
5638
(define_split
5639
  [(set (match_operand:DI 0 "ext_dest_operand" "")
5640
        (match_operand:DI 1 "immediate_operand" ""))]
5641
  "TARGET_SHMEDIA && reload_completed
5642
   && GET_CODE (operands[1]) == CONST_DOUBLE"
5643
  [(set (match_dup 0) (match_dup 2))
5644
  (set (match_dup 0)
5645
       (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5646
  "
5647
{
5648
  unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5649
  unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5650
  unsigned HOST_WIDE_INT val = low;
5651
  unsigned HOST_WIDE_INT sign;
5652
 
5653
  /* Zero-extend the 16 least-significant bits.  */
5654
  val &= 0xffff;
5655
  operands[1] = GEN_INT (val);
5656
 
5657
  /* Arithmetic shift right the double-word by 16 bits.  */
5658
  low >>= 16;
5659
  low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5660
  high >>= 16;
5661
  sign = 1;
5662
  sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5663
  high ^= sign;
5664
  high -= sign;
5665
 
5666
  /* This will only be true if high is a sign-extension of low, i.e.,
5667
     it must be either 0 or (unsigned)-1, and be zero iff the
5668
     most-significant bit of low is set.  */
5669
  if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5670
    operands[2] = GEN_INT (low);
5671
  else
5672
    operands[2] = immed_double_const (low, high, DImode);
5673
}")
5674
 
5675
(define_insn "shori_media"
5676
  [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5677
        (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5678
                           (const_int 16))
5679
                (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5680
  "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5681
  "@
5682
        shori   %u2, %0
5683
        #"
5684
  [(set_attr "type" "arith_media,*")])
5685
 
5686
(define_insn "*shori_media_si"
5687
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5688
        (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5689
                           (const_int 16))
5690
                (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5691
  "TARGET_SHMEDIA"
5692
  "shori        %u2, %0")
5693
 
5694
(define_expand "movdi"
5695
  [(set (match_operand:DI 0 "general_movdst_operand" "")
5696
        (match_operand:DI 1 "general_movsrc_operand" ""))]
5697
  ""
5698
  "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5699
 
5700
(define_insn "movdf_media"
5701
  [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5702
        (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5703
  "TARGET_SHMEDIA_FPU
5704
   && (register_operand (operands[0], DFmode)
5705
       || sh_register_operand (operands[1], DFmode))"
5706
  "@
5707
        fmov.d  %1, %0
5708
        fmov.qd %N1, %0
5709
        fmov.dq %1, %0
5710
        add     %1, r63, %0
5711
        #
5712
        fld%M1.d        %m1, %0
5713
        fst%M0.d        %m0, %1
5714
        ld%M1.q %m1, %0
5715
        st%M0.q %m0, %N1"
5716
  [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5717
 
5718
(define_insn "movdf_media_nofpu"
5719
  [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5720
        (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5721
  "TARGET_SHMEDIA
5722
   && (register_operand (operands[0], DFmode)
5723
       || sh_register_operand (operands[1], DFmode))"
5724
  "@
5725
        add     %1, r63, %0
5726
        #
5727
        ld%M1.q %m1, %0
5728
        st%M0.q %m0, %N1"
5729
  [(set_attr "type" "arith_media,*,load_media,store_media")])
5730
 
5731
(define_split
5732
  [(set (match_operand:DF 0 "arith_reg_dest" "")
5733
        (match_operand:DF 1 "immediate_operand" ""))]
5734
  "TARGET_SHMEDIA && reload_completed"
5735
  [(set (match_dup 3) (match_dup 2))]
5736
  "
5737
{
5738
  int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5739
  long values[2];
5740
  REAL_VALUE_TYPE value;
5741
 
5742
  REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5743
  REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5744
 
5745
  if (HOST_BITS_PER_WIDE_INT >= 64)
5746
    operands[2] = immed_double_const ((unsigned long) values[endian]
5747
                                      | ((HOST_WIDE_INT) values[1 - endian]
5748
                                         << 32), 0, DImode);
5749
  else
5750
    {
5751
      gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5752
      operands[2] = immed_double_const (values[endian], values[1 - endian],
5753
                                        DImode);
5754
    }
5755
 
5756
  operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5757
}")
5758
 
5759
;; ??? This should be a define expand.
5760
 
5761
(define_insn "movdf_k"
5762
  [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5763
        (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5764
  "TARGET_SH1
5765
   && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5766
       /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5767
       || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5768
       || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5769
   && (arith_reg_operand (operands[0], DFmode)
5770
       || arith_reg_operand (operands[1], DFmode))"
5771
  "* return output_movedouble (insn, operands, DFmode);"
5772
  [(set_attr "length" "4")
5773
   (set_attr "type" "move,pcload,load,store")])
5774
 
5775
;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5776
;; However, the d/F/c/z alternative cannot be split directly; it is converted
5777
;; with special code in machine_dependent_reorg into a load of the R0_REG and
5778
;; the d/m/c/X alternative, which is split later into single-precision
5779
;; instructions.  And when not optimizing, no splits are done before fixing
5780
;; up pcloads, so we need usable length information for that.
5781
(define_insn "movdf_i4"
5782
  [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5783
        (match_operand:DF 1 "general_movsrc_operand"  "d,r,F,m,d,FQ,m,r,d,r"))
5784
   (use (match_operand:PSI 2 "fpscr_operand"          "c,c,c,c,c,c,c,c,c,c"))
5785
   (clobber (match_scratch:SI 3                      "=X,X,&z,X,X,X,X,X,X,X"))]
5786
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5787
   && (arith_reg_operand (operands[0], DFmode)
5788
       || arith_reg_operand (operands[1], DFmode))"
5789
  {
5790
    switch (which_alternative)
5791
    {
5792
    case 0:
5793
      if (TARGET_FMOVD)
5794
        return "fmov    %1,%0";
5795
      else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
5796
        return "fmov    %R1,%R0\n\tfmov %S1,%S0";
5797
      else
5798
        return "fmov    %S1,%S0\n\tfmov %R1,%R0";
5799
    case 3:
5800
    case 4:
5801
      return "fmov.d    %1,%0";
5802
    default:
5803
      return "#";
5804
    }
5805
  }
5806
  [(set_attr_alternative "length"
5807
     [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
5808
      (const_int 4)
5809
      (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5810
      (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5811
      (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5812
      (const_int 4)
5813
      (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5814
      ;; We can't use 4-byte push/pop on SHcompact, so we have to
5815
      ;; increment or decrement r15 explicitly.
5816
      (if_then_else
5817
       (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5818
       (const_int 10) (const_int 8))
5819
      (if_then_else
5820
       (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5821
       (const_int 10) (const_int 8))])
5822
   (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5823
   (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5824
   (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5825
                                           (const_string "double")
5826
                                           (const_string "none")))])
5827
 
5828
;; Moving DFmode between fp/general registers through memory
5829
;; (the top of the stack) is faster than moving through fpul even for
5830
;; little endian.  Because the type of an instruction is important for its
5831
;; scheduling,  it is beneficial to split these operations, rather than
5832
;; emitting them in one single chunk, even if this will expose a stack
5833
;; use that will prevent scheduling of other stack accesses beyond this
5834
;; instruction.
5835
(define_split
5836
  [(set (match_operand:DF 0 "register_operand" "")
5837
        (match_operand:DF 1 "register_operand" ""))
5838
   (use (match_operand:PSI 2 "fpscr_operand" ""))
5839
   (clobber (match_scratch:SI 3 "=X"))]
5840
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5841
   && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5842
  [(const_int 0)]
5843
  "
5844
{
5845
  rtx insn, tos;
5846
 
5847
  if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5848
    {
5849
      emit_move_insn (stack_pointer_rtx,
5850
                      plus_constant (stack_pointer_rtx, -8));
5851
      tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5852
    }
5853
  else
5854
    tos = gen_tmp_stack_mem (DFmode,
5855
                             gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5856
  insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5857
  if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5858
    add_reg_note (insn, REG_INC, stack_pointer_rtx);
5859
  if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5860
    tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5861
  else
5862
    tos = gen_tmp_stack_mem (DFmode,
5863
                             gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5864
  insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5865
  if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5866
    emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5867
  else
5868
    add_reg_note (insn, REG_INC, stack_pointer_rtx);
5869
  DONE;
5870
}")
5871
 
5872
;; local-alloc sometimes allocates scratch registers even when not required,
5873
;; so we must be prepared to handle these.
5874
 
5875
;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5876
(define_split
5877
  [(set (match_operand:DF 0 "general_movdst_operand" "")
5878
        (match_operand:DF 1 "general_movsrc_operand"  ""))
5879
   (use (match_operand:PSI 2 "fpscr_operand" ""))
5880
   (clobber (match_scratch:SI 3 ""))]
5881
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5882
   && reload_completed
5883
   && true_regnum (operands[0]) < 16
5884
   && true_regnum (operands[1]) < 16"
5885
  [(set (match_dup 0) (match_dup 1))]
5886
  "
5887
{
5888
  /* If this was a reg <-> mem operation with base + index reg addressing,
5889
     we have to handle this in a special way.  */
5890
  rtx mem = operands[0];
5891
  int store_p = 1;
5892
  if (! memory_operand (mem, DFmode))
5893
    {
5894
      mem = operands[1];
5895
      store_p = 0;
5896
    }
5897
  if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5898
    mem = SUBREG_REG (mem);
5899
  if (MEM_P (mem))
5900
    {
5901
      rtx addr = XEXP (mem, 0);
5902
      if (GET_CODE (addr) == PLUS
5903
          && REG_P (XEXP (addr, 0))
5904
          && REG_P (XEXP (addr, 1)))
5905
        {
5906
          int offset;
5907
          rtx reg0 = gen_rtx_REG (Pmode, 0);
5908
          rtx regop = operands[store_p], word0 ,word1;
5909
 
5910
          if (GET_CODE (regop) == SUBREG)
5911
            alter_subreg (®op);
5912
          if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5913
            offset = 2;
5914
          else
5915
            offset = 4;
5916
          mem = copy_rtx (mem);
5917
          PUT_MODE (mem, SImode);
5918
          word0 = gen_rtx_SUBREG (SImode, regop, 0);
5919
          alter_subreg (&word0);
5920
          word1 = gen_rtx_SUBREG (SImode, regop, 4);
5921
          alter_subreg (&word1);
5922
          if (store_p || ! refers_to_regno_p (REGNO (word0),
5923
                                              REGNO (word0) + 1, addr, 0))
5924
            {
5925
              emit_insn (store_p
5926
                         ? gen_movsi_ie (mem, word0)
5927
                         : gen_movsi_ie (word0, mem));
5928
              emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5929
              mem = copy_rtx (mem);
5930
              emit_insn (store_p
5931
                         ? gen_movsi_ie (mem, word1)
5932
                         : gen_movsi_ie (word1, mem));
5933
              emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5934
            }
5935
          else
5936
            {
5937
              emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5938
              emit_insn (gen_movsi_ie (word1, mem));
5939
              emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5940
              mem = copy_rtx (mem);
5941
              emit_insn (gen_movsi_ie (word0, mem));
5942
            }
5943
          DONE;
5944
        }
5945
    }
5946
}")
5947
 
5948
;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5949
(define_split
5950
  [(set (match_operand:DF 0 "register_operand" "")
5951
        (match_operand:DF 1 "memory_operand"  ""))
5952
   (use (match_operand:PSI 2 "fpscr_operand" ""))
5953
   (clobber (reg:SI R0_REG))]
5954
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5955
  [(parallel [(set (match_dup 0) (match_dup 1))
5956
              (use (match_dup 2))
5957
              (clobber (scratch:SI))])]
5958
  "")
5959
 
5960
(define_expand "reload_indf__frn"
5961
  [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5962
                   (match_operand:DF 1 "immediate_operand" "FQ"))
5963
              (use (reg:PSI FPSCR_REG))
5964
              (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5965
  "TARGET_SH1"
5966
  "")
5967
 
5968
(define_expand "reload_outdf__RnFRm"
5969
  [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5970
                   (match_operand:DF 1 "register_operand" "af,r"))
5971
              (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5972
  "TARGET_SH1"
5973
  "")
5974
 
5975
;; Simplify no-op moves.
5976
(define_split
5977
  [(set (match_operand:SF 0 "register_operand" "")
5978
        (match_operand:SF 1 "register_operand" ""))
5979
   (use (match_operand:PSI 2 "fpscr_operand" ""))
5980
   (clobber (match_scratch:SI 3 ""))]
5981
  "TARGET_SH2E && reload_completed
5982
   && true_regnum (operands[0]) == true_regnum (operands[1])"
5983
  [(set (match_dup 0) (match_dup 0))]
5984
  "")
5985
 
5986
;; fmovd substitute post-reload splits
5987
(define_split
5988
  [(set (match_operand:DF 0 "register_operand" "")
5989
        (match_operand:DF 1 "register_operand" ""))
5990
   (use (match_operand:PSI 2 "fpscr_operand" ""))
5991
   (clobber (match_scratch:SI 3 ""))]
5992
  "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5993
   && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5994
   && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5995
  [(const_int 0)]
5996
  "
5997
{
5998
  int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5999
  emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6000
                           gen_rtx_REG (SFmode, src), operands[2]));
6001
  emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6002
                           gen_rtx_REG (SFmode, src + 1), operands[2]));
6003
  DONE;
6004
}")
6005
 
6006
(define_split
6007
  [(set (match_operand:DF 0 "register_operand" "")
6008
        (mem:DF (match_operand:SI 1 "register_operand" "")))
6009
   (use (match_operand:PSI 2 "fpscr_operand" ""))
6010
   (clobber (match_scratch:SI 3 ""))]
6011
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6012
   && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6013
   && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6014
  [(const_int 0)]
6015
  "
6016
{
6017
  int regno = true_regnum (operands[0]);
6018
  rtx insn;
6019
  rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6020
  rtx mem2
6021
    = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6022
  insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6023
                                           regno + !! TARGET_LITTLE_ENDIAN),
6024
                                  mem2, operands[2]));
6025
  add_reg_note (insn, REG_INC, operands[1]);
6026
  insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6027
                                               regno + ! TARGET_LITTLE_ENDIAN),
6028
                                  change_address (mem, SFmode, NULL_RTX),
6029
                                  operands[2]));
6030
  DONE;
6031
}")
6032
 
6033
(define_split
6034
  [(set (match_operand:DF 0 "register_operand" "")
6035
        (match_operand:DF 1 "memory_operand" ""))
6036
   (use (match_operand:PSI 2 "fpscr_operand" ""))
6037
   (clobber (match_scratch:SI 3 ""))]
6038
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6039
   && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6040
  [(const_int 0)]
6041
{
6042
  int regno = true_regnum (operands[0]);
6043
  rtx addr, insn;
6044
  rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6045
  rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6046
  rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6047
 
6048
  operands[1] = copy_rtx (mem2);
6049
  addr = XEXP (mem2, 0);
6050
 
6051
  switch (GET_CODE (addr))
6052
    {
6053
    case REG:
6054
      /* This is complicated.  If the register is an arithmetic register
6055
         we can just fall through to the REG+DISP case below.  Otherwise
6056
         we have to use a combination of POST_INC and REG addressing...  */
6057
      if (! arith_reg_operand (operands[1], SFmode))
6058
        {
6059
          XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6060
          insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6061
          add_reg_note (insn, REG_INC, XEXP (addr, 0));
6062
 
6063
          emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6064
 
6065
          /* If we have modified the stack pointer, the value that we have
6066
             read with post-increment might be modified by an interrupt,
6067
             so write it back.  */
6068
          if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6069
            emit_insn (gen_push_e (reg0));
6070
          else
6071
            emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6072
          break;
6073
        }
6074
      /* Fall through.  */
6075
 
6076
    case PLUS:
6077
      emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6078
      operands[1] = copy_rtx (operands[1]);
6079
      XEXP (operands[1], 0) = plus_constant (addr, 4);
6080
      emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6081
      break;
6082
 
6083
    case POST_INC:
6084
      insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6085
      add_reg_note (insn, REG_INC, XEXP (addr, 0));
6086
 
6087
      insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6088
      add_reg_note (insn, REG_INC, XEXP (addr, 0));
6089
      break;
6090
 
6091
    default:
6092
      debug_rtx (addr);
6093
      gcc_unreachable ();
6094
    }
6095
 
6096
  DONE;
6097
})
6098
 
6099
(define_split
6100
  [(set (match_operand:DF 0 "memory_operand" "")
6101
        (match_operand:DF 1 "register_operand" ""))
6102
   (use (match_operand:PSI 2 "fpscr_operand" ""))
6103
   (clobber (match_scratch:SI 3 ""))]
6104
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6105
   && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6106
  [(const_int 0)]
6107
{
6108
  int regno = true_regnum (operands[1]);
6109
  rtx insn, addr;
6110
  rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6111
  rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6112
 
6113
  operands[0] = copy_rtx (operands[0]);
6114
  PUT_MODE (operands[0], SFmode);
6115
  addr = XEXP (operands[0], 0);
6116
 
6117
  switch (GET_CODE (addr))
6118
    {
6119
    case REG:
6120
      /* This is complicated.  If the register is an arithmetic register
6121
         we can just fall through to the REG+DISP case below.  Otherwise
6122
         we have to use a combination of REG and PRE_DEC addressing...  */
6123
      if (! arith_reg_operand (operands[0], SFmode))
6124
        {
6125
          emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6126
          emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6127
 
6128
          operands[0] = copy_rtx (operands[0]);
6129
          XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6130
 
6131
          insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6132
          add_reg_note (insn, REG_INC, XEXP (addr, 0));
6133
          break;
6134
        }
6135
      /* Fall through.  */
6136
 
6137
    case PLUS:
6138
      /* Since REG+DISP addressing has already been decided upon by gcc
6139
         we can rely upon it having chosen an arithmetic register as the
6140
         register component of the address.  Just emit the lower numbered
6141
         register first, to the lower address, then the higher numbered
6142
         register to the higher address.  */
6143
      emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6144
 
6145
      operands[0] = copy_rtx (operands[0]);
6146
      XEXP (operands[0], 0) = plus_constant (addr, 4);
6147
 
6148
      emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6149
      break;
6150
 
6151
    case PRE_DEC:
6152
      /* This is easy.  Output the word to go to the higher address
6153
         first (ie the word in the higher numbered register) then the
6154
         word to go to the lower address.  */
6155
 
6156
      insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6157
      add_reg_note (insn, REG_INC, XEXP (addr, 0));
6158
 
6159
      insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6160
      add_reg_note (insn, REG_INC, XEXP (addr, 0));
6161
      break;
6162
 
6163
    default:
6164
      /* FAIL; */
6165
      debug_rtx (addr);
6166
      gcc_unreachable ();
6167
    }
6168
 
6169
  DONE;
6170
})
6171
 
6172
;; If the output is a register and the input is memory or a register, we have
6173
;; to be careful and see which word needs to be loaded first.
6174
 
6175
(define_split
6176
  [(set (match_operand:DF 0 "general_movdst_operand" "")
6177
        (match_operand:DF 1 "general_movsrc_operand" ""))]
6178
  "TARGET_SH1 && reload_completed"
6179
  [(set (match_dup 2) (match_dup 3))
6180
   (set (match_dup 4) (match_dup 5))]
6181
  "
6182
{
6183
  int regno;
6184
 
6185
  if ((MEM_P (operands[0])
6186
       && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6187
      || (MEM_P (operands[1])
6188
          && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6189
    FAIL;
6190
 
6191
  switch (GET_CODE (operands[0]))
6192
    {
6193
    case REG:
6194
      regno = REGNO (operands[0]);
6195
      break;
6196
    case SUBREG:
6197
      regno = subreg_regno (operands[0]);
6198
      break;
6199
    case MEM:
6200
      regno = -1;
6201
      break;
6202
    default:
6203
      gcc_unreachable ();
6204
    }
6205
 
6206
  if (regno == -1
6207
      || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6208
    {
6209
      operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6210
      operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6211
      operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6212
      operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6213
    }
6214
  else
6215
    {
6216
      operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6217
      operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6218
      operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6219
      operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6220
    }
6221
 
6222
  if (operands[2] == 0 || operands[3] == 0
6223
      || operands[4] == 0 || operands[5] == 0)
6224
    FAIL;
6225
}")
6226
 
6227
;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6228
;; used only once, let combine add in the index again.
6229
 
6230
(define_split
6231
  [(set (match_operand:SI 0 "register_operand" "")
6232
        (match_operand:SI 1 "" ""))
6233
   (clobber (match_operand 2 "register_operand" ""))]
6234
  "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6235
   && ALLOW_INDEXED_ADDRESS"
6236
  [(use (reg:SI R0_REG))]
6237
  "
6238
{
6239
  rtx addr, reg, const_int;
6240
 
6241
  if (!MEM_P (operands[1]))
6242
    FAIL;
6243
  addr = XEXP (operands[1], 0);
6244
  if (GET_CODE (addr) != PLUS)
6245
    FAIL;
6246
  reg = XEXP (addr, 0);
6247
  const_int = XEXP (addr, 1);
6248
  if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6249
         && CONST_INT_P (const_int)))
6250
    FAIL;
6251
  emit_move_insn (operands[2], const_int);
6252
  emit_move_insn (operands[0],
6253
                  change_address (operands[1], VOIDmode,
6254
                                  gen_rtx_PLUS (SImode, reg, operands[2])));
6255
  DONE;
6256
}")
6257
 
6258
(define_split
6259
  [(set (match_operand:SI 1 "" "")
6260
        (match_operand:SI 0 "register_operand" ""))
6261
   (clobber (match_operand 2 "register_operand" ""))]
6262
  "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6263
   && ALLOW_INDEXED_ADDRESS"
6264
  [(use (reg:SI R0_REG))]
6265
  "
6266
{
6267
  rtx addr, reg, const_int;
6268
 
6269
  if (!MEM_P (operands[1]))
6270
    FAIL;
6271
  addr = XEXP (operands[1], 0);
6272
  if (GET_CODE (addr) != PLUS)
6273
    FAIL;
6274
  reg = XEXP (addr, 0);
6275
  const_int = XEXP (addr, 1);
6276
  if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6277
         && CONST_INT_P (const_int)))
6278
    FAIL;
6279
  emit_move_insn (operands[2], const_int);
6280
  emit_move_insn (change_address (operands[1], VOIDmode,
6281
                                  gen_rtx_PLUS (SImode, reg, operands[2])),
6282
                  operands[0]);
6283
  DONE;
6284
}")
6285
 
6286
(define_expand "movdf"
6287
  [(set (match_operand:DF 0 "general_movdst_operand" "")
6288
        (match_operand:DF 1 "general_movsrc_operand" ""))]
6289
  ""
6290
  "
6291
{
6292
  if (prepare_move_operands (operands, DFmode)) DONE;
6293
  if (TARGET_SHMEDIA)
6294
    {
6295
      if (TARGET_SHMEDIA_FPU)
6296
        emit_insn (gen_movdf_media (operands[0], operands[1]));
6297
      else
6298
        emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6299
      DONE;
6300
    }
6301
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6302
    {
6303
      emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6304
      DONE;
6305
    }
6306
}")
6307
 
6308
;;This is incompatible with the way gcc uses subregs.
6309
;;(define_insn "movv2sf_i"
6310
;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6311
;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6312
;;  "TARGET_SHMEDIA_FPU
6313
;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6314
;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6315
;;  "@
6316
;;      #
6317
;;      fld%M1.p        %m1, %0
6318
;;      fst%M0.p        %m0, %1"
6319
;;  [(set_attr "type" "*,fload_media,fstore_media")])
6320
 
6321
(define_insn_and_split "movv2sf_i"
6322
  [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6323
        (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6324
  "TARGET_SHMEDIA_FPU"
6325
  "#"
6326
  "TARGET_SHMEDIA_FPU && reload_completed"
6327
  [(set (match_dup 0) (match_dup 1))]
6328
  "
6329
{
6330
  operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6331
  operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6332
}")
6333
 
6334
(define_expand "movv2sf"
6335
  [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6336
        (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6337
  "TARGET_SHMEDIA_FPU"
6338
  "
6339
{
6340
  if (prepare_move_operands (operands, V2SFmode))
6341
    DONE;
6342
}")
6343
 
6344
(define_expand "addv2sf3"
6345
  [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6346
   (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6347
   (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6348
  "TARGET_SHMEDIA_FPU"
6349
  "
6350
{
6351
  sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6352
  DONE;
6353
}")
6354
 
6355
(define_expand "subv2sf3"
6356
  [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6357
   (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6358
   (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6359
  "TARGET_SHMEDIA_FPU"
6360
  "
6361
{
6362
  sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6363
  DONE;
6364
}")
6365
 
6366
(define_expand "mulv2sf3"
6367
  [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6368
   (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6369
   (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6370
  "TARGET_SHMEDIA_FPU"
6371
  "
6372
{
6373
  sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6374
  DONE;
6375
}")
6376
 
6377
(define_expand "divv2sf3"
6378
  [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6379
   (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6380
   (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6381
  "TARGET_SHMEDIA_FPU"
6382
  "
6383
{
6384
  sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6385
  DONE;
6386
}")
6387
 
6388
(define_insn_and_split "*movv4sf_i"
6389
  [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6390
        (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6391
  "TARGET_SHMEDIA_FPU"
6392
  "#"
6393
  "&& reload_completed"
6394
  [(const_int 0)]
6395
  "
6396
{
6397
  int i;
6398
 
6399
  for (i = 0; i < 4/2; i++)
6400
    {
6401
      rtx x, y;
6402
 
6403
      if (MEM_P (operands[0]))
6404
        x = adjust_address (operands[0], V2SFmode,
6405
                            i * GET_MODE_SIZE (V2SFmode));
6406
      else
6407
        x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6408
 
6409
      if (MEM_P (operands[1]))
6410
        y = adjust_address (operands[1], V2SFmode,
6411
                            i * GET_MODE_SIZE (V2SFmode));
6412
      else
6413
        y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6414
 
6415
      emit_insn (gen_movv2sf_i (x, y));
6416
    }
6417
 
6418
  DONE;
6419
}"
6420
  [(set_attr "length" "8")])
6421
 
6422
(define_expand "movv4sf"
6423
  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6424
        (match_operand:V4SF 1 "general_operand" ""))]
6425
  "TARGET_SHMEDIA_FPU"
6426
  "
6427
{
6428
  if (prepare_move_operands (operands, V4SFmode))
6429
    DONE;
6430
}")
6431
 
6432
(define_insn_and_split "*movv16sf_i"
6433
  [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6434
        (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6435
  "TARGET_SHMEDIA_FPU"
6436
  "#"
6437
  "&& reload_completed"
6438
  [(const_int 0)]
6439
  "
6440
{
6441
  int i;
6442
 
6443
  for (i = 0; i < 16/2; i++)
6444
    {
6445
      rtx x,y;
6446
 
6447
      if (MEM_P (operands[0]))
6448
        x = adjust_address (operands[0], V2SFmode,
6449
                            i * GET_MODE_SIZE (V2SFmode));
6450
      else
6451
        {
6452
          x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6453
          alter_subreg (&x);
6454
        }
6455
 
6456
      if (MEM_P (operands[1]))
6457
        y = adjust_address (operands[1], V2SFmode,
6458
                            i * GET_MODE_SIZE (V2SFmode));
6459
      else
6460
        {
6461
          y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6462
          alter_subreg (&y);
6463
        }
6464
 
6465
      emit_insn (gen_movv2sf_i (x, y));
6466
    }
6467
 
6468
  DONE;
6469
}"
6470
  [(set_attr "length" "32")])
6471
 
6472
(define_expand "movv16sf"
6473
  [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6474
        (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6475
  "TARGET_SHMEDIA_FPU"
6476
  "
6477
{
6478
  if (prepare_move_operands (operands, V16SFmode))
6479
    DONE;
6480
}")
6481
 
6482
(define_insn "movsf_media"
6483
  [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6484
        (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6485
  "TARGET_SHMEDIA_FPU
6486
   && (register_operand (operands[0], SFmode)
6487
       || sh_register_operand (operands[1], SFmode))"
6488
  "@
6489
        fmov.s  %1, %0
6490
        fmov.ls %N1, %0
6491
        fmov.sl %1, %0
6492
        add.l   %1, r63, %0
6493
        #
6494
        fld%M1.s        %m1, %0
6495
        fst%M0.s        %m0, %1
6496
        ld%M1.l %m1, %0
6497
        st%M0.l %m0, %N1"
6498
  [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6499
   (set (attr "highpart")
6500
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6501
               (const_string "user")]
6502
              (const_string "ignore")))])
6503
 
6504
(define_insn "movsf_media_nofpu"
6505
  [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6506
        (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6507
  "TARGET_SHMEDIA
6508
   && (register_operand (operands[0], SFmode)
6509
       || sh_register_operand (operands[1], SFmode))"
6510
  "@
6511
        add.l   %1, r63, %0
6512
        #
6513
        ld%M1.l %m1, %0
6514
        st%M0.l %m0, %N1"
6515
  [(set_attr "type" "arith_media,*,load_media,store_media")
6516
   (set (attr "highpart")
6517
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6518
               (const_string "user")]
6519
              (const_string "ignore")))])
6520
 
6521
(define_split
6522
  [(set (match_operand:SF 0 "arith_reg_dest" "")
6523
        (match_operand:SF 1 "immediate_operand" ""))]
6524
  "TARGET_SHMEDIA && reload_completed
6525
   && ! FP_REGISTER_P (true_regnum (operands[0]))"
6526
  [(set (match_dup 3) (match_dup 2))]
6527
  "
6528
{
6529
  long values;
6530
  REAL_VALUE_TYPE value;
6531
 
6532
  REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6533
  REAL_VALUE_TO_TARGET_SINGLE (value, values);
6534
  operands[2] = GEN_INT (values);
6535
 
6536
  operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6537
}")
6538
 
6539
(define_insn "movsf_i"
6540
  [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6541
        (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6542
  "TARGET_SH1
6543
   && (! TARGET_SH2E
6544
       /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6545
       || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6546
       || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6547
   && (arith_reg_operand (operands[0], SFmode)
6548
       || arith_reg_operand (operands[1], SFmode))"
6549
  "@
6550
        mov     %1,%0
6551
        mov     #0,%0
6552
        mov.l   %1,%0
6553
        mov.l   %1,%0
6554
        mov.l   %1,%0
6555
        lds     %1,%0
6556
        sts     %1,%0"
6557
  [(set_attr "type" "move,move,pcload,load,store,move,move")])
6558
 
6559
;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6560
;; update_flow_info would not know where to put REG_EQUAL notes
6561
;; when the destination changes mode.
6562
(define_insn "movsf_ie"
6563
  [(set (match_operand:SF 0 "general_movdst_operand"
6564
         "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6565
        (match_operand:SF 1 "general_movsrc_operand"
6566
          "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6567
   (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"))
6568
   (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6569
 
6570
  "TARGET_SH2E
6571
   && (arith_reg_operand (operands[0], SFmode)
6572
       || arith_reg_operand (operands[1], SFmode)
6573
       || arith_reg_operand (operands[3], SImode)
6574
       || (fpul_operand (operands[0], SFmode)
6575
           && memory_operand (operands[1], SFmode)
6576
           && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6577
       || (fpul_operand (operands[1], SFmode)
6578
           && memory_operand (operands[0], SFmode)
6579
           && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6580
  "@
6581
        fmov    %1,%0
6582
        mov     %1,%0
6583
        fldi0   %0
6584
        fldi1   %0
6585
        #
6586
        fmov.s  %1,%0
6587
        fmov.s  %1,%0
6588
        mov.l   %1,%0
6589
        mov.l   %1,%0
6590
        mov.l   %1,%0
6591
        fsts    fpul,%0
6592
        flds    %1,fpul
6593
        lds.l   %1,%0
6594
        #
6595
        sts     %1,%0
6596
        lds     %1,%0
6597
        sts.l   %1,%0
6598
        lds.l   %1,%0
6599
        ! move optimized away"
6600
  [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6601
   (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6602
   (set_attr_alternative "length"
6603
     [(const_int 2)
6604
      (const_int 2)
6605
      (const_int 2)
6606
      (const_int 2)
6607
      (const_int 4)
6608
      (if_then_else
6609
        (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6610
        (const_int 4) (const_int 2))
6611
      (if_then_else
6612
        (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6613
        (const_int 4) (const_int 2))
6614
      (const_int 2)
6615
      (if_then_else
6616
        (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6617
        (const_int 4) (const_int 2))
6618
      (if_then_else
6619
        (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6620
        (const_int 4) (const_int 2))
6621
      (const_int 2)
6622
      (const_int 2)
6623
      (const_int 2)
6624
      (const_int 4)
6625
      (const_int 2)
6626
      (const_int 2)
6627
      (const_int 2)
6628
      (const_int 2)
6629
      (const_int 0)])
6630
   (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6631
                                           (const_string "single")
6632
                                           (const_string "single")))])
6633
 
6634
(define_split
6635
  [(set (match_operand:SF 0 "register_operand" "")
6636
        (match_operand:SF 1 "register_operand" ""))
6637
   (use (match_operand:PSI 2 "fpscr_operand" ""))
6638
   (clobber (reg:SI FPUL_REG))]
6639
  "TARGET_SH1"
6640
  [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6641
              (use (match_dup 2))
6642
              (clobber (scratch:SI))])
6643
   (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6644
              (use (match_dup 2))
6645
              (clobber (scratch:SI))])]
6646
  "")
6647
 
6648
(define_expand "movsf"
6649
  [(set (match_operand:SF 0 "general_movdst_operand" "")
6650
        (match_operand:SF 1 "general_movsrc_operand" ""))]
6651
  ""
6652
  "
6653
{
6654
  if (prepare_move_operands (operands, SFmode))
6655
    DONE;
6656
  if (TARGET_SHMEDIA)
6657
    {
6658
      if (TARGET_SHMEDIA_FPU)
6659
        emit_insn (gen_movsf_media (operands[0], operands[1]));
6660
      else
6661
        emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6662
      DONE;
6663
    }
6664
  if (TARGET_SH2E)
6665
    {
6666
      emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6667
      DONE;
6668
    }
6669
}")
6670
 
6671
(define_insn "mov_nop"
6672
  [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6673
  "TARGET_SH2E"
6674
  ""
6675
  [(set_attr "length" "0")
6676
   (set_attr "type" "nil")])
6677
 
6678
(define_expand "reload_insf__frn"
6679
  [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6680
                   (match_operand:SF 1 "immediate_operand" "FQ"))
6681
              (use (reg:PSI FPSCR_REG))
6682
              (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6683
  "TARGET_SH1"
6684
  "")
6685
 
6686
(define_expand "reload_insi__i_fpul"
6687
  [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6688
                   (match_operand:SI 1 "immediate_operand" "i"))
6689
              (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6690
  "TARGET_SH1"
6691
  "")
6692
 
6693
(define_expand "ptabs"
6694
  [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6695
  "TARGET_SHMEDIA"
6696
  "
6697
{
6698
  if (!TARGET_PT_FIXED)
6699
    {
6700
      rtx eq = operands[1];
6701
 
6702
      /* ??? For canonical RTL we really should remove any CONST from EQ
6703
         before wrapping it in the AND, and finally wrap the EQ into a
6704
         const if is constant.  However, for reload we must expose the
6705
         input register or symbolic constant, and we can't have
6706
         different insn structures outside of the operands for different
6707
         alternatives of the same pattern.  */
6708
      eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6709
                       GEN_INT (3));
6710
      operands[1]
6711
        = (gen_rtx_IF_THEN_ELSE
6712
            (PDImode,
6713
             eq,
6714
             gen_rtx_MEM (PDImode, operands[1]),
6715
             gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6716
                            PDImode, operands[1])));
6717
    }
6718
}")
6719
 
6720
;; expanded by ptabs expander.
6721
(define_insn "*extendsipdi_media"
6722
  [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6723
        (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6724
                                                          "r,Csy")
6725
                                      (const_int 3))
6726
                              (const_int 3))
6727
                          (mem:PDI (match_dup 1))
6728
                          (sign_extend:PDI (match_dup 1))))]
6729
  "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6730
  "@
6731
        ptabs   %1, %0
6732
        pt      %1, %0"
6733
  [(set_attr "type"   "ptabs_media,pt_media")
6734
   (set_attr "length" "4,*")])
6735
 
6736
(define_insn "*truncdipdi_media"
6737
  [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6738
        (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6739
                                                          "r,Csy")
6740
                                      (const_int 3))
6741
                              (const_int 3))
6742
                          (mem:PDI (match_dup 1))
6743
                          (truncate:PDI (match_dup 1))))]
6744
  "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6745
  "@
6746
        ptabs   %1, %0
6747
        pt      %1, %0"
6748
  [(set_attr "type"   "ptabs_media,pt_media")
6749
   (set_attr "length" "4,*")])
6750
 
6751
(define_insn "*movsi_y"
6752
  [(set (match_operand:SI 0 "register_operand" "=y,y")
6753
        (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6754
   (clobber (match_scratch:SI 2 "=&z,r"))]
6755
  "TARGET_SH2E
6756
   && (reload_in_progress || reload_completed)"
6757
  "#"
6758
  [(set_attr "length" "4")
6759
   (set_attr "type" "pcload,move")])
6760
 
6761
(define_split
6762
  [(set (match_operand:SI 0 "register_operand" "")
6763
        (match_operand:SI 1 "immediate_operand" ""))
6764
   (clobber (match_operand:SI 2 "register_operand" ""))]
6765
  "TARGET_SH1"
6766
  [(set (match_dup 2) (match_dup 1))
6767
   (set (match_dup 0) (match_dup 2))]
6768
  "")
6769
 
6770
(define_split
6771
  [(set (match_operand:SI 0 "register_operand" "")
6772
        (match_operand:SI 1 "memory_operand" ""))
6773
   (clobber (reg:SI R0_REG))]
6774
  "TARGET_SH1"
6775
  [(set (match_dup 0) (match_dup 1))]
6776
  "")
6777
 
6778
;; ------------------------------------------------------------------------
6779
;; Define the real conditional branch instructions.
6780
;; ------------------------------------------------------------------------
6781
 
6782
(define_insn "branch_true"
6783
  [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6784
                           (label_ref (match_operand 0 "" ""))
6785
                           (pc)))]
6786
  "TARGET_SH1"
6787
  "* return output_branch (1, insn, operands);"
6788
  [(set_attr "type" "cbranch")])
6789
 
6790
(define_insn "branch_false"
6791
  [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6792
                           (label_ref (match_operand 0 "" ""))
6793
                           (pc)))]
6794
  "TARGET_SH1"
6795
  "* return output_branch (0, insn, operands);"
6796
  [(set_attr "type" "cbranch")])
6797
 
6798
;; Patterns to prevent reorg from re-combining a condbranch with a branch
6799
;; which destination is too far away.
6800
;; The const_int_operand is distinct for each branch target; it avoids
6801
;; unwanted matches with redundant_insn.
6802
(define_insn "block_branch_redirect"
6803
  [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6804
  "TARGET_SH1"
6805
  ""
6806
  [(set_attr "length" "0")])
6807
 
6808
;; This one has the additional purpose to record a possible scratch register
6809
;; for the following branch.
6810
;; ??? Unfortunately, just setting the scratch register is not good enough,
6811
;; because the insn then might be deemed dead and deleted.  And we can't
6812
;; make the use in the jump insn explicit because that would disable
6813
;; delay slot scheduling from the target.
6814
(define_insn "indirect_jump_scratch"
6815
  [(set (match_operand:SI 0 "register_operand" "=r")
6816
        (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6817
   (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6818
  "TARGET_SH1"
6819
  ""
6820
  [(set_attr "length" "0")])
6821
 
6822
;; This one is used to preemt an insn from beyond the bra / braf / jmp
6823
;; being pulled into the delay slot of a condbranch that has been made to
6824
;; jump around the unconditional jump because it was out of range.
6825
(define_insn "stuff_delay_slot"
6826
  [(set (pc)
6827
        (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
6828
                 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
6829
  "TARGET_SH1"
6830
  ""
6831
  [(set_attr "length" "0")
6832
   (set_attr "cond_delay_slot" "yes")])
6833
 
6834
;; Conditional branch insns
6835
 
6836
(define_expand "cbranchint4_media"
6837
  [(set (pc)
6838
        (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
6839
                       [(match_operand 1 "" "")
6840
                        (match_operand 2 "" "")])
6841
                      (match_operand 3 "" "")
6842
                      (pc)))]
6843
  "TARGET_SHMEDIA"
6844
  "
6845
{
6846
  enum machine_mode mode = GET_MODE (operands[1]);
6847
  if (mode == VOIDmode)
6848
    mode = GET_MODE (operands[2]);
6849
  if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
6850
    {
6851
      operands[1] = force_reg (mode, operands[1]);
6852
      if (CONSTANT_P (operands[2])
6853
          && (! satisfies_constraint_I06 (operands[2])))
6854
        operands[2] = force_reg (mode, operands[2]);
6855
    }
6856
  else
6857
    {
6858
      if (operands[1] != const0_rtx)
6859
        operands[1] = force_reg (mode, operands[1]);
6860
      if (operands[2] != const0_rtx)
6861
        operands[2] = force_reg (mode, operands[2]);
6862
    }
6863
  switch (GET_CODE (operands[0]))
6864
    {
6865
    case LEU:
6866
    case LE:
6867
    case LTU:
6868
    case LT:
6869
      operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
6870
                                    VOIDmode, operands[2], operands[1]);
6871
      operands[1] = XEXP (operands[0], 0);
6872
      operands[2] = XEXP (operands[0], 1);
6873
      break;
6874
    default:
6875
      operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
6876
                                    VOIDmode, operands[1], operands[2]);
6877
      break;
6878
    }
6879
  operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6880
}")
6881
 
6882
(define_expand "cbranchfp4_media"
6883
  [(set (pc)
6884
        (if_then_else (match_operator 0 "sh_float_comparison_operator"
6885
                       [(match_operand 1 "" "")
6886
                        (match_operand 2 "" "")])
6887
                      (match_operand 3 "" "")
6888
                      (pc)))]
6889
  "TARGET_SHMEDIA"
6890
  "
6891
{
6892
  rtx tmp = gen_reg_rtx (SImode);
6893
  rtx cmp;
6894
  if (GET_CODE (operands[0]) == NE)
6895
    cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
6896
  else
6897
    cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
6898
                          operands[1], operands[2]);
6899
 
6900
  emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
6901
 
6902
  if (GET_CODE (cmp) == GET_CODE (operands[0]))
6903
    operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
6904
  else
6905
    operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
6906
  operands[1] = tmp;
6907
  operands[2] = const0_rtx;
6908
  operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6909
}")
6910
 
6911
(define_insn "*beq_media_i"
6912
  [(set (pc)
6913
        (if_then_else (match_operator 3 "equality_comparison_operator"
6914
                        [(match_operand:DI 1 "arith_reg_operand" "r,r")
6915
                         (match_operand:DI 2 "arith_operand" "r,I06")])
6916
                      (match_operand 0 "target_operand" "b,b")
6917
                      (pc)))]
6918
  "TARGET_SHMEDIA"
6919
  "@
6920
        b%o3%'  %1, %2, %0%>
6921
        b%o3i%' %1, %2, %0%>"
6922
  [(set_attr "type" "cbranch_media")])
6923
 
6924
(define_insn "*beq_media_i32"
6925
  [(set (pc)
6926
        (if_then_else (match_operator 3 "equality_comparison_operator"
6927
                        [(match_operand:SI 1 "arith_reg_operand" "r,r")
6928
                         (match_operand:SI 2 "arith_operand" "r,I06")])
6929
                      (match_operand 0 "target_operand" "b,b")
6930
                      (pc)))]
6931
  "TARGET_SHMEDIA"
6932
  "@
6933
        b%o3%'  %1, %2, %0%>
6934
        b%o3i%' %1, %2, %0%>"
6935
  [(set_attr "type" "cbranch_media")])
6936
 
6937
(define_insn "*bgt_media_i"
6938
  [(set (pc)
6939
        (if_then_else (match_operator 3 "greater_comparison_operator"
6940
                        [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6941
                         (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6942
                      (match_operand 0 "target_operand" "b")
6943
                      (pc)))]
6944
  "TARGET_SHMEDIA"
6945
  "b%o3%'       %N1, %N2, %0%>"
6946
  [(set_attr "type" "cbranch_media")])
6947
 
6948
(define_insn "*bgt_media_i32"
6949
  [(set (pc)
6950
        (if_then_else (match_operator 3 "greater_comparison_operator"
6951
                        [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6952
                         (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6953
                      (match_operand 0 "target_operand" "b")
6954
                      (pc)))]
6955
  "TARGET_SHMEDIA"
6956
  "b%o3%'       %N1, %N2, %0%>"
6957
  [(set_attr "type" "cbranch_media")])
6958
 
6959
;; These are only needed to make invert_jump() happy - otherwise, jump
6960
;; optimization will be silently disabled.
6961
(define_insn "*blt_media_i"
6962
  [(set (pc)
6963
        (if_then_else (match_operator 3 "less_comparison_operator"
6964
                        [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6965
                         (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6966
                      (match_operand 0 "target_operand" "b")
6967
                      (pc)))]
6968
  "TARGET_SHMEDIA"
6969
  "b%o3%'       %N2, %N1, %0%>"
6970
  [(set_attr "type" "cbranch_media")])
6971
 
6972
(define_insn "*blt_media_i32"
6973
  [(set (pc)
6974
        (if_then_else (match_operator 3 "less_comparison_operator"
6975
                        [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6976
                         (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6977
                      (match_operand 0 "target_operand" "b")
6978
                      (pc)))]
6979
  "TARGET_SHMEDIA"
6980
  "b%o3%'       %N2, %N1, %0%>"
6981
  [(set_attr "type" "cbranch_media")])
6982
 
6983
;; combiner splitter for test-and-branch on single bit in register.  This
6984
;; is endian dependent because the non-paradoxical subreg looks different
6985
;; on big endian.
6986
(define_split
6987
  [(set (pc)
6988
        (if_then_else
6989
          (match_operator 3 "equality_comparison_operator"
6990
            [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
6991
                                                      "extend_reg_operand" "")
6992
                                                    0)
6993
                                         (const_int 1)
6994
                                         (match_operand 2
6995
                                          "const_int_operand" "")) 0)
6996
             (const_int 0)])
6997
          (match_operand 0 "target_operand" "")
6998
          (pc)))
6999
   (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7000
  "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7001
  [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7002
   (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7003
 
7004
  "
7005
{
7006
  operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7007
  operands[6] = (GET_CODE (operands[3]) == EQ
7008
                 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7009
                 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7010
}")
7011
 
7012
; operand 0 is the loop count pseudo register
7013
; operand 1 is the number of loop iterations or 0 if it is unknown
7014
; operand 2 is the maximum number of loop iterations
7015
; operand 3 is the number of levels of enclosed loops
7016
; operand 4 is the label to jump to at the top of the loop
7017
 
7018
(define_expand "doloop_end"
7019
  [(parallel [(set (pc) (if_then_else
7020
                          (ne:SI (match_operand:SI 0 "" "")
7021
                              (const_int 1))
7022
                          (label_ref (match_operand 4 "" ""))
7023
                          (pc)))
7024
              (set (match_dup 0)
7025
                   (plus:SI (match_dup 0) (const_int -1)))
7026
              (clobber (reg:SI T_REG))])]
7027
  "TARGET_SH2"
7028
  "
7029
{
7030
  if (GET_MODE (operands[0]) != SImode)
7031
    FAIL;
7032
}
7033
")
7034
 
7035
(define_insn_and_split "doloop_end_split"
7036
  [(set (pc)
7037
        (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7038
                          (const_int 1))
7039
                      (label_ref (match_operand 1 "" ""))
7040
                      (pc)))
7041
   (set (match_dup 0)
7042
        (plus (match_dup 0) (const_int -1)))
7043
   (clobber (reg:SI T_REG))]
7044
  "TARGET_SH2"
7045
  "#"
7046
  ""
7047
  [(parallel [(set (reg:SI T_REG)
7048
                   (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7049
                          (const_int 1)))
7050
              (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7051
   (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7052
                           (label_ref (match_operand 1 "" ""))
7053
                           (pc)))]
7054
""
7055
   [(set_attr "type" "cbranch")])
7056
 
7057
 
7058
;; ------------------------------------------------------------------------
7059
;; Jump and linkage insns
7060
;; ------------------------------------------------------------------------
7061
 
7062
(define_insn "jump_compact"
7063
  [(set (pc)
7064
        (label_ref (match_operand 0 "" "")))]
7065
  "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7066
  "*
7067
{
7068
  /* The length is 16 if the delay slot is unfilled.  */
7069
  if (get_attr_length(insn) > 4)
7070
    return output_far_jump(insn, operands[0]);
7071
  else
7072
    return   \"bra      %l0%#\";
7073
}"
7074
  [(set_attr "type" "jump")
7075
   (set_attr "needs_delay_slot" "yes")])
7076
 
7077
;; ??? It would be much saner to explicitly use the scratch register
7078
;; in the jump insn, and have indirect_jump_scratch only set it,
7079
;; but fill_simple_delay_slots would refuse to do delay slot filling
7080
;; from the target then, as it uses simplejump_p.
7081
;;(define_insn "jump_compact_far"
7082
;;  [(set (pc)
7083
;;      (label_ref (match_operand 0 "" "")))
7084
;;   (use (match_operand 1 "register_operand" "r")]
7085
;;  "TARGET_SH1"
7086
;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7087
;;  [(set_attr "type" "jump")
7088
;;   (set_attr "needs_delay_slot" "yes")])
7089
 
7090
(define_insn "jump_media"
7091
  [(set (pc)
7092
        (match_operand 0 "target_operand" "b"))]
7093
  "TARGET_SHMEDIA"
7094
  "blink        %0, r63%>"
7095
  [(set_attr "type" "jump_media")])
7096
 
7097
(define_expand "jump"
7098
  [(set (pc)
7099
        (label_ref (match_operand 0 "" "")))]
7100
  ""
7101
  "
7102
{
7103
  if (TARGET_SH1)
7104
    emit_jump_insn (gen_jump_compact (operands[0]));
7105
  else if (TARGET_SHMEDIA)
7106
    {
7107
      if (reload_in_progress || reload_completed)
7108
        FAIL;
7109
      emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7110
                                                         operands[0])));
7111
    }
7112
  DONE;
7113
}")
7114
 
7115
(define_insn "force_mode_for_call"
7116
  [(use (reg:PSI FPSCR_REG))]
7117
  "TARGET_SHCOMPACT"
7118
  ""
7119
  [(set_attr "length" "0")
7120
   (set (attr "fp_mode")
7121
        (if_then_else (eq_attr "fpu_single" "yes")
7122
                      (const_string "single") (const_string "double")))])
7123
 
7124
(define_insn "calli"
7125
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7126
         (match_operand 1 "" ""))
7127
   (use (reg:PSI FPSCR_REG))
7128
   (clobber (reg:SI PR_REG))]
7129
  "TARGET_SH1"
7130
  "*
7131
   {
7132
     if (TARGET_SH2A && (dbr_sequence_length () == 0))
7133
        return \"jsr/n\\t@%0\";
7134
     else
7135
        return \"jsr\\t@%0%#\";
7136
   }"
7137
 
7138
  [(set_attr "type" "call")
7139
   (set (attr "fp_mode")
7140
        (if_then_else (eq_attr "fpu_single" "yes")
7141
                      (const_string "single") (const_string "double")))
7142
   (set_attr "needs_delay_slot" "yes")
7143
   (set_attr "fp_set" "unknown")])
7144
 
7145
;; This is TBR relative jump instruction for SH2A architecture.
7146
;; Its use is enabled assigning an attribute "function_vector"
7147
;; and the vector number to a function during its declaration.
7148
 
7149
(define_insn "calli_tbr_rel"
7150
  [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7151
         (match_operand 1 "" ""))
7152
   (use (reg:PSI FPSCR_REG))
7153
   (clobber (reg:SI PR_REG))]
7154
  "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7155
  "*
7156
{
7157
  unsigned HOST_WIDE_INT vect_num;
7158
  vect_num = sh2a_get_function_vector_number (operands[0]);
7159
  operands[2] = GEN_INT (vect_num * 4);
7160
 
7161
  return \"jsr/n\\t@@(%O2,tbr)\";
7162
}"
7163
  [(set_attr "type" "call")
7164
   (set (attr "fp_mode")
7165
        (if_then_else (eq_attr "fpu_single" "yes")
7166
                      (const_string "single") (const_string "double")))
7167
   (set_attr "needs_delay_slot" "no")
7168
   (set_attr "fp_set" "unknown")])
7169
 
7170
;; This is a pc-rel call, using bsrf, for use with PIC.
7171
 
7172
(define_insn "calli_pcrel"
7173
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7174
         (match_operand 1 "" ""))
7175
   (use (reg:PSI FPSCR_REG))
7176
   (use (reg:SI PIC_REG))
7177
   (use (match_operand 2 "" ""))
7178
   (clobber (reg:SI PR_REG))]
7179
  "TARGET_SH2"
7180
  "bsrf %0\\n%O2:%#"
7181
  [(set_attr "type" "call")
7182
   (set (attr "fp_mode")
7183
        (if_then_else (eq_attr "fpu_single" "yes")
7184
                      (const_string "single") (const_string "double")))
7185
   (set_attr "needs_delay_slot" "yes")
7186
   (set_attr "fp_set" "unknown")])
7187
 
7188
(define_insn_and_split "call_pcrel"
7189
  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7190
         (match_operand 1 "" ""))
7191
   (use (reg:PSI FPSCR_REG))
7192
   (use (reg:SI PIC_REG))
7193
   (clobber (reg:SI PR_REG))
7194
   (clobber (match_scratch:SI 2 "=r"))]
7195
  "TARGET_SH2"
7196
  "#"
7197
  "reload_completed"
7198
  [(const_int 0)]
7199
  "
7200
{
7201
  rtx lab = PATTERN (gen_call_site ());
7202
 
7203
  if (SYMBOL_REF_LOCAL_P (operands[0]))
7204
    emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7205
  else
7206
    emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7207
  emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7208
  DONE;
7209
}"
7210
  [(set_attr "type" "call")
7211
   (set (attr "fp_mode")
7212
        (if_then_else (eq_attr "fpu_single" "yes")
7213
                      (const_string "single") (const_string "double")))
7214
   (set_attr "needs_delay_slot" "yes")
7215
   (set_attr "fp_set" "unknown")])
7216
 
7217
(define_insn "call_compact"
7218
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7219
         (match_operand 1 "" ""))
7220
   (match_operand 2 "immediate_operand" "n")
7221
   (use (reg:SI R0_REG))
7222
   (use (reg:SI R1_REG))
7223
   (use (reg:PSI FPSCR_REG))
7224
   (clobber (reg:SI PR_REG))]
7225
  "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7226
  "jsr  @%0%#"
7227
  [(set_attr "type" "call")
7228
   (set (attr "fp_mode")
7229
        (if_then_else (eq_attr "fpu_single" "yes")
7230
                      (const_string "single") (const_string "double")))
7231
   (set_attr "needs_delay_slot" "yes")])
7232
 
7233
(define_insn "call_compact_rettramp"
7234
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7235
         (match_operand 1 "" ""))
7236
   (match_operand 2 "immediate_operand" "n")
7237
   (use (reg:SI R0_REG))
7238
   (use (reg:SI R1_REG))
7239
   (use (reg:PSI FPSCR_REG))
7240
   (clobber (reg:SI R10_REG))
7241
   (clobber (reg:SI PR_REG))]
7242
  "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7243
  "jsr  @%0%#"
7244
  [(set_attr "type" "call")
7245
   (set (attr "fp_mode")
7246
        (if_then_else (eq_attr "fpu_single" "yes")
7247
                      (const_string "single") (const_string "double")))
7248
   (set_attr "needs_delay_slot" "yes")])
7249
 
7250
(define_insn "call_media"
7251
  [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7252
         (match_operand 1 "" ""))
7253
   (clobber (reg:DI PR_MEDIA_REG))]
7254
  "TARGET_SHMEDIA"
7255
  "blink        %0, r18"
7256
  [(set_attr "type" "jump_media")])
7257
 
7258
(define_insn "call_valuei"
7259
  [(set (match_operand 0 "" "=rf")
7260
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7261
              (match_operand 2 "" "")))
7262
   (use (reg:PSI FPSCR_REG))
7263
   (clobber (reg:SI PR_REG))]
7264
  "TARGET_SH1"
7265
  "*
7266
   {
7267
     if (TARGET_SH2A && (dbr_sequence_length () == 0))
7268
        return \"jsr/n\\t@%1\";
7269
     else
7270
        return \"jsr\\t@%1%#\";
7271
   }"
7272
  [(set_attr "type" "call")
7273
   (set (attr "fp_mode")
7274
        (if_then_else (eq_attr "fpu_single" "yes")
7275
                      (const_string "single") (const_string "double")))
7276
   (set_attr "needs_delay_slot" "yes")
7277
   (set_attr "fp_set" "unknown")])
7278
 
7279
;; This is TBR relative jump instruction for SH2A architecture.
7280
;; Its use is enabled assigning an attribute "function_vector"
7281
;; and the vector number to a function during its declaration.
7282
 
7283
(define_insn "call_valuei_tbr_rel"
7284
  [(set (match_operand 0 "" "=rf")
7285
        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7286
              (match_operand 2 "" "")))
7287
   (use (reg:PSI FPSCR_REG))
7288
   (clobber (reg:SI PR_REG))]
7289
  "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7290
  "*
7291
{
7292
  unsigned HOST_WIDE_INT vect_num;
7293
  vect_num = sh2a_get_function_vector_number (operands[1]);
7294
  operands[3] = GEN_INT (vect_num * 4);
7295
 
7296
  return \"jsr/n\\t@@(%O3,tbr)\";
7297
}"
7298
  [(set_attr "type" "call")
7299
   (set (attr "fp_mode")
7300
        (if_then_else (eq_attr "fpu_single" "yes")
7301
                      (const_string "single") (const_string "double")))
7302
   (set_attr "needs_delay_slot" "no")
7303
   (set_attr "fp_set" "unknown")])
7304
 
7305
(define_insn "call_valuei_pcrel"
7306
  [(set (match_operand 0 "" "=rf")
7307
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7308
              (match_operand 2 "" "")))
7309
   (use (reg:PSI FPSCR_REG))
7310
   (use (reg:SI PIC_REG))
7311
   (use (match_operand 3 "" ""))
7312
   (clobber (reg:SI PR_REG))]
7313
  "TARGET_SH2"
7314
  "bsrf %1\\n%O3:%#"
7315
  [(set_attr "type" "call")
7316
   (set (attr "fp_mode")
7317
        (if_then_else (eq_attr "fpu_single" "yes")
7318
                      (const_string "single") (const_string "double")))
7319
   (set_attr "needs_delay_slot" "yes")
7320
   (set_attr "fp_set" "unknown")])
7321
 
7322
(define_insn_and_split "call_value_pcrel"
7323
  [(set (match_operand 0 "" "=rf")
7324
        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7325
              (match_operand 2 "" "")))
7326
   (use (reg:PSI FPSCR_REG))
7327
   (use (reg:SI PIC_REG))
7328
   (clobber (reg:SI PR_REG))
7329
   (clobber (match_scratch:SI 3 "=r"))]
7330
  "TARGET_SH2"
7331
  "#"
7332
  "reload_completed"
7333
  [(const_int 0)]
7334
  "
7335
{
7336
  rtx lab = PATTERN (gen_call_site ());
7337
 
7338
  if (SYMBOL_REF_LOCAL_P (operands[1]))
7339
    emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7340
  else
7341
    emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7342
  emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7343
                                         operands[2], copy_rtx (lab)));
7344
  DONE;
7345
}"
7346
  [(set_attr "type" "call")
7347
   (set (attr "fp_mode")
7348
        (if_then_else (eq_attr "fpu_single" "yes")
7349
                      (const_string "single") (const_string "double")))
7350
   (set_attr "needs_delay_slot" "yes")
7351
   (set_attr "fp_set" "unknown")])
7352
 
7353
(define_insn "call_value_compact"
7354
  [(set (match_operand 0 "" "=rf")
7355
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7356
              (match_operand 2 "" "")))
7357
   (match_operand 3 "immediate_operand" "n")
7358
   (use (reg:SI R0_REG))
7359
   (use (reg:SI R1_REG))
7360
   (use (reg:PSI FPSCR_REG))
7361
   (clobber (reg:SI PR_REG))]
7362
  "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7363
  "jsr  @%1%#"
7364
  [(set_attr "type" "call")
7365
   (set (attr "fp_mode")
7366
        (if_then_else (eq_attr "fpu_single" "yes")
7367
                      (const_string "single") (const_string "double")))
7368
   (set_attr "needs_delay_slot" "yes")])
7369
 
7370
(define_insn "call_value_compact_rettramp"
7371
  [(set (match_operand 0 "" "=rf")
7372
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7373
              (match_operand 2 "" "")))
7374
   (match_operand 3 "immediate_operand" "n")
7375
   (use (reg:SI R0_REG))
7376
   (use (reg:SI R1_REG))
7377
   (use (reg:PSI FPSCR_REG))
7378
   (clobber (reg:SI R10_REG))
7379
   (clobber (reg:SI PR_REG))]
7380
  "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7381
  "jsr  @%1%#"
7382
  [(set_attr "type" "call")
7383
   (set (attr "fp_mode")
7384
        (if_then_else (eq_attr "fpu_single" "yes")
7385
                      (const_string "single") (const_string "double")))
7386
   (set_attr "needs_delay_slot" "yes")])
7387
 
7388
(define_insn "call_value_media"
7389
  [(set (match_operand 0 "" "=rf")
7390
        (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7391
              (match_operand 2 "" "")))
7392
   (clobber (reg:DI PR_MEDIA_REG))]
7393
  "TARGET_SHMEDIA"
7394
  "blink        %1, r18"
7395
  [(set_attr "type" "jump_media")])
7396
 
7397
(define_expand "call"
7398
  [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7399
                            (match_operand 1 "" ""))
7400
              (match_operand 2 "" "")
7401
              (use (reg:PSI FPSCR_REG))
7402
              (clobber (reg:SI PR_REG))])]
7403
  ""
7404
  "
7405
{
7406
  if (TARGET_SHMEDIA)
7407
    {
7408
      operands[0] = shmedia_prepare_call_address (operands[0], 0);
7409
      emit_call_insn (gen_call_media (operands[0], operands[1]));
7410
      DONE;
7411
    }
7412
  else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7413
    {
7414
      rtx cookie_rtx = operands[2];
7415
      long cookie = INTVAL (cookie_rtx);
7416
      rtx func = XEXP (operands[0], 0);
7417
      rtx r0, r1;
7418
 
7419
      if (flag_pic)
7420
        {
7421
          if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7422
            {
7423
              rtx reg = gen_reg_rtx (Pmode);
7424
 
7425
              emit_insn (gen_symGOTPLT2reg (reg, func));
7426
              func = reg;
7427
            }
7428
          else
7429
            func = legitimize_pic_address (func, Pmode, 0);
7430
        }
7431
 
7432
      r0 = gen_rtx_REG (SImode, R0_REG);
7433
      r1 = gen_rtx_REG (SImode, R1_REG);
7434
 
7435
      /* Since such a call function may use all call-clobbered
7436
         registers, we force a mode switch earlier, so that we don't
7437
         run out of registers when adjusting fpscr for the call.  */
7438
      emit_insn (gen_force_mode_for_call ());
7439
 
7440
      operands[0]
7441
        = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7442
                           SFUNC_GOT);
7443
      operands[0] = force_reg (SImode, operands[0]);
7444
 
7445
      emit_move_insn (r0, func);
7446
      emit_move_insn (r1, cookie_rtx);
7447
 
7448
      if (cookie & CALL_COOKIE_RET_TRAMP (1))
7449
        emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7450
                                                   operands[2]));
7451
      else
7452
        emit_call_insn (gen_call_compact (operands[0], operands[1],
7453
                                          operands[2]));
7454
 
7455
      DONE;
7456
    }
7457
  else if (TARGET_SHCOMPACT && flag_pic
7458
           && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7459
           && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7460
    {
7461
      rtx reg = gen_reg_rtx (Pmode);
7462
 
7463
      emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7464
      XEXP (operands[0], 0) = reg;
7465
    }
7466
  if (!flag_pic && TARGET_SH2A
7467
      && MEM_P (operands[0])
7468
      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7469
    {
7470
      if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7471
        {
7472
          emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7473
                                             operands[1]));
7474
          DONE;
7475
        }
7476
    }
7477
  if (flag_pic && TARGET_SH2
7478
      && MEM_P (operands[0])
7479
      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7480
    {
7481
      emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7482
      DONE;
7483
    }
7484
  else
7485
  {
7486
    operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7487
    operands[1] = operands[2];
7488
  }
7489
 
7490
  emit_call_insn (gen_calli (operands[0], operands[1]));
7491
  DONE;
7492
}")
7493
 
7494
(define_insn "call_pop_compact"
7495
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7496
         (match_operand 1 "" ""))
7497
   (match_operand 2 "immediate_operand" "n")
7498
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7499
                                 (match_operand 3 "immediate_operand" "n")))
7500
   (use (reg:SI R0_REG))
7501
   (use (reg:SI R1_REG))
7502
   (use (reg:PSI FPSCR_REG))
7503
   (clobber (reg:SI PR_REG))]
7504
  "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7505
  "jsr  @%0%#"
7506
  [(set_attr "type" "call")
7507
   (set (attr "fp_mode")
7508
        (if_then_else (eq_attr "fpu_single" "yes")
7509
                      (const_string "single") (const_string "double")))
7510
   (set_attr "needs_delay_slot" "yes")])
7511
 
7512
(define_insn "call_pop_compact_rettramp"
7513
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7514
         (match_operand 1 "" ""))
7515
   (match_operand 2 "immediate_operand" "n")
7516
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7517
                                 (match_operand 3 "immediate_operand" "n")))
7518
   (use (reg:SI R0_REG))
7519
   (use (reg:SI R1_REG))
7520
   (use (reg:PSI FPSCR_REG))
7521
   (clobber (reg:SI R10_REG))
7522
   (clobber (reg:SI PR_REG))]
7523
  "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7524
  "jsr  @%0%#"
7525
  [(set_attr "type" "call")
7526
   (set (attr "fp_mode")
7527
        (if_then_else (eq_attr "fpu_single" "yes")
7528
                      (const_string "single") (const_string "double")))
7529
   (set_attr "needs_delay_slot" "yes")])
7530
 
7531
(define_expand "call_pop"
7532
  [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7533
                    (match_operand 1 "" ""))
7534
             (match_operand 2 "" "")
7535
             (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7536
                                           (match_operand 3 "" "")))])]
7537
  "TARGET_SHCOMPACT"
7538
  "
7539
{
7540
  rtx cookie_rtx;
7541
  long cookie;
7542
  rtx func;
7543
  rtx r0, r1;
7544
 
7545
  gcc_assert (operands[2] && INTVAL (operands[2]));
7546
  cookie_rtx = operands[2];
7547
  cookie = INTVAL (cookie_rtx);
7548
  func = XEXP (operands[0], 0);
7549
 
7550
  if (flag_pic)
7551
    {
7552
      if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7553
        {
7554
          rtx reg = gen_reg_rtx (Pmode);
7555
          emit_insn (gen_symGOTPLT2reg (reg, func));
7556
          func = reg;
7557
        }
7558
      else
7559
        func = legitimize_pic_address (func, Pmode, 0);
7560
    }
7561
 
7562
  r0 = gen_rtx_REG (SImode, R0_REG);
7563
  r1 = gen_rtx_REG (SImode, R1_REG);
7564
 
7565
  /* Since such a call function may use all call-clobbered
7566
     registers, we force a mode switch earlier, so that we don't
7567
     run out of registers when adjusting fpscr for the call.  */
7568
  emit_insn (gen_force_mode_for_call ());
7569
 
7570
  operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7571
                                 SFUNC_GOT);
7572
  operands[0] = force_reg (SImode, operands[0]);
7573
 
7574
  emit_move_insn (r0, func);
7575
  emit_move_insn (r1, cookie_rtx);
7576
 
7577
  if (cookie & CALL_COOKIE_RET_TRAMP (1))
7578
    emit_call_insn (gen_call_pop_compact_rettramp
7579
                     (operands[0], operands[1], operands[2], operands[3]));
7580
  else
7581
    emit_call_insn (gen_call_pop_compact
7582
                     (operands[0], operands[1], operands[2], operands[3]));
7583
 
7584
  DONE;
7585
}")
7586
 
7587
(define_expand "call_value"
7588
  [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7589
                   (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7590
                                 (match_operand 2 "" "")))
7591
              (match_operand 3 "" "")
7592
              (use (reg:PSI FPSCR_REG))
7593
              (clobber (reg:SI PR_REG))])]
7594
  ""
7595
  "
7596
{
7597
  if (TARGET_SHMEDIA)
7598
    {
7599
      operands[1] = shmedia_prepare_call_address (operands[1], 0);
7600
      emit_call_insn (gen_call_value_media (operands[0], operands[1],
7601
                                            operands[2]));
7602
      DONE;
7603
    }
7604
  else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7605
    {
7606
      rtx cookie_rtx = operands[3];
7607
      long cookie = INTVAL (cookie_rtx);
7608
      rtx func = XEXP (operands[1], 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[1]
7633
        = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7634
                           SFUNC_GOT);
7635
      operands[1] = force_reg (SImode, operands[1]);
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_value_compact_rettramp (operands[0],
7642
                                                         operands[1],
7643
                                                         operands[2],
7644
                                                         operands[3]));
7645
      else
7646
        emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7647
                                                operands[2], operands[3]));
7648
 
7649
      DONE;
7650
    }
7651
  else if (TARGET_SHCOMPACT && flag_pic
7652
           && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7653
           && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7654
    {
7655
      rtx reg = gen_reg_rtx (Pmode);
7656
 
7657
      emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7658
      XEXP (operands[1], 0) = reg;
7659
    }
7660
  if (!flag_pic && TARGET_SH2A
7661
      && MEM_P (operands[1])
7662
      && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7663
    {
7664
      if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7665
        {
7666
          emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7667
                                 XEXP (operands[1], 0), operands[2]));
7668
          DONE;
7669
        }
7670
    }
7671
  if (flag_pic && TARGET_SH2
7672
      && MEM_P (operands[1])
7673
      && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7674
    {
7675
      emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7676
                                            operands[2]));
7677
      DONE;
7678
    }
7679
  else
7680
    operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7681
 
7682
  emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7683
  DONE;
7684
}")
7685
 
7686
(define_insn "sibcalli"
7687
  [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7688
         (match_operand 1 "" ""))
7689
   (use (reg:PSI FPSCR_REG))
7690
   (return)]
7691
  "TARGET_SH1"
7692
  "jmp  @%0%#"
7693
  [(set_attr "needs_delay_slot" "yes")
7694
   (set (attr "fp_mode")
7695
        (if_then_else (eq_attr "fpu_single" "yes")
7696
                      (const_string "single") (const_string "double")))
7697
   (set_attr "type" "jump_ind")])
7698
 
7699
(define_insn "sibcalli_pcrel"
7700
  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7701
         (match_operand 1 "" ""))
7702
   (use (match_operand 2 "" ""))
7703
   (use (reg:PSI FPSCR_REG))
7704
   (return)]
7705
  "TARGET_SH2"
7706
  "braf %0\\n%O2:%#"
7707
  [(set_attr "needs_delay_slot" "yes")
7708
   (set (attr "fp_mode")
7709
        (if_then_else (eq_attr "fpu_single" "yes")
7710
                      (const_string "single") (const_string "double")))
7711
   (set_attr "type" "jump_ind")])
7712
 
7713
;; This uses an unspec to describe that the symbol_ref is very close.
7714
(define_insn "sibcalli_thunk"
7715
  [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7716
                             UNSPEC_THUNK))
7717
         (match_operand 1 "" ""))
7718
   (use (reg:PSI FPSCR_REG))
7719
   (return)]
7720
  "TARGET_SH1"
7721
  "bra  %O0"
7722
  [(set_attr "needs_delay_slot" "yes")
7723
   (set (attr "fp_mode")
7724
        (if_then_else (eq_attr "fpu_single" "yes")
7725
                      (const_string "single") (const_string "double")))
7726
   (set_attr "type" "jump")
7727
   (set_attr "length" "2")])
7728
 
7729
(define_insn_and_split "sibcall_pcrel"
7730
  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7731
         (match_operand 1 "" ""))
7732
   (use (reg:PSI FPSCR_REG))
7733
   (clobber (match_scratch:SI 2 "=k"))
7734
   (return)]
7735
  "TARGET_SH2"
7736
  "#"
7737
  "reload_completed"
7738
  [(const_int 0)]
7739
  "
7740
{
7741
  rtx lab = PATTERN (gen_call_site ());
7742
  rtx call_insn;
7743
 
7744
  emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7745
  call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7746
                                                  copy_rtx (lab)));
7747
  SIBLING_CALL_P (call_insn) = 1;
7748
  DONE;
7749
}"
7750
  [(set_attr "needs_delay_slot" "yes")
7751
   (set (attr "fp_mode")
7752
        (if_then_else (eq_attr "fpu_single" "yes")
7753
                      (const_string "single") (const_string "double")))
7754
   (set_attr "type" "jump_ind")])
7755
 
7756
(define_insn "sibcall_compact"
7757
  [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7758
         (match_operand 1 "" ""))
7759
   (return)
7760
   (use (match_operand:SI 2 "register_operand" "z,x"))
7761
   (use (reg:SI R1_REG))
7762
   (use (reg:PSI FPSCR_REG))
7763
   ;; We want to make sure the `x' above will only match MACH_REG
7764
   ;; because sibcall_epilogue may clobber MACL_REG.
7765
   (clobber (reg:SI MACL_REG))]
7766
  "TARGET_SHCOMPACT"
7767
  "@
7768
        jmp     @%0%#
7769
        jmp     @%0\\n  sts     %2, r0"
7770
  [(set_attr "needs_delay_slot" "yes,no")
7771
   (set_attr "length" "2,4")
7772
   (set (attr "fp_mode") (const_string "single"))
7773
   (set_attr "type" "jump_ind")])
7774
 
7775
(define_insn "sibcall_media"
7776
  [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7777
         (match_operand 1 "" ""))
7778
   (use (reg:SI PR_MEDIA_REG))
7779
   (return)]
7780
  "TARGET_SHMEDIA"
7781
  "blink        %0, r63"
7782
  [(set_attr "type" "jump_media")])
7783
 
7784
(define_expand "sibcall"
7785
  [(parallel
7786
    [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7787
           (match_operand 1 "" ""))
7788
     (match_operand 2 "" "")
7789
     (use (reg:PSI FPSCR_REG))
7790
     (return)])]
7791
  ""
7792
  "
7793
{
7794
  if (TARGET_SHMEDIA)
7795
    {
7796
      operands[0] = shmedia_prepare_call_address (operands[0], 1);
7797
      emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7798
      DONE;
7799
    }
7800
  else if (TARGET_SHCOMPACT && operands[2]
7801
           && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7802
    {
7803
      rtx cookie_rtx = operands[2];
7804
      long cookie = INTVAL (cookie_rtx);
7805
      rtx func = XEXP (operands[0], 0);
7806
      rtx mach, r1;
7807
 
7808
      if (flag_pic)
7809
        {
7810
          if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7811
            {
7812
              rtx reg = gen_reg_rtx (Pmode);
7813
 
7814
              emit_insn (gen_symGOT2reg (reg, func));
7815
              func = reg;
7816
            }
7817
          else
7818
            func = legitimize_pic_address (func, Pmode, 0);
7819
        }
7820
 
7821
      /* FIXME: if we could tell whether all argument registers are
7822
         already taken, we could decide whether to force the use of
7823
         MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7824
         simple way to tell.  We could use the CALL_COOKIE, but we
7825
         can't currently tell a register used for regular argument
7826
         passing from one that is unused.  If we leave it up to reload
7827
         to decide which register to use, it seems to always choose
7828
         R0_REG, which leaves no available registers in SIBCALL_REGS
7829
         to hold the address of the trampoline.  */
7830
      mach = gen_rtx_REG (SImode, MACH_REG);
7831
      r1 = gen_rtx_REG (SImode, R1_REG);
7832
 
7833
      /* Since such a call function may use all call-clobbered
7834
         registers, we force a mode switch earlier, so that we don't
7835
         run out of registers when adjusting fpscr for the call.  */
7836
      emit_insn (gen_force_mode_for_call ());
7837
 
7838
      operands[0]
7839
        = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7840
                           SFUNC_GOT);
7841
      operands[0] = force_reg (SImode, operands[0]);
7842
 
7843
      /* We don't need a return trampoline, since the callee will
7844
         return directly to the upper caller.  */
7845
      if (cookie & CALL_COOKIE_RET_TRAMP (1))
7846
        {
7847
          cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7848
          cookie_rtx = GEN_INT (cookie);
7849
        }
7850
 
7851
      emit_move_insn (mach, func);
7852
      emit_move_insn (r1, cookie_rtx);
7853
 
7854
      emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7855
      DONE;
7856
    }
7857
  else if (TARGET_SHCOMPACT && flag_pic
7858
           && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7859
           && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7860
    {
7861
      rtx reg = gen_reg_rtx (Pmode);
7862
 
7863
      emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7864
      XEXP (operands[0], 0) = reg;
7865
    }
7866
  if (flag_pic && TARGET_SH2
7867
      && MEM_P (operands[0])
7868
      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7869
      /* The PLT needs the PIC register, but the epilogue would have
7870
         to restore it, so we can only use PC-relative PIC calls for
7871
         static functions.  */
7872
      && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7873
    {
7874
      emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7875
      DONE;
7876
    }
7877
  else
7878
    operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7879
 
7880
  emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7881
  DONE;
7882
}")
7883
 
7884
(define_insn "sibcall_valuei"
7885
  [(set (match_operand 0 "" "=rf")
7886
        (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
7887
              (match_operand 2 "" "")))
7888
   (use (reg:PSI FPSCR_REG))
7889
   (return)]
7890
  "TARGET_SH1"
7891
  "jmp  @%1%#"
7892
  [(set_attr "needs_delay_slot" "yes")
7893
   (set (attr "fp_mode")
7894
        (if_then_else (eq_attr "fpu_single" "yes")
7895
                      (const_string "single") (const_string "double")))
7896
   (set_attr "type" "jump_ind")])
7897
 
7898
(define_insn "sibcall_valuei_pcrel"
7899
  [(set (match_operand 0 "" "=rf")
7900
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
7901
              (match_operand 2 "" "")))
7902
   (use (match_operand 3 "" ""))
7903
   (use (reg:PSI FPSCR_REG))
7904
   (return)]
7905
  "TARGET_SH2"
7906
  "braf %1\\n%O3:%#"
7907
  [(set_attr "needs_delay_slot" "yes")
7908
   (set (attr "fp_mode")
7909
        (if_then_else (eq_attr "fpu_single" "yes")
7910
                      (const_string "single") (const_string "double")))
7911
   (set_attr "type" "jump_ind")])
7912
 
7913
(define_insn_and_split "sibcall_value_pcrel"
7914
  [(set (match_operand 0 "" "=rf")
7915
        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7916
              (match_operand 2 "" "")))
7917
   (use (reg:PSI FPSCR_REG))
7918
   (clobber (match_scratch:SI 3 "=k"))
7919
   (return)]
7920
  "TARGET_SH2"
7921
  "#"
7922
  "reload_completed"
7923
  [(const_int 0)]
7924
  "
7925
{
7926
  rtx lab = PATTERN (gen_call_site ());
7927
  rtx call_insn;
7928
 
7929
  emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7930
  call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
7931
                                                        operands[3],
7932
                                                        operands[2],
7933
                                                        copy_rtx (lab)));
7934
  SIBLING_CALL_P (call_insn) = 1;
7935
  DONE;
7936
}"
7937
  [(set_attr "needs_delay_slot" "yes")
7938
   (set (attr "fp_mode")
7939
        (if_then_else (eq_attr "fpu_single" "yes")
7940
                      (const_string "single") (const_string "double")))
7941
   (set_attr "type" "jump_ind")])
7942
 
7943
(define_insn "sibcall_value_compact"
7944
  [(set (match_operand 0 "" "=rf,rf")
7945
        (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
7946
              (match_operand 2 "" "")))
7947
   (return)
7948
   (use (match_operand:SI 3 "register_operand" "z,x"))
7949
   (use (reg:SI R1_REG))
7950
   (use (reg:PSI FPSCR_REG))
7951
   ;; We want to make sure the `x' above will only match MACH_REG
7952
   ;; because sibcall_epilogue may clobber MACL_REG.
7953
   (clobber (reg:SI MACL_REG))]
7954
  "TARGET_SHCOMPACT"
7955
  "@
7956
        jmp     @%1%#
7957
        jmp     @%1\\n  sts     %3, r0"
7958
  [(set_attr "needs_delay_slot" "yes,no")
7959
   (set_attr "length" "2,4")
7960
   (set (attr "fp_mode") (const_string "single"))
7961
   (set_attr "type" "jump_ind")])
7962
 
7963
(define_insn "sibcall_value_media"
7964
  [(set (match_operand 0 "" "=rf")
7965
        (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
7966
              (match_operand 2 "" "")))
7967
   (use (reg:SI PR_MEDIA_REG))
7968
   (return)]
7969
  "TARGET_SHMEDIA"
7970
  "blink        %1, r63"
7971
  [(set_attr "type" "jump_media")])
7972
 
7973
(define_expand "sibcall_value"
7974
  [(parallel
7975
    [(set (match_operand 0 "arith_reg_operand" "")
7976
          (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7977
                (match_operand 2 "" "")))
7978
     (match_operand 3 "" "")
7979
     (use (reg:PSI FPSCR_REG))
7980
     (return)])]
7981
  ""
7982
  "
7983
{
7984
  if (TARGET_SHMEDIA)
7985
    {
7986
      operands[1] = shmedia_prepare_call_address (operands[1], 1);
7987
      emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
7988
                                               operands[2]));
7989
      DONE;
7990
    }
7991
  else if (TARGET_SHCOMPACT && operands[3]
7992
           && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7993
    {
7994
      rtx cookie_rtx = operands[3];
7995
      long cookie = INTVAL (cookie_rtx);
7996
      rtx func = XEXP (operands[1], 0);
7997
      rtx mach, r1;
7998
 
7999
      if (flag_pic)
8000
        {
8001
          if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8002
            {
8003
              rtx reg = gen_reg_rtx (Pmode);
8004
 
8005
              emit_insn (gen_symGOT2reg (reg, func));
8006
              func = reg;
8007
            }
8008
          else
8009
            func = legitimize_pic_address (func, Pmode, 0);
8010
        }
8011
 
8012
      /* FIXME: if we could tell whether all argument registers are
8013
         already taken, we could decide whether to force the use of
8014
         MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8015
         simple way to tell.  We could use the CALL_COOKIE, but we
8016
         can't currently tell a register used for regular argument
8017
         passing from one that is unused.  If we leave it up to reload
8018
         to decide which register to use, it seems to always choose
8019
         R0_REG, which leaves no available registers in SIBCALL_REGS
8020
         to hold the address of the trampoline.  */
8021
      mach = gen_rtx_REG (SImode, MACH_REG);
8022
      r1 = gen_rtx_REG (SImode, R1_REG);
8023
 
8024
      /* Since such a call function may use all call-clobbered
8025
         registers, we force a mode switch earlier, so that we don't
8026
         run out of registers when adjusting fpscr for the call.  */
8027
      emit_insn (gen_force_mode_for_call ());
8028
 
8029
      operands[1]
8030
        = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8031
                           SFUNC_GOT);
8032
      operands[1] = force_reg (SImode, operands[1]);
8033
 
8034
      /* We don't need a return trampoline, since the callee will
8035
         return directly to the upper caller.  */
8036
      if (cookie & CALL_COOKIE_RET_TRAMP (1))
8037
        {
8038
          cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8039
          cookie_rtx = GEN_INT (cookie);
8040
        }
8041
 
8042
      emit_move_insn (mach, func);
8043
      emit_move_insn (r1, cookie_rtx);
8044
 
8045
      emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8046
                                                 operands[2], mach));
8047
      DONE;
8048
    }
8049
  else if (TARGET_SHCOMPACT && flag_pic
8050
           && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8051
           && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8052
    {
8053
      rtx reg = gen_reg_rtx (Pmode);
8054
 
8055
      emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8056
      XEXP (operands[1], 0) = reg;
8057
    }
8058
  if (flag_pic && TARGET_SH2
8059
      && MEM_P (operands[1])
8060
      && GET_CODE (XEXP (operands[1], 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[1], 0)))
8065
    {
8066
      emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8067
                                               XEXP (operands[1], 0),
8068
                                               operands[2]));
8069
      DONE;
8070
    }
8071
  else
8072
    operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8073
 
8074
  emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8075
  DONE;
8076
}")
8077
 
8078
(define_insn "call_value_pop_compact"
8079
  [(set (match_operand 0 "" "=rf")
8080
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8081
              (match_operand 2 "" "")))
8082
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8083
                                 (match_operand 4 "immediate_operand" "n")))
8084
   (match_operand 3 "immediate_operand" "n")
8085
   (use (reg:SI R0_REG))
8086
   (use (reg:SI R1_REG))
8087
   (use (reg:PSI FPSCR_REG))
8088
   (clobber (reg:SI PR_REG))]
8089
  "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8090
  "jsr  @%1%#"
8091
  [(set_attr "type" "call")
8092
   (set (attr "fp_mode")
8093
        (if_then_else (eq_attr "fpu_single" "yes")
8094
                      (const_string "single") (const_string "double")))
8095
   (set_attr "needs_delay_slot" "yes")])
8096
 
8097
(define_insn "call_value_pop_compact_rettramp"
8098
  [(set (match_operand 0 "" "=rf")
8099
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8100
              (match_operand 2 "" "")))
8101
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8102
                                 (match_operand 4 "immediate_operand" "n")))
8103
   (match_operand 3 "immediate_operand" "n")
8104
   (use (reg:SI R0_REG))
8105
   (use (reg:SI R1_REG))
8106
   (use (reg:PSI FPSCR_REG))
8107
   (clobber (reg:SI R10_REG))
8108
   (clobber (reg:SI PR_REG))]
8109
  "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8110
  "jsr  @%1%#"
8111
  [(set_attr "type" "call")
8112
   (set (attr "fp_mode")
8113
        (if_then_else (eq_attr "fpu_single" "yes")
8114
                      (const_string "single") (const_string "double")))
8115
   (set_attr "needs_delay_slot" "yes")])
8116
 
8117
(define_expand "call_value_pop"
8118
  [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8119
                   (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8120
                                 (match_operand 2 "" "")))
8121
              (match_operand 3 "" "")
8122
              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8123
                                            (match_operand 4 "" "")))])]
8124
  "TARGET_SHCOMPACT"
8125
  "
8126
{
8127
  rtx cookie_rtx;
8128
  long cookie;
8129
  rtx func;
8130
  rtx r0, r1;
8131
 
8132
  gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8133
  cookie_rtx = operands[3];
8134
  cookie = INTVAL (cookie_rtx);
8135
  func = XEXP (operands[1], 0);
8136
 
8137
  if (flag_pic)
8138
    {
8139
      if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8140
        {
8141
          rtx reg = gen_reg_rtx (Pmode);
8142
 
8143
          emit_insn (gen_symGOTPLT2reg (reg, func));
8144
          func = reg;
8145
        }
8146
      else
8147
        func = legitimize_pic_address (func, Pmode, 0);
8148
    }
8149
 
8150
  r0 = gen_rtx_REG (SImode, R0_REG);
8151
  r1 = gen_rtx_REG (SImode, R1_REG);
8152
 
8153
  /* Since such a call function may use all call-clobbered
8154
     registers, we force a mode switch earlier, so that we don't
8155
     run out of registers when adjusting fpscr for the call.  */
8156
  emit_insn (gen_force_mode_for_call ());
8157
 
8158
  operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8159
                                 SFUNC_GOT);
8160
  operands[1] = force_reg (SImode, operands[1]);
8161
 
8162
  emit_move_insn (r0, func);
8163
  emit_move_insn (r1, cookie_rtx);
8164
 
8165
  if (cookie & CALL_COOKIE_RET_TRAMP (1))
8166
    emit_call_insn (gen_call_value_pop_compact_rettramp
8167
                        (operands[0], operands[1], operands[2],
8168
                         operands[3], operands[4]));
8169
  else
8170
    emit_call_insn (gen_call_value_pop_compact
8171
                        (operands[0], operands[1], operands[2],
8172
                         operands[3], operands[4]));
8173
 
8174
  DONE;
8175
}")
8176
 
8177
(define_expand "sibcall_epilogue"
8178
  [(return)]
8179
  ""
8180
  "
8181
{
8182
  sh_expand_epilogue (1);
8183
  if (TARGET_SHCOMPACT)
8184
    {
8185
      rtx insn, set;
8186
 
8187
      /* If epilogue clobbers r0, preserve it in macl.  */
8188
      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8189
        if ((set = single_set (insn))
8190
            && REG_P (SET_DEST (set))
8191
            && REGNO (SET_DEST (set)) == R0_REG)
8192
          {
8193
            rtx r0 = gen_rtx_REG (SImode, R0_REG);
8194
            rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8195
 
8196
            /* We can't tell at this point whether the sibcall is a
8197
               sibcall_compact and, if it is, whether it uses r0 or
8198
               mach as operand 2, so let the instructions that
8199
               preserve r0 be optimized away if r0 turns out to be
8200
               dead.  */
8201
            emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8202
            emit_move_insn (r0, tmp);
8203
            break;
8204
          }
8205
    }
8206
  DONE;
8207
}")
8208
 
8209
(define_insn "indirect_jump_compact"
8210
  [(set (pc)
8211
        (match_operand:SI 0 "arith_reg_operand" "r"))]
8212
  "TARGET_SH1"
8213
  "jmp  @%0%#"
8214
  [(set_attr "needs_delay_slot" "yes")
8215
   (set_attr "type" "jump_ind")])
8216
 
8217
(define_expand "indirect_jump"
8218
  [(set (pc)
8219
        (match_operand 0 "register_operand" ""))]
8220
  ""
8221
  "
8222
{
8223
  if (GET_MODE (operands[0]) != Pmode)
8224
    operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8225
}")
8226
 
8227
;; The use of operand 1 / 2 helps us distinguish case table jumps
8228
;; which can be present in structured code from indirect jumps which can not
8229
;; be present in structured code.  This allows -fprofile-arcs to work.
8230
 
8231
;; For SH1 processors.
8232
(define_insn "casesi_jump_1"
8233
  [(set (pc)
8234
        (match_operand:SI 0 "register_operand" "r"))
8235
   (use (label_ref (match_operand 1 "" "")))]
8236
  "TARGET_SH1"
8237
  "jmp  @%0%#"
8238
  [(set_attr "needs_delay_slot" "yes")
8239
   (set_attr "type" "jump_ind")])
8240
 
8241
;; For all later processors.
8242
(define_insn "casesi_jump_2"
8243
  [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8244
                      (label_ref (match_operand 1 "" ""))))
8245
   (use (label_ref (match_operand 2 "" "")))]
8246
  "TARGET_SH2
8247
   && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8248
  "braf %0%#"
8249
  [(set_attr "needs_delay_slot" "yes")
8250
   (set_attr "type" "jump_ind")])
8251
 
8252
(define_insn "casesi_jump_media"
8253
  [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8254
   (use (label_ref (match_operand 1 "" "")))]
8255
  "TARGET_SHMEDIA"
8256
  "blink        %0, r63"
8257
  [(set_attr "type" "jump_media")])
8258
 
8259
;; Call subroutine returning any type.
8260
;; ??? This probably doesn't work.
8261
 
8262
(define_expand "untyped_call"
8263
  [(parallel [(call (match_operand 0 "" "")
8264
                    (const_int 0))
8265
              (match_operand 1 "" "")
8266
              (match_operand 2 "" "")])]
8267
  "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8268
  "
8269
{
8270
  int i;
8271
 
8272
  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8273
 
8274
  for (i = 0; i < XVECLEN (operands[2], 0); i++)
8275
    {
8276
      rtx set = XVECEXP (operands[2], 0, i);
8277
      emit_move_insn (SET_DEST (set), SET_SRC (set));
8278
    }
8279
 
8280
  /* The optimizer does not know that the call sets the function value
8281
     registers we stored in the result block.  We avoid problems by
8282
     claiming that all hard registers are used and clobbered at this
8283
     point.  */
8284
  emit_insn (gen_blockage ());
8285
 
8286
  DONE;
8287
}")
8288
 
8289
;; ------------------------------------------------------------------------
8290
;; Misc insns
8291
;; ------------------------------------------------------------------------
8292
 
8293
(define_insn "dect"
8294
  [(set (reg:SI T_REG)
8295
        (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8296
   (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8297
  "TARGET_SH2"
8298
  "dt   %0"
8299
  [(set_attr "type" "arith")])
8300
 
8301
(define_insn "nop"
8302
  [(const_int 0)]
8303
  ""
8304
  "nop")
8305
 
8306
;; Load address of a label. This is only generated by the casesi expand,
8307
;; and by machine_dependent_reorg (fixing up fp moves).
8308
;; This must use unspec, because this only works for labels that are
8309
;; within range,
8310
 
8311
(define_insn "mova"
8312
  [(set (reg:SI R0_REG)
8313
        (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8314
  "TARGET_SH1"
8315
  "mova %O0,r0"
8316
  [(set_attr "in_delay_slot" "no")
8317
   (set_attr "type" "arith")])
8318
 
8319
;; machine_dependent_reorg will make this a `mova'.
8320
(define_insn "mova_const"
8321
  [(set (reg:SI R0_REG)
8322
        (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8323
  "TARGET_SH1"
8324
  "#"
8325
  [(set_attr "in_delay_slot" "no")
8326
   (set_attr "type" "arith")])
8327
 
8328
(define_expand "GOTaddr2picreg"
8329
  [(set (reg:SI R0_REG)
8330
        (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8331
                   UNSPEC_MOVA))
8332
   (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8333
   (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8334
  "" "
8335
{
8336
  if (TARGET_VXWORKS_RTP)
8337
    {
8338
      rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8339
      rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8340
      emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8341
      DONE;
8342
    }
8343
 
8344
  operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8345
  operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8346
 
8347
  if (TARGET_SHMEDIA)
8348
    {
8349
      rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8350
      rtx pic = operands[0];
8351
      rtx lab = PATTERN (gen_call_site ());
8352
      rtx insn, equiv;
8353
 
8354
      equiv = operands[1];
8355
      operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8356
                                    UNSPEC_PCREL_SYMOFF);
8357
      operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8358
 
8359
      if (Pmode == SImode)
8360
        {
8361
          emit_insn (gen_movsi_const (pic, operands[1]));
8362
          emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8363
        }
8364
      else
8365
        {
8366
          emit_insn (gen_movdi_const (pic, operands[1]));
8367
          emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8368
        }
8369
 
8370
      insn = emit_move_insn (operands[0], tr);
8371
 
8372
      set_unique_reg_note (insn, REG_EQUAL, equiv);
8373
 
8374
      DONE;
8375
    }
8376
}
8377
")
8378
 
8379
;; A helper for GOTaddr2picreg to finish up the initialization of the
8380
;; PIC register.
8381
 
8382
(define_expand "vxworks_picreg"
8383
  [(set (reg:SI PIC_REG)
8384
        (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8385
   (set (reg:SI R0_REG)
8386
        (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8387
   (set (reg:SI PIC_REG)
8388
        (mem:SI (reg:SI PIC_REG)))
8389
   (set (reg:SI PIC_REG)
8390
        (mem:SI (plus:SI (reg:SI PIC_REG)
8391
                         (reg:SI R0_REG))))]
8392
  "TARGET_VXWORKS_RTP")
8393
 
8394
(define_insn "*ptb"
8395
  [(set (match_operand 0 "target_reg_operand" "=b")
8396
        (const (unspec [(match_operand 1 "" "Csy")]
8397
                             UNSPEC_DATALABEL)))]
8398
  "TARGET_SHMEDIA && flag_pic
8399
   && satisfies_constraint_Csy (operands[1])"
8400
  "ptb/u        datalabel %1, %0"
8401
  [(set_attr "type" "ptabs_media")
8402
   (set_attr "length" "*")])
8403
 
8404
(define_insn "ptrel_si"
8405
  [(set (match_operand:SI 0 "target_reg_operand" "=b")
8406
        (plus:SI (match_operand:SI 1 "register_operand" "r")
8407
              (pc)))
8408
   (match_operand:SI 2 "" "")]
8409
  "TARGET_SHMEDIA"
8410
  "%O2: ptrel/u %1, %0"
8411
  [(set_attr "type" "ptabs_media")])
8412
 
8413
(define_insn "ptrel_di"
8414
  [(set (match_operand:DI 0 "target_reg_operand" "=b")
8415
        (plus:DI (match_operand:DI 1 "register_operand" "r")
8416
              (pc)))
8417
   (match_operand:DI 2 "" "")]
8418
  "TARGET_SHMEDIA"
8419
  "%O2: ptrel/u %1, %0"
8420
  [(set_attr "type" "ptabs_media")])
8421
 
8422
(define_expand "builtin_setjmp_receiver"
8423
  [(match_operand 0 "" "")]
8424
  "flag_pic"
8425
  "
8426
{
8427
  emit_insn (gen_GOTaddr2picreg ());
8428
  DONE;
8429
}")
8430
 
8431
(define_expand "call_site"
8432
  [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8433
  "TARGET_SH1"
8434
  "
8435
{
8436
  static HOST_WIDE_INT i = 0;
8437
  operands[0] = GEN_INT (i);
8438
  i++;
8439
}")
8440
 
8441
(define_expand "sym_label2reg"
8442
  [(set (match_operand:SI 0 "" "")
8443
        (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8444
                              (const (plus:SI (match_operand:SI 2 "" "")
8445
                                              (const_int 2)))]
8446
                             UNSPEC_SYMOFF)))]
8447
  "TARGET_SH1" "")
8448
 
8449
(define_expand "symGOT_load"
8450
  [(set (match_dup 2) (match_operand 1 "" ""))
8451
   (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8452
   (set (match_operand 0 "" "") (mem (match_dup 3)))]
8453
  ""
8454
  "
8455
{
8456
  rtx insn, mem;
8457
 
8458
  operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8459
  operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8460
 
8461
  if (TARGET_SHMEDIA)
8462
    {
8463
      rtx reg = operands[2];
8464
 
8465
      if (Pmode == DImode)
8466
        {
8467
          if (flag_pic > 1)
8468
            emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8469
          else
8470
            emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8471
        }
8472
      else
8473
        {
8474
          if (flag_pic > 1)
8475
            emit_insn (gen_movsi_const (reg, operands[1]));
8476
          else
8477
            emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8478
        }
8479
    }
8480
  else
8481
    emit_move_insn (operands[2], operands[1]);
8482
 
8483
  emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8484
                                             operands[2],
8485
                                             gen_rtx_REG (Pmode, PIC_REG)));
8486
 
8487
  /* When stack protector inserts codes after the result is set to
8488
     R0, @(rX, r12) will cause a spill failure for R0.  Don't schedule
8489
     insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8490
     when rX is a GOT address for the guard symbol.  Ugly but doesn't
8491
     matter because this is a rare situation.  */
8492
  if (!TARGET_SHMEDIA
8493
      && flag_stack_protect
8494
      && GET_CODE (operands[1]) == CONST
8495
      && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8496
      && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8497
      && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8498
                 \"__stack_chk_guard\") == 0)
8499
    emit_insn (gen_blockage ());
8500
 
8501
  /* N.B. This is not constant for a GOTPLT relocation.  */
8502
  mem = gen_rtx_MEM (Pmode, operands[3]);
8503
  MEM_NOTRAP_P (mem) = 1;
8504
  /* ??? Should we have a special alias set for the GOT?  */
8505
  insn = emit_move_insn (operands[0], mem);
8506
 
8507
  DONE;
8508
}")
8509
 
8510
(define_expand "sym2GOT"
8511
  [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8512
  ""
8513
  "")
8514
 
8515
(define_expand "symGOT2reg"
8516
  [(match_operand 0 "" "") (match_operand 1 "" "")]
8517
  ""
8518
  "
8519
{
8520
  rtx gotsym, insn;
8521
 
8522
  gotsym = gen_sym2GOT (operands[1]);
8523
  PUT_MODE (gotsym, Pmode);
8524
  insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8525
 
8526
  MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8527
 
8528
  DONE;
8529
}")
8530
 
8531
(define_expand "symGOTPLT2reg"
8532
  [(match_operand 0 "" "") (match_operand 1 "" "")]
8533
  ""
8534
  "
8535
{
8536
  rtx pltsym = gen_rtx_CONST (Pmode,
8537
                              gen_rtx_UNSPEC (Pmode,
8538
                                              gen_rtvec (1, operands[1]),
8539
                                              UNSPEC_GOTPLT));
8540
  emit_insn (gen_symGOT_load (operands[0], pltsym));
8541
  DONE;
8542
}")
8543
 
8544
(define_expand "sym2GOTOFF"
8545
  [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8546
  ""
8547
  "")
8548
 
8549
(define_expand "symGOTOFF2reg"
8550
  [(match_operand 0 "" "") (match_operand 1 "" "")]
8551
  ""
8552
  "
8553
{
8554
  rtx gotoffsym, insn;
8555
  rtx t = (!can_create_pseudo_p ()
8556
           ? operands[0]
8557
           : gen_reg_rtx (GET_MODE (operands[0])));
8558
 
8559
  gotoffsym = gen_sym2GOTOFF (operands[1]);
8560
  PUT_MODE (gotoffsym, Pmode);
8561
  emit_move_insn (t, gotoffsym);
8562
  insn = emit_move_insn (operands[0],
8563
                         gen_rtx_PLUS (Pmode, t,
8564
                                       gen_rtx_REG (Pmode, PIC_REG)));
8565
 
8566
  set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8567
 
8568
  DONE;
8569
}")
8570
 
8571
(define_expand "symPLT_label2reg"
8572
  [(set (match_operand:SI 0 "" "")
8573
        (const:SI
8574
         (unspec:SI
8575
          [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8576
           (const:SI (plus:SI (match_operand:SI 2 "" "")
8577
                              (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8578
   ;; Even though the PIC register is not really used by the call
8579
   ;; sequence in which this is expanded, the PLT code assumes the PIC
8580
   ;; register is set, so we must not skip its initialization.  Since
8581
   ;; we only use this expand as part of calling sequences, and never
8582
   ;; to take the address of a function, this is the best point to
8583
   ;; insert the (use).  Using the PLT to take the address of a
8584
   ;; function would be wrong, not only because the PLT entry could
8585
   ;; then be called from a function that doesn't initialize the PIC
8586
   ;; register to the proper GOT, but also because pointers to the
8587
   ;; same function might not compare equal, should they be set by
8588
   ;; different shared libraries.
8589
   (use (reg:SI PIC_REG))]
8590
  "TARGET_SH1"
8591
  "")
8592
 
8593
(define_expand "sym2PIC"
8594
  [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8595
  ""
8596
  "")
8597
 
8598
;; TLS code generation.
8599
;; ??? this should be a define_insn_and_split
8600
;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8601
;; 
8602
;; for details.
8603
 
8604
(define_insn "tls_global_dynamic"
8605
  [(set (match_operand:SI 0 "register_operand" "=&z")
8606
        (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8607
                                  UNSPEC_TLSGD))
8608
              (const_int 0)))
8609
   (use (reg:PSI FPSCR_REG))
8610
   (use (reg:SI PIC_REG))
8611
   (clobber (reg:SI PR_REG))
8612
   (clobber (scratch:SI))]
8613
  "TARGET_SH1"
8614
  "*
8615
{
8616
  return \"\\
8617
mov.l\\t1f,r4\\n\\
8618
\\tmova\\t2f,r0\\n\\
8619
\\tmov.l\\t2f,r1\\n\\
8620
\\tadd\\tr0,r1\\n\\
8621
\\tjsr\\t@r1\\n\\
8622
\\tadd\\tr12,r4\\n\\
8623
\\tbra\\t3f\\n\\
8624
\\tnop\\n\\
8625
\\t.align\\t2\\n\\
8626
1:\\t.long\\t%a1@TLSGD\\n\\
8627
2:\\t.long\\t__tls_get_addr@PLT\\n\\
8628
3:\";
8629
}"
8630
  [(set_attr "type" "tls_load")
8631
   (set_attr "length" "26")])
8632
 
8633
(define_insn "tls_local_dynamic"
8634
  [(set (match_operand:SI 0 "register_operand" "=&z")
8635
        (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8636
                                  UNSPEC_TLSLDM))
8637
              (const_int 0)))
8638
   (use (reg:PSI FPSCR_REG))
8639
   (use (reg:SI PIC_REG))
8640
   (clobber (reg:SI PR_REG))
8641
   (clobber (scratch:SI))]
8642
  "TARGET_SH1"
8643
  "*
8644
{
8645
  return \"\\
8646
mov.l\\t1f,r4\\n\\
8647
\\tmova\\t2f,r0\\n\\
8648
\\tmov.l\\t2f,r1\\n\\
8649
\\tadd\\tr0,r1\\n\\
8650
\\tjsr\\t@r1\\n\\
8651
\\tadd\\tr12,r4\\n\\
8652
\\tbra\\t3f\\n\\
8653
\\tnop\\n\\
8654
\\t.align\\t2\\n\\
8655
1:\\t.long\\t%a1@TLSLDM\\n\\
8656
2:\\t.long\\t__tls_get_addr@PLT\\n\\
8657
3:\";
8658
}"
8659
  [(set_attr "type" "tls_load")
8660
   (set_attr "length" "26")])
8661
 
8662
(define_expand "sym2DTPOFF"
8663
  [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8664
  ""
8665
  "")
8666
 
8667
(define_expand "symDTPOFF2reg"
8668
  [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8669
  ""
8670
  "
8671
{
8672
  rtx dtpoffsym, insn;
8673
  rtx t = (!can_create_pseudo_p ()
8674
           ? operands[0]
8675
           : gen_reg_rtx (GET_MODE (operands[0])));
8676
 
8677
  dtpoffsym = gen_sym2DTPOFF (operands[1]);
8678
  PUT_MODE (dtpoffsym, Pmode);
8679
  emit_move_insn (t, dtpoffsym);
8680
  insn = emit_move_insn (operands[0],
8681
                         gen_rtx_PLUS (Pmode, t, operands[2]));
8682
  DONE;
8683
}")
8684
 
8685
(define_expand "sym2GOTTPOFF"
8686
  [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8687
  ""
8688
  "")
8689
 
8690
(define_insn "tls_initial_exec"
8691
  [(set (match_operand:SI 0 "register_operand" "=&r")
8692
        (unspec:SI [(match_operand:SI 1 "" "")]
8693
                    UNSPEC_TLSIE))
8694
   (use (reg:SI GBR_REG))
8695
   (use (reg:SI PIC_REG))
8696
   (clobber (reg:SI R0_REG))]
8697
  ""
8698
  "*
8699
{
8700
  return \"\\
8701
mov.l\\t1f,r0\\n\\
8702
\\tstc\\tgbr,%0\\n\\
8703
\\tmov.l\\t@(r0,r12),r0\\n\\
8704
\\tbra\\t2f\\n\\
8705
\\tadd\\tr0,%0\\n\\
8706
\\t.align\\t2\\n\\
8707
1:\\t.long\\t%a1\\n\\
8708
2:\";
8709
}"
8710
  [(set_attr "type" "tls_load")
8711
   (set_attr "length" "16")])
8712
 
8713
(define_expand "sym2TPOFF"
8714
  [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8715
  ""
8716
  "")
8717
 
8718
(define_expand "symTPOFF2reg"
8719
  [(match_operand 0 "" "") (match_operand 1 "" "")]
8720
  ""
8721
  "
8722
{
8723
  rtx tpoffsym, insn;
8724
 
8725
  tpoffsym = gen_sym2TPOFF (operands[1]);
8726
  PUT_MODE (tpoffsym, Pmode);
8727
  insn = emit_move_insn (operands[0], tpoffsym);
8728
  DONE;
8729
}")
8730
 
8731
(define_insn "load_gbr"
8732
  [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8733
   (use (reg:SI GBR_REG))]
8734
  ""
8735
  "stc  gbr,%0"
8736
  [(set_attr "type" "tls_load")])
8737
 
8738
;; case instruction for switch statements.
8739
 
8740
;; Operand 0 is index
8741
;; operand 1 is the minimum bound
8742
;; operand 2 is the maximum bound - minimum bound + 1
8743
;; operand 3 is CODE_LABEL for the table;
8744
;; operand 4 is the CODE_LABEL to go to if index out of range.
8745
 
8746
(define_expand "casesi"
8747
  [(match_operand:SI 0 "arith_reg_operand" "")
8748
   (match_operand:SI 1 "arith_reg_operand" "")
8749
   (match_operand:SI 2 "arith_reg_operand" "")
8750
   (match_operand 3 "" "") (match_operand 4 "" "")]
8751
  ""
8752
  "
8753
{
8754
  rtx reg = gen_reg_rtx (SImode);
8755
  rtx reg2 = gen_reg_rtx (SImode);
8756
  if (TARGET_SHMEDIA)
8757
    {
8758
      rtx reg = gen_reg_rtx (DImode);
8759
      rtx reg2 = gen_reg_rtx (DImode);
8760
      rtx reg3 = gen_reg_rtx (Pmode);
8761
      rtx reg4 = gen_reg_rtx (Pmode);
8762
      rtx reg5 = gen_reg_rtx (Pmode);
8763
      rtx load, test;
8764
 
8765
      operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8766
      operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8767
      operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8768
 
8769
      test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8770
      emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8771
      emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8772
      test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8773
      emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8774
      emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8775
      emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8776
                                               (Pmode, operands[3])));
8777
      /* Messy: can we subreg to clean this up? */
8778
      if (Pmode == DImode)
8779
        load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8780
      else
8781
        load = gen_casesi_load_media (reg4,
8782
                                      gen_rtx_SUBREG (DImode, reg3, 0),
8783
                                      reg2, operands[3]);
8784
      PUT_MODE (SET_SRC (load), Pmode);
8785
      emit_insn (load);
8786
      /* ??? The following add could be eliminated if we used ptrel.  */
8787
      emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8788
      emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8789
      emit_barrier ();
8790
      DONE;
8791
    }
8792
  operands[1] = copy_to_mode_reg (SImode, operands[1]);
8793
  operands[2] = copy_to_mode_reg (SImode, operands[2]);
8794
  /* If optimizing, casesi_worker depends on the mode of the instruction
8795
     before label it 'uses' - operands[3].  */
8796
  emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8797
                           reg));
8798
  emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8799
  if (TARGET_SH2)
8800
    emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8801
  else
8802
    emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8803
  /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8804
     operands[3], but to lab.  We will fix this up in
8805
     machine_dependent_reorg.  */
8806
  emit_barrier ();
8807
  DONE;
8808
}")
8809
 
8810
(define_expand "casesi_0"
8811
  [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8812
   (set (match_dup 4) (minus:SI (match_dup 4)
8813
                                (match_operand:SI 1 "arith_operand" "")))
8814
   (set (reg:SI T_REG)
8815
        (gtu:SI (match_dup 4)
8816
                (match_operand:SI 2 "arith_reg_operand" "")))
8817
   (set (pc)
8818
        (if_then_else (ne (reg:SI T_REG)
8819
                          (const_int 0))
8820
                      (label_ref (match_operand 3 "" ""))
8821
                      (pc)))]
8822
  "TARGET_SH1"
8823
  "")
8824
 
8825
;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8826
;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8827
;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8828
 
8829
(define_insn "casesi_worker_0"
8830
  [(set (match_operand:SI 0 "register_operand" "=r,r")
8831
        (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8832
                 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8833
   (clobber (match_scratch:SI 3 "=X,1"))
8834
   (clobber (match_scratch:SI 4 "=&z,z"))]
8835
  "TARGET_SH1"
8836
  "#")
8837
 
8838
(define_split
8839
  [(set (match_operand:SI 0 "register_operand" "")
8840
        (unspec:SI [(match_operand:SI 1 "register_operand" "")
8841
                    (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8842
   (clobber (match_scratch:SI 3 ""))
8843
   (clobber (match_scratch:SI 4 ""))]
8844
  "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8845
  [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8846
   (parallel [(set (match_dup 0)
8847
              (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8848
                          (label_ref (match_dup 2))] UNSPEC_CASESI))
8849
              (clobber (match_dup 3))])
8850
   (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8851
  "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8852
 
8853
(define_split
8854
  [(set (match_operand:SI 0 "register_operand" "")
8855
        (unspec:SI [(match_operand:SI 1 "register_operand" "")
8856
                    (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8857
   (clobber (match_scratch:SI 3 ""))
8858
   (clobber (match_scratch:SI 4 ""))]
8859
  "TARGET_SH2 && reload_completed"
8860
  [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8861
   (parallel [(set (match_dup 0)
8862
              (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8863
                          (label_ref (match_dup 2))] UNSPEC_CASESI))
8864
              (clobber (match_dup 3))])]
8865
  "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8866
 
8867
(define_insn "casesi_worker_1"
8868
  [(set (match_operand:SI 0 "register_operand" "=r,r")
8869
        (unspec:SI [(reg:SI R0_REG)
8870
                    (match_operand:SI 1 "register_operand" "0,r")
8871
                    (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8872
   (clobber (match_scratch:SI 3 "=X,1"))]
8873
  "TARGET_SH1"
8874
  "*
8875
{
8876
  rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8877
 
8878
  gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8879
 
8880
  switch (GET_MODE (diff_vec))
8881
    {
8882
    case SImode:
8883
      return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8884
    case HImode:
8885
      return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8886
    case QImode:
8887
      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8888
        return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8889
      return \"mov.b    @(r0,%1),%0\";
8890
    default:
8891
      gcc_unreachable ();
8892
    }
8893
}"
8894
  [(set_attr "length" "4")])
8895
 
8896
(define_insn "casesi_worker_2"
8897
  [(set (match_operand:SI 0 "register_operand" "=r,r")
8898
        (unspec:SI [(reg:SI R0_REG)
8899
                    (match_operand:SI 1 "register_operand" "0,r")
8900
                    (label_ref (match_operand 2 "" ""))
8901
                    (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8902
   (clobber (match_operand:SI 4 "" "=X,1"))]
8903
  "TARGET_SH2 && reload_completed && flag_pic"
8904
  "*
8905
{
8906
  rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8907
  const char *load;
8908
 
8909
  gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8910
 
8911
  switch (GET_MODE (diff_vec))
8912
    {
8913
    case SImode:
8914
      output_asm_insn (\"shll2    %1\", operands);
8915
      load = \"mov.l    @(r0,%1),%0\"; break;
8916
    case HImode:
8917
      output_asm_insn (\"add    %1,%1\", operands);
8918
      load = \"mov.w    @(r0,%1),%0\"; break;
8919
    case QImode:
8920
      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8921
        load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8922
      else
8923
        load = \"mov.b  @(r0,%1),%0\";
8924
      break;
8925
    default:
8926
      gcc_unreachable ();
8927
    }
8928
  output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8929
  return load;
8930
}"
8931
  [(set_attr "length" "8")])
8932
 
8933
(define_insn "casesi_shift_media"
8934
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8935
        (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8936
                   (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8937
                    UNSPEC_CASESI)))]
8938
  "TARGET_SHMEDIA"
8939
  "*
8940
{
8941
  rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8942
 
8943
  gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8944
 
8945
  switch (GET_MODE (diff_vec))
8946
    {
8947
    case SImode:
8948
      return \"shlli    %1, 2, %0\";
8949
    case HImode:
8950
      return \"shlli    %1, 1, %0\";
8951
    case QImode:
8952
      if (rtx_equal_p (operands[0], operands[1]))
8953
        return \"\";
8954
      return \"add      %1, r63, %0\";
8955
    default:
8956
      gcc_unreachable ();
8957
    }
8958
}"
8959
  [(set_attr "type" "arith_media")])
8960
 
8961
(define_insn "casesi_load_media"
8962
  [(set (match_operand 0 "any_arith_reg_dest" "=r")
8963
        (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8964
                         (match_operand:DI 2 "arith_reg_operand" "r")
8965
                         (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8966
  "TARGET_SHMEDIA"
8967
  "*
8968
{
8969
  rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8970
 
8971
  gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8972
 
8973
  switch (GET_MODE (diff_vec))
8974
    {
8975
    case SImode:
8976
      return \"ldx.l    %1, %2, %0\";
8977
    case HImode:
8978
#if 0
8979
      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8980
        return \"ldx.uw %1, %2, %0\";
8981
#endif
8982
      return \"ldx.w    %1, %2, %0\";
8983
    case QImode:
8984
      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8985
        return \"ldx.ub %1, %2, %0\";
8986
      return \"ldx.b    %1, %2, %0\";
8987
    default:
8988
      gcc_unreachable ();
8989
    }
8990
}"
8991
  [(set_attr "type" "load_media")])
8992
 
8993
(define_expand "return"
8994
  [(return)]
8995
  "reload_completed && ! sh_need_epilogue ()"
8996
  "
8997
{
8998
  if (TARGET_SHMEDIA)
8999
    {
9000
      emit_jump_insn (gen_return_media ());
9001
      DONE;
9002
    }
9003
 
9004
  if (TARGET_SHCOMPACT
9005
      && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9006
    {
9007
      emit_jump_insn (gen_shcompact_return_tramp ());
9008
      DONE;
9009
    }
9010
}")
9011
 
9012
(define_insn "*return_i"
9013
  [(return)]
9014
  "TARGET_SH1 && ! (TARGET_SHCOMPACT
9015
                    && (crtl->args.info.call_cookie
9016
                        & CALL_COOKIE_RET_TRAMP (1)))
9017
   && reload_completed
9018
   && lookup_attribute (\"trap_exit\",
9019
                        DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9020
  "*
9021
  {
9022
    if (TARGET_SH2A && (dbr_sequence_length () == 0)
9023
                        && !current_function_interrupt)
9024
       return \"rts/n\";
9025
    else
9026
       return \"%@      %#\";
9027
  }"
9028
  [(set_attr "type" "return")
9029
   (set_attr "needs_delay_slot" "yes")])
9030
 
9031
;; trapa has no delay slot.
9032
(define_insn "*return_trapa"
9033
  [(return)]
9034
  "TARGET_SH1 && !TARGET_SHCOMPACT
9035
   && reload_completed"
9036
  "%@"
9037
  [(set_attr "type" "return")])
9038
 
9039
(define_expand "shcompact_return_tramp"
9040
  [(return)]
9041
  "TARGET_SHCOMPACT
9042
   && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9043
  "
9044
{
9045
  rtx reg = gen_rtx_REG (Pmode, R0_REG);
9046
 
9047
  function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9048
  emit_jump_insn (gen_shcompact_return_tramp_i ());
9049
  DONE;
9050
}")
9051
 
9052
(define_insn "shcompact_return_tramp_i"
9053
  [(parallel [(return) (use (reg:SI R0_REG))])]
9054
  "TARGET_SHCOMPACT
9055
   && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9056
  "jmp  @r0%#"
9057
  [(set_attr "type" "jump_ind")
9058
   (set_attr "needs_delay_slot" "yes")])
9059
 
9060
(define_insn "return_media_i"
9061
  [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9062
  "TARGET_SHMEDIA && reload_completed"
9063
  "blink        %0, r63"
9064
  [(set_attr "type" "jump_media")])
9065
 
9066
(define_insn "return_media_rte"
9067
  [(return)]
9068
  "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9069
  "rte"
9070
  [(set_attr "type" "jump_media")])
9071
 
9072
(define_expand "return_media"
9073
  [(return)]
9074
  "TARGET_SHMEDIA && reload_completed"
9075
  "
9076
{
9077
  int tr_regno = sh_media_register_for_return ();
9078
  rtx tr;
9079
 
9080
  if (current_function_interrupt)
9081
    {
9082
      emit_jump_insn (gen_return_media_rte ());
9083
      DONE;
9084
    }
9085
  if (tr_regno < 0)
9086
    {
9087
      rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9088
 
9089
      gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9090
      tr_regno = TR0_REG;
9091
      tr = gen_rtx_REG (Pmode, tr_regno);
9092
      emit_move_insn (tr, r18);
9093
    }
9094
  else
9095
    tr = gen_rtx_REG (Pmode, tr_regno);
9096
 
9097
  emit_jump_insn (gen_return_media_i (tr));
9098
  DONE;
9099
}")
9100
 
9101
(define_insn "shcompact_preserve_incoming_args"
9102
  [(set (match_operand:SI 0 "register_operand" "+r")
9103
        (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9104
  "TARGET_SHCOMPACT"
9105
  ""
9106
  [(set_attr "length" "0")])
9107
 
9108
(define_insn "shcompact_incoming_args"
9109
  [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9110
   (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9111
   (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9112
   (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9113
   (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9114
   (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9115
   (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9116
   (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9117
   (set (mem:BLK (reg:SI MACL_REG))
9118
        (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9119
   (use (reg:SI R0_REG))
9120
   (clobber (reg:SI R0_REG))
9121
   (clobber (reg:SI MACL_REG))
9122
   (clobber (reg:SI MACH_REG))
9123
   (clobber (reg:SI PR_REG))]
9124
  "TARGET_SHCOMPACT"
9125
  "jsr  @r0%#"
9126
  [(set_attr "needs_delay_slot" "yes")])
9127
 
9128
(define_insn "shmedia_save_restore_regs_compact"
9129
  [(set (reg:SI SP_REG)
9130
        (plus:SI (reg:SI SP_REG)
9131
                 (match_operand:SI 0 "immediate_operand" "i")))
9132
   (use (reg:SI R0_REG))
9133
   (clobber (reg:SI PR_REG))]
9134
  "TARGET_SHCOMPACT
9135
   && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9136
       || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9137
  "jsr @r0%#"
9138
  [(set_attr "needs_delay_slot" "yes")])
9139
 
9140
(define_expand "prologue"
9141
  [(const_int 0)]
9142
  ""
9143
  "sh_expand_prologue (); DONE;")
9144
 
9145
(define_expand "epilogue"
9146
  [(return)]
9147
  ""
9148
  "
9149
{
9150
  sh_expand_epilogue (0);
9151
  emit_jump_insn (gen_return ());
9152
  DONE;
9153
}")
9154
 
9155
(define_expand "eh_return"
9156
  [(use (match_operand 0 "register_operand" ""))]
9157
  ""
9158
{
9159
  rtx ra = operands[0];
9160
 
9161
  if (TARGET_SHMEDIA64)
9162
    emit_insn (gen_eh_set_ra_di (ra));
9163
  else
9164
    emit_insn (gen_eh_set_ra_si (ra));
9165
 
9166
  DONE;
9167
})
9168
 
9169
;; Clobber the return address on the stack.  We can't expand this
9170
;; until we know where it will be put in the stack frame.
9171
 
9172
(define_insn "eh_set_ra_si"
9173
  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9174
      UNSPECV_EH_RETURN)
9175
   (clobber (match_scratch:SI 1 "=&r"))]
9176
  "! TARGET_SHMEDIA64"
9177
  "#")
9178
 
9179
(define_insn "eh_set_ra_di"
9180
  [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9181
      UNSPECV_EH_RETURN)
9182
   (clobber (match_scratch:DI 1 "=&r"))]
9183
  "TARGET_SHMEDIA64"
9184
  "#")
9185
 
9186
(define_split
9187
  [(unspec_volatile [(match_operand 0 "register_operand" "")]
9188
      UNSPECV_EH_RETURN)
9189
   (clobber (match_scratch 1 ""))]
9190
  "reload_completed"
9191
  [(const_int 0)]
9192
  "
9193
{
9194
  sh_set_return_address (operands[0], operands[1]);
9195
  DONE;
9196
}")
9197
 
9198
(define_insn "blockage"
9199
  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9200
  ""
9201
  ""
9202
  [(set_attr "length" "0")])
9203
 
9204
;; ------------------------------------------------------------------------
9205
;; Scc instructions
9206
;; ------------------------------------------------------------------------
9207
 
9208
(define_insn "movt"
9209
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9210
        (eq:SI (reg:SI T_REG) (const_int 1)))]
9211
  "TARGET_SH1"
9212
  "movt %0"
9213
  [(set_attr "type" "arith")])
9214
 
9215
(define_expand "cstore4_media"
9216
  [(set (match_operand:SI 0 "register_operand" "=r")
9217
        (match_operator:SI 1 "sh_float_comparison_operator"
9218
         [(match_operand 2 "logical_operand" "")
9219
          (match_operand 3 "cmp_operand" "")]))]
9220
  "TARGET_SHMEDIA"
9221
  "
9222
{
9223
  enum machine_mode mode = GET_MODE (operands[2]);
9224
  enum rtx_code code = GET_CODE (operands[1]);
9225
  bool invert, swap;
9226
  if (mode == VOIDmode)
9227
    mode = GET_MODE (operands[3]);
9228
  if (operands[2] == const0_rtx)
9229
    {
9230
      if (code == EQ || code == NE)
9231
        operands[2] = operands[3], operands[3] = const0_rtx;
9232
    }
9233
  else
9234
    operands[2] = force_reg (mode, operands[2]);
9235
  if (operands[3] != const0_rtx)
9236
    operands[3] = force_reg (mode, operands[3]);
9237
 
9238
  switch (code)
9239
    {
9240
    case GEU:
9241
    case GE:
9242
      swap = invert = !FLOAT_MODE_P (mode);
9243
      break;
9244
 
9245
    case LEU:
9246
    case LE:
9247
      swap = FLOAT_MODE_P (mode), invert = !swap;
9248
      break;
9249
 
9250
    case LTU:
9251
    case LT:
9252
      swap = true, invert = false;
9253
      break;
9254
 
9255
    case GTU:
9256
    case GT:
9257
    case EQ:
9258
    case UNORDERED:
9259
      swap = invert = false;
9260
      break;
9261
 
9262
    case NE:
9263
      swap = invert = true;
9264
      break;
9265
 
9266
    default:
9267
      gcc_unreachable ();
9268
  }
9269
 
9270
  if (swap)
9271
    {
9272
      rtx tem = operands[2];
9273
      operands[2] = operands[3];
9274
      operands[3] = tem;
9275
      code = swap_condition (code);
9276
    }
9277
 
9278
  if (invert)
9279
    {
9280
      rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9281
      code = reverse_condition (code);
9282
      operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9283
      emit_insn (gen_cstore4_media (tem, operands[1],
9284
                                    operands[2], operands[3]));
9285
      code = EQ;
9286
      operands[2] = tem;
9287
      operands[3] = const0_rtx;
9288
    }
9289
 
9290
  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9291
}")
9292
 
9293
(define_expand "cstoresi4"
9294
  [(set (match_operand:SI 0 "register_operand" "=r")
9295
        (match_operator:SI 1 "comparison_operator"
9296
         [(match_operand:SI 2 "cmpsi_operand" "")
9297
          (match_operand:SI 3 "arith_operand" "")]))]
9298
  "TARGET_SH1 || TARGET_SHMEDIA"
9299
  "if (TARGET_SHMEDIA)
9300
    {
9301
      emit_insn (gen_cstore4_media (operands[0], operands[1],
9302
                                    operands[2], operands[3]));
9303
      DONE;
9304
    }
9305
 
9306
   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9307
       && sh_expand_t_scc (operands))
9308
     DONE;
9309
 
9310
   if (! currently_expanding_to_rtl)
9311
     FAIL;
9312
 
9313
   sh_emit_compare_and_set (operands, SImode);
9314
   DONE;
9315
")
9316
 
9317
(define_expand "cstoredi4"
9318
  [(set (match_operand:SI 0 "register_operand" "=r")
9319
        (match_operator:SI 1 "comparison_operator"
9320
         [(match_operand:DI 2 "arith_operand" "")
9321
          (match_operand:DI 3 "arith_operand" "")]))]
9322
  "TARGET_SH2 || TARGET_SHMEDIA"
9323
  "if (TARGET_SHMEDIA)
9324
    {
9325
      emit_insn (gen_cstore4_media (operands[0], operands[1],
9326
                                    operands[2], operands[3]));
9327
      DONE;
9328
    }
9329
 
9330
   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9331
       && sh_expand_t_scc (operands))
9332
     DONE;
9333
 
9334
   if (! currently_expanding_to_rtl)
9335
     FAIL;
9336
 
9337
   sh_emit_compare_and_set (operands, DImode);
9338
   DONE;
9339
")
9340
 
9341
 
9342
 
9343
;; sne moves the complement of the T reg to DEST like this:
9344
;;      cmp/eq ...
9345
;;      mov    #-1,temp
9346
;;      negc   temp,dest
9347
;;   This is better than xoring compare result with 1 because it does
9348
;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9349
;;   loop.
9350
 
9351
(define_expand "movnegt"
9352
  [(set (match_dup 1) (const_int -1))
9353
   (parallel [(set (match_operand:SI 0 "" "")
9354
                   (neg:SI (plus:SI (reg:SI T_REG)
9355
                                    (match_dup 1))))
9356
              (set (reg:SI T_REG)
9357
                   (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9358
                          (const_int 0)))])]
9359
  ""
9360
  "
9361
{
9362
  operands[1] = gen_reg_rtx (SImode);
9363
}")
9364
 
9365
 
9366
;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9367
;; This prevents a regression that occurred when we switched from xor to
9368
;; mov/neg for sne.
9369
 
9370
(define_split
9371
  [(set (match_operand:SI 0 "arith_reg_dest" "")
9372
        (plus:SI (reg:SI T_REG)
9373
                 (const_int -1)))]
9374
  "TARGET_SH1"
9375
  [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9376
   (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9377
  "")
9378
 
9379
(define_expand "cstoresf4"
9380
  [(set (match_operand:SI 0 "register_operand" "=r")
9381
        (match_operator:SI 1 "sh_float_comparison_operator"
9382
         [(match_operand:SF 2 "arith_operand" "")
9383
          (match_operand:SF 3 "arith_operand" "")]))]
9384
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9385
  "if (TARGET_SHMEDIA)
9386
     {
9387
       emit_insn (gen_cstore4_media (operands[0], operands[1],
9388
                                     operands[2], operands[3]));
9389
       DONE;
9390
     }
9391
 
9392
   if (! currently_expanding_to_rtl)
9393
     FAIL;
9394
 
9395
   sh_emit_compare_and_set (operands, SFmode);
9396
   DONE;
9397
")
9398
 
9399
(define_expand "cstoredf4"
9400
  [(set (match_operand:SI 0 "register_operand" "=r")
9401
        (match_operator:SI 1 "sh_float_comparison_operator"
9402
         [(match_operand:DF 2 "arith_operand" "")
9403
          (match_operand:DF 3 "arith_operand" "")]))]
9404
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9405
  "if (TARGET_SHMEDIA)
9406
     {
9407
       emit_insn (gen_cstore4_media (operands[0], operands[1],
9408
                                     operands[2], operands[3]));
9409
       DONE;
9410
     }
9411
 
9412
    if (! currently_expanding_to_rtl)
9413
      FAIL;
9414
 
9415
   sh_emit_compare_and_set (operands, DFmode);
9416
   DONE;
9417
")
9418
 
9419
 
9420
;; -------------------------------------------------------------------------
9421
;; Instructions to cope with inline literal tables
9422
;; -------------------------------------------------------------------------
9423
 
9424
; 2 byte integer in line
9425
 
9426
(define_insn "consttable_2"
9427
 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9428
                    (match_operand 1 "" "")]
9429
                   UNSPECV_CONST2)]
9430
 ""
9431
 "*
9432
{
9433
  if (operands[1] != const0_rtx)
9434
    assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9435
  return \"\";
9436
}"
9437
 [(set_attr "length" "2")
9438
 (set_attr "in_delay_slot" "no")])
9439
 
9440
; 4 byte integer in line
9441
 
9442
(define_insn "consttable_4"
9443
 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9444
                    (match_operand 1 "" "")]
9445
                   UNSPECV_CONST4)]
9446
 ""
9447
 "*
9448
{
9449
  if (operands[1] != const0_rtx)
9450
    {
9451
      assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9452
      mark_symbol_refs_as_used (operands[0]);
9453
    }
9454
  return \"\";
9455
}"
9456
 [(set_attr "length" "4")
9457
  (set_attr "in_delay_slot" "no")])
9458
 
9459
; 8 byte integer in line
9460
 
9461
(define_insn "consttable_8"
9462
 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9463
                    (match_operand 1 "" "")]
9464
                   UNSPECV_CONST8)]
9465
 ""
9466
 "*
9467
{
9468
  if (operands[1] != const0_rtx)
9469
    assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9470
  return \"\";
9471
}"
9472
 [(set_attr "length" "8")
9473
  (set_attr "in_delay_slot" "no")])
9474
 
9475
; 4 byte floating point
9476
 
9477
(define_insn "consttable_sf"
9478
 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9479
                    (match_operand 1 "" "")]
9480
                   UNSPECV_CONST4)]
9481
 ""
9482
 "*
9483
{
9484
  if (operands[1] != const0_rtx)
9485
    {
9486
      REAL_VALUE_TYPE d;
9487
      REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9488
      assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9489
    }
9490
  return \"\";
9491
}"
9492
 [(set_attr "length" "4")
9493
  (set_attr "in_delay_slot" "no")])
9494
 
9495
; 8 byte floating point
9496
 
9497
(define_insn "consttable_df"
9498
 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9499
                    (match_operand 1 "" "")]
9500
                   UNSPECV_CONST8)]
9501
 ""
9502
 "*
9503
{
9504
  if (operands[1] != const0_rtx)
9505
    {
9506
      REAL_VALUE_TYPE d;
9507
      REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9508
      assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9509
    }
9510
  return \"\";
9511
}"
9512
 [(set_attr "length" "8")
9513
  (set_attr "in_delay_slot" "no")])
9514
 
9515
;; Alignment is needed for some constant tables; it may also be added for
9516
;; Instructions at the start of loops, or after unconditional branches.
9517
;; ??? We would get more accurate lengths if we did instruction
9518
;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9519
;; here is too conservative.
9520
 
9521
; align to a two byte boundary
9522
 
9523
(define_expand "align_2"
9524
 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9525
 ""
9526
 "")
9527
 
9528
; align to a four byte boundary
9529
;; align_4 and align_log are instructions for the starts of loops, or
9530
;; after unconditional branches, which may take up extra room.
9531
 
9532
(define_expand "align_4"
9533
 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9534
 ""
9535
 "")
9536
 
9537
; align to a cache line boundary
9538
 
9539
(define_insn "align_log"
9540
 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9541
 ""
9542
 ""
9543
 [(set_attr "length" "0")
9544
  (set_attr "in_delay_slot" "no")])
9545
 
9546
; emitted at the end of the literal table, used to emit the
9547
; 32bit branch labels if needed.
9548
 
9549
(define_insn "consttable_end"
9550
  [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9551
  ""
9552
  "* return output_jump_label_table ();"
9553
  [(set_attr "in_delay_slot" "no")])
9554
 
9555
; emitted at the end of the window in the literal table.
9556
 
9557
(define_insn "consttable_window_end"
9558
  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9559
  ""
9560
  ""
9561
  [(set_attr "length" "0")
9562
   (set_attr "in_delay_slot" "no")])
9563
 
9564
;; -------------------------------------------------------------------------
9565
;; Misc
9566
;; -------------------------------------------------------------------------
9567
 
9568
;; String/block move insn.
9569
 
9570
(define_expand "movmemsi"
9571
  [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9572
                   (mem:BLK (match_operand:BLK 1 "" "")))
9573
              (use (match_operand:SI 2 "nonmemory_operand" ""))
9574
              (use (match_operand:SI 3 "immediate_operand" ""))
9575
              (clobber (reg:SI PR_REG))
9576
              (clobber (reg:SI R4_REG))
9577
              (clobber (reg:SI R5_REG))
9578
              (clobber (reg:SI R0_REG))])]
9579
  "TARGET_SH1 && ! TARGET_SH5"
9580
  "
9581
{
9582
  if(expand_block_move (operands))
9583
     DONE;
9584
  else FAIL;
9585
}")
9586
 
9587
(define_insn "block_move_real"
9588
  [(parallel [(set (mem:BLK (reg:SI R4_REG))
9589
                   (mem:BLK (reg:SI R5_REG)))
9590
              (use (match_operand:SI 0 "arith_reg_operand" "r"))
9591
              (clobber (reg:SI PR_REG))
9592
              (clobber (reg:SI R0_REG))])]
9593
  "TARGET_SH1 && ! TARGET_HARD_SH4"
9594
  "jsr  @%0%#"
9595
  [(set_attr "type" "sfunc")
9596
   (set_attr "needs_delay_slot" "yes")])
9597
 
9598
(define_insn "block_lump_real"
9599
  [(parallel [(set (mem:BLK (reg:SI R4_REG))
9600
                   (mem:BLK (reg:SI R5_REG)))
9601
              (use (match_operand:SI 0 "arith_reg_operand" "r"))
9602
              (use (reg:SI R6_REG))
9603
              (clobber (reg:SI PR_REG))
9604
              (clobber (reg:SI T_REG))
9605
              (clobber (reg:SI R4_REG))
9606
              (clobber (reg:SI R5_REG))
9607
              (clobber (reg:SI R6_REG))
9608
              (clobber (reg:SI R0_REG))])]
9609
  "TARGET_SH1 && ! TARGET_HARD_SH4"
9610
  "jsr  @%0%#"
9611
  [(set_attr "type" "sfunc")
9612
   (set_attr "needs_delay_slot" "yes")])
9613
 
9614
(define_insn "block_move_real_i4"
9615
  [(parallel [(set (mem:BLK (reg:SI R4_REG))
9616
                   (mem:BLK (reg:SI R5_REG)))
9617
              (use (match_operand:SI 0 "arith_reg_operand" "r"))
9618
              (clobber (reg:SI PR_REG))
9619
              (clobber (reg:SI R0_REG))
9620
              (clobber (reg:SI R1_REG))
9621
              (clobber (reg:SI R2_REG))])]
9622
  "TARGET_HARD_SH4"
9623
  "jsr  @%0%#"
9624
  [(set_attr "type" "sfunc")
9625
   (set_attr "needs_delay_slot" "yes")])
9626
 
9627
(define_insn "block_lump_real_i4"
9628
  [(parallel [(set (mem:BLK (reg:SI R4_REG))
9629
                   (mem:BLK (reg:SI R5_REG)))
9630
              (use (match_operand:SI 0 "arith_reg_operand" "r"))
9631
              (use (reg:SI R6_REG))
9632
              (clobber (reg:SI PR_REG))
9633
              (clobber (reg:SI T_REG))
9634
              (clobber (reg:SI R4_REG))
9635
              (clobber (reg:SI R5_REG))
9636
              (clobber (reg:SI R6_REG))
9637
              (clobber (reg:SI R0_REG))
9638
              (clobber (reg:SI R1_REG))
9639
              (clobber (reg:SI R2_REG))
9640
              (clobber (reg:SI R3_REG))])]
9641
  "TARGET_HARD_SH4"
9642
  "jsr  @%0%#"
9643
  [(set_attr "type" "sfunc")
9644
   (set_attr "needs_delay_slot" "yes")])
9645
 
9646
;; -------------------------------------------------------------------------
9647
;; Floating point instructions.
9648
;; -------------------------------------------------------------------------
9649
 
9650
;; ??? All patterns should have a type attribute.
9651
 
9652
(define_expand "movpsi"
9653
  [(set (match_operand:PSI 0 "register_operand" "")
9654
        (match_operand:PSI 1 "general_movsrc_operand" ""))]
9655
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9656
  "")
9657
 
9658
;; The c / m alternative is a fake to guide reload to load directly into
9659
;; fpscr, since reload doesn't know how to use post-increment.
9660
;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9661
;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9662
;; predicate after reload.
9663
;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9664
;; like a mac -> gpr move.
9665
(define_insn "fpu_switch"
9666
  [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9667
        (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9668
  "TARGET_SH2E
9669
   && (! reload_completed
9670
       || true_regnum (operands[0]) != FPSCR_REG
9671
       || !MEM_P (operands[1])
9672
       || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9673
  "@
9674
        ! precision stays the same
9675
        lds.l   %1,fpscr
9676
        mov.l   %1,%0
9677
        #
9678
        lds     %1,fpscr
9679
        mov     %1,%0
9680
        mov.l   %1,%0
9681
        sts     fpscr,%0
9682
        sts.l   fpscr,%0"
9683
  [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9684
   (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9685
 
9686
(define_peephole2
9687
  [(set (reg:PSI FPSCR_REG)
9688
        (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9689
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9690
  [(const_int 0)]
9691
{
9692
  rtx fpscr, mem, new_insn;
9693
 
9694
  fpscr = SET_DEST (PATTERN (curr_insn));
9695
  mem = SET_SRC (PATTERN (curr_insn));
9696
  mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9697
 
9698
  new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9699
  add_reg_note (new_insn, REG_INC, operands[0]);
9700
  DONE;
9701
})
9702
 
9703
(define_split
9704
  [(set (reg:PSI FPSCR_REG)
9705
        (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9706
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9707
   && (flag_peephole2 ? epilogue_completed : reload_completed)"
9708
  [(const_int 0)]
9709
{
9710
  rtx fpscr, mem, new_insn;
9711
 
9712
  fpscr = SET_DEST (PATTERN (curr_insn));
9713
  mem = SET_SRC (PATTERN (curr_insn));
9714
  mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9715
 
9716
  new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9717
  add_reg_note (new_insn, REG_INC, operands[0]);
9718
 
9719
  if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9720
    emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9721
  DONE;
9722
})
9723
 
9724
;; ??? This uses the fp unit, but has no type indicating that.
9725
;; If we did that, this would either give a bogus latency or introduce
9726
;; a bogus FIFO constraint.
9727
;; Since this insn is currently only used for prologues/epilogues,
9728
;; it is probably best to claim no function unit, which matches the
9729
;; current setting.
9730
(define_insn "toggle_sz"
9731
  [(set (reg:PSI FPSCR_REG)
9732
        (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9733
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9734
  "fschg"
9735
  [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9736
 
9737
;; There's no way we can use it today, since optimize mode switching
9738
;; doesn't enable us to know from which mode we're switching to the
9739
;; mode it requests, to tell whether we can use a relative mode switch
9740
;; (like toggle_pr) or an absolute switch (like loading fpscr from
9741
;; memory).
9742
(define_insn "toggle_pr"
9743
  [(set (reg:PSI FPSCR_REG)
9744
        (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9745
  "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9746
  "fpchg"
9747
  [(set_attr "type" "fpscr_toggle")])
9748
 
9749
(define_expand "addsf3"
9750
  [(set (match_operand:SF 0 "arith_reg_operand" "")
9751
        (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9752
                 (match_operand:SF 2 "arith_reg_operand" "")))]
9753
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9754
  "
9755
{
9756
  if (TARGET_SH2E)
9757
    {
9758
      expand_sf_binop (&gen_addsf3_i, operands);
9759
      DONE;
9760
    }
9761
}")
9762
 
9763
(define_insn "*addsf3_media"
9764
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9765
        (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9766
                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9767
  "TARGET_SHMEDIA_FPU"
9768
  "fadd.s       %1, %2, %0"
9769
  [(set_attr "type" "fparith_media")])
9770
 
9771
(define_insn_and_split "unary_sf_op"
9772
  [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9773
        (vec_select:V2SF
9774
         (vec_concat:V2SF
9775
          (vec_select:SF
9776
           (match_dup 0)
9777
           (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9778
          (match_operator:SF 2 "unary_float_operator"
9779
            [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9780
                            (parallel [(match_operand 4
9781
                                        "const_int_operand" "n")]))]))
9782
         (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9783
  "TARGET_SHMEDIA_FPU"
9784
  "#"
9785
  "TARGET_SHMEDIA_FPU && reload_completed"
9786
  [(set (match_dup 5) (match_dup 6))]
9787
  "
9788
{
9789
  int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9790
  rtx op1 = gen_rtx_REG (SFmode,
9791
                         (true_regnum (operands[1])
9792
                          + (INTVAL (operands[4]) ^ endian)));
9793
 
9794
  operands[7] = gen_rtx_REG (SFmode,
9795
                             (true_regnum (operands[0])
9796
                              + (INTVAL (operands[3]) ^ endian)));
9797
  operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9798
}"
9799
  [(set_attr "type" "fparith_media")])
9800
 
9801
(define_insn_and_split "binary_sf_op0"
9802
  [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9803
        (vec_concat:V2SF
9804
          (match_operator:SF 3 "binary_float_operator"
9805
            [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9806
                            (parallel [(const_int 0)]))
9807
             (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9808
                            (parallel [(const_int 0)]))])
9809
          (vec_select:SF
9810
           (match_dup 0)
9811
           (parallel [(const_int 1)]))))]
9812
  "TARGET_SHMEDIA_FPU"
9813
  "#"
9814
  "&& reload_completed"
9815
  [(set (match_dup 4) (match_dup 5))]
9816
  "
9817
{
9818
  int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9819
  rtx op1 = gen_rtx_REG (SFmode,
9820
                         true_regnum (operands[1]) + endian);
9821
  rtx op2 = gen_rtx_REG (SFmode,
9822
                         true_regnum (operands[2]) + endian);
9823
 
9824
  operands[4] = gen_rtx_REG (SFmode,
9825
                             true_regnum (operands[0]) + endian);
9826
  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9827
}"
9828
  [(set_attr "type" "fparith_media")])
9829
 
9830
(define_insn_and_split "binary_sf_op1"
9831
  [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9832
        (vec_concat:V2SF
9833
          (vec_select:SF
9834
           (match_dup 0)
9835
           (parallel [(const_int 0)]))
9836
          (match_operator:SF 3 "binary_float_operator"
9837
            [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9838
                            (parallel [(const_int 1)]))
9839
             (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9840
                            (parallel [(const_int 1)]))])))]
9841
  "TARGET_SHMEDIA_FPU"
9842
  "#"
9843
  "&& reload_completed"
9844
  [(set (match_dup 4) (match_dup 5))]
9845
  "
9846
{
9847
  int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9848
  rtx op1 = gen_rtx_REG (SFmode,
9849
                         true_regnum (operands[1]) + (1 ^ endian));
9850
  rtx op2 = gen_rtx_REG (SFmode,
9851
                         true_regnum (operands[2]) + (1 ^ endian));
9852
 
9853
  operands[4] = gen_rtx_REG (SFmode,
9854
                             true_regnum (operands[0]) + (1 ^ endian));
9855
  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9856
}"
9857
  [(set_attr "type" "fparith_media")])
9858
 
9859
(define_insn "addsf3_i"
9860
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9861
        (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9862
                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9863
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9864
  "TARGET_SH2E"
9865
  "fadd %2,%0"
9866
  [(set_attr "type" "fp")
9867
   (set_attr "fp_mode" "single")])
9868
 
9869
(define_expand "subsf3"
9870
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9871
        (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9872
                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9873
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9874
  "
9875
{
9876
  if (TARGET_SH2E)
9877
    {
9878
      expand_sf_binop (&gen_subsf3_i, operands);
9879
      DONE;
9880
    }
9881
}")
9882
 
9883
(define_insn "*subsf3_media"
9884
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9885
        (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9886
                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9887
  "TARGET_SHMEDIA_FPU"
9888
  "fsub.s       %1, %2, %0"
9889
  [(set_attr "type" "fparith_media")])
9890
 
9891
(define_insn "subsf3_i"
9892
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9893
        (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9894
                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9895
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9896
  "TARGET_SH2E"
9897
  "fsub %2,%0"
9898
  [(set_attr "type" "fp")
9899
   (set_attr "fp_mode" "single")])
9900
 
9901
(define_expand "mulsf3"
9902
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9903
        (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9904
                 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9905
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9906
  "")
9907
 
9908
(define_insn "*mulsf3_media"
9909
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9910
        (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9911
                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9912
  "TARGET_SHMEDIA_FPU"
9913
  "fmul.s       %1, %2, %0"
9914
  [(set_attr "type" "fparith_media")])
9915
 
9916
;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
9917
;; register in feeding fp instructions.  Thus, in order to generate fmac,
9918
;; we start out with a mulsf pattern that does not depend on fpscr.
9919
;; This is split after combine to introduce the dependency, in order to
9920
;; get mode switching and scheduling right.
9921
(define_insn_and_split "mulsf3_ie"
9922
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9923
        (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9924
                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9925
  "TARGET_SH2E"
9926
  "fmul %2,%0"
9927
  "TARGET_SH4 || TARGET_SH2A_SINGLE"
9928
  [(const_int 0)]
9929
  "
9930
{
9931
  emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
9932
             get_fpscr_rtx ()));
9933
  DONE;
9934
}"
9935
  [(set_attr "type" "fp")])
9936
 
9937
(define_insn "mulsf3_i4"
9938
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9939
        (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9940
                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9941
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9942
  "TARGET_SH2E"
9943
  "fmul %2,%0"
9944
  [(set_attr "type" "fp")
9945
   (set_attr "fp_mode" "single")])
9946
 
9947
(define_insn "mac_media"
9948
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9949
        (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9950
                          (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9951
                 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
9952
  "TARGET_SHMEDIA_FPU && TARGET_FMAC"
9953
  "fmac.s %1, %2, %0"
9954
  [(set_attr "type" "fparith_media")])
9955
 
9956
(define_insn "*macsf3"
9957
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9958
        (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
9959
                          (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9960
                 (match_operand:SF 3 "arith_reg_operand" "0")))
9961
   (use (match_operand:PSI 4 "fpscr_operand" "c"))]
9962
  "TARGET_SH2E && TARGET_FMAC"
9963
  "fmac fr0,%2,%0"
9964
  [(set_attr "type" "fp")
9965
   (set_attr "fp_mode" "single")])
9966
 
9967
(define_expand "divsf3"
9968
  [(set (match_operand:SF 0 "arith_reg_operand" "")
9969
        (div:SF (match_operand:SF 1 "arith_reg_operand" "")
9970
                (match_operand:SF 2 "arith_reg_operand" "")))]
9971
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9972
  "
9973
{
9974
  if (TARGET_SH2E)
9975
    {
9976
      expand_sf_binop (&gen_divsf3_i, operands);
9977
      DONE;
9978
    }
9979
}")
9980
 
9981
(define_insn "*divsf3_media"
9982
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9983
        (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9984
                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9985
  "TARGET_SHMEDIA_FPU"
9986
  "fdiv.s       %1, %2, %0"
9987
  [(set_attr "type" "fdiv_media")])
9988
 
9989
(define_insn "divsf3_i"
9990
  [(set (match_operand:SF 0 "arith_reg_dest" "=f")
9991
        (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
9992
                 (match_operand:SF 2 "arith_reg_operand" "f")))
9993
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9994
  "TARGET_SH2E"
9995
  "fdiv %2,%0"
9996
  [(set_attr "type" "fdiv")
9997
   (set_attr "fp_mode" "single")])
9998
 
9999
(define_insn "floatdisf2"
10000
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10001
        (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10002
  "TARGET_SHMEDIA_FPU"
10003
  "float.qs %1, %0"
10004
  [(set_attr "type" "fpconv_media")])
10005
 
10006
(define_expand "floatsisf2"
10007
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10008
        (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10009
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10010
  "
10011
{
10012
  if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10013
    {
10014
      emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10015
      DONE;
10016
    }
10017
}")
10018
 
10019
(define_insn "*floatsisf2_media"
10020
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10021
        (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10022
  "TARGET_SHMEDIA_FPU"
10023
  "float.ls     %1, %0"
10024
  [(set_attr "type" "fpconv_media")])
10025
 
10026
(define_insn "floatsisf2_i4"
10027
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10028
        (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10029
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10030
  "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10031
  "float        %1,%0"
10032
  [(set_attr "type" "fp")
10033
   (set_attr "fp_mode" "single")])
10034
 
10035
(define_insn "*floatsisf2_ie"
10036
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10037
        (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10038
  "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10039
  "float        %1,%0"
10040
  [(set_attr "type" "fp")])
10041
 
10042
(define_insn "fix_truncsfdi2"
10043
  [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10044
        (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10045
  "TARGET_SHMEDIA_FPU"
10046
  "ftrc.sq %1, %0"
10047
  [(set_attr "type" "fpconv_media")])
10048
 
10049
(define_expand "fix_truncsfsi2"
10050
  [(set (match_operand:SI 0 "fpul_operand" "=y")
10051
        (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10052
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10053
  "
10054
{
10055
  if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10056
    {
10057
      emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10058
      DONE;
10059
    }
10060
}")
10061
 
10062
(define_insn "*fix_truncsfsi2_media"
10063
  [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10064
        (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10065
  "TARGET_SHMEDIA_FPU"
10066
  "ftrc.sl      %1, %0"
10067
  [(set_attr "type" "fpconv_media")])
10068
 
10069
(define_insn "fix_truncsfsi2_i4"
10070
  [(set (match_operand:SI 0 "fpul_operand" "=y")
10071
        (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10072
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10073
  "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10074
  "ftrc %1,%0"
10075
  [(set_attr "type" "ftrc_s")
10076
   (set_attr "fp_mode" "single")])
10077
 
10078
;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10079
;; fix_truncsfsi2_i4.
10080
;; (define_insn "fix_truncsfsi2_i4_2"
10081
;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10082
;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10083
;;   (use (reg:PSI FPSCR_REG))
10084
;;   (clobber (reg:SI FPUL_REG))]
10085
;;  "TARGET_SH4"
10086
;;  "#"
10087
;;  [(set_attr "length" "4")
10088
;;   (set_attr "fp_mode" "single")])
10089
 
10090
;;(define_split
10091
;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10092
;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10093
;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10094
;;   (clobber (reg:SI FPUL_REG))]
10095
;;  "TARGET_SH4"
10096
;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10097
;;            (use (match_dup 2))])
10098
;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10099
 
10100
(define_insn "*fixsfsi"
10101
  [(set (match_operand:SI 0 "fpul_operand" "=y")
10102
        (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10103
  "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10104
  "ftrc %1,%0"
10105
  [(set_attr "type" "fp")])
10106
 
10107
(define_insn "cmpgtsf_t"
10108
  [(set (reg:SI T_REG)
10109
        (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10110
               (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10111
  "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10112
  "fcmp/gt      %1,%0"
10113
  [(set_attr "type" "fp_cmp")
10114
   (set_attr "fp_mode" "single")])
10115
 
10116
(define_insn "cmpeqsf_t"
10117
  [(set (reg:SI T_REG)
10118
        (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10119
               (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10120
  "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10121
  "fcmp/eq      %1,%0"
10122
  [(set_attr "type" "fp_cmp")
10123
   (set_attr "fp_mode" "single")])
10124
 
10125
(define_insn "ieee_ccmpeqsf_t"
10126
  [(set (reg:SI T_REG)
10127
        (ior:SI (reg:SI T_REG)
10128
                (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10129
                       (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10130
  "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10131
  "* return output_ieee_ccmpeq (insn, operands);"
10132
  [(set_attr "length" "4")])
10133
 
10134
 
10135
(define_insn "cmpgtsf_t_i4"
10136
  [(set (reg:SI T_REG)
10137
        (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10138
               (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10139
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10140
  "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10141
  "fcmp/gt      %1,%0"
10142
  [(set_attr "type" "fp_cmp")
10143
   (set_attr "fp_mode" "single")])
10144
 
10145
(define_insn "cmpeqsf_t_i4"
10146
  [(set (reg:SI T_REG)
10147
        (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10148
               (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10149
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10150
  "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10151
  "fcmp/eq      %1,%0"
10152
  [(set_attr "type" "fp_cmp")
10153
   (set_attr "fp_mode" "single")])
10154
 
10155
(define_insn "*ieee_ccmpeqsf_t_4"
10156
  [(set (reg:SI T_REG)
10157
        (ior:SI (reg:SI T_REG)
10158
                (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10159
                       (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10160
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10161
  "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10162
  "* return output_ieee_ccmpeq (insn, operands);"
10163
  [(set_attr "length" "4")
10164
   (set_attr "fp_mode" "single")])
10165
 
10166
(define_insn "cmpeqsf_media"
10167
  [(set (match_operand:SI 0 "register_operand" "=r")
10168
        (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10169
               (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10170
  "TARGET_SHMEDIA_FPU"
10171
  "fcmpeq.s     %1, %2, %0"
10172
  [(set_attr "type" "fcmp_media")])
10173
 
10174
(define_insn "cmpgtsf_media"
10175
  [(set (match_operand:SI 0 "register_operand" "=r")
10176
        (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10177
               (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10178
  "TARGET_SHMEDIA_FPU"
10179
  "fcmpgt.s     %1, %2, %0"
10180
  [(set_attr "type" "fcmp_media")])
10181
 
10182
(define_insn "cmpgesf_media"
10183
  [(set (match_operand:SI 0 "register_operand" "=r")
10184
        (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10185
               (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10186
  "TARGET_SHMEDIA_FPU"
10187
  "fcmpge.s     %1, %2, %0"
10188
  [(set_attr "type" "fcmp_media")])
10189
 
10190
(define_insn "cmpunsf_media"
10191
  [(set (match_operand:SI 0 "register_operand" "=r")
10192
        (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10193
                      (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10194
  "TARGET_SHMEDIA_FPU"
10195
  "fcmpun.s     %1, %2, %0"
10196
  [(set_attr "type" "fcmp_media")])
10197
 
10198
(define_expand "cbranchsf4"
10199
  [(set (pc)
10200
        (if_then_else (match_operator 0 "sh_float_comparison_operator"
10201
                       [(match_operand:SF 1 "arith_operand" "")
10202
                        (match_operand:SF 2 "arith_operand" "")])
10203
                      (match_operand 3 "" "")
10204
                      (pc)))]
10205
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10206
  "
10207
{
10208
  if (TARGET_SHMEDIA)
10209
    emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10210
                                          operands[3]));
10211
  else
10212
    sh_emit_compare_and_branch (operands, SFmode);
10213
  DONE;
10214
}")
10215
 
10216
(define_expand "negsf2"
10217
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10218
        (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10219
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10220
  "
10221
{
10222
  if (TARGET_SH2E)
10223
    {
10224
      expand_sf_unop (&gen_negsf2_i, operands);
10225
      DONE;
10226
    }
10227
}")
10228
 
10229
(define_insn "*negsf2_media"
10230
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10231
        (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10232
  "TARGET_SHMEDIA_FPU"
10233
  "fneg.s       %1, %0"
10234
  [(set_attr "type" "fmove_media")])
10235
 
10236
(define_insn "negsf2_i"
10237
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10238
        (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10239
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10240
  "TARGET_SH2E"
10241
  "fneg %0"
10242
  [(set_attr "type" "fmove")
10243
   (set_attr "fp_mode" "single")])
10244
 
10245
(define_expand "sqrtsf2"
10246
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10247
        (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10248
  "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10249
  "
10250
{
10251
  if (TARGET_SH3E)
10252
    {
10253
      expand_sf_unop (&gen_sqrtsf2_i, operands);
10254
      DONE;
10255
    }
10256
}")
10257
 
10258
(define_insn "*sqrtsf2_media"
10259
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10260
        (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10261
  "TARGET_SHMEDIA_FPU"
10262
  "fsqrt.s      %1, %0"
10263
  [(set_attr "type" "fdiv_media")])
10264
 
10265
(define_insn "sqrtsf2_i"
10266
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10267
        (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10268
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10269
  "TARGET_SH3E"
10270
  "fsqrt        %0"
10271
  [(set_attr "type" "fdiv")
10272
   (set_attr "fp_mode" "single")])
10273
 
10274
(define_insn "rsqrtsf2"
10275
  [(set (match_operand:SF 0 "register_operand" "=f")
10276
        (div:SF (match_operand:SF 1 "immediate_operand" "i")
10277
                (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10278
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10279
  "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10280
   && operands[1] == CONST1_RTX (SFmode)"
10281
  "fsrra        %0"
10282
  [(set_attr "type" "fsrra")
10283
   (set_attr "fp_mode" "single")])
10284
 
10285
(define_insn "fsca"
10286
  [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10287
        (vec_concat:V2SF
10288
         (unspec:SF [(mult:SF
10289
                      (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10290
                      (match_operand:SF 2 "immediate_operand" "i"))
10291
                    ] UNSPEC_FSINA)
10292
         (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10293
                    ] UNSPEC_FCOSA)))
10294
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10295
  "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10296
   && operands[2] == sh_fsca_int2sf ()"
10297
  "fsca fpul,%d0"
10298
  [(set_attr "type" "fsca")
10299
   (set_attr "fp_mode" "single")])
10300
 
10301
(define_expand "sinsf2"
10302
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
10303
        (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10304
                   UNSPEC_FSINA))]
10305
  "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10306
  "
10307
{
10308
  rtx scaled = gen_reg_rtx (SFmode);
10309
  rtx truncated = gen_reg_rtx (SImode);
10310
  rtx fsca = gen_reg_rtx (V2SFmode);
10311
  rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10312
 
10313
  emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10314
  emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10315
  emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10316
                          get_fpscr_rtx ()));
10317
  emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10318
  DONE;
10319
}")
10320
 
10321
(define_expand "cossf2"
10322
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
10323
        (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10324
                   UNSPEC_FCOSA))]
10325
  "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10326
  "
10327
{
10328
  rtx scaled = gen_reg_rtx (SFmode);
10329
  rtx truncated = gen_reg_rtx (SImode);
10330
  rtx fsca = gen_reg_rtx (V2SFmode);
10331
  rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10332
 
10333
  emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10334
  emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10335
  emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10336
                          get_fpscr_rtx ()));
10337
  emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10338
  DONE;
10339
}")
10340
 
10341
(define_expand "sindf2"
10342
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10343
        (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10344
                   UNSPEC_FSINA))]
10345
  "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10346
  "
10347
{
10348
  rtx scaled = gen_reg_rtx (DFmode);
10349
  rtx truncated = gen_reg_rtx (SImode);
10350
  rtx fsca = gen_reg_rtx (V2SFmode);
10351
  rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10352
  rtx sfresult = gen_reg_rtx (SFmode);
10353
 
10354
  emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10355
  emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10356
  emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10357
                          get_fpscr_rtx ()));
10358
  emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10359
  emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10360
  DONE;
10361
}")
10362
 
10363
(define_expand "cosdf2"
10364
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10365
        (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10366
                   UNSPEC_FCOSA))]
10367
  "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10368
  "
10369
{
10370
  rtx scaled = gen_reg_rtx (DFmode);
10371
  rtx truncated = gen_reg_rtx (SImode);
10372
  rtx fsca = gen_reg_rtx (V2SFmode);
10373
  rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10374
  rtx sfresult = gen_reg_rtx (SFmode);
10375
 
10376
  emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10377
  emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10378
  emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10379
                          get_fpscr_rtx ()));
10380
  emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10381
  emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10382
  DONE;
10383
}")
10384
 
10385
(define_expand "abssf2"
10386
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10387
        (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10388
  "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10389
  "
10390
{
10391
  if (TARGET_SH2E)
10392
    {
10393
      expand_sf_unop (&gen_abssf2_i, operands);
10394
      DONE;
10395
    }
10396
}")
10397
 
10398
(define_insn "*abssf2_media"
10399
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10400
        (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10401
  "TARGET_SHMEDIA_FPU"
10402
  "fabs.s       %1, %0"
10403
  [(set_attr "type" "fmove_media")])
10404
 
10405
(define_insn "abssf2_i"
10406
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10407
        (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10408
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10409
  "TARGET_SH2E"
10410
  "fabs %0"
10411
  [(set_attr "type" "fmove")
10412
   (set_attr "fp_mode" "single")])
10413
 
10414
(define_expand "adddf3"
10415
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10416
        (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10417
                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10418
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10419
  "
10420
{
10421
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10422
    {
10423
      expand_df_binop (&gen_adddf3_i, operands);
10424
      DONE;
10425
    }
10426
}")
10427
 
10428
(define_insn "*adddf3_media"
10429
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10430
        (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10431
                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10432
  "TARGET_SHMEDIA_FPU"
10433
  "fadd.d       %1, %2, %0"
10434
  [(set_attr "type" "dfparith_media")])
10435
 
10436
(define_insn "adddf3_i"
10437
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10438
        (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10439
                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10440
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10441
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10442
  "fadd %2,%0"
10443
  [(set_attr "type" "dfp_arith")
10444
   (set_attr "fp_mode" "double")])
10445
 
10446
(define_expand "subdf3"
10447
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10448
        (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10449
                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10450
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10451
  "
10452
{
10453
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10454
    {
10455
      expand_df_binop (&gen_subdf3_i, operands);
10456
      DONE;
10457
    }
10458
}")
10459
 
10460
(define_insn "*subdf3_media"
10461
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10462
        (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10463
                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10464
  "TARGET_SHMEDIA_FPU"
10465
  "fsub.d       %1, %2, %0"
10466
  [(set_attr "type" "dfparith_media")])
10467
 
10468
(define_insn "subdf3_i"
10469
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10470
        (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10471
                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10472
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10473
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10474
  "fsub %2,%0"
10475
  [(set_attr "type" "dfp_arith")
10476
   (set_attr "fp_mode" "double")])
10477
 
10478
(define_expand "muldf3"
10479
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10480
        (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10481
                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10482
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10483
  "
10484
{
10485
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10486
    {
10487
      expand_df_binop (&gen_muldf3_i, operands);
10488
      DONE;
10489
    }
10490
}")
10491
 
10492
(define_insn "*muldf3_media"
10493
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10494
        (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10495
                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10496
  "TARGET_SHMEDIA_FPU"
10497
  "fmul.d       %1, %2, %0"
10498
  [(set_attr "type" "dfmul_media")])
10499
 
10500
(define_insn "muldf3_i"
10501
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10502
        (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10503
                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10504
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10505
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10506
  "fmul %2,%0"
10507
  [(set_attr "type" "dfp_mul")
10508
   (set_attr "fp_mode" "double")])
10509
 
10510
(define_expand "divdf3"
10511
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10512
        (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10513
                (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10514
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10515
  "
10516
{
10517
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10518
    {
10519
      expand_df_binop (&gen_divdf3_i, operands);
10520
      DONE;
10521
    }
10522
}")
10523
 
10524
(define_insn "*divdf3_media"
10525
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10526
        (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10527
                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10528
  "TARGET_SHMEDIA_FPU"
10529
  "fdiv.d       %1, %2, %0"
10530
  [(set_attr "type" "dfdiv_media")])
10531
 
10532
(define_insn "divdf3_i"
10533
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10534
        (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10535
                (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10536
   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10537
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10538
  "fdiv %2,%0"
10539
  [(set_attr "type" "dfdiv")
10540
   (set_attr "fp_mode" "double")])
10541
 
10542
(define_insn "floatdidf2"
10543
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10544
        (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10545
  "TARGET_SHMEDIA_FPU"
10546
  "float.qd     %1, %0"
10547
  [(set_attr "type" "dfpconv_media")])
10548
 
10549
(define_expand "floatsidf2"
10550
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10551
        (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10552
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10553
  "
10554
{
10555
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10556
    {
10557
      emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10558
                                      get_fpscr_rtx ()));
10559
      DONE;
10560
    }
10561
}")
10562
 
10563
(define_insn "*floatsidf2_media"
10564
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10565
        (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10566
  "TARGET_SHMEDIA_FPU"
10567
  "float.ld     %1, %0"
10568
  [(set_attr "type" "dfpconv_media")])
10569
 
10570
(define_insn "floatsidf2_i"
10571
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10572
        (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10573
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10574
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10575
  "float        %1,%0"
10576
  [(set_attr "type" "dfp_conv")
10577
   (set_attr "fp_mode" "double")])
10578
 
10579
(define_insn "fix_truncdfdi2"
10580
  [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10581
        (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10582
  "TARGET_SHMEDIA_FPU"
10583
  "ftrc.dq      %1, %0"
10584
  [(set_attr "type" "dfpconv_media")])
10585
 
10586
(define_expand "fix_truncdfsi2"
10587
  [(set (match_operand:SI 0 "fpul_operand" "")
10588
        (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10589
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10590
  "
10591
{
10592
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10593
    {
10594
      emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10595
                                          get_fpscr_rtx ()));
10596
      DONE;
10597
    }
10598
}")
10599
 
10600
(define_insn "*fix_truncdfsi2_media"
10601
  [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10602
        (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10603
  "TARGET_SHMEDIA_FPU"
10604
  "ftrc.dl      %1, %0"
10605
  [(set_attr "type" "dfpconv_media")])
10606
 
10607
(define_insn "fix_truncdfsi2_i"
10608
  [(set (match_operand:SI 0 "fpul_operand" "=y")
10609
        (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10610
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10611
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10612
  "ftrc %1,%0"
10613
  [(set_attr "type" "dfp_conv")
10614
   (set_attr "dfp_comp" "no")
10615
   (set_attr "fp_mode" "double")])
10616
 
10617
;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10618
;; fix_truncdfsi2_i.
10619
;; (define_insn "fix_truncdfsi2_i4"
10620
;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10621
;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10622
;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10623
;;    (clobber (reg:SI FPUL_REG))]
10624
;;   "TARGET_SH4"
10625
;;   "#"
10626
;;   [(set_attr "length" "4")
10627
;;    (set_attr "fp_mode" "double")])
10628
;;
10629
;; (define_split
10630
;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10631
;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10632
;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10633
;;    (clobber (reg:SI FPUL_REG))]
10634
;;   "TARGET_SH4"
10635
;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10636
;;            (use (match_dup 2))])
10637
;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10638
 
10639
(define_insn "cmpgtdf_t"
10640
  [(set (reg:SI T_REG)
10641
        (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10642
               (match_operand:DF 1 "arith_reg_operand" "f")))
10643
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10644
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10645
  "fcmp/gt      %1,%0"
10646
  [(set_attr "type" "dfp_cmp")
10647
   (set_attr "fp_mode" "double")])
10648
 
10649
(define_insn "cmpeqdf_t"
10650
  [(set (reg:SI T_REG)
10651
        (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10652
               (match_operand:DF 1 "arith_reg_operand" "f")))
10653
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10654
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10655
  "fcmp/eq      %1,%0"
10656
  [(set_attr "type" "dfp_cmp")
10657
   (set_attr "fp_mode" "double")])
10658
 
10659
(define_insn "*ieee_ccmpeqdf_t"
10660
  [(set (reg:SI T_REG)
10661
        (ior:SI (reg:SI T_REG)
10662
                (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10663
                       (match_operand:DF 1 "arith_reg_operand" "f"))))
10664
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10665
  "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10666
  "* return output_ieee_ccmpeq (insn, operands);"
10667
  [(set_attr "length" "4")
10668
   (set_attr "fp_mode" "double")])
10669
 
10670
(define_insn "cmpeqdf_media"
10671
  [(set (match_operand:SI 0 "register_operand" "=r")
10672
        (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10673
               (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10674
  "TARGET_SHMEDIA_FPU"
10675
  "fcmpeq.d     %1,%2,%0"
10676
  [(set_attr "type" "fcmp_media")])
10677
 
10678
(define_insn "cmpgtdf_media"
10679
  [(set (match_operand:SI 0 "register_operand" "=r")
10680
        (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10681
               (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10682
  "TARGET_SHMEDIA_FPU"
10683
  "fcmpgt.d     %1,%2,%0"
10684
  [(set_attr "type" "fcmp_media")])
10685
 
10686
(define_insn "cmpgedf_media"
10687
  [(set (match_operand:SI 0 "register_operand" "=r")
10688
        (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10689
               (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10690
  "TARGET_SHMEDIA_FPU"
10691
  "fcmpge.d     %1,%2,%0"
10692
  [(set_attr "type" "fcmp_media")])
10693
 
10694
(define_insn "cmpundf_media"
10695
  [(set (match_operand:SI 0 "register_operand" "=r")
10696
        (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10697
                      (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10698
  "TARGET_SHMEDIA_FPU"
10699
  "fcmpun.d     %1,%2,%0"
10700
  [(set_attr "type" "fcmp_media")])
10701
 
10702
(define_expand "cbranchdf4"
10703
  [(set (pc)
10704
        (if_then_else (match_operator 0 "sh_float_comparison_operator"
10705
                       [(match_operand:DF 1 "arith_operand" "")
10706
                        (match_operand:DF 2 "arith_operand" "")])
10707
                      (match_operand 3 "" "")
10708
                      (pc)))]
10709
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10710
  "
10711
{
10712
  if (TARGET_SHMEDIA)
10713
    emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10714
                                          operands[3]));
10715
  else
10716
    sh_emit_compare_and_branch (operands, DFmode);
10717
  DONE;
10718
}")
10719
 
10720
 
10721
(define_expand "negdf2"
10722
  [(set (match_operand:DF 0 "arith_reg_operand" "")
10723
        (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10724
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10725
  "
10726
{
10727
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10728
    {
10729
      expand_df_unop (&gen_negdf2_i, operands);
10730
      DONE;
10731
    }
10732
}")
10733
 
10734
(define_insn "*negdf2_media"
10735
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10736
        (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10737
  "TARGET_SHMEDIA_FPU"
10738
  "fneg.d       %1, %0"
10739
  [(set_attr "type" "fmove_media")])
10740
 
10741
(define_insn "negdf2_i"
10742
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10743
        (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10744
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10745
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10746
  "fneg %0"
10747
  [(set_attr "type" "fmove")
10748
   (set_attr "fp_mode" "double")])
10749
 
10750
(define_expand "sqrtdf2"
10751
  [(set (match_operand:DF 0 "arith_reg_operand" "")
10752
        (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10753
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10754
  "
10755
{
10756
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10757
    {
10758
      expand_df_unop (&gen_sqrtdf2_i, operands);
10759
      DONE;
10760
    }
10761
}")
10762
 
10763
(define_insn "*sqrtdf2_media"
10764
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10765
        (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10766
  "TARGET_SHMEDIA_FPU"
10767
  "fsqrt.d      %1, %0"
10768
  [(set_attr "type" "dfdiv_media")])
10769
 
10770
(define_insn "sqrtdf2_i"
10771
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10772
        (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10773
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10774
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10775
  "fsqrt        %0"
10776
  [(set_attr "type" "dfdiv")
10777
   (set_attr "fp_mode" "double")])
10778
 
10779
(define_expand "absdf2"
10780
  [(set (match_operand:DF 0 "arith_reg_operand" "")
10781
        (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10782
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10783
  "
10784
{
10785
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10786
    {
10787
      expand_df_unop (&gen_absdf2_i, operands);
10788
      DONE;
10789
    }
10790
}")
10791
 
10792
(define_insn "*absdf2_media"
10793
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10794
        (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10795
  "TARGET_SHMEDIA_FPU"
10796
  "fabs.d       %1, %0"
10797
  [(set_attr "type" "fmove_media")])
10798
 
10799
(define_insn "absdf2_i"
10800
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10801
        (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10802
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10803
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10804
  "fabs %0"
10805
  [(set_attr "type" "fmove")
10806
   (set_attr "fp_mode" "double")])
10807
 
10808
(define_expand "extendsfdf2"
10809
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10810
        (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10811
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10812
  "
10813
{
10814
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10815
    {
10816
      emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10817
                                        get_fpscr_rtx ()));
10818
      DONE;
10819
    }
10820
}")
10821
 
10822
(define_insn "*extendsfdf2_media"
10823
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10824
        (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10825
  "TARGET_SHMEDIA_FPU"
10826
  "fcnv.sd      %1, %0"
10827
  [(set_attr "type" "dfpconv_media")])
10828
 
10829
(define_insn "extendsfdf2_i4"
10830
  [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10831
        (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10832
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10833
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10834
  "fcnvsd  %1,%0"
10835
  [(set_attr "type" "fp")
10836
   (set_attr "fp_mode" "double")])
10837
 
10838
(define_expand "truncdfsf2"
10839
  [(set (match_operand:SF 0 "fpul_operand" "")
10840
        (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10841
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10842
  "
10843
{
10844
  if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10845
    {
10846
      emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10847
                                       get_fpscr_rtx ()));
10848
      DONE;
10849
    }
10850
}")
10851
 
10852
(define_insn "*truncdfsf2_media"
10853
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10854
        (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10855
  "TARGET_SHMEDIA_FPU"
10856
  "fcnv.ds      %1, %0"
10857
  [(set_attr "type" "dfpconv_media")])
10858
 
10859
(define_insn "truncdfsf2_i4"
10860
  [(set (match_operand:SF 0 "fpul_operand" "=y")
10861
        (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10862
   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10863
  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10864
  "fcnvds  %1,%0"
10865
  [(set_attr "type" "fp")
10866
   (set_attr "fp_mode" "double")])
10867
 
10868
;; Bit field extract patterns.  These give better code for packed bitfields,
10869
;; because they allow auto-increment addresses to be generated.
10870
 
10871
(define_expand "insv"
10872
  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10873
                         (match_operand:SI 1 "immediate_operand" "")
10874
                         (match_operand:SI 2 "immediate_operand" ""))
10875
        (match_operand:SI 3 "general_operand" ""))]
10876
  "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10877
  "
10878
{
10879
  rtx addr_target, orig_address, shift_reg, qi_val;
10880
  HOST_WIDE_INT bitsize, size, v = 0;
10881
  rtx x = operands[3];
10882
 
10883
  if (TARGET_SH2A && TARGET_BITOPS
10884
      && (satisfies_constraint_Sbw (operands[0])
10885
          || satisfies_constraint_Sbv (operands[0]))
10886
      && satisfies_constraint_M (operands[1])
10887
      && satisfies_constraint_K03 (operands[2]))
10888
    {
10889
      if (satisfies_constraint_N (operands[3]))
10890
        {
10891
          emit_insn (gen_bclr_m2a (operands[0], operands[2]));
10892
          DONE;
10893
        }
10894
      else if (satisfies_constraint_M (operands[3]))
10895
        {
10896
          emit_insn (gen_bset_m2a (operands[0], operands[2]));
10897
          DONE;
10898
        }
10899
      else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
10900
                && satisfies_constraint_M (operands[1]))
10901
        {
10902
          emit_insn (gen_bst_m2a (operands[0], operands[2]));
10903
          DONE;
10904
        }
10905
      else if (REG_P (operands[3])
10906
               && satisfies_constraint_M (operands[1]))
10907
        {
10908
          emit_insn (gen_bld_reg (operands[3], const0_rtx));
10909
          emit_insn (gen_bst_m2a (operands[0], operands[2]));
10910
          DONE;
10911
        }
10912
    }
10913
  /* ??? expmed doesn't care for non-register predicates.  */
10914
  if (! memory_operand (operands[0], VOIDmode)
10915
      || ! immediate_operand (operands[1], VOIDmode)
10916
      || ! immediate_operand (operands[2], VOIDmode)
10917
      || ! general_operand (x, VOIDmode))
10918
    FAIL;
10919
  /* If this isn't a 16 / 24 / 32 bit field, or if
10920
     it doesn't start on a byte boundary, then fail.  */
10921
  bitsize = INTVAL (operands[1]);
10922
  if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10923
      || (INTVAL (operands[2]) % 8) != 0)
10924
    FAIL;
10925
 
10926
  size = bitsize / 8;
10927
  orig_address = XEXP (operands[0], 0);
10928
  shift_reg = gen_reg_rtx (SImode);
10929
  if (CONST_INT_P (x))
10930
    {
10931
      v = INTVAL (x);
10932
      qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
10933
    }
10934
  else
10935
    {
10936
      emit_insn (gen_movsi (shift_reg, operands[3]));
10937
      qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10938
    }
10939
  addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
10940
 
10941
  operands[0] = replace_equiv_address (operands[0], addr_target);
10942
  emit_insn (gen_movqi (operands[0], qi_val));
10943
 
10944
  while (size -= 1)
10945
    {
10946
      if (CONST_INT_P (x))
10947
        qi_val
10948
          = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
10949
      else
10950
        {
10951
          emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
10952
          qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10953
        }
10954
      emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
10955
      emit_insn (gen_movqi (operands[0], qi_val));
10956
    }
10957
 
10958
  DONE;
10959
}")
10960
 
10961
(define_insn "movua"
10962
  [(set (match_operand:SI 0 "register_operand" "=z")
10963
        (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
10964
                   UNSPEC_MOVUA))]
10965
  "TARGET_SH4A_ARCH"
10966
  "movua.l      %1,%0"
10967
  [(set_attr "type" "movua")])
10968
 
10969
;; We shouldn't need this, but cse replaces increments with references
10970
;; to other regs before flow has a chance to create post_inc
10971
;; addressing modes, and only postreload's cse_move2add brings the
10972
;; increments back to a usable form.
10973
(define_peephole2
10974
  [(set (match_operand:SI 0 "register_operand" "")
10975
        (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
10976
                         (const_int 32) (const_int 0)))
10977
   (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
10978
  "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
10979
  [(set (match_operand:SI 0 "register_operand" "")
10980
        (sign_extract:SI (mem:SI (post_inc:SI
10981
                                  (match_operand:SI 1 "register_operand" "")))
10982
                         (const_int 32) (const_int 0)))]
10983
  "")
10984
 
10985
(define_expand "extv"
10986
  [(set (match_operand:SI 0 "register_operand" "")
10987
        (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
10988
                         (match_operand 2 "const_int_operand" "")
10989
                         (match_operand 3 "const_int_operand" "")))]
10990
  "TARGET_SH4A_ARCH || TARGET_SH2A"
10991
{
10992
  if (TARGET_SH2A && TARGET_BITOPS
10993
      && (satisfies_constraint_Sbw (operands[1])
10994
          || satisfies_constraint_Sbv (operands[1]))
10995
      && satisfies_constraint_M (operands[2])
10996
      && satisfies_constraint_K03 (operands[3]))
10997
   {
10998
      emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
10999
      if (REGNO (operands[0]) != T_REG)
11000
        emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11001
      DONE;
11002
   }
11003
  if (TARGET_SH4A_ARCH
11004
      && INTVAL (operands[2]) == 32
11005
      && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11006
      && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11007
    {
11008
      rtx src = adjust_address (operands[1], BLKmode, 0);
11009
      set_mem_size (src, GEN_INT (4));
11010
      emit_insn (gen_movua (operands[0], src));
11011
      DONE;
11012
    }
11013
 
11014
  FAIL;
11015
})
11016
 
11017
(define_expand "extzv"
11018
  [(set (match_operand:SI 0 "register_operand" "")
11019
        (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11020
                         (match_operand 2 "const_int_operand" "")
11021
                         (match_operand 3 "const_int_operand" "")))]
11022
  "TARGET_SH4A_ARCH || TARGET_SH2A"
11023
{
11024
  if (TARGET_SH2A && TARGET_BITOPS
11025
      && (satisfies_constraint_Sbw (operands[1])
11026
          || satisfies_constraint_Sbv (operands[1]))
11027
      && satisfies_constraint_M (operands[2])
11028
      && satisfies_constraint_K03 (operands[3]))
11029
    {
11030
      emit_insn (gen_bld_m2a (operands[1], operands[3]));
11031
      if (REGNO (operands[0]) != T_REG)
11032
        emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11033
      DONE;
11034
    }
11035
  if (TARGET_SH4A_ARCH
11036
      && INTVAL (operands[2]) == 32
11037
      && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11038
      && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11039
    {
11040
      rtx src = adjust_address (operands[1], BLKmode, 0);
11041
      set_mem_size (src, GEN_INT (4));
11042
      emit_insn (gen_movua (operands[0], src));
11043
      DONE;
11044
    }
11045
 
11046
  FAIL;
11047
})
11048
 
11049
;; SH2A instructions for bitwise operations.
11050
 
11051
;; Clear a bit in a memory location.
11052
(define_insn "bclr_m2a"
11053
  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11054
        (and:QI
11055
            (not:QI (ashift:QI (const_int 1)
11056
                        (match_operand:QI 1 "const_int_operand" "K03,K03")))
11057
            (match_dup 0)))]
11058
  "TARGET_SH2A && TARGET_BITOPS"
11059
  "@
11060
        bclr.b\\t%1,%0
11061
        bclr.b\\t%1,@(0,%t0)"
11062
[(set_attr "length" "4,4")])
11063
 
11064
(define_insn "bclrmem_m2a"
11065
  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11066
        (and:QI (match_dup 0)
11067
                (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11068
  "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11069
  "@
11070
        bclr.b\\t%W1,%0
11071
        bclr.b\\t%W1,@(0,%t0)"
11072
  [(set_attr "length" "4,4")])
11073
 
11074
;; Set a bit in a memory location.
11075
(define_insn "bset_m2a"
11076
  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11077
        (ior:QI
11078
            (ashift:QI (const_int 1)
11079
                       (match_operand:QI 1 "const_int_operand" "K03,K03"))
11080
            (match_dup 0)))]
11081
  "TARGET_SH2A && TARGET_BITOPS"
11082
  "@
11083
        bset.b\\t%1,%0
11084
        bset.b\\t%1,@(0,%t0)"
11085
  [(set_attr "length" "4,4")])
11086
 
11087
(define_insn "bsetmem_m2a"
11088
  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11089
        (ior:QI (match_dup 0)
11090
                (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11091
  "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11092
  "@
11093
        bset.b\\t%V1,%0
11094
        bset.b\\t%V1,@(0,%t0)"
11095
  [(set_attr "length" "4,4")])
11096
 
11097
;;; Transfer the contents of the T bit to a specified bit of memory.
11098
(define_insn "bst_m2a"
11099
  [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11100
        (if_then_else (eq (reg:SI T_REG) (const_int 0))
11101
            (and:QI
11102
                (not:QI (ashift:QI (const_int 1)
11103
                        (match_operand:QI 1 "const_int_operand" "K03,K03")))
11104
                (match_dup 0))
11105
            (ior:QI
11106
                (ashift:QI (const_int 1) (match_dup 1))
11107
                (match_dup 0))))]
11108
  "TARGET_SH2A && TARGET_BITOPS"
11109
  "@
11110
        bst.b\\t%1,%0
11111
        bst.b\\t%1,@(0,%t0)"
11112
  [(set_attr "length" "4")])
11113
 
11114
;; Store a specified bit of memory in the T bit.
11115
(define_insn "bld_m2a"
11116
  [(set (reg:SI T_REG)
11117
        (zero_extract:SI
11118
            (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11119
            (const_int 1)
11120
            (match_operand 1 "const_int_operand" "K03,K03")))]
11121
  "TARGET_SH2A && TARGET_BITOPS"
11122
  "@
11123
        bld.b\\t%1,%0
11124
        bld.b\\t%1,@(0,%t0)"
11125
  [(set_attr "length" "4,4")])
11126
 
11127
;; Store a specified bit of memory in the T bit.
11128
(define_insn "bldsign_m2a"
11129
  [(set (reg:SI T_REG)
11130
        (sign_extract:SI
11131
            (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11132
            (const_int 1)
11133
            (match_operand 1 "const_int_operand" "K03,K03")))]
11134
  "TARGET_SH2A && TARGET_BITOPS"
11135
  "@
11136
        bld.b\\t%1,%0
11137
        bld.b\\t%1,@(0,%t0)"
11138
  [(set_attr "length" "4,4")])
11139
 
11140
;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11141
(define_insn "bld_reg"
11142
  [(set (reg:SI T_REG)
11143
        (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11144
                         (const_int 1)
11145
                         (match_operand 1 "const_int_operand" "K03")))]
11146
  "TARGET_SH2A"
11147
  "bld\\t%1,%0")
11148
 
11149
(define_insn "*bld_regqi"
11150
  [(set (reg:SI T_REG)
11151
        (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11152
                         (const_int 1)
11153
                         (match_operand 1 "const_int_operand" "K03")))]
11154
  "TARGET_SH2A"
11155
  "bld\\t%1,%0")
11156
 
11157
;; Take logical and of a specified bit of memory with the T bit and
11158
;; store its result in the T bit.
11159
(define_insn "band_m2a"
11160
  [(set (reg:SI T_REG)
11161
        (and:SI (reg:SI T_REG)
11162
                (zero_extract:SI
11163
                    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11164
                    (const_int 1)
11165
                    (match_operand 1 "const_int_operand" "K03,K03"))))]
11166
  "TARGET_SH2A && TARGET_BITOPS"
11167
  "@
11168
        band.b\\t%1,%0
11169
        band.b\\t%1,@(0,%t0)"
11170
  [(set_attr "length" "4,4")])
11171
 
11172
(define_insn "bandreg_m2a"
11173
  [(set (match_operand:SI 0 "register_operand" "=r,r")
11174
        (and:SI (zero_extract:SI
11175
                    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11176
                    (const_int 1)
11177
                    (match_operand 2 "const_int_operand" "K03,K03"))
11178
                (match_operand:SI 3 "register_operand" "r,r")))]
11179
  "TARGET_SH2A && TARGET_BITOPS"
11180
  "@
11181
        band.b\\t%2,%1\;movt\\t%0
11182
        band.b\\t%2,@(0,%t1)\;movt\\t%0"
11183
  [(set_attr "length" "6,6")])
11184
 
11185
;; Take logical or of a specified bit of memory with the T bit and
11186
;; store its result in the T bit.
11187
(define_insn "bor_m2a"
11188
  [(set (reg:SI T_REG)
11189
        (ior:SI (reg:SI T_REG)
11190
                (zero_extract:SI
11191
                    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11192
                    (const_int 1)
11193
                    (match_operand 1 "const_int_operand" "K03,K03"))))]
11194
  "TARGET_SH2A && TARGET_BITOPS"
11195
  "@
11196
        bor.b\\t%1,%0
11197
        bor.b\\t%1,@(0,%t0)"
11198
  [(set_attr "length" "4,4")])
11199
 
11200
(define_insn "borreg_m2a"
11201
  [(set (match_operand:SI 0 "register_operand" "=r,r")
11202
        (ior:SI (zero_extract:SI
11203
                    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11204
                    (const_int 1)
11205
                    (match_operand 2 "const_int_operand" "K03,K03"))
11206
                (match_operand:SI 3 "register_operand" "=r,r")))]
11207
  "TARGET_SH2A && TARGET_BITOPS"
11208
  "@
11209
        bor.b\\t%2,%1\;movt\\t%0
11210
        bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11211
  [(set_attr "length" "6,6")])
11212
 
11213
;; Take exclusive or of a specified bit of memory with the T bit and
11214
;; store its result in the T bit.
11215
(define_insn "bxor_m2a"
11216
  [(set (reg:SI T_REG)
11217
        (xor:SI (reg:SI T_REG)
11218
                (zero_extract:SI
11219
                    (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11220
                    (const_int 1)
11221
                    (match_operand 1 "const_int_operand" "K03,K03"))))]
11222
  "TARGET_SH2A && TARGET_BITOPS"
11223
  "@
11224
        bxor.b\\t%1,%0
11225
        bxor.b\\t%1,@(0,%t0)"
11226
  [(set_attr "length" "4,4")])
11227
 
11228
(define_insn "bxorreg_m2a"
11229
  [(set (match_operand:SI 0 "register_operand" "=r,r")
11230
        (xor:SI (zero_extract:SI
11231
                    (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11232
                    (const_int 1)
11233
                    (match_operand 2 "const_int_operand" "K03,K03"))
11234
                (match_operand:SI 3 "register_operand" "=r,r")))]
11235
  "TARGET_SH2A && TARGET_BITOPS"
11236
  "@
11237
        bxor.b\\t%2,%1\;movt\\t%0
11238
        bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11239
  [(set_attr "length" "6,6")])
11240
 
11241
 
11242
;; -------------------------------------------------------------------------
11243
;; Peepholes
11244
;; -------------------------------------------------------------------------
11245
;; This matches cases where the bit in a memory location is set.
11246
(define_peephole2
11247
  [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11248
        (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11249
   (set (match_dup 0)
11250
        (ior:SI (match_dup 0)
11251
        (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11252
   (set (match_dup 1)
11253
        (match_operand 3 "arith_reg_operand" "r,r"))]
11254
  "TARGET_SH2A && TARGET_BITOPS
11255
   && satisfies_constraint_Pso (operands[2])
11256
   && REGNO (operands[0]) == REGNO (operands[3])"
11257
  [(set (match_dup 1)
11258
        (ior:QI (match_dup 1)
11259
                (match_dup 2)))]
11260
  "")
11261
 
11262
;; This matches cases where the bit in a memory location is cleared.
11263
(define_peephole2
11264
  [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11265
        (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11266
   (set (match_dup 0)
11267
        (and:SI (match_dup 0)
11268
        (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11269
   (set (match_dup 1)
11270
        (match_operand 3 "arith_reg_operand" "r,r"))]
11271
  "TARGET_SH2A && TARGET_BITOPS
11272
   && satisfies_constraint_Psz (operands[2])
11273
   && REGNO (operands[0]) == REGNO (operands[3])"
11274
  [(set (match_dup 1)
11275
        (and:QI (match_dup 1)
11276
                (match_dup 2)))]
11277
  "")
11278
 
11279
;; This matches cases where a stack pointer increment at the start of the
11280
;; epilogue combines with a stack slot read loading the return value.
11281
 
11282
(define_peephole
11283
  [(set (match_operand:SI 0 "arith_reg_operand" "")
11284
        (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11285
   (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11286
  "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11287
  "mov.l        @%1+,%0")
11288
 
11289
;; See the comment on the dt combiner pattern above.
11290
 
11291
(define_peephole
11292
  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11293
        (plus:SI (match_dup 0)
11294
                 (const_int -1)))
11295
   (set (reg:SI T_REG)
11296
        (eq:SI (match_dup 0)
11297
               (const_int 0)))]
11298
  "TARGET_SH2"
11299
  "dt   %0")
11300
 
11301
;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11302
;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11303
;; reload when the constant is too large for a reg+offset address.
11304
 
11305
;; ??? We would get much better code if this was done in reload.  This would
11306
;; require modifying find_reloads_address to recognize that if the constant
11307
;; is out-of-range for an immediate add, then we get better code by reloading
11308
;; the constant into a register than by reloading the sum into a register,
11309
;; since the former is one instruction shorter if the address does not need
11310
;; to be offsettable.  Unfortunately this does not work, because there is
11311
;; only one register, r0, that can be used as an index register.  This register
11312
;; is also the function return value register.  So, if we try to force reload
11313
;; to use double-reg addresses, then we end up with some instructions that
11314
;; need to use r0 twice.  The only way to fix this is to change the calling
11315
;; convention so that r0 is not used to return values.
11316
 
11317
(define_peephole
11318
  [(set (match_operand:SI 0 "register_operand" "=r")
11319
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11320
   (set (mem:SI (match_dup 0))
11321
        (match_operand:SI 2 "general_movsrc_operand" ""))]
11322
  "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11323
  "mov.l        %2,@(%0,%1)")
11324
 
11325
(define_peephole
11326
  [(set (match_operand:SI 0 "register_operand" "=r")
11327
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11328
   (set (match_operand:SI 2 "general_movdst_operand" "")
11329
        (mem:SI (match_dup 0)))]
11330
  "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11331
  "mov.l        @(%0,%1),%2")
11332
 
11333
(define_peephole
11334
  [(set (match_operand:SI 0 "register_operand" "=r")
11335
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11336
   (set (mem:HI (match_dup 0))
11337
        (match_operand:HI 2 "general_movsrc_operand" ""))]
11338
  "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11339
  "mov.w        %2,@(%0,%1)")
11340
 
11341
(define_peephole
11342
  [(set (match_operand:SI 0 "register_operand" "=r")
11343
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11344
   (set (match_operand:HI 2 "general_movdst_operand" "")
11345
        (mem:HI (match_dup 0)))]
11346
  "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11347
  "mov.w        @(%0,%1),%2")
11348
 
11349
(define_peephole
11350
  [(set (match_operand:SI 0 "register_operand" "=r")
11351
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11352
   (set (mem:QI (match_dup 0))
11353
        (match_operand:QI 2 "general_movsrc_operand" ""))]
11354
  "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11355
  "mov.b        %2,@(%0,%1)")
11356
 
11357
(define_peephole
11358
  [(set (match_operand:SI 0 "register_operand" "=r")
11359
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11360
   (set (match_operand:QI 2 "general_movdst_operand" "")
11361
        (mem:QI (match_dup 0)))]
11362
  "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11363
  "mov.b        @(%0,%1),%2")
11364
 
11365
(define_peephole
11366
  [(set (match_operand:SI 0 "register_operand" "=r")
11367
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11368
   (set (mem:SF (match_dup 0))
11369
        (match_operand:SF 2 "general_movsrc_operand" ""))]
11370
  "TARGET_SH1 && REGNO (operands[0]) == 0
11371
   && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11372
       || (GET_CODE (operands[2]) == SUBREG
11373
           && REGNO (SUBREG_REG (operands[2])) < 16))
11374
   && reg_unused_after (operands[0], insn)"
11375
  "mov.l        %2,@(%0,%1)")
11376
 
11377
(define_peephole
11378
  [(set (match_operand:SI 0 "register_operand" "=r")
11379
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11380
   (set (match_operand:SF 2 "general_movdst_operand" "")
11381
 
11382
        (mem:SF (match_dup 0)))]
11383
  "TARGET_SH1 && REGNO (operands[0]) == 0
11384
   && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11385
       || (GET_CODE (operands[2]) == SUBREG
11386
           && REGNO (SUBREG_REG (operands[2])) < 16))
11387
   && reg_unused_after (operands[0], insn)"
11388
  "mov.l        @(%0,%1),%2")
11389
 
11390
(define_peephole
11391
  [(set (match_operand:SI 0 "register_operand" "=r")
11392
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11393
   (set (mem:SF (match_dup 0))
11394
        (match_operand:SF 2 "general_movsrc_operand" ""))]
11395
  "TARGET_SH2E && REGNO (operands[0]) == 0
11396
   && ((REG_P (operands[2])
11397
        && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11398
       || (GET_CODE (operands[2]) == SUBREG
11399
           && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11400
   && reg_unused_after (operands[0], insn)"
11401
  "fmov{.s|}    %2,@(%0,%1)")
11402
 
11403
(define_peephole
11404
  [(set (match_operand:SI 0 "register_operand" "=r")
11405
        (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11406
   (set (match_operand:SF 2 "general_movdst_operand" "")
11407
 
11408
        (mem:SF (match_dup 0)))]
11409
  "TARGET_SH2E && REGNO (operands[0]) == 0
11410
   && ((REG_P (operands[2])
11411
        && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11412
       || (GET_CODE (operands[2]) == SUBREG
11413
           && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11414
   && reg_unused_after (operands[0], insn)"
11415
  "fmov{.s|}    @(%0,%1),%2")
11416
 
11417
;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11418
(define_insn "sp_switch_1"
11419
  [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11420
  "TARGET_SH1"
11421
  "*
11422
{
11423
  output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11424
  output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11425
  return \"mov r0,r15\";
11426
}"
11427
  [(set_attr "length" "10")])
11428
 
11429
;; Switch back to the original stack for interrupt functions with the
11430
;; sp_switch attribute.  */
11431
(define_insn "sp_switch_2"
11432
  [(const_int 2)]
11433
  "TARGET_SH1"
11434
  "mov.l @r15+,r15\;mov.l @r15+,r0"
11435
  [(set_attr "length" "4")])
11436
 
11437
;; Integer vector moves
11438
 
11439
(define_expand "movv8qi"
11440
  [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11441
        (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11442
  "TARGET_SHMEDIA"
11443
  "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11444
 
11445
(define_insn "movv8qi_i"
11446
  [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11447
        (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11448
  "TARGET_SHMEDIA
11449
   && (register_operand (operands[0], V8QImode)
11450
       || sh_register_operand (operands[1], V8QImode))"
11451
  "@
11452
        add     %1, r63, %0
11453
        movi    %1, %0
11454
        #
11455
        ld%M1.q %m1, %0
11456
        st%M0.q %m0, %N1"
11457
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11458
   (set_attr "length" "4,4,16,4,4")])
11459
 
11460
(define_split
11461
  [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11462
        (subreg:V8QI (const_int 0) 0))]
11463
  "TARGET_SHMEDIA"
11464
  [(set (match_dup 0)
11465
        (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11466
                            (const_int 0) (const_int 0) (const_int 0)
11467
                            (const_int 0) (const_int 0)]))])
11468
 
11469
(define_split
11470
  [(set (match_operand 0 "arith_reg_dest" "")
11471
        (match_operand 1 "sh_rep_vec" ""))]
11472
  "TARGET_SHMEDIA && reload_completed
11473
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
11474
   && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11475
   && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11476
   && (XVECEXP (operands[1], 0, 0) != const0_rtx
11477
       || XVECEXP (operands[1], 0, 1) != const0_rtx)
11478
   && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11479
       || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11480
  [(set (match_dup 0) (match_dup 1))
11481
   (match_dup 2)]
11482
  "
11483
{
11484
  int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11485
  rtx elt1 = XVECEXP (operands[1], 0, 1);
11486
 
11487
  if (unit_size > 2)
11488
    operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11489
  else
11490
    {
11491
      if (unit_size < 2)
11492
        operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11493
      operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11494
    }
11495
  operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11496
  operands[1] = XVECEXP (operands[1], 0, 0);
11497
  if (unit_size < 2)
11498
    {
11499
      if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11500
        operands[1]
11501
          = GEN_INT (TARGET_LITTLE_ENDIAN
11502
                     ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11503
                     : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11504
      else
11505
        {
11506
          operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11507
          operands[1]
11508
            = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11509
        }
11510
    }
11511
}")
11512
 
11513
(define_split
11514
  [(set (match_operand 0 "arith_reg_dest" "")
11515
        (match_operand 1 "sh_const_vec" ""))]
11516
  "TARGET_SHMEDIA && reload_completed
11517
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
11518
   && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11519
  [(set (match_dup 0) (match_dup 1))]
11520
  "
11521
{
11522
  rtx v = operands[1];
11523
  enum machine_mode new_mode
11524
    = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11525
 
11526
  operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11527
  operands[1]
11528
    = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11529
}")
11530
 
11531
(define_expand "movv2hi"
11532
  [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11533
        (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11534
  "TARGET_SHMEDIA"
11535
  "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11536
 
11537
(define_insn "movv2hi_i"
11538
  [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11539
        (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11540
  "TARGET_SHMEDIA
11541
   && (register_operand (operands[0], V2HImode)
11542
       || sh_register_operand (operands[1], V2HImode))"
11543
  "@
11544
        add.l   %1, r63, %0
11545
        movi    %1, %0
11546
        #
11547
        ld%M1.l %m1, %0
11548
        st%M0.l %m0, %N1"
11549
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11550
   (set_attr "length" "4,4,16,4,4")
11551
   (set (attr "highpart")
11552
        (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11553
               (const_string "user")]
11554
              (const_string "ignore")))])
11555
 
11556
(define_expand "movv4hi"
11557
  [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11558
        (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11559
  "TARGET_SHMEDIA"
11560
  "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11561
 
11562
(define_insn "movv4hi_i"
11563
  [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11564
        (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11565
  "TARGET_SHMEDIA
11566
   && (register_operand (operands[0], V4HImode)
11567
       || sh_register_operand (operands[1], V4HImode))"
11568
  "@
11569
        add     %1, r63, %0
11570
        movi    %1, %0
11571
        #
11572
        ld%M1.q %m1, %0
11573
        st%M0.q %m0, %N1"
11574
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11575
   (set_attr "length" "4,4,16,4,4")
11576
   (set_attr "highpart" "depend")])
11577
 
11578
(define_expand "movv2si"
11579
  [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11580
        (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11581
  "TARGET_SHMEDIA"
11582
  "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11583
 
11584
(define_insn "movv2si_i"
11585
  [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11586
        (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11587
  "TARGET_SHMEDIA
11588
   && (register_operand (operands[0], V2SImode)
11589
       || sh_register_operand (operands[1], V2SImode))"
11590
  "@
11591
        add     %1, r63, %0
11592
        #
11593
        #
11594
        ld%M1.q %m1, %0
11595
        st%M0.q %m0, %N1"
11596
  [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11597
   (set_attr "length" "4,4,16,4,4")
11598
   (set_attr "highpart" "depend")])
11599
 
11600
;; Multimedia Intrinsics
11601
 
11602
(define_insn "absv2si2"
11603
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11604
        (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11605
  "TARGET_SHMEDIA"
11606
  "mabs.l       %1, %0"
11607
  [(set_attr "type" "mcmp_media")
11608
   (set_attr "highpart" "depend")])
11609
 
11610
(define_insn "absv4hi2"
11611
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11612
        (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11613
  "TARGET_SHMEDIA"
11614
  "mabs.w       %1, %0"
11615
  [(set_attr "type" "mcmp_media")
11616
   (set_attr "highpart" "depend")])
11617
 
11618
(define_insn "addv2si3"
11619
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11620
        (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11621
                   (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11622
  "TARGET_SHMEDIA"
11623
  "madd.l       %1, %2, %0"
11624
  [(set_attr "type" "arith_media")
11625
   (set_attr "highpart" "depend")])
11626
 
11627
(define_insn "addv4hi3"
11628
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11629
        (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11630
                   (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11631
  "TARGET_SHMEDIA"
11632
  "madd.w       %1, %2, %0"
11633
  [(set_attr "type" "arith_media")
11634
   (set_attr "highpart" "depend")])
11635
 
11636
(define_insn_and_split "addv2hi3"
11637
  [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11638
        (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11639
                   (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11640
  "TARGET_SHMEDIA"
11641
  "#"
11642
  "TARGET_SHMEDIA"
11643
  [(const_int 0)]
11644
  "
11645
{
11646
  rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11647
  rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11648
  rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11649
  rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11650
  rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11651
 
11652
  emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11653
  emit_insn (gen_truncdisi2 (si_dst, di_dst));
11654
  DONE;
11655
}"
11656
  [(set_attr "highpart" "must_split")])
11657
 
11658
(define_insn "ssaddv2si3"
11659
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11660
        (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11661
                      (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11662
  "TARGET_SHMEDIA"
11663
  "madds.l      %1, %2, %0"
11664
  [(set_attr "type" "mcmp_media")
11665
   (set_attr "highpart" "depend")])
11666
 
11667
(define_insn "usaddv8qi3"
11668
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11669
        (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11670
                      (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11671
  "TARGET_SHMEDIA"
11672
  "madds.ub     %1, %2, %0"
11673
  [(set_attr "type" "mcmp_media")
11674
   (set_attr "highpart" "depend")])
11675
 
11676
(define_insn "ssaddv4hi3"
11677
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11678
        (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11679
                      (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11680
  "TARGET_SHMEDIA"
11681
  "madds.w      %1, %2, %0"
11682
  [(set_attr "type" "mcmp_media")
11683
   (set_attr "highpart" "depend")])
11684
 
11685
(define_insn "negcmpeqv8qi"
11686
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11687
        (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11688
                           (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11689
  "TARGET_SHMEDIA"
11690
  "mcmpeq.b     %N1, %N2, %0"
11691
  [(set_attr "type" "mcmp_media")
11692
   (set_attr "highpart" "depend")])
11693
 
11694
(define_insn "negcmpeqv2si"
11695
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11696
        (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11697
                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11698
  "TARGET_SHMEDIA"
11699
  "mcmpeq.l     %N1, %N2, %0"
11700
  [(set_attr "type" "mcmp_media")
11701
   (set_attr "highpart" "depend")])
11702
 
11703
(define_insn "negcmpeqv4hi"
11704
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11705
        (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11706
                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11707
  "TARGET_SHMEDIA"
11708
  "mcmpeq.w     %N1, %N2, %0"
11709
  [(set_attr "type" "mcmp_media")
11710
   (set_attr "highpart" "depend")])
11711
 
11712
(define_insn "negcmpgtuv8qi"
11713
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11714
        (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11715
                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11716
  "TARGET_SHMEDIA"
11717
  "mcmpgt.ub    %N1, %N2, %0"
11718
  [(set_attr "type" "mcmp_media")
11719
   (set_attr "highpart" "depend")])
11720
 
11721
(define_insn "negcmpgtv2si"
11722
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11723
        (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11724
                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11725
  "TARGET_SHMEDIA"
11726
  "mcmpgt.l     %N1, %N2, %0"
11727
  [(set_attr "type" "mcmp_media")
11728
   (set_attr "highpart" "depend")])
11729
 
11730
(define_insn "negcmpgtv4hi"
11731
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11732
        (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11733
                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11734
  "TARGET_SHMEDIA"
11735
  "mcmpgt.w     %N1, %N2, %0"
11736
  [(set_attr "type" "mcmp_media")
11737
   (set_attr "highpart" "depend")])
11738
 
11739
(define_insn "mcmv"
11740
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11741
        (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11742
                        (match_operand:DI 2 "arith_reg_operand" "r"))
11743
                (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11744
                        (not:DI (match_dup 2)))))]
11745
  "TARGET_SHMEDIA"
11746
  "mcmv %N1, %2, %0"
11747
  [(set_attr "type" "arith_media")
11748
   (set_attr "highpart" "depend")])
11749
 
11750
(define_insn "mcnvs_lw"
11751
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11752
        (vec_concat:V4HI
11753
         (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11754
         (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11755
  "TARGET_SHMEDIA"
11756
  "mcnvs.lw     %N1, %N2, %0"
11757
  [(set_attr "type" "mcmp_media")])
11758
 
11759
(define_insn "mcnvs_wb"
11760
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11761
        (vec_concat:V8QI
11762
         (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11763
         (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11764
  "TARGET_SHMEDIA"
11765
  "mcnvs.wb     %N1, %N2, %0"
11766
  [(set_attr "type" "mcmp_media")])
11767
 
11768
(define_insn "mcnvs_wub"
11769
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11770
        (vec_concat:V8QI
11771
         (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11772
         (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11773
  "TARGET_SHMEDIA"
11774
  "mcnvs.wub    %N1, %N2, %0"
11775
  [(set_attr "type" "mcmp_media")])
11776
 
11777
(define_insn "mextr_rl"
11778
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11779
        (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11780
                             (match_operand:HI 3 "mextr_bit_offset" "i"))
11781
               (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11782
                          (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11783
  "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11784
  "*
11785
{
11786
  static char templ[21];
11787
 
11788
  sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11789
           (int) INTVAL (operands[3]) >> 3);
11790
  return templ;
11791
}"
11792
  [(set_attr "type" "arith_media")])
11793
 
11794
(define_insn "*mextr_lr"
11795
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11796
        (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11797
                           (match_operand:HI 3 "mextr_bit_offset" "i"))
11798
               (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11799
                            (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11800
  "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11801
  "*
11802
{
11803
  static char templ[21];
11804
 
11805
  sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11806
           (int) INTVAL (operands[4]) >> 3);
11807
  return templ;
11808
}"
11809
  [(set_attr "type" "arith_media")])
11810
 
11811
; mextrN can be modelled with vec_select / vec_concat, but the selection
11812
; vector then varies depending on endianness.
11813
(define_expand "mextr1"
11814
  [(match_operand:DI 0 "arith_reg_dest" "")
11815
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11816
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11817
  "TARGET_SHMEDIA"
11818
  "
11819
{
11820
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11821
                           GEN_INT (1 * 8), GEN_INT (7 * 8)));
11822
  DONE;
11823
}")
11824
 
11825
(define_expand "mextr2"
11826
  [(match_operand:DI 0 "arith_reg_dest" "")
11827
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11828
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11829
  "TARGET_SHMEDIA"
11830
  "
11831
{
11832
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11833
                           GEN_INT (2 * 8), GEN_INT (6 * 8)));
11834
  DONE;
11835
}")
11836
 
11837
(define_expand "mextr3"
11838
  [(match_operand:DI 0 "arith_reg_dest" "")
11839
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11840
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11841
  "TARGET_SHMEDIA"
11842
  "
11843
{
11844
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11845
                           GEN_INT (3 * 8), GEN_INT (5 * 8)));
11846
  DONE;
11847
}")
11848
 
11849
(define_expand "mextr4"
11850
  [(match_operand:DI 0 "arith_reg_dest" "")
11851
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11852
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11853
  "TARGET_SHMEDIA"
11854
  "
11855
{
11856
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11857
                           GEN_INT (4 * 8), GEN_INT (4 * 8)));
11858
  DONE;
11859
}")
11860
 
11861
(define_expand "mextr5"
11862
  [(match_operand:DI 0 "arith_reg_dest" "")
11863
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11864
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11865
  "TARGET_SHMEDIA"
11866
  "
11867
{
11868
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11869
                           GEN_INT (5 * 8), GEN_INT (3 * 8)));
11870
  DONE;
11871
}")
11872
 
11873
(define_expand "mextr6"
11874
  [(match_operand:DI 0 "arith_reg_dest" "")
11875
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11876
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11877
  "TARGET_SHMEDIA"
11878
  "
11879
{
11880
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11881
                           GEN_INT (6 * 8), GEN_INT (2 * 8)));
11882
  DONE;
11883
}")
11884
 
11885
(define_expand "mextr7"
11886
  [(match_operand:DI 0 "arith_reg_dest" "")
11887
   (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11888
   (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11889
  "TARGET_SHMEDIA"
11890
  "
11891
{
11892
  emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11893
                           GEN_INT (7 * 8), GEN_INT (1 * 8)));
11894
  DONE;
11895
}")
11896
 
11897
(define_expand "mmacfx_wl"
11898
  [(match_operand:V2SI 0 "arith_reg_dest" "")
11899
   (match_operand:V2HI 1 "extend_reg_operand" "")
11900
   (match_operand:V2HI 2 "extend_reg_operand" "")
11901
   (match_operand:V2SI 3 "arith_reg_operand" "")]
11902
  "TARGET_SHMEDIA"
11903
  "
11904
{
11905
  emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11906
                              operands[1], operands[2]));
11907
  DONE;
11908
}")
11909
 
11910
;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11911
;; is depend
11912
(define_insn "mmacfx_wl_i"
11913
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11914
        (ss_plus:V2SI
11915
         (match_operand:V2SI 1 "arith_reg_operand" "0")
11916
         (ss_truncate:V2SI
11917
          (ashift:V2DI
11918
           (sign_extend:V2DI
11919
            (mult:V2SI
11920
             (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11921
             (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11922
           (const_int 1)))))]
11923
  "TARGET_SHMEDIA"
11924
  "mmacfx.wl    %2, %3, %0"
11925
  [(set_attr "type" "mac_media")
11926
   (set_attr "highpart" "depend")])
11927
 
11928
(define_expand "mmacnfx_wl"
11929
  [(match_operand:V2SI 0 "arith_reg_dest" "")
11930
   (match_operand:V2HI 1 "extend_reg_operand" "")
11931
   (match_operand:V2HI 2 "extend_reg_operand" "")
11932
   (match_operand:V2SI 3 "arith_reg_operand" "")]
11933
  "TARGET_SHMEDIA"
11934
  "
11935
{
11936
  emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11937
                               operands[1], operands[2]));
11938
  DONE;
11939
}")
11940
 
11941
(define_insn "mmacnfx_wl_i"
11942
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11943
        (ss_minus:V2SI
11944
         (match_operand:V2SI 1 "arith_reg_operand" "0")
11945
         (ss_truncate:V2SI
11946
          (ashift:V2DI
11947
           (sign_extend:V2DI
11948
            (mult:V2SI
11949
             (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11950
             (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11951
           (const_int 1)))))]
11952
  "TARGET_SHMEDIA"
11953
  "mmacnfx.wl   %2, %3, %0"
11954
  [(set_attr "type" "mac_media")
11955
   (set_attr "highpart" "depend")])
11956
 
11957
(define_insn "mulv2si3"
11958
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11959
        (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11960
                   (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11961
  "TARGET_SHMEDIA"
11962
  "mmul.l       %1, %2, %0"
11963
  [(set_attr "type" "d2mpy_media")
11964
   (set_attr "highpart" "depend")])
11965
 
11966
(define_insn "mulv4hi3"
11967
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11968
        (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11969
                   (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11970
  "TARGET_SHMEDIA"
11971
  "mmul.w       %1, %2, %0"
11972
  [(set_attr "type" "dmpy_media")
11973
   (set_attr "highpart" "depend")])
11974
 
11975
(define_insn "mmulfx_l"
11976
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11977
        (ss_truncate:V2SI
11978
         (ashiftrt:V2DI
11979
          (mult:V2DI
11980
           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11981
           (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11982
          (const_int 31))))]
11983
  "TARGET_SHMEDIA"
11984
  "mmulfx.l     %1, %2, %0"
11985
  [(set_attr "type" "d2mpy_media")
11986
   (set_attr "highpart" "depend")])
11987
 
11988
(define_insn "mmulfx_w"
11989
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11990
        (ss_truncate:V4HI
11991
         (ashiftrt:V4SI
11992
          (mult:V4SI
11993
           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11994
           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11995
          (const_int 15))))]
11996
  "TARGET_SHMEDIA"
11997
  "mmulfx.w     %1, %2, %0"
11998
  [(set_attr "type" "dmpy_media")
11999
   (set_attr "highpart" "depend")])
12000
 
12001
(define_insn "mmulfxrp_w"
12002
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12003
        (ss_truncate:V4HI
12004
         (ashiftrt:V4SI
12005
          (plus:V4SI
12006
           (mult:V4SI
12007
            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12008
            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12009
           (const_int 16384))
12010
          (const_int 15))))]
12011
  "TARGET_SHMEDIA"
12012
  "mmulfxrp.w   %1, %2, %0"
12013
  [(set_attr "type" "dmpy_media")
12014
   (set_attr "highpart" "depend")])
12015
 
12016
 
12017
(define_expand "mmulhi_wl"
12018
  [(match_operand:V2SI 0 "arith_reg_dest" "")
12019
   (match_operand:V4HI 1 "arith_reg_operand" "")
12020
   (match_operand:V4HI 2 "arith_reg_operand" "")]
12021
  "TARGET_SHMEDIA"
12022
  "
12023
{
12024
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12025
             (operands[0], operands[1], operands[2]));
12026
  DONE;
12027
}")
12028
 
12029
(define_expand "mmullo_wl"
12030
  [(match_operand:V2SI 0 "arith_reg_dest" "")
12031
   (match_operand:V4HI 1 "arith_reg_operand" "")
12032
   (match_operand:V4HI 2 "arith_reg_operand" "")]
12033
  "TARGET_SHMEDIA"
12034
  "
12035
{
12036
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12037
             (operands[0], operands[1], operands[2]));
12038
  DONE;
12039
}")
12040
 
12041
(define_insn "mmul23_wl"
12042
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12043
        (vec_select:V2SI
12044
         (mult:V4SI
12045
          (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12046
          (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12047
         (parallel [(const_int 2) (const_int 3)])))]
12048
  "TARGET_SHMEDIA"
12049
  "* return (TARGET_LITTLE_ENDIAN
12050
             ? \"mmulhi.wl      %1, %2, %0\"
12051
             : \"mmullo.wl      %1, %2, %0\");"
12052
  [(set_attr "type" "dmpy_media")
12053
   (set (attr "highpart")
12054
        (cond [(eq_attr "endian" "big") (const_string "ignore")]
12055
         (const_string "user")))])
12056
 
12057
(define_insn "mmul01_wl"
12058
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12059
        (vec_select:V2SI
12060
         (mult:V4SI
12061
          (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12062
          (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12063
         (parallel [(const_int 0) (const_int 1)])))]
12064
  "TARGET_SHMEDIA"
12065
  "* return (TARGET_LITTLE_ENDIAN
12066
             ? \"mmullo.wl      %1, %2, %0\"
12067
             : \"mmulhi.wl      %1, %2, %0\");"
12068
  [(set_attr "type" "dmpy_media")
12069
   (set (attr "highpart")
12070
        (cond [(eq_attr "endian" "little") (const_string "ignore")]
12071
         (const_string "user")))])
12072
 
12073
 
12074
(define_expand "mmulsum_wq"
12075
  [(match_operand:DI 0 "arith_reg_dest" "")
12076
   (match_operand:V4HI 1 "arith_reg_operand" "")
12077
   (match_operand:V4HI 2 "arith_reg_operand" "")
12078
   (match_operand:DI 3 "arith_reg_operand" "")]
12079
  "TARGET_SHMEDIA"
12080
  "
12081
{
12082
  emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12083
                               operands[1], operands[2]));
12084
  DONE;
12085
}")
12086
 
12087
(define_insn "mmulsum_wq_i"
12088
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12089
        (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12090
         (plus:DI
12091
          (plus:DI
12092
           (vec_select:DI
12093
            (mult:V4DI
12094
             (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12095
             (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12096
            (parallel [(const_int 0)]))
12097
           (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12098
                                     (sign_extend:V4DI (match_dup 3)))
12099
                          (parallel [(const_int 1)])))
12100
          (plus:DI
12101
           (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12102
                                     (sign_extend:V4DI (match_dup 3)))
12103
                          (parallel [(const_int 2)]))
12104
           (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12105
                                     (sign_extend:V4DI (match_dup 3)))
12106
                          (parallel [(const_int 3)]))))))]
12107
  "TARGET_SHMEDIA"
12108
  "mmulsum.wq   %2, %3, %0"
12109
  [(set_attr "type" "mac_media")])
12110
 
12111
(define_expand "mperm_w"
12112
  [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12113
   (match_operand:V4HI 1 "arith_reg_operand" "r")
12114
   (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12115
  "TARGET_SHMEDIA"
12116
  "
12117
{
12118
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12119
             (operands[0], operands[1], operands[2]));
12120
  DONE;
12121
}")
12122
 
12123
; This use of vec_select isn't exactly correct according to rtl.texi
12124
; (because not constant), but it seems a straightforward extension.
12125
(define_insn "mperm_w_little"
12126
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12127
        (vec_select:V4HI
12128
         (match_operand:V4HI 1 "arith_reg_operand" "r")
12129
         (parallel
12130
          [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12131
                            (const_int 2) (const_int 0))
12132
           (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12133
           (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12134
           (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12135
  "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12136
  "mperm.w      %1, %N2, %0"
12137
  [(set_attr "type" "arith_media")])
12138
 
12139
(define_insn "mperm_w_big"
12140
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12141
        (vec_select:V4HI
12142
         (match_operand:V4HI 1 "arith_reg_operand" "r")
12143
         (parallel
12144
          [(zero_extract:QI (not:QI (match_operand:QI 2
12145
                                     "extend_reg_or_0_operand" "rZ"))
12146
                            (const_int 2) (const_int 0))
12147
           (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12148
           (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12149
           (zero_extract:QI (not:QI (match_dup 2))
12150
                            (const_int 2) (const_int 6))])))]
12151
  "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12152
  "mperm.w      %1, %N2, %0"
12153
  [(set_attr "type" "arith_media")])
12154
 
12155
(define_insn "mperm_w0"
12156
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12157
        (vec_duplicate:V4HI (truncate:HI (match_operand 1
12158
                                          "trunc_hi_operand" "r"))))]
12159
  "TARGET_SHMEDIA"
12160
  "mperm.w      %1, r63, %0"
12161
  [(set_attr "type" "arith_media")
12162
   (set_attr "highpart" "ignore")])
12163
 
12164
(define_expand "msad_ubq"
12165
  [(match_operand:DI 0 "arith_reg_dest" "")
12166
   (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12167
   (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12168
   (match_operand:DI 3 "arith_reg_operand" "")]
12169
  "TARGET_SHMEDIA"
12170
  "
12171
{
12172
  emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12173
                             operands[1], operands[2]));
12174
  DONE;
12175
}")
12176
 
12177
(define_insn "msad_ubq_i"
12178
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12179
        (plus:DI
12180
         (plus:DI
12181
          (plus:DI
12182
           (plus:DI
12183
            (match_operand:DI 1 "arith_reg_operand" "0")
12184
            (abs:DI (vec_select:DI
12185
                     (minus:V8DI
12186
                      (zero_extend:V8DI
12187
                       (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12188
                      (zero_extend:V8DI
12189
                       (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12190
                     (parallel [(const_int 0)]))))
12191
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12192
                                              (zero_extend:V8DI (match_dup 3)))
12193
                                  (parallel [(const_int 1)]))))
12194
          (plus:DI
12195
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12196
                                              (zero_extend:V8DI (match_dup 3)))
12197
                                  (parallel [(const_int 2)])))
12198
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12199
                                              (zero_extend:V8DI (match_dup 3)))
12200
                                  (parallel [(const_int 3)])))))
12201
         (plus:DI
12202
          (plus:DI
12203
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12204
                                              (zero_extend:V8DI (match_dup 3)))
12205
                                  (parallel [(const_int 4)])))
12206
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12207
                                              (zero_extend:V8DI (match_dup 3)))
12208
                                  (parallel [(const_int 5)]))))
12209
          (plus:DI
12210
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12211
                                              (zero_extend:V8DI (match_dup 3)))
12212
                                  (parallel [(const_int 6)])))
12213
           (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12214
                                              (zero_extend:V8DI (match_dup 3)))
12215
                                  (parallel [(const_int 7)])))))))]
12216
  "TARGET_SHMEDIA"
12217
  "msad.ubq     %N2, %N3, %0"
12218
  [(set_attr "type" "mac_media")])
12219
 
12220
(define_insn "mshalds_l"
12221
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12222
        (ss_truncate:V2SI
12223
         (ashift:V2DI
12224
          (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12225
          (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12226
                  (const_int 31)))))]
12227
  "TARGET_SHMEDIA"
12228
  "mshalds.l    %1, %2, %0"
12229
  [(set_attr "type" "mcmp_media")
12230
   (set_attr "highpart" "depend")])
12231
 
12232
(define_insn "mshalds_w"
12233
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12234
        (ss_truncate:V4HI
12235
         (ashift:V4SI
12236
          (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12237
          (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12238
                  (const_int 15)))))]
12239
  "TARGET_SHMEDIA"
12240
  "mshalds.w    %1, %2, %0"
12241
  [(set_attr "type" "mcmp_media")
12242
   (set_attr "highpart" "depend")])
12243
 
12244
(define_insn "ashrv2si3"
12245
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12246
        (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12247
                       (match_operand:DI 2 "arith_reg_operand" "r")))]
12248
  "TARGET_SHMEDIA"
12249
  "mshard.l     %1, %2, %0"
12250
  [(set_attr "type" "arith_media")
12251
   (set_attr "highpart" "depend")])
12252
 
12253
(define_insn "ashrv4hi3"
12254
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12255
        (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12256
                       (match_operand:DI 2 "arith_reg_operand" "r")))]
12257
  "TARGET_SHMEDIA"
12258
  "mshard.w     %1, %2, %0"
12259
  [(set_attr "type" "arith_media")
12260
   (set_attr "highpart" "depend")])
12261
 
12262
(define_insn "mshards_q"
12263
  [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12264
        (ss_truncate:HI
12265
         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12266
                      (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12267
  "TARGET_SHMEDIA"
12268
  "mshards.q    %1, %N2, %0"
12269
  [(set_attr "type" "mcmp_media")])
12270
 
12271
(define_expand "mshfhi_b"
12272
  [(match_operand:V8QI 0 "arith_reg_dest" "")
12273
   (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12274
   (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12275
  "TARGET_SHMEDIA"
12276
  "
12277
{
12278
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12279
             (operands[0], operands[1], operands[2]));
12280
  DONE;
12281
}")
12282
 
12283
(define_expand "mshflo_b"
12284
  [(match_operand:V8QI 0 "arith_reg_dest" "")
12285
   (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12286
   (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12287
  "TARGET_SHMEDIA"
12288
  "
12289
{
12290
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12291
             (operands[0], operands[1], operands[2]));
12292
  DONE;
12293
}")
12294
 
12295
(define_insn "mshf4_b"
12296
  [(set
12297
    (match_operand:V8QI 0 "arith_reg_dest" "=r")
12298
    (vec_select:V8QI
12299
     (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12300
                       (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12301
     (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12302
                (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12303
  "TARGET_SHMEDIA"
12304
  "* return (TARGET_LITTLE_ENDIAN
12305
             ? \"mshfhi.b       %N1, %N2, %0\"
12306
             : \"mshflo.b       %N1, %N2, %0\");"
12307
  [(set_attr "type" "arith_media")
12308
   (set (attr "highpart")
12309
        (cond [(eq_attr "endian" "big") (const_string "ignore")]
12310
         (const_string "user")))])
12311
 
12312
(define_insn "mshf0_b"
12313
  [(set
12314
    (match_operand:V8QI 0 "arith_reg_dest" "=r")
12315
    (vec_select:V8QI
12316
     (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12317
                       (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12318
     (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12319
                (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12320
  "TARGET_SHMEDIA"
12321
  "* return (TARGET_LITTLE_ENDIAN
12322
             ? \"mshflo.b       %N1, %N2, %0\"
12323
             : \"mshfhi.b       %N1, %N2, %0\");"
12324
  [(set_attr "type" "arith_media")
12325
   (set (attr "highpart")
12326
        (cond [(eq_attr "endian" "little") (const_string "ignore")]
12327
         (const_string "user")))])
12328
 
12329
(define_expand "mshfhi_l"
12330
  [(match_operand:V2SI 0 "arith_reg_dest" "")
12331
   (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12332
   (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12333
  "TARGET_SHMEDIA"
12334
  "
12335
{
12336
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12337
             (operands[0], operands[1], operands[2]));
12338
  DONE;
12339
}")
12340
 
12341
(define_expand "mshflo_l"
12342
  [(match_operand:V2SI 0 "arith_reg_dest" "")
12343
   (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12344
   (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12345
  "TARGET_SHMEDIA"
12346
  "
12347
{
12348
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12349
             (operands[0], operands[1], operands[2]));
12350
  DONE;
12351
}")
12352
 
12353
(define_insn "mshf4_l"
12354
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12355
        (vec_select:V2SI
12356
         (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12357
                          (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12358
         (parallel [(const_int 1) (const_int 3)])))]
12359
  "TARGET_SHMEDIA"
12360
  "* return (TARGET_LITTLE_ENDIAN
12361
             ? \"mshfhi.l       %N1, %N2, %0\"
12362
             : \"mshflo.l       %N1, %N2, %0\");"
12363
  [(set_attr "type" "arith_media")
12364
   (set (attr "highpart")
12365
        (cond [(eq_attr "endian" "big") (const_string "ignore")]
12366
         (const_string "user")))])
12367
 
12368
(define_insn "mshf0_l"
12369
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12370
        (vec_select:V2SI
12371
         (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12372
                          (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12373
         (parallel [(const_int 0) (const_int 2)])))]
12374
  "TARGET_SHMEDIA"
12375
  "* return (TARGET_LITTLE_ENDIAN
12376
             ? \"mshflo.l       %N1, %N2, %0\"
12377
             : \"mshfhi.l       %N1, %N2, %0\");"
12378
  [(set_attr "type" "arith_media")
12379
   (set (attr "highpart")
12380
        (cond [(eq_attr "endian" "little") (const_string "ignore")]
12381
         (const_string "user")))])
12382
 
12383
(define_expand "mshfhi_w"
12384
  [(match_operand:V4HI 0 "arith_reg_dest" "")
12385
   (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12386
   (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12387
  "TARGET_SHMEDIA"
12388
  "
12389
{
12390
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12391
             (operands[0], operands[1], operands[2]));
12392
  DONE;
12393
}")
12394
 
12395
(define_expand "mshflo_w"
12396
  [(match_operand:V4HI 0 "arith_reg_dest" "")
12397
   (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12398
   (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12399
  "TARGET_SHMEDIA"
12400
  "
12401
{
12402
  emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12403
             (operands[0], operands[1], operands[2]));
12404
  DONE;
12405
}")
12406
 
12407
(define_insn "mshf4_w"
12408
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12409
        (vec_select:V4HI
12410
         (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12411
                          (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12412
         (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12413
  "TARGET_SHMEDIA"
12414
  "* return (TARGET_LITTLE_ENDIAN
12415
             ? \"mshfhi.w       %N1, %N2, %0\"
12416
             : \"mshflo.w       %N1, %N2, %0\");"
12417
  [(set_attr "type" "arith_media")
12418
   (set (attr "highpart")
12419
        (cond [(eq_attr "endian" "big") (const_string "ignore")]
12420
         (const_string "user")))])
12421
 
12422
(define_insn "mshf0_w"
12423
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12424
        (vec_select:V4HI
12425
         (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12426
                          (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12427
         (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12428
  "TARGET_SHMEDIA"
12429
  "* return (TARGET_LITTLE_ENDIAN
12430
             ? \"mshflo.w       %N1, %N2, %0\"
12431
             : \"mshfhi.w       %N1, %N2, %0\");"
12432
  [(set_attr "type" "arith_media")
12433
   (set (attr "highpart")
12434
        (cond [(eq_attr "endian" "little") (const_string "ignore")]
12435
         (const_string "user")))])
12436
 
12437
(define_insn "mshflo_w_x"
12438
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12439
        (vec_select:V4HI
12440
         (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12441
                          (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12442
         (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12443
  "TARGET_SHMEDIA"
12444
  "mshflo.w     %N1, %N2, %0"
12445
  [(set_attr "type" "arith_media")
12446
   (set_attr "highpart" "ignore")])
12447
 
12448
/* These are useful to expand ANDs and as combiner patterns.  */
12449
(define_insn_and_split "mshfhi_l_di"
12450
  [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12451
        (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12452
                             (const_int 32))
12453
                (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12454
                        (const_int -4294967296))))]
12455
  "TARGET_SHMEDIA"
12456
  "@
12457
        mshfhi.l        %N1, %N2, %0
12458
        #"
12459
  "TARGET_SHMEDIA && reload_completed
12460
   && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12461
  [(set (match_dup 3) (match_dup 4))
12462
   (set (match_dup 5) (match_dup 6))]
12463
  "
12464
{
12465
  operands[3] = gen_lowpart (SImode, operands[0]);
12466
  operands[4] = gen_highpart (SImode, operands[1]);
12467
  operands[5] = gen_highpart (SImode, operands[0]);
12468
  operands[6] = gen_highpart (SImode, operands[2]);
12469
}"
12470
  [(set_attr "type" "arith_media")])
12471
 
12472
(define_insn "*mshfhi_l_di_rev"
12473
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12474
        (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12475
                        (const_int -4294967296))
12476
                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12477
                             (const_int 32))))]
12478
  "TARGET_SHMEDIA"
12479
  "mshfhi.l     %N2, %N1, %0"
12480
  [(set_attr "type" "arith_media")])
12481
 
12482
(define_split
12483
  [(set (match_operand:DI 0 "arith_reg_dest" "")
12484
        (ior:DI (zero_extend:DI (match_operand:SI 1
12485
                                              "extend_reg_or_0_operand" ""))
12486
                (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12487
                        (const_int -4294967296))))
12488
   (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12489
  "TARGET_SHMEDIA"
12490
  [(const_int 0)]
12491
  "
12492
{
12493
  emit_insn (gen_ashldi3_media (operands[3],
12494
                                simplify_gen_subreg (DImode, operands[1],
12495
                                                     SImode, 0),
12496
                                GEN_INT (32)));
12497
  emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12498
  DONE;
12499
}")
12500
 
12501
(define_insn "mshflo_l_di"
12502
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12503
        (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12504
                        (const_int 4294967295))
12505
                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12506
                           (const_int 32))))]
12507
 
12508
  "TARGET_SHMEDIA"
12509
  "mshflo.l     %N1, %N2, %0"
12510
  [(set_attr "type" "arith_media")
12511
   (set_attr "highpart" "ignore")])
12512
 
12513
(define_insn "*mshflo_l_di_rev"
12514
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12515
        (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12516
                           (const_int 32))
12517
                (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12518
                        (const_int 4294967295))))]
12519
 
12520
  "TARGET_SHMEDIA"
12521
  "mshflo.l     %N2, %N1, %0"
12522
  [(set_attr "type" "arith_media")
12523
   (set_attr "highpart" "ignore")])
12524
 
12525
;; Combiner pattern for trampoline initialization.
12526
(define_insn_and_split "*double_shori"
12527
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12528
        (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12529
                           (const_int 32))
12530
                (match_operand:DI 2 "const_int_operand" "n")))]
12531
  "TARGET_SHMEDIA
12532
   && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12533
  "#"
12534
  "rtx_equal_p (operands[0], operands[1])"
12535
  [(const_int 0)]
12536
  "
12537
{
12538
  HOST_WIDE_INT v = INTVAL (operands[2]);
12539
 
12540
  emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12541
  emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12542
  DONE;
12543
}"
12544
  [(set_attr "highpart" "ignore")])
12545
 
12546
 
12547
(define_insn "*mshflo_l_di_x"
12548
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12549
        (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12550
                                 "rZ"))
12551
                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12552
                           (const_int 32))))]
12553
 
12554
  "TARGET_SHMEDIA"
12555
  "mshflo.l     %N1, %N2, %0"
12556
  [(set_attr "type" "arith_media")
12557
   (set_attr "highpart" "ignore")])
12558
 
12559
(define_insn_and_split "concat_v2sf"
12560
  [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12561
;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12562
        (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12563
                         (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12564
 
12565
  "TARGET_SHMEDIA"
12566
  "@
12567
        mshflo.l        %N1, %N2, %0
12568
        #
12569
        #"
12570
  "TARGET_SHMEDIA && reload_completed
12571
   && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12572
  [(set (match_dup 3) (match_dup 1))
12573
   (set (match_dup 4) (match_dup 2))]
12574
  "
12575
{
12576
  operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12577
  operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12578
}"
12579
  [(set_attr "type" "arith_media")
12580
   (set_attr "highpart" "ignore")])
12581
 
12582
(define_insn "*mshflo_l_di_x_rev"
12583
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12584
        (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12585
                           (const_int 32))
12586
                (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12587
 
12588
  "TARGET_SHMEDIA"
12589
  "mshflo.l     %N2, %N1, %0"
12590
  [(set_attr "type" "arith_media")
12591
   (set_attr "highpart" "ignore")])
12592
 
12593
(define_insn "ashlv2si3"
12594
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12595
        (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12596
                     (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12597
  "TARGET_SHMEDIA"
12598
  "mshlld.l     %1, %2, %0"
12599
  [(set_attr "type" "arith_media")
12600
   (set_attr "highpart" "depend")])
12601
 
12602
(define_split
12603
  [(set (match_operand 0 "any_register_operand" "")
12604
        (match_operator 3 "shift_operator"
12605
          [(match_operand 1 "any_register_operand" "")
12606
           (match_operand 2 "shift_count_reg_operand" "")]))]
12607
  "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12608
  [(set (match_dup 0) (match_dup 3))]
12609
  "
12610
{
12611
  rtx count = operands[2];
12612
  enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12613
 
12614
  while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12615
         || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12616
         || GET_CODE (count) == TRUNCATE)
12617
    count = XEXP (count, 0);
12618
  inner_mode = GET_MODE (count);
12619
  count = simplify_gen_subreg (outer_mode, count, inner_mode,
12620
                               subreg_lowpart_offset (outer_mode, inner_mode));
12621
  operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12622
                                operands[1], count);
12623
}")
12624
 
12625
(define_insn "ashlv4hi3"
12626
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12627
        (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12628
                     (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12629
  "TARGET_SHMEDIA"
12630
  "mshlld.w     %1, %2, %0"
12631
  [(set_attr "type" "arith_media")
12632
   (set_attr "highpart" "depend")])
12633
 
12634
(define_insn "lshrv2si3"
12635
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12636
        (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12637
                     (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12638
  "TARGET_SHMEDIA"
12639
  "mshlrd.l     %1, %2, %0"
12640
  [(set_attr "type" "arith_media")
12641
   (set_attr "highpart" "depend")])
12642
 
12643
(define_insn "lshrv4hi3"
12644
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12645
        (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12646
                       (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12647
  "TARGET_SHMEDIA"
12648
  "mshlrd.w     %1, %2, %0"
12649
  [(set_attr "type" "arith_media")
12650
   (set_attr "highpart" "depend")])
12651
 
12652
(define_insn "subv2si3"
12653
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12654
        (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12655
                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12656
  "TARGET_SHMEDIA"
12657
  "msub.l       %N1, %2, %0"
12658
  [(set_attr "type" "arith_media")
12659
   (set_attr "highpart" "depend")])
12660
 
12661
(define_insn "subv4hi3"
12662
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12663
        (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12664
                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12665
  "TARGET_SHMEDIA"
12666
  "msub.w       %N1, %2, %0"
12667
  [(set_attr "type" "arith_media")
12668
   (set_attr "highpart" "depend")])
12669
 
12670
(define_insn_and_split "subv2hi3"
12671
  [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12672
        (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12673
                   (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12674
  "TARGET_SHMEDIA"
12675
  "#"
12676
  "TARGET_SHMEDIA"
12677
  [(const_int 0)]
12678
  "
12679
{
12680
  rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12681
  rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12682
  rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12683
  rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12684
  rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12685
 
12686
  emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12687
  emit_insn (gen_truncdisi2 (si_dst, di_dst));
12688
  DONE;
12689
}"
12690
  [(set_attr "highpart" "must_split")])
12691
 
12692
(define_insn "sssubv2si3"
12693
  [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12694
        (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12695
                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12696
  "TARGET_SHMEDIA"
12697
  "msubs.l      %N1, %2, %0"
12698
  [(set_attr "type" "mcmp_media")
12699
   (set_attr "highpart" "depend")])
12700
 
12701
(define_insn "ussubv8qi3"
12702
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12703
        (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12704
                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12705
  "TARGET_SHMEDIA"
12706
  "msubs.ub     %N1, %2, %0"
12707
  [(set_attr "type" "mcmp_media")
12708
   (set_attr "highpart" "depend")])
12709
 
12710
(define_insn "sssubv4hi3"
12711
  [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12712
        (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12713
                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12714
  "TARGET_SHMEDIA"
12715
  "msubs.w      %N1, %2, %0"
12716
  [(set_attr "type" "mcmp_media")
12717
   (set_attr "highpart" "depend")])
12718
 
12719
;; Floating Point Intrinsics
12720
 
12721
(define_insn "fcosa_s"
12722
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12723
        (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12724
                   UNSPEC_FCOSA))]
12725
  "TARGET_SHMEDIA"
12726
  "fcosa.s      %1, %0"
12727
  [(set_attr "type" "atrans_media")])
12728
 
12729
(define_insn "fsina_s"
12730
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12731
        (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12732
                   UNSPEC_FSINA))]
12733
  "TARGET_SHMEDIA"
12734
  "fsina.s      %1, %0"
12735
  [(set_attr "type" "atrans_media")])
12736
 
12737
(define_insn "fipr"
12738
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12739
        (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12740
                                                    "fp_arith_reg_operand" "f")
12741
                                                   (match_operand:V4SF 2
12742
                                                    "fp_arith_reg_operand" "f"))
12743
                                         (parallel [(const_int 0)]))
12744
                          (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12745
                                         (parallel [(const_int 1)])))
12746
                 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12747
                                         (parallel [(const_int 2)]))
12748
                          (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12749
                                         (parallel [(const_int 3)])))))]
12750
  "TARGET_SHMEDIA"
12751
  "fipr.s       %1, %2, %0"
12752
  [(set_attr "type" "fparith_media")])
12753
 
12754
(define_insn "fsrra_s"
12755
  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12756
        (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12757
                   UNSPEC_FSRRA))]
12758
  "TARGET_SHMEDIA"
12759
  "fsrra.s      %1, %0"
12760
  [(set_attr "type" "atrans_media")])
12761
 
12762
(define_insn "ftrv"
12763
  [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12764
        (plus:V4SF
12765
         (plus:V4SF
12766
          (mult:V4SF
12767
           (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12768
                            (parallel [(const_int 0) (const_int 5)
12769
                                       (const_int 10) (const_int 15)]))
12770
           (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12771
          (mult:V4SF
12772
           (vec_select:V4SF (match_dup 1)
12773
                            (parallel [(const_int 4) (const_int 9)
12774
                                       (const_int 14) (const_int 3)]))
12775
           (vec_select:V4SF (match_dup 2)
12776
                            (parallel [(const_int 1) (const_int 2)
12777
                                       (const_int 3) (const_int 0)]))))
12778
         (plus:V4SF
12779
          (mult:V4SF
12780
           (vec_select:V4SF (match_dup 1)
12781
                            (parallel [(const_int 8) (const_int 13)
12782
                                       (const_int 2) (const_int 7)]))
12783
           (vec_select:V4SF (match_dup 2)
12784
                            (parallel [(const_int 2) (const_int 3)
12785
                                       (const_int 0) (const_int 1)])))
12786
          (mult:V4SF
12787
           (vec_select:V4SF (match_dup 1)
12788
                            (parallel [(const_int 12) (const_int 1)
12789
                                       (const_int 6) (const_int 11)]))
12790
           (vec_select:V4SF (match_dup 2)
12791
                            (parallel [(const_int 3) (const_int 0)
12792
                                       (const_int 1) (const_int 2)]))))))]
12793
  "TARGET_SHMEDIA"
12794
  "ftrv.s %1, %2, %0"
12795
  [(set_attr "type" "fparith_media")])
12796
 
12797
(define_insn "ldhi_l"
12798
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12799
        (zero_extract:SI
12800
         (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12801
                                  (const_int 3))
12802
                          (const_int -3)))
12803
         (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12804
         (const_int 0)))]
12805
  "TARGET_SHMEDIA32"
12806
  "ldhi.l       %U1, %0"
12807
  [(set_attr "type" "load_media")])
12808
 
12809
(define_insn "ldhi_q"
12810
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12811
        (zero_extract:DI
12812
         (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12813
                                  (const_int 7))
12814
                          (const_int -7)))
12815
         (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12816
         (const_int 0)))]
12817
  "TARGET_SHMEDIA32"
12818
  "ldhi.q       %U1, %0"
12819
  [(set_attr "type" "load_media")])
12820
 
12821
(define_insn_and_split "*ldhi_q_comb0"
12822
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12823
        (zero_extract:DI
12824
         (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12825
                                            "register_operand" "r")
12826
                                           (match_operand:SI 2
12827
                                            "ua_offset" "I06"))
12828
                                  (const_int 7))
12829
                          (const_int -7)))
12830
         (plus:SI (and:SI (match_dup 1) (const_int 7))
12831
                  (const_int 1))
12832
         (const_int 0)))]
12833
  "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12834
  "#"
12835
  ""
12836
  [(pc)]
12837
  "emit_insn (gen_ldhi_q (operands[0],
12838
                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
12839
   DONE;")
12840
 
12841
 
12842
(define_insn_and_split "*ldhi_q_comb1"
12843
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12844
        (zero_extract:DI
12845
         (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12846
                                            "register_operand" "r")
12847
                                           (match_operand:SI 2
12848
                                            "ua_offset" "I06"))
12849
                                  (const_int 7))
12850
                          (const_int -7)))
12851
         (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12852
                                                   "ua_offset" "I06"))
12853
                          (const_int 7))
12854
                  (const_int 1))
12855
         (const_int 0)))]
12856
  "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12857
   && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12858
  "#"
12859
  ""
12860
  [(pc)]
12861
  "emit_insn (gen_ldhi_q (operands[0],
12862
                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
12863
   DONE;")
12864
 
12865
 
12866
(define_insn "ldlo_l"
12867
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12868
        (zero_extract:SI
12869
         (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12870
                         (const_int -4)))
12871
         (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12872
         (and:SI (match_dup 1) (const_int 3))))]
12873
  "TARGET_SHMEDIA32"
12874
  "ldlo.l       %U1, %0"
12875
  [(set_attr "type" "load_media")])
12876
 
12877
(define_insn "ldlo_q"
12878
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12879
        (zero_extract:DI
12880
         (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12881
                         (const_int -8)))
12882
         (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12883
         (and:SI (match_dup 1) (const_int 7))))]
12884
  "TARGET_SHMEDIA32"
12885
  "ldlo.q       %U1, %0"
12886
  [(set_attr "type" "load_media")])
12887
 
12888
(define_insn_and_split "*ldlo_q_comb0"
12889
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12890
        (zero_extract:DI
12891
         (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12892
                                  (match_operand:SI 2 "ua_offset" "I06"))
12893
                         (const_int -8)))
12894
         (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12895
         (and:SI (match_dup 1) (const_int 7))))]
12896
  "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12897
  "#"
12898
  ""
12899
  [(pc)]
12900
  "emit_insn (gen_ldlo_q (operands[0],
12901
                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
12902
   DONE;")
12903
 
12904
(define_insn_and_split "*ldlo_q_comb1"
12905
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12906
        (zero_extract:DI
12907
         (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12908
                                  (match_operand:SI 2 "ua_offset" "I06"))
12909
                         (const_int -8)))
12910
         (minus:SI (const_int 8)
12911
                   (and:SI (plus:SI (match_dup 1)
12912
                                    (match_operand:SI 3 "ua_offset" "I06"))
12913
                           (const_int 7)))
12914
         (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12915
  "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12916
   && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12917
  "#"
12918
  ""
12919
  [(pc)]
12920
  "emit_insn (gen_ldlo_q (operands[0],
12921
                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
12922
   DONE;")
12923
 
12924
(define_insn "sthi_l"
12925
  [(set (zero_extract:SI
12926
         (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12927
                                  (const_int 3))
12928
                          (const_int -3)))
12929
         (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12930
         (const_int 0))
12931
        (match_operand:SI 1 "arith_reg_operand" "r"))]
12932
  "TARGET_SHMEDIA32"
12933
  "sthi.l       %U0, %1"
12934
  [(set_attr "type" "ustore_media")])
12935
 
12936
;; All unaligned stores are considered to be 'narrow' because they typically
12937
;; operate on less that a quadword, and when they operate on a full quadword,
12938
;; the vanilla store high / store low sequence will cause a stall if not
12939
;; scheduled apart.
12940
(define_insn "sthi_q"
12941
  [(set (zero_extract:DI
12942
         (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12943
                                  (const_int 7))
12944
                          (const_int -7)))
12945
         (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12946
         (const_int 0))
12947
        (match_operand:DI 1 "arith_reg_operand" "r"))]
12948
  "TARGET_SHMEDIA32"
12949
  "sthi.q       %U0, %1"
12950
  [(set_attr "type" "ustore_media")])
12951
 
12952
(define_insn_and_split "*sthi_q_comb0"
12953
  [(set (zero_extract:DI
12954
         (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12955
                                            "register_operand" "r")
12956
                                           (match_operand:SI 1 "ua_offset"
12957
                                            "I06"))
12958
                                  (const_int 7))
12959
                          (const_int -7)))
12960
         (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12961
         (const_int 0))
12962
        (match_operand:DI 2 "arith_reg_operand" "r"))]
12963
  "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12964
  "#"
12965
  ""
12966
  [(pc)]
12967
  "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12968
                          operands[2]));
12969
   DONE;")
12970
 
12971
(define_insn_and_split "*sthi_q_comb1"
12972
  [(set (zero_extract:DI
12973
         (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12974
                                            "register_operand" "r")
12975
                                           (match_operand:SI 1 "ua_offset"
12976
                                            "I06"))
12977
                                  (const_int 7))
12978
                          (const_int -7)))
12979
         (plus:SI (and:SI (plus:SI (match_dup 0)
12980
                                   (match_operand:SI 2 "ua_offset" "I06"))
12981
                          (const_int 7))
12982
                  (const_int 1))
12983
         (const_int 0))
12984
        (match_operand:DI 3 "arith_reg_operand" "r"))]
12985
  "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12986
   && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12987
  "#"
12988
  ""
12989
  [(pc)]
12990
  "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12991
                          operands[3]));
12992
   DONE;")
12993
 
12994
;; This is highpart user because the address is used as full 64 bit.
12995
(define_insn "stlo_l"
12996
  [(set (zero_extract:SI
12997
         (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12998
                         (const_int -4)))
12999
         (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13000
         (and:SI (match_dup 0) (const_int 3)))
13001
        (match_operand:SI 1 "arith_reg_operand" "r"))]
13002
  "TARGET_SHMEDIA32"
13003
  "stlo.l       %U0, %1"
13004
  [(set_attr "type" "ustore_media")])
13005
 
13006
(define_insn "stlo_q"
13007
  [(set (zero_extract:DI
13008
         (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13009
                         (const_int -8)))
13010
         (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13011
         (and:SI (match_dup 0) (const_int 7)))
13012
        (match_operand:DI 1 "arith_reg_operand" "r"))]
13013
  "TARGET_SHMEDIA32"
13014
  "stlo.q       %U0, %1"
13015
  [(set_attr "type" "ustore_media")])
13016
 
13017
(define_insn_and_split "*stlo_q_comb0"
13018
  [(set (zero_extract:DI
13019
         (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13020
                                  (match_operand:SI 1 "ua_offset" "I06"))
13021
                         (const_int -8)))
13022
         (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13023
         (and:SI (match_dup 0) (const_int 7)))
13024
        (match_operand:DI 2 "arith_reg_operand" "r"))]
13025
  "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13026
  "#"
13027
  ""
13028
  [(pc)]
13029
  "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13030
                          operands[2]));
13031
   DONE;")
13032
 
13033
(define_insn_and_split "*stlo_q_comb1"
13034
  [(set (zero_extract:DI
13035
         (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13036
                                  (match_operand:SI 1 "ua_offset" "I06"))
13037
                         (const_int -8)))
13038
         (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13039
                                                  (match_operand:SI 2
13040
                                                   "ua_offset" "I06"))
13041
                                         (const_int 7)))
13042
         (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13043
        (match_operand:DI 3 "arith_reg_operand" "r"))]
13044
  "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13045
  "#"
13046
  ""
13047
  [(pc)]
13048
  "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13049
                          operands[3]));
13050
   DONE;")
13051
 
13052
(define_insn "ldhi_l64"
13053
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13054
        (zero_extract:SI
13055
         (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13056
                                  (const_int 3))
13057
                          (const_int -3)))
13058
         (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13059
         (const_int 0)))]
13060
  "TARGET_SHMEDIA64"
13061
  "ldhi.l       %U1, %0"
13062
  [(set_attr "type" "load_media")])
13063
 
13064
(define_insn "ldhi_q64"
13065
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13066
        (zero_extract:DI
13067
         (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13068
                                  (const_int 7))
13069
                          (const_int -7)))
13070
         (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13071
         (const_int 0)))]
13072
  "TARGET_SHMEDIA64"
13073
  "ldhi.q       %U1, %0"
13074
  [(set_attr "type" "load_media")])
13075
 
13076
(define_insn "ldlo_l64"
13077
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13078
        (zero_extract:SI
13079
         (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13080
                         (const_int -4)))
13081
         (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13082
         (and:DI (match_dup 1) (const_int 3))))]
13083
  "TARGET_SHMEDIA64"
13084
  "ldlo.l       %U1, %0"
13085
  [(set_attr "type" "load_media")])
13086
 
13087
(define_insn "ldlo_q64"
13088
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13089
        (zero_extract:DI
13090
         (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13091
                         (const_int -8)))
13092
         (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13093
         (and:DI (match_dup 1) (const_int 7))))]
13094
  "TARGET_SHMEDIA64"
13095
  "ldlo.q       %U1, %0"
13096
  [(set_attr "type" "load_media")])
13097
 
13098
(define_insn "sthi_l64"
13099
  [(set (zero_extract:SI
13100
         (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13101
                                  (const_int 3))
13102
                          (const_int -3)))
13103
         (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13104
         (const_int 0))
13105
        (match_operand:SI 1 "arith_reg_operand" "r"))]
13106
  "TARGET_SHMEDIA64"
13107
  "sthi.l       %U0, %1"
13108
  [(set_attr "type" "ustore_media")])
13109
 
13110
(define_insn "sthi_q64"
13111
  [(set (zero_extract:DI
13112
         (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13113
                                  (const_int 7))
13114
                          (const_int -7)))
13115
         (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13116
         (const_int 0))
13117
        (match_operand:DI 1 "arith_reg_operand" "r"))]
13118
  "TARGET_SHMEDIA64"
13119
  "sthi.q       %U0, %1"
13120
  [(set_attr "type" "ustore_media")])
13121
 
13122
(define_insn "stlo_l64"
13123
  [(set (zero_extract:SI
13124
         (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13125
                         (const_int -4)))
13126
         (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13127
         (and:DI (match_dup 0) (const_int 3)))
13128
        (match_operand:SI 1 "arith_reg_operand" "r"))]
13129
  "TARGET_SHMEDIA64"
13130
  "stlo.l       %U0, %1"
13131
  [(set_attr "type" "ustore_media")])
13132
 
13133
(define_insn "stlo_q64"
13134
  [(set (zero_extract:DI
13135
         (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13136
                         (const_int -8)))
13137
         (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13138
         (and:DI (match_dup 0) (const_int 7)))
13139
        (match_operand:DI 1 "arith_reg_operand" "r"))]
13140
  "TARGET_SHMEDIA64"
13141
  "stlo.q       %U0, %1"
13142
  [(set_attr "type" "ustore_media")])
13143
 
13144
(define_insn "nsb"
13145
  [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13146
        (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13147
                   UNSPEC_NSB))]
13148
  "TARGET_SHMEDIA"
13149
  "nsb  %1, %0"
13150
  [(set_attr "type" "arith_media")])
13151
 
13152
(define_insn "nsbsi"
13153
  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13154
        (zero_extend:SI
13155
         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13156
                    UNSPEC_NSB)))]
13157
  "TARGET_SHMEDIA"
13158
  "nsb  %1, %0"
13159
  [(set_attr "type" "arith_media")])
13160
 
13161
(define_insn "nsbdi"
13162
  [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13163
        (zero_extend:DI
13164
         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13165
                    UNSPEC_NSB)))]
13166
  "TARGET_SHMEDIA"
13167
  "nsb  %1, %0"
13168
  [(set_attr "type" "arith_media")])
13169
 
13170
(define_expand "ffsdi2"
13171
  [(set (match_operand:DI 0 "arith_reg_dest" "")
13172
        (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13173
  "TARGET_SHMEDIA"
13174
  "
13175
{
13176
  rtx scratch = gen_reg_rtx (DImode);
13177
  rtx last;
13178
 
13179
  emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13180
  emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13181
  emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13182
  emit_insn (gen_nsbdi (scratch, scratch));
13183
  emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13184
  emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13185
  last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13186
  set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13187
 
13188
  DONE;
13189
}")
13190
 
13191
(define_expand "ffssi2"
13192
  [(set (match_operand:SI 0 "arith_reg_dest" "")
13193
        (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13194
  "TARGET_SHMEDIA"
13195
  "
13196
{
13197
  rtx scratch = gen_reg_rtx (SImode);
13198
  rtx discratch = gen_reg_rtx (DImode);
13199
  rtx last;
13200
 
13201
  emit_insn (gen_adddi3 (discratch,
13202
                         simplify_gen_subreg (DImode, operands[1], SImode, 0),
13203
                         constm1_rtx));
13204
  emit_insn (gen_andcdi3 (discratch,
13205
                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13206
                          discratch));
13207
  emit_insn (gen_nsbsi (scratch, discratch));
13208
  last = emit_insn (gen_subsi3 (operands[0],
13209
                                force_reg (SImode, GEN_INT (63)), scratch));
13210
  set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13211
 
13212
  DONE;
13213
}")
13214
 
13215
(define_insn "byterev"
13216
  [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13217
        (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13218
                         (parallel [(const_int 7) (const_int 6) (const_int 5)
13219
                                    (const_int 4) (const_int 3) (const_int 2)
13220
                                    (const_int 1) (const_int 0)])))]
13221
  "TARGET_SHMEDIA"
13222
  "byterev      %1, %0"
13223
  [(set_attr "type" "arith_media")])
13224
 
13225
(define_insn "*prefetch_media"
13226
  [(prefetch (match_operand:QI 0 "address_operand" "p")
13227
             (match_operand:SI 1 "const_int_operand" "n")
13228
             (match_operand:SI 2 "const_int_operand" "n"))]
13229
  "TARGET_SHMEDIA"
13230
  "*
13231
{
13232
  operands[0] = gen_rtx_MEM (QImode, operands[0]);
13233
  output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13234
  return \"\";
13235
}"
13236
  [(set_attr "type" "other")])
13237
 
13238
(define_insn "*prefetch_i4"
13239
  [(prefetch (match_operand:SI 0 "register_operand" "r")
13240
             (match_operand:SI 1 "const_int_operand" "n")
13241
             (match_operand:SI 2 "const_int_operand" "n"))]
13242
  "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13243
  "*
13244
{
13245
  return \"pref @%0\";
13246
}"
13247
  [(set_attr "type" "other")])
13248
 
13249
;; In user mode, the "pref" instruction will raise a RADDERR exception
13250
;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
13251
;; implementation of __builtin_prefetch for VxWorks RTPs.
13252
(define_expand "prefetch"
13253
  [(prefetch (match_operand 0 "address_operand" "p")
13254
             (match_operand:SI 1 "const_int_operand" "n")
13255
             (match_operand:SI 2 "const_int_operand" "n"))]
13256
  "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13257
   && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13258
  "
13259
{
13260
  if (GET_MODE (operands[0]) != Pmode
13261
      || !CONST_INT_P (operands[1])
13262
      || !CONST_INT_P (operands[2]))
13263
    FAIL;
13264
  if (! TARGET_SHMEDIA)
13265
    operands[0] = force_reg (Pmode, operands[0]);
13266
}")
13267
 
13268
(define_insn "prefetch_m2a"
13269
  [(prefetch (match_operand:SI 0 "register_operand" "r")
13270
             (match_operand:SI 1 "const_int_operand" "n")
13271
             (match_operand:SI 2 "const_int_operand" "n"))]
13272
  "TARGET_SH2A"
13273
  "pref\\t@%0"
13274
  [(set_attr "type" "other")])
13275
 
13276
(define_insn "alloco_i"
13277
  [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13278
        (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13279
  "TARGET_SHMEDIA32"
13280
  "*
13281
{
13282
  rtx xops[2];
13283
 
13284
  if (GET_CODE (operands[0]) == PLUS)
13285
    {
13286
      xops[0] = XEXP (operands[0], 0);
13287
      xops[1] = XEXP (operands[0], 1);
13288
    }
13289
  else
13290
    {
13291
      xops[0] = operands[0];
13292
      xops[1] = const0_rtx;
13293
    }
13294
  output_asm_insn (\"alloco   %0, %1\", xops);
13295
  return \"\";
13296
}"
13297
  [(set_attr "type" "other")])
13298
 
13299
(define_split
13300
  [(set (match_operand 0 "any_register_operand" "")
13301
        (match_operand 1 "" ""))]
13302
  "TARGET_SHMEDIA && reload_completed"
13303
  [(set (match_dup 0) (match_dup 1))]
13304
  "
13305
{
13306
  int n_changes = 0;
13307
 
13308
  for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13309
  if (!n_changes)
13310
    FAIL;
13311
}")
13312
 
13313
; Stack Protector Patterns
13314
 
13315
(define_expand "stack_protect_set"
13316
  [(set (match_operand 0 "memory_operand" "")
13317
        (match_operand 1 "memory_operand" ""))]
13318
  ""
13319
{
13320
  if (TARGET_SHMEDIA)
13321
    {
13322
      if (TARGET_SHMEDIA64)
13323
        emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13324
      else
13325
        emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13326
    }
13327
  else
13328
    emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13329
 
13330
  DONE;
13331
})
13332
 
13333
(define_insn "stack_protect_set_si"
13334
  [(set (match_operand:SI 0 "memory_operand" "=m")
13335
        (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13336
   (set (match_scratch:SI 2 "=&r") (const_int 0))]
13337
  "!TARGET_SHMEDIA"
13338
  "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13339
  [(set_attr "type" "other")
13340
   (set_attr "length" "6")])
13341
 
13342
(define_insn "stack_protect_set_si_media"
13343
  [(set (match_operand:SI 0 "memory_operand" "=m")
13344
        (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13345
   (set (match_scratch:SI 2 "=&r") (const_int 0))]
13346
  "TARGET_SHMEDIA"
13347
  "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13348
  [(set_attr "type" "other")
13349
   (set_attr "length" "12")])
13350
 
13351
(define_insn "stack_protect_set_di_media"
13352
  [(set (match_operand:DI 0 "memory_operand" "=m")
13353
        (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13354
   (set (match_scratch:DI 2 "=&r") (const_int 0))]
13355
  "TARGET_SHMEDIA64"
13356
  "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13357
  [(set_attr "type" "other")
13358
   (set_attr "length" "12")])
13359
 
13360
(define_expand "stack_protect_test"
13361
  [(match_operand 0 "memory_operand" "")
13362
   (match_operand 1 "memory_operand" "")
13363
   (match_operand 2 "" "")]
13364
  ""
13365
{
13366
  if (TARGET_SHMEDIA)
13367
    {
13368
      rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13369
      rtx test;
13370
 
13371
      test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13372
      if (TARGET_SHMEDIA64)
13373
        {
13374
          emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13375
                                                      operands[1]));
13376
          emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13377
        }
13378
      else
13379
        {
13380
          emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13381
                                                      operands[1]));
13382
          emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13383
        }
13384
    }
13385
  else
13386
    {
13387
      emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13388
      emit_jump_insn (gen_branch_true (operands[2]));
13389
    }
13390
 
13391
  DONE;
13392
})
13393
 
13394
(define_insn "stack_protect_test_si"
13395
  [(set (reg:SI T_REG)
13396
        (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13397
                    (match_operand:SI 1 "memory_operand" "m")]
13398
                   UNSPEC_SP_TEST))
13399
  (set (match_scratch:SI 2 "=&r") (const_int 0))
13400
  (set (match_scratch:SI 3 "=&r") (const_int 0))]
13401
  "!TARGET_SHMEDIA"
13402
  "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13403
  [(set_attr "type" "other")
13404
   (set_attr "length" "10")])
13405
 
13406
(define_insn "stack_protect_test_si_media"
13407
  [(set (match_operand:SI 0 "register_operand" "=&r")
13408
        (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13409
                    (match_operand:SI 2 "memory_operand" "m")]
13410
                   UNSPEC_SP_TEST))
13411
  (set (match_scratch:SI 3 "=&r") (const_int 0))]
13412
  "TARGET_SHMEDIA"
13413
  "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13414
  [(set_attr "type" "other")
13415
   (set_attr "length" "16")])
13416
 
13417
(define_insn "stack_protect_test_di_media"
13418
  [(set (match_operand:DI 0 "register_operand" "=&r")
13419
        (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13420
                    (match_operand:DI 2 "memory_operand" "m")]
13421
                   UNSPEC_SP_TEST))
13422
  (set (match_scratch:DI 3 "=&r") (const_int 0))]
13423
  "TARGET_SHMEDIA64"
13424
  "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13425
  [(set_attr "type" "other")
13426
   (set_attr "length" "16")])

powered by: WebSVN 2.1.0

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