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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [v850/] [v850.md] - Blame information for rev 38

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

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

powered by: WebSVN 2.1.0

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