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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [config/] [v850/] [v850.md] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
;; GCC machine description for NEC V850
2
;; Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2005
3
;; Free Software Foundation, Inc.
4
;; Contributed by Jeff Law (law@cygnus.com).
5
 
6
;; This file is part of GCC.
7
 
8
;; GCC is free software; you can redistribute it and/or modify
9
;; it under the terms of the GNU General Public License as published by
10
;; the Free Software Foundation; either version 2, or (at your option)
11
;; any later version.
12
 
13
;; GCC is distributed in the hope that it will be useful,
14
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
;; GNU General Public License for more details.
17
 
18
;; You should have received a copy of the GNU General Public License
19
;; along with GCC; see the file COPYING.  If not, write to
20
;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21
;; Boston, MA 02110-1301, USA.
22
 
23
;; The original PO technology requires these to be ordered by speed,
24
;; so that assigner will pick the fastest.
25
 
26
;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27
 
28
;; The V851 manual states that the instruction address space is 16M;
29
;; the various branch/call instructions only have a 22bit offset (4M range).
30
;;
31
;; One day we'll probably need to handle calls to targets more than 4M
32
;; away.
33
 
34
;; The size of instructions in bytes.
35
 
36
(define_attr "length" ""
37
  (const_int 4))
38
 
39
(define_attr "long_calls" "yes,no"
40
  (const (if_then_else (symbol_ref "TARGET_LONG_CALLS")
41
                       (const_string "yes")
42
                       (const_string "no"))))
43
 
44
;; Types of instructions (for scheduling purposes).
45
 
46
(define_attr "type" "load,mult,other"
47
  (const_string "other"))
48
 
49
;; Condition code settings.
50
;; none - insn does not affect cc
51
;; none_0hit - insn does not affect cc but it does modify operand 0
52
;;      This attribute is used to keep track of when operand 0 changes.
53
;;      See the description of NOTICE_UPDATE_CC for more info.
54
;; set_znv - sets z,n,v to usable values; c is unknown.
55
;; set_zn  - sets z,n to usable values; v,c is unknown.
56
;; compare - compare instruction
57
;; clobber - value of cc is unknown
58
(define_attr "cc" "none,none_0hit,set_zn,set_znv,compare,clobber"
59
  (const_string "clobber"))
60
 
61
;; Function units for the V850.  As best as I can tell, there's
62
;; a traditional memory load/use stall as well as a stall if
63
;; the result of a multiply is used too early.
64
 
65
(define_insn_reservation "v850_other" 1
66
                         (eq_attr "type" "other")
67
                         "nothing")
68
(define_insn_reservation "v850_mult" 2
69
                         (eq_attr "type" "mult")
70
                         "nothing")
71
(define_insn_reservation "v850_memory" 2
72
                         (eq_attr "type" "load")
73
                         "nothing")
74
 
75
(include "predicates.md")
76
 
77
;; ----------------------------------------------------------------------
78
;; MOVE INSTRUCTIONS
79
;; ----------------------------------------------------------------------
80
 
81
;; movqi
82
 
83
(define_expand "movqi"
84
  [(set (match_operand:QI 0 "general_operand" "")
85
        (match_operand:QI 1 "general_operand" ""))]
86
  ""
87
  "
88
{
89
  /* One of the ops has to be in a register or 0 */
90
  if (!register_operand (operand0, QImode)
91
      && !reg_or_0_operand (operand1, QImode))
92
    operands[1] = copy_to_mode_reg (QImode, operand1);
93
}")
94
 
95
(define_insn "*movqi_internal"
96
  [(set (match_operand:QI 0 "general_operand" "=r,r,r,Q,r,m,m")
97
        (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
98
  "register_operand (operands[0], QImode)
99
   || reg_or_0_operand (operands[1], QImode)"
100
  "* return output_move_single (operands);"
101
  [(set_attr "length" "2,4,2,2,4,4,4")
102
   (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
103
   (set_attr "type" "other,other,load,other,load,other,other")])
104
 
105
;; movhi
106
 
107
(define_expand "movhi"
108
  [(set (match_operand:HI 0 "general_operand" "")
109
        (match_operand:HI 1 "general_operand" ""))]
110
  ""
111
  "
112
{
113
  /* One of the ops has to be in a register or 0 */
114
  if (!register_operand (operand0, HImode)
115
      && !reg_or_0_operand (operand1, HImode))
116
    operands[1] = copy_to_mode_reg (HImode, operand1);
117
}")
118
 
119
(define_insn "*movhi_internal"
120
  [(set (match_operand:HI 0 "general_operand" "=r,r,r,Q,r,m,m")
121
        (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
122
  "register_operand (operands[0], HImode)
123
   || reg_or_0_operand (operands[1], HImode)"
124
  "* return output_move_single (operands);"
125
  [(set_attr "length" "2,4,2,2,4,4,4")
126
   (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
127
   (set_attr "type" "other,other,load,other,load,other,other")])
128
 
129
;; movsi and helpers
130
 
131
(define_insn "*movsi_high"
132
  [(set (match_operand:SI 0 "register_operand" "=r")
133
        (high:SI (match_operand 1 "" "")))]
134
  ""
135
  "movhi hi(%1),%.,%0"
136
  [(set_attr "length" "4")
137
   (set_attr "cc" "none_0hit")
138
   (set_attr "type" "other")])
139
 
140
(define_insn "*movsi_lo"
141
  [(set (match_operand:SI 0 "register_operand" "=r")
142
        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
143
                   (match_operand:SI 2 "immediate_operand" "i")))]
144
  ""
145
  "movea lo(%2),%1,%0"
146
  [(set_attr "length" "4")
147
   (set_attr "cc" "none_0hit")
148
   (set_attr "type" "other")])
149
 
150
(define_expand "movsi"
151
  [(set (match_operand:SI 0 "general_operand" "")
152
        (match_operand:SI 1 "general_operand" ""))]
153
  ""
154
  "
155
{
156
  /* One of the ops has to be in a register or 0 */
157
  if (!register_operand (operand0, SImode)
158
      && !reg_or_0_operand (operand1, SImode))
159
    operands[1] = copy_to_mode_reg (SImode, operand1);
160
 
161
  /* Some constants, as well as symbolic operands
162
     must be done with HIGH & LO_SUM patterns.  */
163
  if (CONSTANT_P (operands[1])
164
      && GET_CODE (operands[1]) != HIGH
165
      && ! TARGET_V850E
166
      && !special_symbolref_operand (operands[1], VOIDmode)
167
      && !(GET_CODE (operands[1]) == CONST_INT
168
           && (CONST_OK_FOR_J (INTVAL (operands[1]))
169
               || CONST_OK_FOR_K (INTVAL (operands[1]))
170
               || CONST_OK_FOR_L (INTVAL (operands[1])))))
171
    {
172
      rtx temp;
173
 
174
      if (reload_in_progress || reload_completed)
175
        temp = operands[0];
176
      else
177
        temp = gen_reg_rtx (SImode);
178
 
179
      emit_insn (gen_rtx_SET (SImode, temp,
180
                              gen_rtx_HIGH (SImode, operand1)));
181
      emit_insn (gen_rtx_SET (SImode, operand0,
182
                              gen_rtx_LO_SUM (SImode, temp, operand1)));
183
      DONE;
184
    }
185
}")
186
 
187
;; This is the same as the following pattern, except that it includes
188
;; support for arbitrary 32 bit immediates.
189
 
190
;; ??? This always loads addresses using hilo.  If the only use of this address
191
;; was in a load/store, then we would get smaller code if we only loaded the
192
;; upper part with hi, and then put the lower part in the load/store insn.
193
 
194
(define_insn "*movsi_internal_v850e"
195
  [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m,r")
196
        (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))]
197
  "TARGET_V850E
198
   && (register_operand (operands[0], SImode)
199
       || reg_or_0_operand (operands[1], SImode))"
200
  "* return output_move_single (operands);"
201
  [(set_attr "length" "2,4,4,2,2,4,4,4,4,6")
202
   (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
203
   (set_attr "type" "other,other,other,load,other,load,other,other,other,other")])
204
 
205
(define_insn "*movsi_internal"
206
  [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m")
207
        (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
208
  "register_operand (operands[0], SImode)
209
   || reg_or_0_operand (operands[1], SImode)"
210
  "* return output_move_single (operands);"
211
  [(set_attr "length" "2,4,4,2,2,4,4,4,4")
212
   (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
213
   (set_attr "type" "other,other,other,load,other,load,other,other,other")])
214
 
215
 
216
 
217
(define_expand "movdi"
218
  [(set (match_operand:DI 0 "general_operand" "")
219
        (match_operand:DI 1 "general_operand" ""))]
220
  ""
221
  "
222
{
223
  /* One of the ops has to be in a register or 0 */
224
  if (!register_operand (operand0, DImode)
225
      && !reg_or_0_operand (operand1, DImode))
226
    operands[1] = copy_to_mode_reg (DImode, operand1);
227
}")
228
 
229
(define_insn "*movdi_internal"
230
  [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,m,r")
231
        (match_operand:DI 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
232
  "register_operand (operands[0], DImode)
233
   || reg_or_0_operand (operands[1], DImode)"
234
  "* return output_move_double (operands);"
235
  [(set_attr "length" "4,8,8,16,8,8,8,16")
236
   (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
237
   (set_attr "type" "other,other,other,other,load,other,other,other")])
238
 
239
(define_expand "movsf"
240
  [(set (match_operand:SF 0 "general_operand" "")
241
        (match_operand:SF 1 "general_operand" ""))]
242
  ""
243
  "
244
{
245
  /* One of the ops has to be in a register or 0 */
246
  if (!register_operand (operand0, SFmode)
247
      && !reg_or_0_operand (operand1, SFmode))
248
    operands[1] = copy_to_mode_reg (SFmode, operand1);
249
}")
250
 
251
(define_insn "*movsf_internal"
252
  [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r")
253
        (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
254
  "register_operand (operands[0], SFmode)
255
   || reg_or_0_operand (operands[1], SFmode)"
256
  "* return output_move_single (operands);"
257
  [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
258
   (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
259
   (set_attr "type" "other,other,other,other,load,other,load,other,other,other")])
260
 
261
(define_expand "movdf"
262
  [(set (match_operand:DF 0 "general_operand" "")
263
        (match_operand:DF 1 "general_operand" ""))]
264
  ""
265
  "
266
{
267
  /* One of the ops has to be in a register or 0 */
268
  if (!register_operand (operand0, DFmode)
269
      && !reg_or_0_operand (operand1, DFmode))
270
    operands[1] = copy_to_mode_reg (DFmode, operand1);
271
}")
272
 
273
(define_insn "*movdf_internal"
274
  [(set (match_operand:DF 0 "general_operand" "=r,r,r,r,r,m,m,r")
275
        (match_operand:DF 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
276
  "register_operand (operands[0], DFmode)
277
   || reg_or_0_operand (operands[1], DFmode)"
278
  "* return output_move_double (operands);"
279
  [(set_attr "length" "4,8,8,16,8,8,8,16")
280
   (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
281
   (set_attr "type" "other,other,other,other,load,other,other,other")])
282
 
283
 
284
;; ----------------------------------------------------------------------
285
;; TEST INSTRUCTIONS
286
;; ----------------------------------------------------------------------
287
 
288
(define_insn "*v850_tst1"
289
  [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
290
                               (const_int 1)
291
                               (match_operand:QI 1 "const_int_operand" "n")))]
292
  ""
293
  "tst1 %1,%0"
294
  [(set_attr "length" "4")
295
   (set_attr "cc" "clobber")])
296
 
297
;; This replaces ld.b;sar;andi with tst1;setf nz.
298
 
299
;; ??? The zero_extract sets the Z bit to the opposite of what one would
300
;; expect.  This perhaps should be wrapped in a (eq: X (const_int 0)).
301
 
302
(define_split
303
  [(set (match_operand:SI 0 "register_operand" "")
304
        (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
305
                         (const_int 1)
306
                         (match_operand 2 "const_int_operand" "")))]
307
  ""
308
  [(set (cc0) (zero_extract:SI (match_dup 1)
309
                               (const_int 1)
310
                               (match_dup 2)))
311
   (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
312
 
313
(define_insn "tstsi"
314
  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
315
  ""
316
  "cmp %.,%0"
317
  [(set_attr "length" "2")
318
   (set_attr "cc" "set_znv")])
319
 
320
(define_insn "cmpsi"
321
  [(set (cc0)
322
        (compare (match_operand:SI 0 "register_operand" "r,r")
323
                 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
324
  ""
325
  "@
326
  cmp %1,%0
327
  cmp %1,%0"
328
  [(set_attr "length" "2,2")
329
   (set_attr "cc" "compare")])
330
 
331
;; ----------------------------------------------------------------------
332
;; ADD INSTRUCTIONS
333
;; ----------------------------------------------------------------------
334
 
335
(define_insn "addsi3"
336
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
337
        (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
338
                 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))]
339
  ""
340
  "@
341
   add %2,%0
342
   addi %2,%1,%0
343
   addi %O2(%P2),%1,%0"
344
  [(set_attr "length" "2,4,4")
345
   (set_attr "cc" "set_zn,set_zn,set_zn")])
346
 
347
;; ----------------------------------------------------------------------
348
;; SUBTRACT INSTRUCTIONS
349
;; ----------------------------------------------------------------------
350
 
351
(define_insn "subsi3"
352
  [(set (match_operand:SI 0 "register_operand" "=r,r")
353
        (minus:SI (match_operand:SI 1 "register_operand" "0,r")
354
                  (match_operand:SI 2 "register_operand" "r,0")))]
355
  ""
356
  "@
357
  sub %2,%0
358
  subr %1,%0"
359
  [(set_attr "length" "2,2")
360
   (set_attr "cc" "set_zn")])
361
 
362
(define_insn "negsi2"
363
  [(set (match_operand:SI 0 "register_operand" "=r")
364
        (neg:SI (match_operand:SI 1 "register_operand" "0")))]
365
  ""
366
  "subr %.,%0"
367
  [(set_attr "length" "2")
368
   (set_attr "cc" "set_zn")])
369
 
370
;; ----------------------------------------------------------------------
371
;; MULTIPLY INSTRUCTIONS
372
;; ----------------------------------------------------------------------
373
 
374
(define_expand "mulhisi3"
375
  [(set (match_operand:SI 0 "register_operand" "")
376
        (mult:SI
377
          (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
378
          (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
379
  ""
380
  "if (GET_CODE (operands[2]) == CONST_INT)
381
     {
382
       emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));
383
       DONE;
384
     }")
385
 
386
(define_insn "*mulhisi3_internal1"
387
  [(set (match_operand:SI 0 "register_operand" "=r")
388
        (mult:SI
389
          (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
390
          (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
391
  ""
392
  "mulh %2,%0"
393
  [(set_attr "length" "2")
394
   (set_attr "cc" "none_0hit")
395
   (set_attr "type" "mult")])
396
 
397
(define_insn "mulhisi3_internal2"
398
  [(set (match_operand:SI 0 "register_operand" "=r,r")
399
        (mult:SI
400
          (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
401
          (match_operand:HI 2 "const_int_operand" "J,K")))]
402
  ""
403
  "@
404
   mulh %2,%0
405
   mulhi %2,%1,%0"
406
  [(set_attr "length" "2,4")
407
   (set_attr "cc" "none_0hit,none_0hit")
408
   (set_attr "type" "mult")])
409
 
410
;; ??? The scheduling info is probably wrong.
411
 
412
;; ??? This instruction can also generate the 32 bit highpart, but using it
413
;; may increase code size counter to the desired result.
414
 
415
;; ??? This instructions can also give a DImode result.
416
 
417
;; ??? There is unsigned version, but it matters only for the DImode/highpart
418
;; results.
419
 
420
(define_insn "mulsi3"
421
  [(set (match_operand:SI 0 "register_operand" "=r")
422
        (mult:SI (match_operand:SI 1 "register_operand" "%0")
423
                 (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
424
  "TARGET_V850E"
425
  "mul %2,%1,%."
426
  [(set_attr "length" "4")
427
   (set_attr "cc" "none_0hit")
428
   (set_attr "type" "mult")])
429
 
430
;; ----------------------------------------------------------------------
431
;; DIVIDE INSTRUCTIONS
432
;; ----------------------------------------------------------------------
433
 
434
;; ??? These insns do set the Z/N condition codes, except that they are based
435
;; on only one of the two results, so it doesn't seem to make sense to use
436
;; them.
437
 
438
;; ??? The scheduling info is probably wrong.
439
 
440
(define_insn "divmodsi4"
441
  [(set (match_operand:SI 0 "register_operand" "=r")
442
        (div:SI (match_operand:SI 1 "register_operand" "0")
443
                (match_operand:SI 2 "register_operand" "r")))
444
   (set (match_operand:SI 3 "register_operand" "=r")
445
        (mod:SI (match_dup 1)
446
                (match_dup 2)))]
447
  "TARGET_V850E"
448
  "div %2,%0,%3"
449
  [(set_attr "length" "4")
450
   (set_attr "cc" "clobber")
451
   (set_attr "type" "other")])
452
 
453
(define_insn "udivmodsi4"
454
  [(set (match_operand:SI 0 "register_operand" "=r")
455
        (udiv:SI (match_operand:SI 1 "register_operand" "0")
456
                 (match_operand:SI 2 "register_operand" "r")))
457
   (set (match_operand:SI 3 "register_operand" "=r")
458
        (umod:SI (match_dup 1)
459
                 (match_dup 2)))]
460
  "TARGET_V850E"
461
  "divu %2,%0,%3"
462
  [(set_attr "length" "4")
463
   (set_attr "cc" "clobber")
464
   (set_attr "type" "other")])
465
 
466
;; ??? There is a 2 byte instruction for generating only the quotient.
467
;; However, it isn't clear how to compute the length field correctly.
468
 
469
(define_insn "divmodhi4"
470
  [(set (match_operand:HI 0 "register_operand" "=r")
471
        (div:HI (match_operand:HI 1 "register_operand" "0")
472
                (match_operand:HI 2 "register_operand" "r")))
473
   (set (match_operand:HI 3 "register_operand" "=r")
474
        (mod:HI (match_dup 1)
475
                (match_dup 2)))]
476
  "TARGET_V850E"
477
  "divh %2,%0,%3"
478
  [(set_attr "length" "4")
479
   (set_attr "cc" "clobber")
480
   (set_attr "type" "other")])
481
 
482
;; Half-words are sign-extended by default, so we must zero extend to a word
483
;; here before doing the divide.
484
 
485
(define_insn "udivmodhi4"
486
  [(set (match_operand:HI 0 "register_operand" "=r")
487
        (udiv:HI (match_operand:HI 1 "register_operand" "0")
488
                 (match_operand:HI 2 "register_operand" "r")))
489
   (set (match_operand:HI 3 "register_operand" "=r")
490
        (umod:HI (match_dup 1)
491
                 (match_dup 2)))]
492
  "TARGET_V850E"
493
  "zxh %0 ; divhu %2,%0,%3"
494
  [(set_attr "length" "4")
495
   (set_attr "cc" "clobber")
496
   (set_attr "type" "other")])
497
 
498
;; ----------------------------------------------------------------------
499
;; AND INSTRUCTIONS
500
;; ----------------------------------------------------------------------
501
 
502
(define_insn "*v850_clr1_1"
503
  [(set (match_operand:QI 0 "memory_operand" "=m")
504
        (subreg:QI
505
          (and:SI (subreg:SI (match_dup 0) 0)
506
                  (match_operand:QI 1 "not_power_of_two_operand" "")) 0))]
507
  ""
508
  "*
509
{
510
  rtx xoperands[2];
511
  xoperands[0] = operands[0];
512
  xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
513
  output_asm_insn (\"clr1 %M1,%0\", xoperands);
514
  return \"\";
515
}"
516
  [(set_attr "length" "4")
517
   (set_attr "cc" "clobber")])
518
 
519
(define_insn "*v850_clr1_2"
520
  [(set (match_operand:HI 0 "indirect_operand" "=m")
521
        (subreg:HI
522
          (and:SI (subreg:SI (match_dup 0) 0)
523
                  (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
524
  ""
525
  "*
526
{
527
  int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
528
 
529
  rtx xoperands[2];
530
  xoperands[0] = gen_rtx_MEM (QImode,
531
                              plus_constant (XEXP (operands[0], 0), log2 / 8));
532
  xoperands[1] = GEN_INT (log2 % 8);
533
  output_asm_insn (\"clr1 %1,%0\", xoperands);
534
  return \"\";
535
}"
536
  [(set_attr "length" "4")
537
   (set_attr "cc" "clobber")])
538
 
539
(define_insn "*v850_clr1_3"
540
  [(set (match_operand:SI 0 "indirect_operand" "=m")
541
        (and:SI (match_dup 0)
542
                (match_operand:SI 1 "not_power_of_two_operand" "")))]
543
  ""
544
  "*
545
{
546
  int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
547
 
548
  rtx xoperands[2];
549
  xoperands[0] = gen_rtx_MEM (QImode,
550
                              plus_constant (XEXP (operands[0], 0), log2 / 8));
551
  xoperands[1] = GEN_INT (log2 % 8);
552
  output_asm_insn (\"clr1 %1,%0\", xoperands);
553
  return \"\";
554
}"
555
  [(set_attr "length" "4")
556
   (set_attr "cc" "clobber")])
557
 
558
(define_insn "andsi3"
559
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
560
        (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
561
                (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
562
  ""
563
  "@
564
  and %2,%0
565
  and %.,%0
566
  andi %2,%1,%0"
567
  [(set_attr "length" "2,2,4")
568
   (set_attr "cc" "set_znv")])
569
 
570
;; ----------------------------------------------------------------------
571
;; OR INSTRUCTIONS
572
;; ----------------------------------------------------------------------
573
 
574
(define_insn "*v850_set1_1"
575
  [(set (match_operand:QI 0 "memory_operand" "=m")
576
        (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
577
                           (match_operand 1 "power_of_two_operand" "")) 0))]
578
  ""
579
  "set1 %M1,%0"
580
  [(set_attr "length" "4")
581
   (set_attr "cc" "clobber")])
582
 
583
(define_insn "*v850_set1_2"
584
  [(set (match_operand:HI 0 "indirect_operand" "=m")
585
        (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
586
                           (match_operand 1 "power_of_two_operand" "")) 0))]
587
  ""
588
  "*
589
{
590
  int log2 = exact_log2 (INTVAL (operands[1]));
591
 
592
  if (log2 < 8)
593
    return \"set1 %M1,%0\";
594
  else
595
    {
596
      rtx xoperands[2];
597
      xoperands[0] = gen_rtx_MEM (QImode,
598
                                  plus_constant (XEXP (operands[0], 0),
599
                                                 log2 / 8));
600
      xoperands[1] = GEN_INT (log2 % 8);
601
      output_asm_insn (\"set1 %1,%0\", xoperands);
602
    }
603
  return \"\";
604
}"
605
  [(set_attr "length" "4")
606
   (set_attr "cc" "clobber")])
607
 
608
(define_insn "*v850_set1_3"
609
  [(set (match_operand:SI 0 "indirect_operand" "=m")
610
        (ior:SI (match_dup 0)
611
                (match_operand 1 "power_of_two_operand" "")))]
612
  ""
613
  "*
614
{
615
  int log2 = exact_log2 (INTVAL (operands[1]));
616
 
617
  if (log2 < 8)
618
    return \"set1 %M1,%0\";
619
  else
620
    {
621
      rtx xoperands[2];
622
      xoperands[0] = gen_rtx_MEM (QImode,
623
                                  plus_constant (XEXP (operands[0], 0),
624
                                                 log2 / 8));
625
      xoperands[1] = GEN_INT (log2 % 8);
626
      output_asm_insn (\"set1 %1,%0\", xoperands);
627
    }
628
  return \"\";
629
}"
630
  [(set_attr "length" "4")
631
   (set_attr "cc" "clobber")])
632
 
633
(define_insn "iorsi3"
634
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
635
        (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
636
                (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
637
  ""
638
  "@
639
  or %2,%0
640
  or %.,%0
641
  ori %2,%1,%0"
642
  [(set_attr "length" "2,2,4")
643
   (set_attr "cc" "set_znv")])
644
 
645
;; ----------------------------------------------------------------------
646
;; XOR INSTRUCTIONS
647
;; ----------------------------------------------------------------------
648
 
649
(define_insn "*v850_not1_1"
650
  [(set (match_operand:QI 0 "memory_operand" "=m")
651
        (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
652
                           (match_operand 1 "power_of_two_operand" "")) 0))]
653
  ""
654
  "not1 %M1,%0"
655
  [(set_attr "length" "4")
656
   (set_attr "cc" "clobber")])
657
 
658
(define_insn "*v850_not1_2"
659
  [(set (match_operand:HI 0 "indirect_operand" "=m")
660
        (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
661
                           (match_operand 1 "power_of_two_operand" "")) 0))]
662
  ""
663
  "*
664
{
665
  int log2 = exact_log2 (INTVAL (operands[1]));
666
 
667
  if (log2 < 8)
668
    return \"not1 %M1,%0\";
669
  else
670
    {
671
      rtx xoperands[2];
672
      xoperands[0] = gen_rtx_MEM (QImode,
673
                                  plus_constant (XEXP (operands[0], 0),
674
                                                 log2 / 8));
675
      xoperands[1] = GEN_INT (log2 % 8);
676
      output_asm_insn (\"not1 %1,%0\", xoperands);
677
    }
678
  return \"\";
679
}"
680
  [(set_attr "length" "4")
681
   (set_attr "cc" "clobber")])
682
 
683
(define_insn "*v850_not1_3"
684
  [(set (match_operand:SI 0 "indirect_operand" "=m")
685
        (xor:SI (match_dup 0)
686
                (match_operand 1 "power_of_two_operand" "")))]
687
  ""
688
  "*
689
{
690
  int log2 = exact_log2 (INTVAL (operands[1]));
691
 
692
  if (log2 < 8)
693
    return \"not1 %M1,%0\";
694
  else
695
    {
696
      rtx xoperands[2];
697
      xoperands[0] = gen_rtx_MEM (QImode,
698
                                  plus_constant (XEXP (operands[0], 0),
699
                                                 log2 / 8));
700
      xoperands[1] = GEN_INT (log2 % 8);
701
      output_asm_insn (\"not1 %1,%0\", xoperands);
702
    }
703
  return \"\";
704
}"
705
  [(set_attr "length" "4")
706
   (set_attr "cc" "clobber")])
707
 
708
(define_insn "xorsi3"
709
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
710
        (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
711
                (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
712
  ""
713
  "@
714
  xor %2,%0
715
  xor %.,%0
716
  xori %2,%1,%0"
717
  [(set_attr "length" "2,2,4")
718
   (set_attr "cc" "set_znv")])
719
 
720
;; ----------------------------------------------------------------------
721
;; NOT INSTRUCTIONS
722
;; ----------------------------------------------------------------------
723
 
724
(define_insn "one_cmplsi2"
725
  [(set (match_operand:SI 0 "register_operand" "=r")
726
        (not:SI (match_operand:SI 1 "register_operand" "r")))]
727
  ""
728
  "not %1,%0"
729
  [(set_attr "length" "2")
730
   (set_attr "cc" "set_znv")])
731
 
732
;; -----------------------------------------------------------------
733
;; BIT FIELDS
734
;; -----------------------------------------------------------------
735
 
736
;; ??? Is it worth defining insv and extv for the V850 series?!?
737
 
738
;; An insv pattern would be useful, but does not get used because
739
;; store_bit_field never calls insv when storing a constant value into a
740
;; single-bit bitfield.
741
 
742
;; extv/extzv patterns would be useful, but do not get used because
743
;; optimize_bitfield_compare in fold-const usually converts single
744
;; bit extracts into an AND with a mask.
745
 
746
;; -----------------------------------------------------------------
747
;; Scc INSTRUCTIONS
748
;; -----------------------------------------------------------------
749
 
750
(define_insn "sle"
751
  [(set (match_operand:SI 0 "register_operand" "=r")
752
        (le:SI (cc0) (const_int 0)))]
753
  ""
754
  "*
755
{
756
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
757
    return 0;
758
 
759
  return \"setf le,%0\";
760
}"
761
  [(set_attr "length" "4")
762
   (set_attr "cc" "none_0hit")])
763
 
764
(define_insn "sleu"
765
  [(set (match_operand:SI 0 "register_operand" "=r")
766
        (leu:SI (cc0) (const_int 0)))]
767
  ""
768
  "setf nh,%0"
769
  [(set_attr "length" "4")
770
   (set_attr "cc" "none_0hit")])
771
 
772
(define_insn "sge"
773
  [(set (match_operand:SI 0 "register_operand" "=r")
774
        (ge:SI (cc0) (const_int 0)))]
775
  ""
776
  "*
777
{
778
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
779
    return 0;
780
 
781
  return \"setf ge,%0\";
782
}"
783
  [(set_attr "length" "4")
784
   (set_attr "cc" "none_0hit")])
785
 
786
(define_insn "sgeu"
787
  [(set (match_operand:SI 0 "register_operand" "=r")
788
        (geu:SI (cc0) (const_int 0)))]
789
  ""
790
  "setf nl,%0"
791
  [(set_attr "length" "4")
792
   (set_attr "cc" "none_0hit")])
793
 
794
(define_insn "slt"
795
  [(set (match_operand:SI 0 "register_operand" "=r")
796
        (lt:SI (cc0) (const_int 0)))]
797
  ""
798
  "*
799
{
800
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
801
    return 0;
802
 
803
  return \"setf lt,%0\";
804
}"
805
  [(set_attr "length" "4")
806
   (set_attr "cc" "none_0hit")])
807
 
808
(define_insn "sltu"
809
  [(set (match_operand:SI 0 "register_operand" "=r")
810
        (ltu:SI (cc0) (const_int 0)))]
811
  ""
812
  "setf l,%0"
813
  [(set_attr "length" "4")
814
   (set_attr "cc" "none_0hit")])
815
 
816
(define_insn "sgt"
817
  [(set (match_operand:SI 0 "register_operand" "=r")
818
        (gt:SI (cc0) (const_int 0)))]
819
  ""
820
  "*
821
{
822
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
823
    return 0;
824
 
825
  return \"setf gt,%0\";
826
}"
827
  [(set_attr "length" "4")
828
   (set_attr "cc" "none_0hit")])
829
 
830
(define_insn "sgtu"
831
  [(set (match_operand:SI 0 "register_operand" "=r")
832
        (gtu:SI (cc0) (const_int 0)))]
833
  ""
834
  "setf h,%0"
835
  [(set_attr "length" "4")
836
   (set_attr "cc" "none_0hit")])
837
 
838
(define_insn "seq"
839
  [(set (match_operand:SI 0 "register_operand" "=r")
840
        (eq:SI (cc0) (const_int 0)))]
841
  ""
842
  "setf z,%0"
843
  [(set_attr "length" "4")
844
   (set_attr "cc" "none_0hit")])
845
 
846
(define_insn "sne"
847
  [(set (match_operand:SI 0 "register_operand" "=r")
848
        (ne:SI (cc0) (const_int 0)))]
849
  ""
850
  "setf nz,%0"
851
  [(set_attr "length" "4")
852
   (set_attr "cc" "none_0hit")])
853
 
854
;; ----------------------------------------------------------------------
855
;; CONDITIONAL MOVE INSTRUCTIONS
856
;; ----------------------------------------------------------------------
857
 
858
;; Instructions using cc0 aren't allowed to have input reloads, so we must
859
;; hide the fact that this instruction uses cc0.  We do so by including the
860
;; compare instruction inside it.
861
 
862
;; ??? This is very ugly.  The right way to do this is to modify cmpsi so
863
;; that it doesn't emit RTL, and then modify the bcc/scc patterns so that
864
;; they emit RTL for the compare instruction.  Unfortunately, this requires
865
;; lots of changes that will be hard to sanitize.  So for now, cmpsi still
866
;; emits RTL, and I get the compare operands here from the previous insn.
867
 
868
(define_expand "movsicc"
869
  [(set (match_operand:SI 0 "register_operand" "=r")
870
        (if_then_else:SI
871
         (match_operator 1 "comparison_operator"
872
                         [(match_dup 4) (match_dup 5)])
873
         (match_operand:SI 2 "reg_or_const_operand" "rJ")
874
         (match_operand:SI 3 "reg_or_const_operand" "rI")))]
875
  "TARGET_V850E"
876
  "
877
{
878
  rtx insn = get_last_insn_anywhere ();
879
  rtx src;
880
 
881
  if (   (GET_CODE (operands[2]) == CONST_INT
882
       && GET_CODE (operands[3]) == CONST_INT))
883
    {
884
      int o2 = INTVAL (operands[2]);
885
      int o3 = INTVAL (operands[3]);
886
 
887
      if (o2 == 1 && o3 == 0)
888
        FAIL;   /* setf */
889
      if (o3 == 1 && o2 == 0)
890
        FAIL;   /* setf */
891
      if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
892
        FAIL;   /* setf + shift */
893
      if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
894
        FAIL;   /* setf + shift */
895
      if (o2 != 0)
896
        operands[2] = copy_to_mode_reg (SImode, operands[2]);
897
      if (o3 !=0 )
898
        operands[3] = copy_to_mode_reg (SImode, operands[3]);
899
    }
900
  else
901
    {
902
      if (GET_CODE (operands[2]) != REG)
903
        operands[2] = copy_to_mode_reg (SImode,operands[2]);
904
      if (GET_CODE (operands[3]) != REG)
905
        operands[3] = copy_to_mode_reg (SImode, operands[3]);
906
    }
907
  gcc_assert (GET_CODE (insn) == INSN
908
              && GET_CODE (PATTERN (insn)) == SET
909
              && SET_DEST (PATTERN (insn)) == cc0_rtx);
910
 
911
  src = SET_SRC (PATTERN (insn));
912
 
913
  switch (GET_CODE (src))
914
    {
915
    case COMPARE:
916
      operands[4] = XEXP (src, 0);
917
      operands[5] = XEXP (src, 1);
918
      break;
919
 
920
    case REG:
921
    case SUBREG:
922
      operands[4] = src;
923
      operands[5] = const0_rtx;
924
      break;
925
 
926
    default:
927
      gcc_unreachable ();
928
    }
929
}")
930
 
931
;; ??? Clobbering the condition codes is overkill.
932
 
933
;; ??? We sometimes emit an unnecessary compare instruction because the
934
;; condition codes may have already been set by an earlier instruction,
935
;; but we have no code here to avoid the compare if it is unnecessary.
936
 
937
(define_insn "*movsicc_normal"
938
  [(set (match_operand:SI 0 "register_operand" "=r")
939
        (if_then_else:SI
940
         (match_operator 1 "comparison_operator"
941
                         [(match_operand:SI 4 "register_operand" "r")
942
                          (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
943
         (match_operand:SI 2 "reg_or_int5_operand" "rJ")
944
         (match_operand:SI 3 "reg_or_0_operand" "rI")))]
945
  "TARGET_V850E"
946
  "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
947
  [(set_attr "length" "6")
948
   (set_attr "cc" "clobber")])
949
 
950
(define_insn "*movsicc_reversed"
951
  [(set (match_operand:SI 0 "register_operand" "=r")
952
        (if_then_else:SI
953
         (match_operator 1 "comparison_operator"
954
                         [(match_operand:SI 4 "register_operand" "r")
955
                          (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
956
         (match_operand:SI 2 "reg_or_0_operand" "rI")
957
         (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
958
  "TARGET_V850E"
959
  "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
960
  [(set_attr "length" "6")
961
   (set_attr "cc" "clobber")])
962
 
963
(define_insn "*movsicc_tst1"
964
  [(set (match_operand:SI 0 "register_operand" "=r")
965
        (if_then_else:SI
966
         (match_operator 1 "comparison_operator"
967
                         [(zero_extract:SI
968
                           (match_operand:QI 2 "memory_operand" "m")
969
                           (const_int 1)
970
                           (match_operand 3 "const_int_operand" "n"))
971
                          (const_int 0)])
972
         (match_operand:SI 4 "reg_or_int5_operand" "rJ")
973
         (match_operand:SI 5 "reg_or_0_operand" "rI")))]
974
  "TARGET_V850E"
975
  "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
976
  [(set_attr "length" "8")
977
   (set_attr "cc" "clobber")])
978
 
979
(define_insn "*movsicc_tst1_reversed"
980
  [(set (match_operand:SI 0 "register_operand" "=r")
981
        (if_then_else:SI
982
         (match_operator 1 "comparison_operator"
983
                         [(zero_extract:SI
984
                           (match_operand:QI 2 "memory_operand" "m")
985
                           (const_int 1)
986
                           (match_operand 3 "const_int_operand" "n"))
987
                          (const_int 0)])
988
         (match_operand:SI 4 "reg_or_0_operand" "rI")
989
         (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
990
  "TARGET_V850E"
991
  "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
992
  [(set_attr "length" "8")
993
   (set_attr "cc" "clobber")])
994
 
995
;; Matching for sasf requires combining 4 instructions, so we provide a
996
;; dummy pattern to match the first 3, which will always be turned into the
997
;; second pattern by subsequent combining.  As above, we must include the
998
;; comparison to avoid input reloads in an insn using cc0.
999
 
1000
(define_insn "*sasf_1"
1001
  [(set (match_operand:SI 0 "register_operand" "")
1002
        (ior:SI (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
1003
                (ashift:SI (match_operand:SI 2 "register_operand" "")
1004
                           (const_int 1))))]
1005
  "TARGET_V850E"
1006
  "* gcc_unreachable ();")
1007
 
1008
(define_insn "*sasf_2"
1009
  [(set (match_operand:SI 0 "register_operand" "=r")
1010
        (ior:SI
1011
         (match_operator 1 "comparison_operator"
1012
                         [(match_operand:SI 3 "register_operand" "r")
1013
                          (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
1014
         (ashift:SI (match_operand:SI 2 "register_operand" "0")
1015
                    (const_int 1))))]
1016
  "TARGET_V850E"
1017
  "cmp %4,%3 ; sasf %c1,%0"
1018
  [(set_attr "length" "6")
1019
   (set_attr "cc" "clobber")])
1020
 
1021
(define_split
1022
  [(set (match_operand:SI 0 "register_operand" "")
1023
        (if_then_else:SI
1024
         (match_operator 1 "comparison_operator"
1025
                         [(match_operand:SI 4 "register_operand" "")
1026
                          (match_operand:SI 5 "reg_or_int5_operand" "")])
1027
         (match_operand:SI 2 "const_int_operand" "")
1028
         (match_operand:SI 3 "const_int_operand" "")))]
1029
  "TARGET_V850E
1030
   && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
1031
   && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
1032
   && (GET_CODE (operands[5]) == CONST_INT
1033
      || REGNO (operands[0]) != REGNO (operands[5]))
1034
   && REGNO (operands[0]) != REGNO (operands[4])"
1035
  [(set (match_dup 0) (match_dup 6))
1036
   (set (match_dup 0)
1037
        (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
1038
                (ashift:SI (match_dup 0) (const_int 1))))]
1039
  "
1040
{
1041
  operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
1042
  if (INTVAL (operands[2]) & 0x1)
1043
    operands[7] = operands[1];
1044
  else
1045
    operands[7] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
1046
                                  GET_MODE (operands[1]),
1047
                                  XEXP (operands[1], 0), XEXP (operands[1], 1));
1048
}")
1049
;; ---------------------------------------------------------------------
1050
;; BYTE SWAP INSTRUCTIONS
1051
;; ---------------------------------------------------------------------
1052
 
1053
(define_expand "rotlhi3"
1054
  [(set (match_operand:HI 0 "register_operand" "")
1055
        (rotate:HI (match_operand:HI 1 "register_operand" "")
1056
                   (match_operand:HI 2 "const_int_operand" "")))]
1057
  "TARGET_V850E"
1058
  "
1059
{
1060
  if (INTVAL (operands[2]) != 8)
1061
    FAIL;
1062
}")
1063
 
1064
(define_insn "*rotlhi3_8"
1065
  [(set (match_operand:HI 0 "register_operand" "=r")
1066
        (rotate:HI (match_operand:HI 1 "register_operand" "r")
1067
                   (const_int 8)))]
1068
  "TARGET_V850E"
1069
  "bsh %1,%0"
1070
  [(set_attr "length" "4")
1071
   (set_attr "cc" "clobber")])
1072
 
1073
(define_expand "rotlsi3"
1074
  [(set (match_operand:SI 0 "register_operand" "")
1075
        (rotate:SI (match_operand:SI 1 "register_operand" "")
1076
                   (match_operand:SI 2 "const_int_operand" "")))]
1077
  "TARGET_V850E"
1078
  "
1079
{
1080
  if (INTVAL (operands[2]) != 16)
1081
    FAIL;
1082
}")
1083
 
1084
(define_insn "*rotlsi3_16"
1085
  [(set (match_operand:SI 0 "register_operand" "=r")
1086
        (rotate:SI (match_operand:SI 1 "register_operand" "r")
1087
                   (const_int 16)))]
1088
  "TARGET_V850E"
1089
  "hsw %1,%0"
1090
  [(set_attr "length" "4")
1091
   (set_attr "cc" "clobber")])
1092
 
1093
;; ----------------------------------------------------------------------
1094
;; JUMP INSTRUCTIONS
1095
;; ----------------------------------------------------------------------
1096
 
1097
;; Conditional jump instructions
1098
 
1099
(define_expand "ble"
1100
  [(set (pc)
1101
        (if_then_else (le (cc0)
1102
                          (const_int 0))
1103
                      (label_ref (match_operand 0 "" ""))
1104
                      (pc)))]
1105
  ""
1106
  "")
1107
 
1108
(define_expand "bleu"
1109
  [(set (pc)
1110
        (if_then_else (leu (cc0)
1111
                           (const_int 0))
1112
                      (label_ref (match_operand 0 "" ""))
1113
                      (pc)))]
1114
  ""
1115
  "")
1116
 
1117
(define_expand "bge"
1118
  [(set (pc)
1119
        (if_then_else (ge (cc0)
1120
                          (const_int 0))
1121
                      (label_ref (match_operand 0 "" ""))
1122
                      (pc)))]
1123
  ""
1124
  "")
1125
 
1126
(define_expand "bgeu"
1127
  [(set (pc)
1128
        (if_then_else (geu (cc0)
1129
                           (const_int 0))
1130
                      (label_ref (match_operand 0 "" ""))
1131
                      (pc)))]
1132
  ""
1133
  "")
1134
 
1135
(define_expand "blt"
1136
  [(set (pc)
1137
        (if_then_else (lt (cc0)
1138
                          (const_int 0))
1139
                      (label_ref (match_operand 0 "" ""))
1140
                      (pc)))]
1141
  ""
1142
  "")
1143
 
1144
(define_expand "bltu"
1145
  [(set (pc)
1146
        (if_then_else (ltu (cc0)
1147
                           (const_int 0))
1148
                      (label_ref (match_operand 0 "" ""))
1149
                      (pc)))]
1150
  ""
1151
  "")
1152
 
1153
(define_expand "bgt"
1154
  [(set (pc)
1155
        (if_then_else (gt (cc0)
1156
                          (const_int 0))
1157
                      (label_ref (match_operand 0 "" ""))
1158
                      (pc)))]
1159
  ""
1160
  "")
1161
 
1162
(define_expand "bgtu"
1163
  [(set (pc)
1164
        (if_then_else (gtu (cc0)
1165
                           (const_int 0))
1166
                      (label_ref (match_operand 0 "" ""))
1167
                      (pc)))]
1168
  ""
1169
  "")
1170
 
1171
(define_expand "beq"
1172
  [(set (pc)
1173
        (if_then_else (eq (cc0)
1174
                          (const_int 0))
1175
                      (label_ref (match_operand 0 "" ""))
1176
                      (pc)))]
1177
  ""
1178
  "")
1179
 
1180
(define_expand "bne"
1181
  [(set (pc)
1182
        (if_then_else (ne (cc0)
1183
                          (const_int 0))
1184
                      (label_ref (match_operand 0 "" ""))
1185
                      (pc)))]
1186
  ""
1187
  "")
1188
 
1189
(define_insn "*branch_normal"
1190
  [(set (pc)
1191
        (if_then_else (match_operator 1 "comparison_operator"
1192
                                      [(cc0) (const_int 0)])
1193
                      (label_ref (match_operand 0 "" ""))
1194
                      (pc)))]
1195
  ""
1196
  "*
1197
{
1198
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1199
      && (GET_CODE (operands[1]) == GT
1200
          || GET_CODE (operands[1]) == GE
1201
          || GET_CODE (operands[1]) == LE
1202
          || GET_CODE (operands[1]) == LT))
1203
    return 0;
1204
 
1205
  if (get_attr_length (insn) == 2)
1206
    return \"b%b1 %l0\";
1207
  else
1208
    return \"b%B1 .+6 ; jr %l0\";
1209
}"
1210
 [(set (attr "length")
1211
    (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1212
                      (const_int 256))
1213
                  (const_int 2)
1214
                  (const_int 6)))
1215
  (set_attr "cc" "none")])
1216
 
1217
(define_insn "*branch_invert"
1218
  [(set (pc)
1219
        (if_then_else (match_operator 1 "comparison_operator"
1220
                                      [(cc0) (const_int 0)])
1221
                      (pc)
1222
                      (label_ref (match_operand 0 "" ""))))]
1223
  ""
1224
  "*
1225
{
1226
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1227
      && (GET_CODE (operands[1]) == GT
1228
          || GET_CODE (operands[1]) == GE
1229
          || GET_CODE (operands[1]) == LE
1230
          || GET_CODE (operands[1]) == LT))
1231
    return 0;
1232
  if (get_attr_length (insn) == 2)
1233
    return \"b%B1 %l0\";
1234
  else
1235
    return \"b%b1 .+6 ; jr %l0\";
1236
}"
1237
 [(set (attr "length")
1238
    (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1239
                      (const_int 256))
1240
                  (const_int 2)
1241
                  (const_int 6)))
1242
  (set_attr "cc" "none")])
1243
 
1244
;; Unconditional and other jump instructions.
1245
 
1246
(define_insn "jump"
1247
  [(set (pc)
1248
        (label_ref (match_operand 0 "" "")))]
1249
  ""
1250
  "*
1251
{
1252
  if (get_attr_length (insn) == 2)
1253
    return \"br %0\";
1254
  else
1255
    return \"jr %0\";
1256
}"
1257
 [(set (attr "length")
1258
    (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1259
                      (const_int 256))
1260
                  (const_int 2)
1261
                  (const_int 4)))
1262
  (set_attr "cc" "none")])
1263
 
1264
(define_insn "indirect_jump"
1265
  [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1266
  ""
1267
  "jmp %0"
1268
  [(set_attr "length" "2")
1269
   (set_attr "cc" "none")])
1270
 
1271
(define_insn "tablejump"
1272
  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1273
   (use (label_ref (match_operand 1 "" "")))]
1274
  ""
1275
  "jmp  %0"
1276
  [(set_attr "length" "2")
1277
   (set_attr "cc" "none")])
1278
 
1279
(define_insn "switch"
1280
  [(set (pc)
1281
        (plus:SI
1282
         (sign_extend:SI
1283
          (mem:HI
1284
           (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1285
                               (const_int 1))
1286
                    (label_ref (match_operand 1 "" "")))))
1287
         (label_ref (match_dup 1))))]
1288
  "TARGET_V850E"
1289
  "switch %0"
1290
  [(set_attr "length" "2")
1291
   (set_attr "cc" "none")])
1292
 
1293
(define_expand "casesi"
1294
  [(match_operand:SI 0 "register_operand" "")
1295
   (match_operand:SI 1 "register_operand" "")
1296
   (match_operand:SI 2 "register_operand" "")
1297
   (match_operand 3 "" "") (match_operand 4 "" "")]
1298
  ""
1299
  "
1300
{
1301
  rtx reg = gen_reg_rtx (SImode);
1302
  rtx tableaddress = gen_reg_rtx (SImode);
1303
  rtx mem;
1304
 
1305
  /* Subtract the lower bound from the index.  */
1306
  emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1307
  /* Compare the result against the number of table entries.  */
1308
  emit_insn (gen_cmpsi (reg, operands[2]));
1309
  /* Branch to the default label if out of range of the table.  */
1310
  emit_jump_insn (gen_bgtu (operands[4]));
1311
 
1312
  /* Disabled because the switch pattern is not being recognized
1313
     properly at the moment.  eg. compiling vfscanf.c in newlib.  */
1314
  if (0 && ! TARGET_BIG_SWITCH && TARGET_V850E)
1315
    {
1316
      emit_jump_insn (gen_switch (reg, operands[3]));
1317
      DONE;
1318
    }
1319
 
1320
  /* Shift index for the table array access.  */
1321
  emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1322
  /* Load the table address into a pseudo.  */
1323
  emit_insn (gen_movsi (tableaddress,
1324
                        gen_rtx_LABEL_REF (Pmode, operands[3])));
1325
  /* Add the table address to the index.  */
1326
  emit_insn (gen_addsi3 (reg, reg, tableaddress));
1327
  /* Load the table entry.  */
1328
  mem = gen_const_mem (CASE_VECTOR_MODE, reg);
1329
  if (! TARGET_BIG_SWITCH)
1330
    {
1331
      rtx reg2 = gen_reg_rtx (HImode);
1332
      emit_insn (gen_movhi (reg2, mem));
1333
      emit_insn (gen_extendhisi2 (reg, reg2));
1334
    }
1335
  else
1336
    emit_insn (gen_movsi (reg, mem));
1337
  /* Add the table address.  */
1338
  emit_insn (gen_addsi3 (reg, reg, tableaddress));
1339
  /* Branch to the switch label.  */
1340
  emit_jump_insn (gen_tablejump (reg, operands[3]));
1341
  DONE;
1342
}")
1343
 
1344
;; Call subroutine with no return value.
1345
 
1346
(define_expand "call"
1347
  [(call (match_operand:QI 0 "general_operand" "")
1348
         (match_operand:SI 1 "general_operand" ""))]
1349
  ""
1350
  "
1351
{
1352
  if (! call_address_operand (XEXP (operands[0], 0), QImode)
1353
      || TARGET_LONG_CALLS)
1354
    XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1355
  if (TARGET_LONG_CALLS)
1356
    emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1357
  else
1358
    emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1359
 
1360
  DONE;
1361
}")
1362
 
1363
(define_insn "call_internal_short"
1364
  [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1365
         (match_operand:SI 1 "general_operand" "g,g"))
1366
   (clobber (reg:SI 31))]
1367
  "! TARGET_LONG_CALLS"
1368
  "@
1369
  jarl %0,r31
1370
  jarl .+4,r31 ; add 4,r31 ; jmp %0"
1371
  [(set_attr "length" "4,8")]
1372
)
1373
 
1374
(define_insn "call_internal_long"
1375
  [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1376
         (match_operand:SI 1 "general_operand" "g,g"))
1377
   (clobber (reg:SI 31))]
1378
  "TARGET_LONG_CALLS"
1379
  "*
1380
  {
1381
  if (which_alternative == 0)
1382
    {
1383
      if (GET_CODE (operands[0]) == REG)
1384
        return \"jarl %0,r31\";
1385
      else
1386
        return \"movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11\";
1387
    }
1388
  else
1389
    return \"jarl .+4,r31 ; add 4,r31 ; jmp %0\";
1390
  }"
1391
  [(set_attr "length" "16,8")]
1392
)
1393
 
1394
;; Call subroutine, returning value in operand 0
1395
;; (which must be a hard register).
1396
 
1397
(define_expand "call_value"
1398
  [(set (match_operand 0 "" "")
1399
        (call (match_operand:QI 1 "general_operand" "")
1400
              (match_operand:SI 2 "general_operand" "")))]
1401
  ""
1402
  "
1403
{
1404
  if (! call_address_operand (XEXP (operands[1], 0), QImode)
1405
      || TARGET_LONG_CALLS)
1406
    XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1407
  if (TARGET_LONG_CALLS)
1408
    emit_call_insn (gen_call_value_internal_long (operands[0],
1409
                                                  XEXP (operands[1], 0),
1410
                                                  operands[2]));
1411
  else
1412
    emit_call_insn (gen_call_value_internal_short (operands[0],
1413
                                                   XEXP (operands[1], 0),
1414
                                                   operands[2]));
1415
  DONE;
1416
}")
1417
 
1418
(define_insn "call_value_internal_short"
1419
  [(set (match_operand 0 "" "=r,r")
1420
        (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1421
              (match_operand:SI 2 "general_operand" "g,g")))
1422
   (clobber (reg:SI 31))]
1423
  "! TARGET_LONG_CALLS"
1424
  "@
1425
  jarl %1,r31
1426
  jarl .+4,r31 ; add 4,r31 ; jmp %1"
1427
  [(set_attr "length" "4,8")]
1428
)
1429
 
1430
(define_insn "call_value_internal_long"
1431
  [(set (match_operand 0 "" "=r,r")
1432
        (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1433
              (match_operand:SI 2 "general_operand" "g,g")))
1434
   (clobber (reg:SI 31))]
1435
  "TARGET_LONG_CALLS"
1436
  "*
1437
  {
1438
  if (which_alternative == 0)
1439
    {
1440
      if (GET_CODE (operands[1]) == REG)
1441
        return \"jarl %1, r31\";
1442
      else
1443
      /* Reload can generate this pattern....  */
1444
        return \"movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11\";
1445
    }
1446
  else
1447
    return \"jarl .+4, r31 ; add 4, r31 ; jmp %1\";
1448
  }"
1449
  [(set_attr "length" "16,8")]
1450
)
1451
 
1452
(define_insn "nop"
1453
  [(const_int 0)]
1454
  ""
1455
  "nop"
1456
  [(set_attr "length" "2")
1457
   (set_attr "cc" "none")])
1458
 
1459
;; ----------------------------------------------------------------------
1460
;; EXTEND INSTRUCTIONS
1461
;; ----------------------------------------------------------------------
1462
 
1463
(define_insn ""
1464
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1465
        (zero_extend:SI
1466
         (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))]
1467
  "TARGET_V850E"
1468
  "@
1469
   zxh %0
1470
   andi 65535,%1,%0
1471
   sld.hu %1,%0
1472
   ld.hu %1,%0"
1473
  [(set_attr "length" "2,4,2,4")
1474
   (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
1475
 
1476
(define_insn "zero_extendhisi2"
1477
  [(set (match_operand:SI 0 "register_operand" "=r")
1478
        (zero_extend:SI
1479
         (match_operand:HI 1 "register_operand" "r")))]
1480
  ""
1481
  "andi 65535,%1,%0"
1482
  [(set_attr "length" "4")
1483
   (set_attr "cc" "set_znv")])
1484
 
1485
(define_insn ""
1486
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1487
        (zero_extend:SI
1488
         (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))]
1489
  "TARGET_V850E"
1490
  "@
1491
   zxb %0
1492
   andi 255,%1,%0
1493
   sld.bu %1,%0
1494
   ld.bu %1,%0"
1495
  [(set_attr "length" "2,4,2,4")
1496
   (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
1497
 
1498
(define_insn "zero_extendqisi2"
1499
  [(set (match_operand:SI 0 "register_operand" "=r")
1500
        (zero_extend:SI
1501
         (match_operand:QI 1 "register_operand" "r")))]
1502
  ""
1503
  "andi 255,%1,%0"
1504
  [(set_attr "length" "4")
1505
   (set_attr "cc" "set_znv")])
1506
 
1507
;;- sign extension instructions
1508
 
1509
;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1510
 
1511
(define_insn "*extendhisi_insn"
1512
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1513
        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))]
1514
  "TARGET_V850E"
1515
  "@
1516
   sxh %0
1517
   sld.h %1,%0
1518
   ld.h %1,%0"
1519
  [(set_attr "length" "2,2,4")
1520
   (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1521
 
1522
;; ??? This is missing a sign extend from memory pattern to match the ld.h
1523
;; instruction.
1524
 
1525
(define_expand "extendhisi2"
1526
  [(set (match_dup 2)
1527
        (ashift:SI (match_operand:HI 1 "register_operand" "")
1528
                   (const_int 16)))
1529
   (set (match_operand:SI 0 "register_operand" "")
1530
       (ashiftrt:SI (match_dup 2)
1531
                     (const_int 16)))]
1532
  ""
1533
  "
1534
{
1535
  operands[1] = gen_lowpart (SImode, operands[1]);
1536
  operands[2] = gen_reg_rtx (SImode);
1537
}")
1538
 
1539
;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1540
 
1541
(define_insn "*extendqisi_insn"
1542
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1543
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))]
1544
  "TARGET_V850E"
1545
  "@
1546
   sxb %0
1547
   sld.b %1,%0
1548
   ld.b %1,%0"
1549
  [(set_attr "length" "2,2,4")
1550
   (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1551
 
1552
;; ??? This is missing a sign extend from memory pattern to match the ld.b
1553
;; instruction.
1554
 
1555
(define_expand "extendqisi2"
1556
  [(set (match_dup 2)
1557
        (ashift:SI (match_operand:QI 1 "register_operand" "")
1558
                   (const_int 24)))
1559
   (set (match_operand:SI 0 "register_operand" "")
1560
        (ashiftrt:SI (match_dup 2)
1561
                     (const_int 24)))]
1562
  ""
1563
  "
1564
{
1565
  operands[1] = gen_lowpart (SImode, operands[1]);
1566
  operands[2] = gen_reg_rtx (SImode);
1567
}")
1568
 
1569
;; ----------------------------------------------------------------------
1570
;; SHIFTS
1571
;; ----------------------------------------------------------------------
1572
 
1573
(define_insn "ashlsi3"
1574
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1575
        (ashift:SI
1576
         (match_operand:SI 1 "register_operand" "0,0")
1577
         (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1578
  ""
1579
  "@
1580
  shl %2,%0
1581
  shl %2,%0"
1582
  [(set_attr "length" "4,2")
1583
   (set_attr "cc" "set_znv")])
1584
 
1585
(define_insn "lshrsi3"
1586
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1587
        (lshiftrt:SI
1588
         (match_operand:SI 1 "register_operand" "0,0")
1589
         (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1590
  ""
1591
  "@
1592
  shr %2,%0
1593
  shr %2,%0"
1594
  [(set_attr "length" "4,2")
1595
   (set_attr "cc" "set_znv")])
1596
 
1597
(define_insn "ashrsi3"
1598
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1599
        (ashiftrt:SI
1600
         (match_operand:SI 1 "register_operand" "0,0")
1601
         (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1602
  ""
1603
  "@
1604
  sar %2,%0
1605
  sar %2,%0"
1606
  [(set_attr "length" "4,2")
1607
   (set_attr "cc" "set_znv")])
1608
 
1609
;; ----------------------------------------------------------------------
1610
;; PROLOGUE/EPILOGUE
1611
;; ----------------------------------------------------------------------
1612
(define_expand "prologue"
1613
  [(const_int 0)]
1614
  ""
1615
  "expand_prologue (); DONE;")
1616
 
1617
(define_expand "epilogue"
1618
  [(return)]
1619
  ""
1620
  "
1621
{
1622
  /* Try to use the trivial return first.  Else use the
1623
     full epilogue.  */
1624
  if (0)
1625
    emit_jump_insn (gen_return ());
1626
  else
1627
    expand_epilogue ();
1628
  DONE;
1629
}")
1630
 
1631
(define_insn "return"
1632
  [(return)]
1633
  "reload_completed && compute_frame_size (get_frame_size (), (long *)0) == 0"
1634
  "jmp [r31]"
1635
  [(set_attr "length" "2")
1636
   (set_attr "cc" "none")])
1637
 
1638
(define_insn "return_internal"
1639
  [(return)
1640
   (use (reg:SI 31))]
1641
  ""
1642
  "jmp [r31]"
1643
  [(set_attr "length" "2")
1644
   (set_attr "cc" "none")])
1645
 
1646
 
1647
 
1648
;; ----------------------------------------------------------------------
1649
;; HELPER INSTRUCTIONS for saving the prologue and epilog registers
1650
;; ----------------------------------------------------------------------
1651
 
1652
;; This pattern will match a stack adjust RTX followed by any number of push
1653
;; RTXs.  These RTXs will then be turned into a suitable call to a worker
1654
;; function.
1655
 
1656
;;
1657
;; Actually, convert the RTXs into a PREPARE instruction.
1658
;;
1659
(define_insn ""
1660
 [(match_parallel 0 "pattern_is_ok_for_prepare"
1661
   [(set (reg:SI 3)
1662
         (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1663
    (set (mem:SI (plus:SI (reg:SI 3)
1664
                          (match_operand:SI 2 "immediate_operand" "i")))
1665
         (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1666
 "TARGET_PROLOG_FUNCTION && TARGET_V850E"
1667
 "* return construct_prepare_instruction (operands[0]);
1668
 "
1669
 [(set_attr "length" "4")
1670
  (set_attr "cc"     "none")])
1671
 
1672
(define_insn ""
1673
 [(match_parallel 0 "pattern_is_ok_for_prologue"
1674
   [(set (reg:SI 3)
1675
         (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1676
    (set (mem:SI (plus:SI (reg:SI 3)
1677
                           (match_operand:SI 2 "immediate_operand" "i")))
1678
         (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1679
 "TARGET_PROLOG_FUNCTION && TARGET_V850"
1680
 "* return construct_save_jarl (operands[0]);
1681
 "
1682
 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1683
                                     (const_string "16")
1684
                                     (const_string "4")))
1685
  (set_attr "cc"     "clobber")])
1686
 
1687
;;
1688
;; Actually, turn the RTXs into a DISPOSE instruction.
1689
;;
1690
(define_insn ""
1691
 [(match_parallel 0 "pattern_is_ok_for_dispose"
1692
   [(return)
1693
    (set (reg:SI 3)
1694
         (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1695
    (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1696
         (mem:SI (plus:SI (reg:SI 3)
1697
                          (match_operand:SI 3 "immediate_operand" "i"))))])]
1698
 "TARGET_PROLOG_FUNCTION && TARGET_V850E"
1699
 "* return construct_dispose_instruction (operands[0]);
1700
 "
1701
 [(set_attr "length" "4")
1702
  (set_attr "cc"     "none")])
1703
 
1704
;; This pattern will match a return RTX followed by any number of pop RTXs
1705
;; and possible a stack adjustment as well.  These RTXs will be turned into
1706
;; a suitable call to a worker function.
1707
 
1708
(define_insn ""
1709
[(match_parallel 0 "pattern_is_ok_for_epilogue"
1710
   [(return)
1711
    (set (reg:SI 3)
1712
         (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1713
    (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1714
         (mem:SI (plus:SI (reg:SI 3)
1715
                          (match_operand:SI 3 "immediate_operand" "i"))))])]
1716
 "TARGET_PROLOG_FUNCTION && TARGET_V850"
1717
 "* return construct_restore_jr (operands[0]);
1718
 "
1719
 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1720
                                     (const_string "12")
1721
                                     (const_string "4")))
1722
  (set_attr "cc"     "clobber")])
1723
 
1724
;; Initialize an interrupt function.  Do not depend on TARGET_PROLOG_FUNCTION.
1725
(define_insn "callt_save_interrupt"
1726
  [(unspec_volatile [(const_int 0)] 2)]
1727
    "TARGET_V850E && !TARGET_DISABLE_CALLT"
1728
    ;; The CALLT instruction stores the next address of CALLT to CTPC register
1729
    ;; without saving its previous value.  So if the interrupt handler
1730
    ;; or its caller could possibly execute the CALLT insn, save_interrupt
1731
    ;; MUST NOT be called via CALLT.
1732
    "*
1733
{
1734
  output_asm_insn (\"addi -24,   sp, sp\", operands);
1735
  output_asm_insn (\"st.w r10,   12[sp]\", operands);
1736
  output_asm_insn (\"stsr ctpc,  r10\",    operands);
1737
  output_asm_insn (\"st.w r10,   16[sp]\", operands);
1738
  output_asm_insn (\"stsr ctpsw, r10\",    operands);
1739
  output_asm_insn (\"st.w r10,   20[sp]\", operands);
1740
  output_asm_insn (\"callt ctoff(__callt_save_interrupt)\", operands);
1741
  return \"\";
1742
}"
1743
   [(set_attr "length" "26")
1744
    (set_attr "cc" "none")])
1745
 
1746
(define_insn "callt_return_interrupt"
1747
  [(unspec_volatile [(const_int 0)] 3)]
1748
  "TARGET_V850E && !TARGET_DISABLE_CALLT"
1749
  "callt ctoff(__callt_return_interrupt)"
1750
  [(set_attr "length" "2")
1751
   (set_attr "cc" "clobber")])
1752
 
1753
(define_insn "save_interrupt"
1754
  [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
1755
   (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 30))
1756
   (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 4))
1757
   (set (mem:SI (plus:SI (reg:SI 3) (const_int  -8))) (reg:SI 1))
1758
   (set (mem:SI (plus:SI (reg:SI 3) (const_int  -4))) (reg:SI 10))]
1759
  ""
1760
  "*
1761
{
1762
  if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1763
    return \"add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10\";
1764
  else
1765
    {
1766
      output_asm_insn (\"add   -16, sp\", operands);
1767
      output_asm_insn (\"st.w  r10, 12[sp]\", operands);
1768
      output_asm_insn (\"st.w  ep, 0[sp]\", operands);
1769
      output_asm_insn (\"st.w  gp, 4[sp]\", operands);
1770
      output_asm_insn (\"st.w  r1, 8[sp]\", operands);
1771
      output_asm_insn (\"movhi hi(__ep), r0, ep\", operands);
1772
      output_asm_insn (\"movea lo(__ep), ep, ep\", operands);
1773
      output_asm_insn (\"movhi hi(__gp), r0, gp\", operands);
1774
      output_asm_insn (\"movea lo(__gp), gp, gp\", operands);
1775
      return \"\";
1776
    }
1777
}"
1778
  [(set (attr "length")
1779
        (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1780
                       (const_int 10)
1781
                       (const_int 34)))
1782
   (set_attr "cc" "clobber")])
1783
 
1784
;; Restore r1, r4, r10, and return from the interrupt
1785
(define_insn "return_interrupt"
1786
  [(return)
1787
   (set (reg:SI 3)  (plus:SI (reg:SI 3) (const_int 16)))
1788
   (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
1789
   (set (reg:SI 1)  (mem:SI (plus:SI (reg:SI 3) (const_int  8))))
1790
   (set (reg:SI 4)  (mem:SI (plus:SI (reg:SI 3) (const_int  4))))
1791
   (set (reg:SI 30) (mem:SI (reg:SI 3)))]
1792
  ""
1793
  "*
1794
{
1795
  if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1796
    return \"jr __return_interrupt\";
1797
  else
1798
    {
1799
      output_asm_insn (\"ld.w 0[sp],  ep\",   operands);
1800
      output_asm_insn (\"ld.w 4[sp],  gp\",   operands);
1801
      output_asm_insn (\"ld.w 8[sp],  r1\",   operands);
1802
      output_asm_insn (\"ld.w 12[sp], r10\", operands);
1803
      output_asm_insn (\"addi 16, sp, sp\",   operands);
1804
      output_asm_insn (\"reti\",            operands);
1805
      return \"\";
1806
    }
1807
}"
1808
  [(set (attr "length")
1809
        (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1810
                       (const_int 4)
1811
                       (const_int 24)))
1812
   (set_attr "cc" "clobber")])
1813
 
1814
;; Save all registers except for the registers saved in save_interrupt when
1815
;; an interrupt function makes a call.
1816
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1817
;; all of memory.  This blocks insns from being moved across this point.
1818
;; This is needed because the rest of the compiler is not ready to handle
1819
;; insns this complicated.
1820
 
1821
(define_insn "callt_save_all_interrupt"
1822
  [(unspec_volatile [(const_int 0)] 0)]
1823
  "TARGET_V850E && !TARGET_DISABLE_CALLT"
1824
  "callt ctoff(__callt_save_all_interrupt)"
1825
  [(set_attr "length" "2")
1826
   (set_attr "cc" "none")])
1827
 
1828
(define_insn "save_all_interrupt"
1829
  [(unspec_volatile [(const_int 0)] 0)]
1830
  ""
1831
  "*
1832
{
1833
  if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1834
    return \"jarl __save_all_interrupt,r10\";
1835
 
1836
  output_asm_insn (\"addi -120, sp, sp\", operands);
1837
 
1838
  if (TARGET_EP)
1839
    {
1840
      output_asm_insn (\"mov ep, r1\", operands);
1841
      output_asm_insn (\"mov sp, ep\", operands);
1842
      output_asm_insn (\"sst.w r31, 116[ep]\", operands);
1843
      output_asm_insn (\"sst.w r2,  112[ep]\", operands);
1844
      output_asm_insn (\"sst.w gp,  108[ep]\", operands);
1845
      output_asm_insn (\"sst.w r6,  104[ep]\", operands);
1846
      output_asm_insn (\"sst.w r7,  100[ep]\", operands);
1847
      output_asm_insn (\"sst.w r8,   96[ep]\", operands);
1848
      output_asm_insn (\"sst.w r9,   92[ep]\", operands);
1849
      output_asm_insn (\"sst.w r11,  88[ep]\", operands);
1850
      output_asm_insn (\"sst.w r12,  84[ep]\", operands);
1851
      output_asm_insn (\"sst.w r13,  80[ep]\", operands);
1852
      output_asm_insn (\"sst.w r14,  76[ep]\", operands);
1853
      output_asm_insn (\"sst.w r15,  72[ep]\", operands);
1854
      output_asm_insn (\"sst.w r16,  68[ep]\", operands);
1855
      output_asm_insn (\"sst.w r17,  64[ep]\", operands);
1856
      output_asm_insn (\"sst.w r18,  60[ep]\", operands);
1857
      output_asm_insn (\"sst.w r19,  56[ep]\", operands);
1858
      output_asm_insn (\"sst.w r20,  52[ep]\", operands);
1859
      output_asm_insn (\"sst.w r21,  48[ep]\", operands);
1860
      output_asm_insn (\"sst.w r22,  44[ep]\", operands);
1861
      output_asm_insn (\"sst.w r23,  40[ep]\", operands);
1862
      output_asm_insn (\"sst.w r24,  36[ep]\", operands);
1863
      output_asm_insn (\"sst.w r25,  32[ep]\", operands);
1864
      output_asm_insn (\"sst.w r26,  28[ep]\", operands);
1865
      output_asm_insn (\"sst.w r27,  24[ep]\", operands);
1866
      output_asm_insn (\"sst.w r28,  20[ep]\", operands);
1867
      output_asm_insn (\"sst.w r29,  16[ep]\", operands);
1868
      output_asm_insn (\"mov   r1,   ep\", operands);
1869
    }
1870
  else
1871
    {
1872
      output_asm_insn (\"st.w r31, 116[sp]\", operands);
1873
      output_asm_insn (\"st.w r2,  112[sp]\", operands);
1874
      output_asm_insn (\"st.w gp,  108[sp]\", operands);
1875
      output_asm_insn (\"st.w r6,  104[sp]\", operands);
1876
      output_asm_insn (\"st.w r7,  100[sp]\", operands);
1877
      output_asm_insn (\"st.w r8,   96[sp]\", operands);
1878
      output_asm_insn (\"st.w r9,   92[sp]\", operands);
1879
      output_asm_insn (\"st.w r11,  88[sp]\", operands);
1880
      output_asm_insn (\"st.w r12,  84[sp]\", operands);
1881
      output_asm_insn (\"st.w r13,  80[sp]\", operands);
1882
      output_asm_insn (\"st.w r14,  76[sp]\", operands);
1883
      output_asm_insn (\"st.w r15,  72[sp]\", operands);
1884
      output_asm_insn (\"st.w r16,  68[sp]\", operands);
1885
      output_asm_insn (\"st.w r17,  64[sp]\", operands);
1886
      output_asm_insn (\"st.w r18,  60[sp]\", operands);
1887
      output_asm_insn (\"st.w r19,  56[sp]\", operands);
1888
      output_asm_insn (\"st.w r20,  52[sp]\", operands);
1889
      output_asm_insn (\"st.w r21,  48[sp]\", operands);
1890
      output_asm_insn (\"st.w r22,  44[sp]\", operands);
1891
      output_asm_insn (\"st.w r23,  40[sp]\", operands);
1892
      output_asm_insn (\"st.w r24,  36[sp]\", operands);
1893
      output_asm_insn (\"st.w r25,  32[sp]\", operands);
1894
      output_asm_insn (\"st.w r26,  28[sp]\", operands);
1895
      output_asm_insn (\"st.w r27,  24[sp]\", operands);
1896
      output_asm_insn (\"st.w r28,  20[sp]\", operands);
1897
      output_asm_insn (\"st.w r29,  16[sp]\", operands);
1898
    }
1899
 
1900
  return \"\";
1901
}"
1902
  [(set (attr "length")
1903
        (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1904
                       (const_int 4)
1905
                       (const_int 62)
1906
        ))
1907
   (set_attr "cc" "clobber")])
1908
 
1909
(define_insn "_save_all_interrupt"
1910
  [(unspec_volatile [(const_int 0)] 0)]
1911
  "TARGET_V850 && ! TARGET_LONG_CALLS"
1912
  "jarl __save_all_interrupt,r10"
1913
  [(set_attr "length" "4")
1914
   (set_attr "cc" "clobber")])
1915
 
1916
;; Restore all registers saved when an interrupt function makes a call.
1917
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1918
;; all of memory.  This blocks insns from being moved across this point.
1919
;; This is needed because the rest of the compiler is not ready to handle
1920
;; insns this complicated.
1921
 
1922
(define_insn "callt_restore_all_interrupt"
1923
  [(unspec_volatile [(const_int 0)] 1)]
1924
  "TARGET_V850E && !TARGET_DISABLE_CALLT"
1925
  "callt ctoff(__callt_restore_all_interrupt)"
1926
  [(set_attr "length" "2")
1927
   (set_attr "cc" "none")])
1928
 
1929
(define_insn "restore_all_interrupt"
1930
  [(unspec_volatile [(const_int 0)] 1)]
1931
  ""
1932
  "*
1933
{
1934
  if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1935
    return \"jarl __restore_all_interrupt,r10\";
1936
 
1937
  if (TARGET_EP)
1938
    {
1939
      output_asm_insn (\"mov   ep,      r1\", operands);
1940
      output_asm_insn (\"mov   sp,      ep\", operands);
1941
      output_asm_insn (\"sld.w 116[ep], r31\", operands);
1942
      output_asm_insn (\"sld.w 112[ep], r2\", operands);
1943
      output_asm_insn (\"sld.w 108[ep], gp\", operands);
1944
      output_asm_insn (\"sld.w 104[ep], r6\", operands);
1945
      output_asm_insn (\"sld.w 100[ep], r7\", operands);
1946
      output_asm_insn (\"sld.w 96[ep],  r8\", operands);
1947
      output_asm_insn (\"sld.w 92[ep],  r9\", operands);
1948
      output_asm_insn (\"sld.w 88[ep],  r11\", operands);
1949
      output_asm_insn (\"sld.w 84[ep],  r12\", operands);
1950
      output_asm_insn (\"sld.w 80[ep],  r13\", operands);
1951
      output_asm_insn (\"sld.w 76[ep],  r14\", operands);
1952
      output_asm_insn (\"sld.w 72[ep],  r15\", operands);
1953
      output_asm_insn (\"sld.w 68[ep],  r16\", operands);
1954
      output_asm_insn (\"sld.w 64[ep],  r17\", operands);
1955
      output_asm_insn (\"sld.w 60[ep],  r18\", operands);
1956
      output_asm_insn (\"sld.w 56[ep],  r19\", operands);
1957
      output_asm_insn (\"sld.w 52[ep],  r20\", operands);
1958
      output_asm_insn (\"sld.w 48[ep],  r21\", operands);
1959
      output_asm_insn (\"sld.w 44[ep],  r22\", operands);
1960
      output_asm_insn (\"sld.w 40[ep],  r23\", operands);
1961
      output_asm_insn (\"sld.w 36[ep],  r24\", operands);
1962
      output_asm_insn (\"sld.w 32[ep],  r25\", operands);
1963
      output_asm_insn (\"sld.w 28[ep],  r26\", operands);
1964
      output_asm_insn (\"sld.w 24[ep],  r27\", operands);
1965
      output_asm_insn (\"sld.w 20[ep],  r28\", operands);
1966
      output_asm_insn (\"sld.w 16[ep],  r29\", operands);
1967
      output_asm_insn (\"mov   r1,      ep\", operands);
1968
    }
1969
  else
1970
    {
1971
      output_asm_insn (\"ld.w 116[sp], r31\", operands);
1972
      output_asm_insn (\"ld.w 112[sp], r2\", operands);
1973
      output_asm_insn (\"ld.w 108[sp], gp\", operands);
1974
      output_asm_insn (\"ld.w 104[sp], r6\", operands);
1975
      output_asm_insn (\"ld.w 100[sp], r7\", operands);
1976
      output_asm_insn (\"ld.w 96[sp],  r8\", operands);
1977
      output_asm_insn (\"ld.w 92[sp],  r9\", operands);
1978
      output_asm_insn (\"ld.w 88[sp],  r11\", operands);
1979
      output_asm_insn (\"ld.w 84[sp],  r12\", operands);
1980
      output_asm_insn (\"ld.w 80[sp],  r13\", operands);
1981
      output_asm_insn (\"ld.w 76[sp],  r14\", operands);
1982
      output_asm_insn (\"ld.w 72[sp],  r15\", operands);
1983
      output_asm_insn (\"ld.w 68[sp],  r16\", operands);
1984
      output_asm_insn (\"ld.w 64[sp],  r17\", operands);
1985
      output_asm_insn (\"ld.w 60[sp],  r18\", operands);
1986
      output_asm_insn (\"ld.w 56[sp],  r19\", operands);
1987
      output_asm_insn (\"ld.w 52[sp],  r20\", operands);
1988
      output_asm_insn (\"ld.w 48[sp],  r21\", operands);
1989
      output_asm_insn (\"ld.w 44[sp],  r22\", operands);
1990
      output_asm_insn (\"ld.w 40[sp],  r23\", operands);
1991
      output_asm_insn (\"ld.w 36[sp],  r24\", operands);
1992
      output_asm_insn (\"ld.w 32[sp],  r25\", operands);
1993
      output_asm_insn (\"ld.w 28[sp],  r26\", operands);
1994
      output_asm_insn (\"ld.w 24[sp],  r27\", operands);
1995
      output_asm_insn (\"ld.w 20[sp],  r28\", operands);
1996
      output_asm_insn (\"ld.w 16[sp],  r29\", operands);
1997
    }
1998
  output_asm_insn (\"addi  120, sp, sp\", operands);
1999
  return \"\";
2000
}"
2001
  [(set (attr "length")
2002
        (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
2003
                       (const_int 4)
2004
                       (const_int 62)
2005
        ))
2006
   (set_attr "cc" "clobber")])
2007
 
2008
(define_insn "_restore_all_interrupt"
2009
  [(unspec_volatile [(const_int 0)] 1)]
2010
  "TARGET_V850 && ! TARGET_LONG_CALLS"
2011
  "jarl __restore_all_interrupt,r10"
2012
  [(set_attr "length" "4")
2013
   (set_attr "cc" "clobber")])
2014
 
2015
;; Save r6-r9 for a variable argument function
2016
(define_insn "save_r6_r9_v850e"
2017
  [(set (mem:SI (reg:SI 3)) (reg:SI 6))
2018
   (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
2019
   (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
2020
   (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
2021
  ]
2022
  "TARGET_PROLOG_FUNCTION && TARGET_V850E && !TARGET_DISABLE_CALLT"
2023
  "callt ctoff(__callt_save_r6_r9)"
2024
  [(set_attr "length" "2")
2025
   (set_attr "cc" "none")])
2026
 
2027
(define_insn "save_r6_r9"
2028
  [(set (mem:SI (reg:SI 3)) (reg:SI 6))
2029
   (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
2030
   (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
2031
   (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
2032
   (clobber (reg:SI 10))]
2033
  "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS"
2034
  "jarl __save_r6_r9,r10"
2035
  [(set_attr "length" "4")
2036
   (set_attr "cc" "clobber")])
2037
 

powered by: WebSVN 2.1.0

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