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

Subversion Repositories openrisc_me

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 282 jeremybenn
;; GCC machine description for NEC V850
2
;; Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2005, 2007, 2008
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
(define_insn "*movsf_internal"
215
  [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r")
216
        (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
217
  "register_operand (operands[0], SFmode)
218
   || reg_or_0_operand (operands[1], SFmode)"
219
  "* return output_move_single (operands);"
220
  [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
221
   (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
222
   (set_attr "type" "other,other,other,other,load,other,load,other,other,other")])
223
 
224
 
225
;; ----------------------------------------------------------------------
226
;; TEST INSTRUCTIONS
227
;; ----------------------------------------------------------------------
228
 
229
(define_insn "*v850_tst1"
230
  [(set (cc0)
231
        (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
232
                                  (const_int 1)
233
                                  (match_operand:QI 1 "const_int_operand" "n"))
234
                 (const_int 0)))]
235
  ""
236
  "tst1 %1,%0"
237
  [(set_attr "length" "4")
238
   (set_attr "cc" "clobber")])
239
 
240
;; This replaces ld.b;sar;andi with tst1;setf nz.
241
 
242
(define_split
243
  [(set (match_operand:SI 0 "register_operand" "")
244
        (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
245
                                  (const_int 1)
246
                                  (match_operand 2 "const_int_operand" ""))
247
                 (const_int 0)))]
248
  ""
249
  [(set (cc0) (compare (zero_extract:SI (match_dup 1)
250
                                        (const_int 1)
251
                                        (match_dup 2))
252
                       (const_int 0)))
253
   (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
254
 
255
(define_expand "cbranchsi4"
256
  [(set (cc0)
257
        (compare (match_operand:SI 1 "register_operand" "")
258
                 (match_operand:SI 2 "reg_or_int5_operand" "")))
259
   (set (pc)
260
        (if_then_else
261
              (match_operator 0 "ordered_comparison_operator" [(cc0)
262
                                                               (const_int 0)])
263
              (label_ref (match_operand 3 "" ""))
264
              (pc)))]
265
 "")
266
 
267
(define_expand "cstoresi4"
268
  [(set (cc0)
269
        (compare (match_operand:SI 2 "register_operand" "")
270
                 (match_operand:SI 3 "reg_or_int5_operand" "")))
271
   (set (match_operand:SI 0 "register_operand")
272
        (match_operator:SI 1 "ordered_comparison_operator" [(cc0)
273
                                                            (const_int 0)]))]
274
  "")
275
 
276
(define_insn "*cmpsi"
277
  [(set (cc0)
278
        (compare (match_operand:SI 0 "register_operand" "r,r,r")
279
                 (match_operand:SI 1 "reg_or_int5_operand" "r,I,J")))]
280
  ""
281
  "@
282
  cmp %1,%0
283
  cmp %.,%0
284
  cmp %1,%0"
285
  [(set_attr "length" "2,2,2")
286
   (set_attr "cc" "compare,set_znv,compare")])
287
 
288
 
289
;; ----------------------------------------------------------------------
290
;; ADD INSTRUCTIONS
291
;; ----------------------------------------------------------------------
292
 
293
(define_insn "addsi3"
294
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
295
        (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
296
                 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))]
297
  ""
298
  "@
299
   add %2,%0
300
   addi %2,%1,%0
301
   addi %O2(%P2),%1,%0"
302
  [(set_attr "length" "2,4,4")
303
   (set_attr "cc" "set_zn,set_zn,set_zn")])
304
 
305
;; ----------------------------------------------------------------------
306
;; SUBTRACT INSTRUCTIONS
307
;; ----------------------------------------------------------------------
308
 
309
(define_insn "subsi3"
310
  [(set (match_operand:SI 0 "register_operand" "=r,r")
311
        (minus:SI (match_operand:SI 1 "register_operand" "0,r")
312
                  (match_operand:SI 2 "register_operand" "r,0")))]
313
  ""
314
  "@
315
  sub %2,%0
316
  subr %1,%0"
317
  [(set_attr "length" "2,2")
318
   (set_attr "cc" "set_zn")])
319
 
320
(define_insn "negsi2"
321
  [(set (match_operand:SI 0 "register_operand" "=r")
322
        (neg:SI (match_operand:SI 1 "register_operand" "0")))]
323
  ""
324
  "subr %.,%0"
325
  [(set_attr "length" "2")
326
   (set_attr "cc" "set_zn")])
327
 
328
;; ----------------------------------------------------------------------
329
;; MULTIPLY INSTRUCTIONS
330
;; ----------------------------------------------------------------------
331
 
332
(define_expand "mulhisi3"
333
  [(set (match_operand:SI 0 "register_operand" "")
334
        (mult:SI
335
          (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
336
          (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
337
  ""
338
  "if (GET_CODE (operands[2]) == CONST_INT)
339
     {
340
       emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));
341
       DONE;
342
     }")
343
 
344
(define_insn "*mulhisi3_internal1"
345
  [(set (match_operand:SI 0 "register_operand" "=r")
346
        (mult:SI
347
          (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
348
          (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
349
  ""
350
  "mulh %2,%0"
351
  [(set_attr "length" "2")
352
   (set_attr "cc" "none_0hit")
353
   (set_attr "type" "mult")])
354
 
355
(define_insn "mulhisi3_internal2"
356
  [(set (match_operand:SI 0 "register_operand" "=r,r")
357
        (mult:SI
358
          (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
359
          (match_operand:HI 2 "const_int_operand" "J,K")))]
360
  ""
361
  "@
362
   mulh %2,%0
363
   mulhi %2,%1,%0"
364
  [(set_attr "length" "2,4")
365
   (set_attr "cc" "none_0hit,none_0hit")
366
   (set_attr "type" "mult")])
367
 
368
;; ??? The scheduling info is probably wrong.
369
 
370
;; ??? This instruction can also generate the 32-bit highpart, but using it
371
;; may increase code size counter to the desired result.
372
 
373
;; ??? This instructions can also give a DImode result.
374
 
375
;; ??? There is unsigned version, but it matters only for the DImode/highpart
376
;; results.
377
 
378
(define_insn "mulsi3"
379
  [(set (match_operand:SI 0 "register_operand" "=r")
380
        (mult:SI (match_operand:SI 1 "register_operand" "%0")
381
                 (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
382
  "TARGET_V850E"
383
  "mul %2,%1,%."
384
  [(set_attr "length" "4")
385
   (set_attr "cc" "none_0hit")
386
   (set_attr "type" "mult")])
387
 
388
;; ----------------------------------------------------------------------
389
;; DIVIDE INSTRUCTIONS
390
;; ----------------------------------------------------------------------
391
 
392
;; ??? These insns do set the Z/N condition codes, except that they are based
393
;; on only one of the two results, so it doesn't seem to make sense to use
394
;; them.
395
 
396
;; ??? The scheduling info is probably wrong.
397
 
398
(define_insn "divmodsi4"
399
  [(set (match_operand:SI 0 "register_operand" "=r")
400
        (div:SI (match_operand:SI 1 "register_operand" "0")
401
                (match_operand:SI 2 "register_operand" "r")))
402
   (set (match_operand:SI 3 "register_operand" "=r")
403
        (mod:SI (match_dup 1)
404
                (match_dup 2)))]
405
  "TARGET_V850E"
406
  "div %2,%0,%3"
407
  [(set_attr "length" "4")
408
   (set_attr "cc" "clobber")
409
   (set_attr "type" "other")])
410
 
411
(define_insn "udivmodsi4"
412
  [(set (match_operand:SI 0 "register_operand" "=r")
413
        (udiv:SI (match_operand:SI 1 "register_operand" "0")
414
                 (match_operand:SI 2 "register_operand" "r")))
415
   (set (match_operand:SI 3 "register_operand" "=r")
416
        (umod:SI (match_dup 1)
417
                 (match_dup 2)))]
418
  "TARGET_V850E"
419
  "divu %2,%0,%3"
420
  [(set_attr "length" "4")
421
   (set_attr "cc" "clobber")
422
   (set_attr "type" "other")])
423
 
424
;; ??? There is a 2 byte instruction for generating only the quotient.
425
;; However, it isn't clear how to compute the length field correctly.
426
 
427
(define_insn "divmodhi4"
428
  [(set (match_operand:HI 0 "register_operand" "=r")
429
        (div:HI (match_operand:HI 1 "register_operand" "0")
430
                (match_operand:HI 2 "register_operand" "r")))
431
   (set (match_operand:HI 3 "register_operand" "=r")
432
        (mod:HI (match_dup 1)
433
                (match_dup 2)))]
434
  "TARGET_V850E"
435
  "divh %2,%0,%3"
436
  [(set_attr "length" "4")
437
   (set_attr "cc" "clobber")
438
   (set_attr "type" "other")])
439
 
440
;; Half-words are sign-extended by default, so we must zero extend to a word
441
;; here before doing the divide.
442
 
443
(define_insn "udivmodhi4"
444
  [(set (match_operand:HI 0 "register_operand" "=r")
445
        (udiv:HI (match_operand:HI 1 "register_operand" "0")
446
                 (match_operand:HI 2 "register_operand" "r")))
447
   (set (match_operand:HI 3 "register_operand" "=r")
448
        (umod:HI (match_dup 1)
449
                 (match_dup 2)))]
450
  "TARGET_V850E"
451
  "zxh %0 ; divhu %2,%0,%3"
452
  [(set_attr "length" "4")
453
   (set_attr "cc" "clobber")
454
   (set_attr "type" "other")])
455
 
456
;; ----------------------------------------------------------------------
457
;; AND INSTRUCTIONS
458
;; ----------------------------------------------------------------------
459
 
460
(define_insn "*v850_clr1_1"
461
  [(set (match_operand:QI 0 "memory_operand" "=m")
462
        (subreg:QI
463
          (and:SI (subreg:SI (match_dup 0) 0)
464
                  (match_operand:QI 1 "not_power_of_two_operand" "")) 0))]
465
  ""
466
  "*
467
{
468
  rtx xoperands[2];
469
  xoperands[0] = operands[0];
470
  xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
471
  output_asm_insn (\"clr1 %M1,%0\", xoperands);
472
  return \"\";
473
}"
474
  [(set_attr "length" "4")
475
   (set_attr "cc" "clobber")])
476
 
477
(define_insn "*v850_clr1_2"
478
  [(set (match_operand:HI 0 "indirect_operand" "=m")
479
        (subreg:HI
480
          (and:SI (subreg:SI (match_dup 0) 0)
481
                  (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
482
  ""
483
  "*
484
{
485
  int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
486
 
487
  rtx xoperands[2];
488
  xoperands[0] = gen_rtx_MEM (QImode,
489
                              plus_constant (XEXP (operands[0], 0), log2 / 8));
490
  xoperands[1] = GEN_INT (log2 % 8);
491
  output_asm_insn (\"clr1 %1,%0\", xoperands);
492
  return \"\";
493
}"
494
  [(set_attr "length" "4")
495
   (set_attr "cc" "clobber")])
496
 
497
(define_insn "*v850_clr1_3"
498
  [(set (match_operand:SI 0 "indirect_operand" "=m")
499
        (and:SI (match_dup 0)
500
                (match_operand:SI 1 "not_power_of_two_operand" "")))]
501
  ""
502
  "*
503
{
504
  int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
505
 
506
  rtx xoperands[2];
507
  xoperands[0] = gen_rtx_MEM (QImode,
508
                              plus_constant (XEXP (operands[0], 0), log2 / 8));
509
  xoperands[1] = GEN_INT (log2 % 8);
510
  output_asm_insn (\"clr1 %1,%0\", xoperands);
511
  return \"\";
512
}"
513
  [(set_attr "length" "4")
514
   (set_attr "cc" "clobber")])
515
 
516
(define_insn "andsi3"
517
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
518
        (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
519
                (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
520
  ""
521
  "@
522
  and %2,%0
523
  and %.,%0
524
  andi %2,%1,%0"
525
  [(set_attr "length" "2,2,4")
526
   (set_attr "cc" "set_znv")])
527
 
528
;; ----------------------------------------------------------------------
529
;; OR INSTRUCTIONS
530
;; ----------------------------------------------------------------------
531
 
532
(define_insn "*v850_set1_1"
533
  [(set (match_operand:QI 0 "memory_operand" "=m")
534
        (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
535
                           (match_operand 1 "power_of_two_operand" "")) 0))]
536
  ""
537
  "set1 %M1,%0"
538
  [(set_attr "length" "4")
539
   (set_attr "cc" "clobber")])
540
 
541
(define_insn "*v850_set1_2"
542
  [(set (match_operand:HI 0 "indirect_operand" "=m")
543
        (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
544
                           (match_operand 1 "power_of_two_operand" "")) 0))]
545
  ""
546
  "*
547
{
548
  int log2 = exact_log2 (INTVAL (operands[1]));
549
 
550
  if (log2 < 8)
551
    return \"set1 %M1,%0\";
552
  else
553
    {
554
      rtx xoperands[2];
555
      xoperands[0] = gen_rtx_MEM (QImode,
556
                                  plus_constant (XEXP (operands[0], 0),
557
                                                 log2 / 8));
558
      xoperands[1] = GEN_INT (log2 % 8);
559
      output_asm_insn (\"set1 %1,%0\", xoperands);
560
    }
561
  return \"\";
562
}"
563
  [(set_attr "length" "4")
564
   (set_attr "cc" "clobber")])
565
 
566
(define_insn "*v850_set1_3"
567
  [(set (match_operand:SI 0 "indirect_operand" "=m")
568
        (ior:SI (match_dup 0)
569
                (match_operand 1 "power_of_two_operand" "")))]
570
  ""
571
  "*
572
{
573
  int log2 = exact_log2 (INTVAL (operands[1]));
574
 
575
  if (log2 < 8)
576
    return \"set1 %M1,%0\";
577
  else
578
    {
579
      rtx xoperands[2];
580
      xoperands[0] = gen_rtx_MEM (QImode,
581
                                  plus_constant (XEXP (operands[0], 0),
582
                                                 log2 / 8));
583
      xoperands[1] = GEN_INT (log2 % 8);
584
      output_asm_insn (\"set1 %1,%0\", xoperands);
585
    }
586
  return \"\";
587
}"
588
  [(set_attr "length" "4")
589
   (set_attr "cc" "clobber")])
590
 
591
(define_insn "iorsi3"
592
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
593
        (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
594
                (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
595
  ""
596
  "@
597
  or %2,%0
598
  or %.,%0
599
  ori %2,%1,%0"
600
  [(set_attr "length" "2,2,4")
601
   (set_attr "cc" "set_znv")])
602
 
603
;; ----------------------------------------------------------------------
604
;; XOR INSTRUCTIONS
605
;; ----------------------------------------------------------------------
606
 
607
(define_insn "*v850_not1_1"
608
  [(set (match_operand:QI 0 "memory_operand" "=m")
609
        (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
610
                           (match_operand 1 "power_of_two_operand" "")) 0))]
611
  ""
612
  "not1 %M1,%0"
613
  [(set_attr "length" "4")
614
   (set_attr "cc" "clobber")])
615
 
616
(define_insn "*v850_not1_2"
617
  [(set (match_operand:HI 0 "indirect_operand" "=m")
618
        (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
619
                           (match_operand 1 "power_of_two_operand" "")) 0))]
620
  ""
621
  "*
622
{
623
  int log2 = exact_log2 (INTVAL (operands[1]));
624
 
625
  if (log2 < 8)
626
    return \"not1 %M1,%0\";
627
  else
628
    {
629
      rtx xoperands[2];
630
      xoperands[0] = gen_rtx_MEM (QImode,
631
                                  plus_constant (XEXP (operands[0], 0),
632
                                                 log2 / 8));
633
      xoperands[1] = GEN_INT (log2 % 8);
634
      output_asm_insn (\"not1 %1,%0\", xoperands);
635
    }
636
  return \"\";
637
}"
638
  [(set_attr "length" "4")
639
   (set_attr "cc" "clobber")])
640
 
641
(define_insn "*v850_not1_3"
642
  [(set (match_operand:SI 0 "indirect_operand" "=m")
643
        (xor:SI (match_dup 0)
644
                (match_operand 1 "power_of_two_operand" "")))]
645
  ""
646
  "*
647
{
648
  int log2 = exact_log2 (INTVAL (operands[1]));
649
 
650
  if (log2 < 8)
651
    return \"not1 %M1,%0\";
652
  else
653
    {
654
      rtx xoperands[2];
655
      xoperands[0] = gen_rtx_MEM (QImode,
656
                                  plus_constant (XEXP (operands[0], 0),
657
                                                 log2 / 8));
658
      xoperands[1] = GEN_INT (log2 % 8);
659
      output_asm_insn (\"not1 %1,%0\", xoperands);
660
    }
661
  return \"\";
662
}"
663
  [(set_attr "length" "4")
664
   (set_attr "cc" "clobber")])
665
 
666
(define_insn "xorsi3"
667
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
668
        (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
669
                (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
670
  ""
671
  "@
672
  xor %2,%0
673
  xor %.,%0
674
  xori %2,%1,%0"
675
  [(set_attr "length" "2,2,4")
676
   (set_attr "cc" "set_znv")])
677
 
678
;; ----------------------------------------------------------------------
679
;; NOT INSTRUCTIONS
680
;; ----------------------------------------------------------------------
681
 
682
(define_insn "one_cmplsi2"
683
  [(set (match_operand:SI 0 "register_operand" "=r")
684
        (not:SI (match_operand:SI 1 "register_operand" "r")))]
685
  ""
686
  "not %1,%0"
687
  [(set_attr "length" "2")
688
   (set_attr "cc" "set_znv")])
689
 
690
;; -----------------------------------------------------------------
691
;; BIT FIELDS
692
;; -----------------------------------------------------------------
693
 
694
;; ??? Is it worth defining insv and extv for the V850 series?!?
695
 
696
;; An insv pattern would be useful, but does not get used because
697
;; store_bit_field never calls insv when storing a constant value into a
698
;; single-bit bitfield.
699
 
700
;; extv/extzv patterns would be useful, but do not get used because
701
;; optimize_bitfield_compare in fold-const usually converts single
702
;; bit extracts into an AND with a mask.
703
 
704
;; -----------------------------------------------------------------
705
;; Scc INSTRUCTIONS
706
;; -----------------------------------------------------------------
707
 
708
(define_insn "*setcc"
709
  [(set (match_operand:SI 0 "register_operand" "=r")
710
        (match_operator:SI 1 "comparison_operator"
711
         [(cc0) (const_int 0)]))]
712
  ""
713
  "*
714
{
715
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
716
      && (GET_CODE (operands[1]) == GT
717
          || GET_CODE (operands[1]) == GE
718
          || GET_CODE (operands[1]) == LE
719
          || GET_CODE (operands[1]) == LT))
720
    return 0;
721
 
722
  return \"setf %c1,%0\";
723
}"
724
  [(set_attr "length" "4")
725
   (set_attr "cc" "none_0hit")])
726
 
727
;; ----------------------------------------------------------------------
728
;; CONDITIONAL MOVE INSTRUCTIONS
729
;; ----------------------------------------------------------------------
730
 
731
;; Instructions using cc0 aren't allowed to have input reloads, so we must
732
;; hide the fact that this instruction uses cc0.  We do so by including the
733
;; compare instruction inside it.
734
 
735
(define_expand "movsicc"
736
  [(set (match_operand:SI 0 "register_operand" "=r")
737
        (if_then_else:SI
738
         (match_operand 1 "comparison_operator")
739
         (match_operand:SI 2 "reg_or_const_operand" "rJ")
740
         (match_operand:SI 3 "reg_or_const_operand" "rI")))]
741
  "TARGET_V850E"
742
  "
743
{
744
  if (   (GET_CODE (operands[2]) == CONST_INT
745
       && GET_CODE (operands[3]) == CONST_INT))
746
    {
747
      int o2 = INTVAL (operands[2]);
748
      int o3 = INTVAL (operands[3]);
749
 
750
      if (o2 == 1 && o3 == 0)
751
        FAIL;   /* setf */
752
      if (o3 == 1 && o2 == 0)
753
        FAIL;   /* setf */
754
      if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
755
        FAIL;   /* setf + shift */
756
      if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
757
        FAIL;   /* setf + shift */
758
      if (o2 != 0)
759
        operands[2] = copy_to_mode_reg (SImode, operands[2]);
760
      if (o3 !=0 )
761
        operands[3] = copy_to_mode_reg (SImode, operands[3]);
762
    }
763
  else
764
    {
765
      if (GET_CODE (operands[2]) != REG)
766
        operands[2] = copy_to_mode_reg (SImode,operands[2]);
767
      if (GET_CODE (operands[3]) != REG)
768
        operands[3] = copy_to_mode_reg (SImode, operands[3]);
769
    }
770
}")
771
 
772
;; ??? Clobbering the condition codes is overkill.
773
 
774
;; ??? We sometimes emit an unnecessary compare instruction because the
775
;; condition codes may have already been set by an earlier instruction,
776
;; but we have no code here to avoid the compare if it is unnecessary.
777
 
778
(define_insn "*movsicc_normal"
779
  [(set (match_operand:SI 0 "register_operand" "=r")
780
        (if_then_else:SI
781
         (match_operator 1 "comparison_operator"
782
                         [(match_operand:SI 4 "register_operand" "r")
783
                          (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
784
         (match_operand:SI 2 "reg_or_int5_operand" "rJ")
785
         (match_operand:SI 3 "reg_or_0_operand" "rI")))]
786
  "TARGET_V850E"
787
  "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
788
  [(set_attr "length" "6")
789
   (set_attr "cc" "clobber")])
790
 
791
(define_insn "*movsicc_reversed"
792
  [(set (match_operand:SI 0 "register_operand" "=r")
793
        (if_then_else:SI
794
         (match_operator 1 "comparison_operator"
795
                         [(match_operand:SI 4 "register_operand" "r")
796
                          (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
797
         (match_operand:SI 2 "reg_or_0_operand" "rI")
798
         (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
799
  "TARGET_V850E"
800
  "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
801
  [(set_attr "length" "6")
802
   (set_attr "cc" "clobber")])
803
 
804
(define_insn "*movsicc_tst1"
805
  [(set (match_operand:SI 0 "register_operand" "=r")
806
        (if_then_else:SI
807
         (match_operator 1 "comparison_operator"
808
                         [(zero_extract:SI
809
                           (match_operand:QI 2 "memory_operand" "m")
810
                           (const_int 1)
811
                           (match_operand 3 "const_int_operand" "n"))
812
                          (const_int 0)])
813
         (match_operand:SI 4 "reg_or_int5_operand" "rJ")
814
         (match_operand:SI 5 "reg_or_0_operand" "rI")))]
815
  "TARGET_V850E"
816
  "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
817
  [(set_attr "length" "8")
818
   (set_attr "cc" "clobber")])
819
 
820
(define_insn "*movsicc_tst1_reversed"
821
  [(set (match_operand:SI 0 "register_operand" "=r")
822
        (if_then_else:SI
823
         (match_operator 1 "comparison_operator"
824
                         [(zero_extract:SI
825
                           (match_operand:QI 2 "memory_operand" "m")
826
                           (const_int 1)
827
                           (match_operand 3 "const_int_operand" "n"))
828
                          (const_int 0)])
829
         (match_operand:SI 4 "reg_or_0_operand" "rI")
830
         (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
831
  "TARGET_V850E"
832
  "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
833
  [(set_attr "length" "8")
834
   (set_attr "cc" "clobber")])
835
 
836
;; Matching for sasf requires combining 4 instructions, so we provide a
837
;; dummy pattern to match the first 3, which will always be turned into the
838
;; second pattern by subsequent combining.  As above, we must include the
839
;; comparison to avoid input reloads in an insn using cc0.
840
 
841
(define_insn "*sasf_1"
842
  [(set (match_operand:SI 0 "register_operand" "")
843
        (ior:SI (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
844
                (ashift:SI (match_operand:SI 2 "register_operand" "")
845
                           (const_int 1))))]
846
  "TARGET_V850E"
847
  "* gcc_unreachable ();")
848
 
849
(define_insn "*sasf_2"
850
  [(set (match_operand:SI 0 "register_operand" "=r")
851
        (ior:SI
852
         (match_operator 1 "comparison_operator"
853
                         [(match_operand:SI 3 "register_operand" "r")
854
                          (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
855
         (ashift:SI (match_operand:SI 2 "register_operand" "0")
856
                    (const_int 1))))]
857
  "TARGET_V850E"
858
  "cmp %4,%3 ; sasf %c1,%0"
859
  [(set_attr "length" "6")
860
   (set_attr "cc" "clobber")])
861
 
862
(define_split
863
  [(set (match_operand:SI 0 "register_operand" "")
864
        (if_then_else:SI
865
         (match_operator 1 "comparison_operator"
866
                         [(match_operand:SI 4 "register_operand" "")
867
                          (match_operand:SI 5 "reg_or_int5_operand" "")])
868
         (match_operand:SI 2 "const_int_operand" "")
869
         (match_operand:SI 3 "const_int_operand" "")))]
870
  "TARGET_V850E
871
   && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
872
   && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
873
   && (GET_CODE (operands[5]) == CONST_INT
874
      || REGNO (operands[0]) != REGNO (operands[5]))
875
   && REGNO (operands[0]) != REGNO (operands[4])"
876
  [(set (match_dup 0) (match_dup 6))
877
   (set (match_dup 0)
878
        (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
879
                (ashift:SI (match_dup 0) (const_int 1))))]
880
  "
881
{
882
  operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
883
  if (INTVAL (operands[2]) & 0x1)
884
    operands[7] = operands[1];
885
  else
886
    operands[7] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
887
                                  GET_MODE (operands[1]),
888
                                  XEXP (operands[1], 0), XEXP (operands[1], 1));
889
}")
890
;; ---------------------------------------------------------------------
891
;; BYTE SWAP INSTRUCTIONS
892
;; ---------------------------------------------------------------------
893
 
894
(define_expand "rotlhi3"
895
  [(set (match_operand:HI 0 "register_operand" "")
896
        (rotate:HI (match_operand:HI 1 "register_operand" "")
897
                   (match_operand:HI 2 "const_int_operand" "")))]
898
  "TARGET_V850E"
899
  "
900
{
901
  if (INTVAL (operands[2]) != 8)
902
    FAIL;
903
}")
904
 
905
(define_insn "*rotlhi3_8"
906
  [(set (match_operand:HI 0 "register_operand" "=r")
907
        (rotate:HI (match_operand:HI 1 "register_operand" "r")
908
                   (const_int 8)))]
909
  "TARGET_V850E"
910
  "bsh %1,%0"
911
  [(set_attr "length" "4")
912
   (set_attr "cc" "clobber")])
913
 
914
(define_expand "rotlsi3"
915
  [(set (match_operand:SI 0 "register_operand" "")
916
        (rotate:SI (match_operand:SI 1 "register_operand" "")
917
                   (match_operand:SI 2 "const_int_operand" "")))]
918
  "TARGET_V850E"
919
  "
920
{
921
  if (INTVAL (operands[2]) != 16)
922
    FAIL;
923
}")
924
 
925
(define_insn "*rotlsi3_16"
926
  [(set (match_operand:SI 0 "register_operand" "=r")
927
        (rotate:SI (match_operand:SI 1 "register_operand" "r")
928
                   (const_int 16)))]
929
  "TARGET_V850E"
930
  "hsw %1,%0"
931
  [(set_attr "length" "4")
932
   (set_attr "cc" "clobber")])
933
 
934
;; ----------------------------------------------------------------------
935
;; JUMP INSTRUCTIONS
936
;; ----------------------------------------------------------------------
937
 
938
;; Conditional jump instructions
939
 
940
(define_insn "*branch_normal"
941
  [(set (pc)
942
        (if_then_else (match_operator 1 "comparison_operator"
943
                                      [(cc0) (const_int 0)])
944
                      (label_ref (match_operand 0 "" ""))
945
                      (pc)))]
946
  ""
947
  "*
948
{
949
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
950
      && (GET_CODE (operands[1]) == GT
951
          || GET_CODE (operands[1]) == GE
952
          || GET_CODE (operands[1]) == LE
953
          || GET_CODE (operands[1]) == LT))
954
    return 0;
955
 
956
  if (get_attr_length (insn) == 2)
957
    return \"b%b1 %l0\";
958
  else
959
    return \"b%B1 .+6 ; jr %l0\";
960
}"
961
 [(set (attr "length")
962
    (if_then_else (lt (abs (minus (match_dup 0) (pc)))
963
                      (const_int 256))
964
                  (const_int 2)
965
                  (const_int 6)))
966
  (set_attr "cc" "none")])
967
 
968
(define_insn "*branch_invert"
969
  [(set (pc)
970
        (if_then_else (match_operator 1 "comparison_operator"
971
                                      [(cc0) (const_int 0)])
972
                      (pc)
973
                      (label_ref (match_operand 0 "" ""))))]
974
  ""
975
  "*
976
{
977
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
978
      && (GET_CODE (operands[1]) == GT
979
          || GET_CODE (operands[1]) == GE
980
          || GET_CODE (operands[1]) == LE
981
          || GET_CODE (operands[1]) == LT))
982
    return 0;
983
  if (get_attr_length (insn) == 2)
984
    return \"b%B1 %l0\";
985
  else
986
    return \"b%b1 .+6 ; jr %l0\";
987
}"
988
 [(set (attr "length")
989
    (if_then_else (lt (abs (minus (match_dup 0) (pc)))
990
                      (const_int 256))
991
                  (const_int 2)
992
                  (const_int 6)))
993
  (set_attr "cc" "none")])
994
 
995
;; Unconditional and other jump instructions.
996
 
997
(define_insn "jump"
998
  [(set (pc)
999
        (label_ref (match_operand 0 "" "")))]
1000
  ""
1001
  "*
1002
{
1003
  if (get_attr_length (insn) == 2)
1004
    return \"br %0\";
1005
  else
1006
    return \"jr %0\";
1007
}"
1008
 [(set (attr "length")
1009
    (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1010
                      (const_int 256))
1011
                  (const_int 2)
1012
                  (const_int 4)))
1013
  (set_attr "cc" "none")])
1014
 
1015
(define_insn "indirect_jump"
1016
  [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1017
  ""
1018
  "jmp %0"
1019
  [(set_attr "length" "2")
1020
   (set_attr "cc" "none")])
1021
 
1022
(define_insn "tablejump"
1023
  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1024
   (use (label_ref (match_operand 1 "" "")))]
1025
  ""
1026
  "jmp  %0"
1027
  [(set_attr "length" "2")
1028
   (set_attr "cc" "none")])
1029
 
1030
(define_insn "switch"
1031
  [(set (pc)
1032
        (plus:SI
1033
         (sign_extend:SI
1034
          (mem:HI
1035
           (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1036
                               (const_int 1))
1037
                    (label_ref (match_operand 1 "" "")))))
1038
         (label_ref (match_dup 1))))]
1039
  "TARGET_V850E"
1040
  "switch %0"
1041
  [(set_attr "length" "2")
1042
   (set_attr "cc" "none")])
1043
 
1044
(define_expand "casesi"
1045
  [(match_operand:SI 0 "register_operand" "")
1046
   (match_operand:SI 1 "register_operand" "")
1047
   (match_operand:SI 2 "register_operand" "")
1048
   (match_operand 3 "" "") (match_operand 4 "" "")]
1049
  ""
1050
  "
1051
{
1052
  rtx reg = gen_reg_rtx (SImode);
1053
  rtx tableaddress = gen_reg_rtx (SImode);
1054
  rtx test;
1055
  rtx mem;
1056
 
1057
  /* Subtract the lower bound from the index.  */
1058
  emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1059
 
1060
  /* Compare the result against the number of table entries;
1061
     branch to the default label if out of range of the table.  */
1062
  test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]);
1063
  emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4]));
1064
 
1065
  /* Shift index for the table array access.  */
1066
  emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1067
  /* Load the table address into a pseudo.  */
1068
  emit_insn (gen_movsi (tableaddress,
1069
                        gen_rtx_LABEL_REF (Pmode, operands[3])));
1070
  /* Add the table address to the index.  */
1071
  emit_insn (gen_addsi3 (reg, reg, tableaddress));
1072
  /* Load the table entry.  */
1073
  mem = gen_const_mem (CASE_VECTOR_MODE, reg);
1074
  if (! TARGET_BIG_SWITCH)
1075
    {
1076
      rtx reg2 = gen_reg_rtx (HImode);
1077
      emit_insn (gen_movhi (reg2, mem));
1078
      emit_insn (gen_extendhisi2 (reg, reg2));
1079
    }
1080
  else
1081
    emit_insn (gen_movsi (reg, mem));
1082
  /* Add the table address.  */
1083
  emit_insn (gen_addsi3 (reg, reg, tableaddress));
1084
  /* Branch to the switch label.  */
1085
  emit_jump_insn (gen_tablejump (reg, operands[3]));
1086
  DONE;
1087
}")
1088
 
1089
;; Call subroutine with no return value.
1090
 
1091
(define_expand "call"
1092
  [(call (match_operand:QI 0 "general_operand" "")
1093
         (match_operand:SI 1 "general_operand" ""))]
1094
  ""
1095
  "
1096
{
1097
  if (! call_address_operand (XEXP (operands[0], 0), QImode)
1098
      || TARGET_LONG_CALLS)
1099
    XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1100
  if (TARGET_LONG_CALLS)
1101
    emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1102
  else
1103
    emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1104
 
1105
  DONE;
1106
}")
1107
 
1108
(define_insn "call_internal_short"
1109
  [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1110
         (match_operand:SI 1 "general_operand" "g,g"))
1111
   (clobber (reg:SI 31))]
1112
  "! TARGET_LONG_CALLS"
1113
  "@
1114
  jarl %0,r31
1115
  jarl .+4,r31 ; add 4,r31 ; jmp %0"
1116
  [(set_attr "length" "4,8")]
1117
)
1118
 
1119
(define_insn "call_internal_long"
1120
  [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1121
         (match_operand:SI 1 "general_operand" "g,g"))
1122
   (clobber (reg:SI 31))]
1123
  "TARGET_LONG_CALLS"
1124
  "*
1125
  {
1126
  if (which_alternative == 0)
1127
    {
1128
      if (GET_CODE (operands[0]) == REG)
1129
        return \"jarl %0,r31\";
1130
      else
1131
        return \"movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11\";
1132
    }
1133
  else
1134
    return \"jarl .+4,r31 ; add 4,r31 ; jmp %0\";
1135
  }"
1136
  [(set_attr "length" "16,8")]
1137
)
1138
 
1139
;; Call subroutine, returning value in operand 0
1140
;; (which must be a hard register).
1141
 
1142
(define_expand "call_value"
1143
  [(set (match_operand 0 "" "")
1144
        (call (match_operand:QI 1 "general_operand" "")
1145
              (match_operand:SI 2 "general_operand" "")))]
1146
  ""
1147
  "
1148
{
1149
  if (! call_address_operand (XEXP (operands[1], 0), QImode)
1150
      || TARGET_LONG_CALLS)
1151
    XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1152
  if (TARGET_LONG_CALLS)
1153
    emit_call_insn (gen_call_value_internal_long (operands[0],
1154
                                                  XEXP (operands[1], 0),
1155
                                                  operands[2]));
1156
  else
1157
    emit_call_insn (gen_call_value_internal_short (operands[0],
1158
                                                   XEXP (operands[1], 0),
1159
                                                   operands[2]));
1160
  DONE;
1161
}")
1162
 
1163
(define_insn "call_value_internal_short"
1164
  [(set (match_operand 0 "" "=r,r")
1165
        (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1166
              (match_operand:SI 2 "general_operand" "g,g")))
1167
   (clobber (reg:SI 31))]
1168
  "! TARGET_LONG_CALLS"
1169
  "@
1170
  jarl %1,r31
1171
  jarl .+4,r31 ; add 4,r31 ; jmp %1"
1172
  [(set_attr "length" "4,8")]
1173
)
1174
 
1175
(define_insn "call_value_internal_long"
1176
  [(set (match_operand 0 "" "=r,r")
1177
        (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1178
              (match_operand:SI 2 "general_operand" "g,g")))
1179
   (clobber (reg:SI 31))]
1180
  "TARGET_LONG_CALLS"
1181
  "*
1182
  {
1183
  if (which_alternative == 0)
1184
    {
1185
      if (GET_CODE (operands[1]) == REG)
1186
        return \"jarl %1, r31\";
1187
      else
1188
      /* Reload can generate this pattern....  */
1189
        return \"movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11\";
1190
    }
1191
  else
1192
    return \"jarl .+4, r31 ; add 4, r31 ; jmp %1\";
1193
  }"
1194
  [(set_attr "length" "16,8")]
1195
)
1196
 
1197
(define_insn "nop"
1198
  [(const_int 0)]
1199
  ""
1200
  "nop"
1201
  [(set_attr "length" "2")
1202
   (set_attr "cc" "none")])
1203
 
1204
;; ----------------------------------------------------------------------
1205
;; EXTEND INSTRUCTIONS
1206
;; ----------------------------------------------------------------------
1207
 
1208
(define_insn ""
1209
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1210
        (zero_extend:SI
1211
         (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))]
1212
  "TARGET_V850E"
1213
  "@
1214
   zxh %0
1215
   andi 65535,%1,%0
1216
   sld.hu %1,%0
1217
   ld.hu %1,%0"
1218
  [(set_attr "length" "2,4,2,4")
1219
   (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
1220
 
1221
(define_insn "zero_extendhisi2"
1222
  [(set (match_operand:SI 0 "register_operand" "=r")
1223
        (zero_extend:SI
1224
         (match_operand:HI 1 "register_operand" "r")))]
1225
  ""
1226
  "andi 65535,%1,%0"
1227
  [(set_attr "length" "4")
1228
   (set_attr "cc" "set_znv")])
1229
 
1230
(define_insn ""
1231
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1232
        (zero_extend:SI
1233
         (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))]
1234
  "TARGET_V850E"
1235
  "@
1236
   zxb %0
1237
   andi 255,%1,%0
1238
   sld.bu %1,%0
1239
   ld.bu %1,%0"
1240
  [(set_attr "length" "2,4,2,4")
1241
   (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
1242
 
1243
(define_insn "zero_extendqisi2"
1244
  [(set (match_operand:SI 0 "register_operand" "=r")
1245
        (zero_extend:SI
1246
         (match_operand:QI 1 "register_operand" "r")))]
1247
  ""
1248
  "andi 255,%1,%0"
1249
  [(set_attr "length" "4")
1250
   (set_attr "cc" "set_znv")])
1251
 
1252
;;- sign extension instructions
1253
 
1254
;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1255
 
1256
(define_insn "*extendhisi_insn"
1257
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1258
        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))]
1259
  "TARGET_V850E"
1260
  "@
1261
   sxh %0
1262
   sld.h %1,%0
1263
   ld.h %1,%0"
1264
  [(set_attr "length" "2,2,4")
1265
   (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1266
 
1267
;; ??? This is missing a sign extend from memory pattern to match the ld.h
1268
;; instruction.
1269
 
1270
(define_expand "extendhisi2"
1271
  [(set (match_dup 2)
1272
        (ashift:SI (match_operand:HI 1 "register_operand" "")
1273
                   (const_int 16)))
1274
   (set (match_operand:SI 0 "register_operand" "")
1275
       (ashiftrt:SI (match_dup 2)
1276
                     (const_int 16)))]
1277
  ""
1278
  "
1279
{
1280
  operands[1] = gen_lowpart (SImode, operands[1]);
1281
  operands[2] = gen_reg_rtx (SImode);
1282
}")
1283
 
1284
;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1285
 
1286
(define_insn "*extendqisi_insn"
1287
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1288
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))]
1289
  "TARGET_V850E"
1290
  "@
1291
   sxb %0
1292
   sld.b %1,%0
1293
   ld.b %1,%0"
1294
  [(set_attr "length" "2,2,4")
1295
   (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1296
 
1297
;; ??? This is missing a sign extend from memory pattern to match the ld.b
1298
;; instruction.
1299
 
1300
(define_expand "extendqisi2"
1301
  [(set (match_dup 2)
1302
        (ashift:SI (match_operand:QI 1 "register_operand" "")
1303
                   (const_int 24)))
1304
   (set (match_operand:SI 0 "register_operand" "")
1305
        (ashiftrt:SI (match_dup 2)
1306
                     (const_int 24)))]
1307
  ""
1308
  "
1309
{
1310
  operands[1] = gen_lowpart (SImode, operands[1]);
1311
  operands[2] = gen_reg_rtx (SImode);
1312
}")
1313
 
1314
;; ----------------------------------------------------------------------
1315
;; SHIFTS
1316
;; ----------------------------------------------------------------------
1317
 
1318
(define_insn "ashlsi3"
1319
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1320
        (ashift:SI
1321
         (match_operand:SI 1 "register_operand" "0,0")
1322
         (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1323
  ""
1324
  "@
1325
  shl %2,%0
1326
  shl %2,%0"
1327
  [(set_attr "length" "4,2")
1328
   (set_attr "cc" "set_znv")])
1329
 
1330
(define_insn "lshrsi3"
1331
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1332
        (lshiftrt:SI
1333
         (match_operand:SI 1 "register_operand" "0,0")
1334
         (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1335
  ""
1336
  "@
1337
  shr %2,%0
1338
  shr %2,%0"
1339
  [(set_attr "length" "4,2")
1340
   (set_attr "cc" "set_znv")])
1341
 
1342
(define_insn "ashrsi3"
1343
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1344
        (ashiftrt:SI
1345
         (match_operand:SI 1 "register_operand" "0,0")
1346
         (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1347
  ""
1348
  "@
1349
  sar %2,%0
1350
  sar %2,%0"
1351
  [(set_attr "length" "4,2")
1352
   (set_attr "cc" "set_znv")])
1353
 
1354
;; ----------------------------------------------------------------------
1355
;; PROLOGUE/EPILOGUE
1356
;; ----------------------------------------------------------------------
1357
(define_expand "prologue"
1358
  [(const_int 0)]
1359
  ""
1360
  "expand_prologue (); DONE;")
1361
 
1362
(define_expand "epilogue"
1363
  [(return)]
1364
  ""
1365
  "
1366
{
1367
  expand_epilogue ();
1368
  DONE;
1369
}")
1370
 
1371
(define_insn "return_simple"
1372
  [(return)]
1373
  "reload_completed"
1374
  "jmp [r31]"
1375
  [(set_attr "length" "2")
1376
   (set_attr "cc" "none")])
1377
 
1378
(define_insn "return_internal"
1379
  [(return)
1380
   (use (reg:SI 31))]
1381
  ""
1382
  "jmp [r31]"
1383
  [(set_attr "length" "2")
1384
   (set_attr "cc" "none")])
1385
 
1386
 
1387
 
1388
;; ----------------------------------------------------------------------
1389
;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers
1390
;; ----------------------------------------------------------------------
1391
 
1392
;; This pattern will match a stack adjust RTX followed by any number of push
1393
;; RTXs.  These RTXs will then be turned into a suitable call to a worker
1394
;; function.
1395
 
1396
;;
1397
;; Actually, convert the RTXs into a PREPARE instruction.
1398
;;
1399
(define_insn ""
1400
 [(match_parallel 0 "pattern_is_ok_for_prepare"
1401
   [(set (reg:SI 3)
1402
         (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1403
    (set (mem:SI (plus:SI (reg:SI 3)
1404
                          (match_operand:SI 2 "immediate_operand" "i")))
1405
         (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1406
 "TARGET_PROLOG_FUNCTION && TARGET_V850E"
1407
 "* return construct_prepare_instruction (operands[0]);
1408
 "
1409
 [(set_attr "length" "4")
1410
  (set_attr "cc"     "none")])
1411
 
1412
(define_insn ""
1413
 [(match_parallel 0 "pattern_is_ok_for_prologue"
1414
   [(set (reg:SI 3)
1415
         (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1416
    (set (mem:SI (plus:SI (reg:SI 3)
1417
                           (match_operand:SI 2 "immediate_operand" "i")))
1418
         (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1419
 "TARGET_PROLOG_FUNCTION && TARGET_V850"
1420
 "* return construct_save_jarl (operands[0]);
1421
 "
1422
 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1423
                                     (const_string "16")
1424
                                     (const_string "4")))
1425
  (set_attr "cc"     "clobber")])
1426
 
1427
;;
1428
;; Actually, turn the RTXs into a DISPOSE instruction.
1429
;;
1430
(define_insn ""
1431
 [(match_parallel 0 "pattern_is_ok_for_dispose"
1432
   [(return)
1433
    (set (reg:SI 3)
1434
         (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1435
    (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1436
         (mem:SI (plus:SI (reg:SI 3)
1437
                          (match_operand:SI 3 "immediate_operand" "i"))))])]
1438
 "TARGET_PROLOG_FUNCTION && TARGET_V850E"
1439
 "* return construct_dispose_instruction (operands[0]);
1440
 "
1441
 [(set_attr "length" "4")
1442
  (set_attr "cc"     "none")])
1443
 
1444
;; This pattern will match a return RTX followed by any number of pop RTXs
1445
;; and possible a stack adjustment as well.  These RTXs will be turned into
1446
;; a suitable call to a worker function.
1447
 
1448
(define_insn ""
1449
[(match_parallel 0 "pattern_is_ok_for_epilogue"
1450
   [(return)
1451
    (set (reg:SI 3)
1452
         (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1453
    (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1454
         (mem:SI (plus:SI (reg:SI 3)
1455
                          (match_operand:SI 3 "immediate_operand" "i"))))])]
1456
 "TARGET_PROLOG_FUNCTION && TARGET_V850"
1457
 "* return construct_restore_jr (operands[0]);
1458
 "
1459
 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1460
                                     (const_string "12")
1461
                                     (const_string "4")))
1462
  (set_attr "cc"     "clobber")])
1463
 
1464
;; Initialize an interrupt function.  Do not depend on TARGET_PROLOG_FUNCTION.
1465
(define_insn "callt_save_interrupt"
1466
  [(unspec_volatile [(const_int 0)] 2)]
1467
    "TARGET_V850E && !TARGET_DISABLE_CALLT"
1468
    ;; The CALLT instruction stores the next address of CALLT to CTPC register
1469
    ;; without saving its previous value.  So if the interrupt handler
1470
    ;; or its caller could possibly execute the CALLT insn, save_interrupt
1471
    ;; MUST NOT be called via CALLT.
1472
    "*
1473
{
1474
  output_asm_insn (\"addi -24,   sp, sp\", operands);
1475
  output_asm_insn (\"st.w r10,   12[sp]\", operands);
1476
  output_asm_insn (\"stsr ctpc,  r10\",    operands);
1477
  output_asm_insn (\"st.w r10,   16[sp]\", operands);
1478
  output_asm_insn (\"stsr ctpsw, r10\",    operands);
1479
  output_asm_insn (\"st.w r10,   20[sp]\", operands);
1480
  output_asm_insn (\"callt ctoff(__callt_save_interrupt)\", operands);
1481
  return \"\";
1482
}"
1483
   [(set_attr "length" "26")
1484
    (set_attr "cc" "none")])
1485
 
1486
(define_insn "callt_return_interrupt"
1487
  [(unspec_volatile [(const_int 0)] 3)]
1488
  "TARGET_V850E && !TARGET_DISABLE_CALLT"
1489
  "callt ctoff(__callt_return_interrupt)"
1490
  [(set_attr "length" "2")
1491
   (set_attr "cc" "clobber")])
1492
 
1493
(define_insn "save_interrupt"
1494
  [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
1495
   (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 30))
1496
   (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 4))
1497
   (set (mem:SI (plus:SI (reg:SI 3) (const_int  -8))) (reg:SI 1))
1498
   (set (mem:SI (plus:SI (reg:SI 3) (const_int  -4))) (reg:SI 10))]
1499
  ""
1500
  "*
1501
{
1502
  if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1503
    return \"add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10\";
1504
  else
1505
    {
1506
      output_asm_insn (\"add   -16, sp\", operands);
1507
      output_asm_insn (\"st.w  r10, 12[sp]\", operands);
1508
      output_asm_insn (\"st.w  ep, 0[sp]\", operands);
1509
      output_asm_insn (\"st.w  gp, 4[sp]\", operands);
1510
      output_asm_insn (\"st.w  r1, 8[sp]\", operands);
1511
      output_asm_insn (\"movhi hi(__ep), r0, ep\", operands);
1512
      output_asm_insn (\"movea lo(__ep), ep, ep\", operands);
1513
      output_asm_insn (\"movhi hi(__gp), r0, gp\", operands);
1514
      output_asm_insn (\"movea lo(__gp), gp, gp\", operands);
1515
      return \"\";
1516
    }
1517
}"
1518
  [(set (attr "length")
1519
        (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1520
                       (const_int 10)
1521
                       (const_int 34)))
1522
   (set_attr "cc" "clobber")])
1523
 
1524
;; Restore r1, r4, r10, and return from the interrupt
1525
(define_insn "return_interrupt"
1526
  [(return)
1527
   (set (reg:SI 3)  (plus:SI (reg:SI 3) (const_int 16)))
1528
   (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
1529
   (set (reg:SI 1)  (mem:SI (plus:SI (reg:SI 3) (const_int  8))))
1530
   (set (reg:SI 4)  (mem:SI (plus:SI (reg:SI 3) (const_int  4))))
1531
   (set (reg:SI 30) (mem:SI (reg:SI 3)))]
1532
  ""
1533
  "*
1534
{
1535
  if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1536
    return \"jr __return_interrupt\";
1537
  else
1538
    {
1539
      output_asm_insn (\"ld.w 0[sp],  ep\",   operands);
1540
      output_asm_insn (\"ld.w 4[sp],  gp\",   operands);
1541
      output_asm_insn (\"ld.w 8[sp],  r1\",   operands);
1542
      output_asm_insn (\"ld.w 12[sp], r10\", operands);
1543
      output_asm_insn (\"addi 16, sp, sp\",   operands);
1544
      output_asm_insn (\"reti\",            operands);
1545
      return \"\";
1546
    }
1547
}"
1548
  [(set (attr "length")
1549
        (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1550
                       (const_int 4)
1551
                       (const_int 24)))
1552
   (set_attr "cc" "clobber")])
1553
 
1554
;; Save all registers except for the registers saved in save_interrupt when
1555
;; an interrupt function makes a call.
1556
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1557
;; all of memory.  This blocks insns from being moved across this point.
1558
;; This is needed because the rest of the compiler is not ready to handle
1559
;; insns this complicated.
1560
 
1561
(define_insn "callt_save_all_interrupt"
1562
  [(unspec_volatile [(const_int 0)] 0)]
1563
  "TARGET_V850E && !TARGET_DISABLE_CALLT"
1564
  "callt ctoff(__callt_save_all_interrupt)"
1565
  [(set_attr "length" "2")
1566
   (set_attr "cc" "none")])
1567
 
1568
(define_insn "save_all_interrupt"
1569
  [(unspec_volatile [(const_int 0)] 0)]
1570
  ""
1571
  "*
1572
{
1573
  if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1574
    return \"jarl __save_all_interrupt,r10\";
1575
 
1576
  output_asm_insn (\"addi -120, sp, sp\", operands);
1577
 
1578
  if (TARGET_EP)
1579
    {
1580
      output_asm_insn (\"mov ep, r1\", operands);
1581
      output_asm_insn (\"mov sp, ep\", operands);
1582
      output_asm_insn (\"sst.w r31, 116[ep]\", operands);
1583
      output_asm_insn (\"sst.w r2,  112[ep]\", operands);
1584
      output_asm_insn (\"sst.w gp,  108[ep]\", operands);
1585
      output_asm_insn (\"sst.w r6,  104[ep]\", operands);
1586
      output_asm_insn (\"sst.w r7,  100[ep]\", operands);
1587
      output_asm_insn (\"sst.w r8,   96[ep]\", operands);
1588
      output_asm_insn (\"sst.w r9,   92[ep]\", operands);
1589
      output_asm_insn (\"sst.w r11,  88[ep]\", operands);
1590
      output_asm_insn (\"sst.w r12,  84[ep]\", operands);
1591
      output_asm_insn (\"sst.w r13,  80[ep]\", operands);
1592
      output_asm_insn (\"sst.w r14,  76[ep]\", operands);
1593
      output_asm_insn (\"sst.w r15,  72[ep]\", operands);
1594
      output_asm_insn (\"sst.w r16,  68[ep]\", operands);
1595
      output_asm_insn (\"sst.w r17,  64[ep]\", operands);
1596
      output_asm_insn (\"sst.w r18,  60[ep]\", operands);
1597
      output_asm_insn (\"sst.w r19,  56[ep]\", operands);
1598
      output_asm_insn (\"sst.w r20,  52[ep]\", operands);
1599
      output_asm_insn (\"sst.w r21,  48[ep]\", operands);
1600
      output_asm_insn (\"sst.w r22,  44[ep]\", operands);
1601
      output_asm_insn (\"sst.w r23,  40[ep]\", operands);
1602
      output_asm_insn (\"sst.w r24,  36[ep]\", operands);
1603
      output_asm_insn (\"sst.w r25,  32[ep]\", operands);
1604
      output_asm_insn (\"sst.w r26,  28[ep]\", operands);
1605
      output_asm_insn (\"sst.w r27,  24[ep]\", operands);
1606
      output_asm_insn (\"sst.w r28,  20[ep]\", operands);
1607
      output_asm_insn (\"sst.w r29,  16[ep]\", operands);
1608
      output_asm_insn (\"mov   r1,   ep\", operands);
1609
    }
1610
  else
1611
    {
1612
      output_asm_insn (\"st.w r31, 116[sp]\", operands);
1613
      output_asm_insn (\"st.w r2,  112[sp]\", operands);
1614
      output_asm_insn (\"st.w gp,  108[sp]\", operands);
1615
      output_asm_insn (\"st.w r6,  104[sp]\", operands);
1616
      output_asm_insn (\"st.w r7,  100[sp]\", operands);
1617
      output_asm_insn (\"st.w r8,   96[sp]\", operands);
1618
      output_asm_insn (\"st.w r9,   92[sp]\", operands);
1619
      output_asm_insn (\"st.w r11,  88[sp]\", operands);
1620
      output_asm_insn (\"st.w r12,  84[sp]\", operands);
1621
      output_asm_insn (\"st.w r13,  80[sp]\", operands);
1622
      output_asm_insn (\"st.w r14,  76[sp]\", operands);
1623
      output_asm_insn (\"st.w r15,  72[sp]\", operands);
1624
      output_asm_insn (\"st.w r16,  68[sp]\", operands);
1625
      output_asm_insn (\"st.w r17,  64[sp]\", operands);
1626
      output_asm_insn (\"st.w r18,  60[sp]\", operands);
1627
      output_asm_insn (\"st.w r19,  56[sp]\", operands);
1628
      output_asm_insn (\"st.w r20,  52[sp]\", operands);
1629
      output_asm_insn (\"st.w r21,  48[sp]\", operands);
1630
      output_asm_insn (\"st.w r22,  44[sp]\", operands);
1631
      output_asm_insn (\"st.w r23,  40[sp]\", operands);
1632
      output_asm_insn (\"st.w r24,  36[sp]\", operands);
1633
      output_asm_insn (\"st.w r25,  32[sp]\", operands);
1634
      output_asm_insn (\"st.w r26,  28[sp]\", operands);
1635
      output_asm_insn (\"st.w r27,  24[sp]\", operands);
1636
      output_asm_insn (\"st.w r28,  20[sp]\", operands);
1637
      output_asm_insn (\"st.w r29,  16[sp]\", operands);
1638
    }
1639
 
1640
  return \"\";
1641
}"
1642
  [(set (attr "length")
1643
        (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1644
                       (const_int 4)
1645
                       (const_int 62)
1646
        ))
1647
   (set_attr "cc" "clobber")])
1648
 
1649
(define_insn "_save_all_interrupt"
1650
  [(unspec_volatile [(const_int 0)] 0)]
1651
  "TARGET_V850 && ! TARGET_LONG_CALLS"
1652
  "jarl __save_all_interrupt,r10"
1653
  [(set_attr "length" "4")
1654
   (set_attr "cc" "clobber")])
1655
 
1656
;; Restore all registers saved when an interrupt function makes a call.
1657
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1658
;; all of memory.  This blocks insns from being moved across this point.
1659
;; This is needed because the rest of the compiler is not ready to handle
1660
;; insns this complicated.
1661
 
1662
(define_insn "callt_restore_all_interrupt"
1663
  [(unspec_volatile [(const_int 0)] 1)]
1664
  "TARGET_V850E && !TARGET_DISABLE_CALLT"
1665
  "callt ctoff(__callt_restore_all_interrupt)"
1666
  [(set_attr "length" "2")
1667
   (set_attr "cc" "none")])
1668
 
1669
(define_insn "restore_all_interrupt"
1670
  [(unspec_volatile [(const_int 0)] 1)]
1671
  ""
1672
  "*
1673
{
1674
  if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1675
    return \"jarl __restore_all_interrupt,r10\";
1676
 
1677
  if (TARGET_EP)
1678
    {
1679
      output_asm_insn (\"mov   ep,      r1\", operands);
1680
      output_asm_insn (\"mov   sp,      ep\", operands);
1681
      output_asm_insn (\"sld.w 116[ep], r31\", operands);
1682
      output_asm_insn (\"sld.w 112[ep], r2\", operands);
1683
      output_asm_insn (\"sld.w 108[ep], gp\", operands);
1684
      output_asm_insn (\"sld.w 104[ep], r6\", operands);
1685
      output_asm_insn (\"sld.w 100[ep], r7\", operands);
1686
      output_asm_insn (\"sld.w 96[ep],  r8\", operands);
1687
      output_asm_insn (\"sld.w 92[ep],  r9\", operands);
1688
      output_asm_insn (\"sld.w 88[ep],  r11\", operands);
1689
      output_asm_insn (\"sld.w 84[ep],  r12\", operands);
1690
      output_asm_insn (\"sld.w 80[ep],  r13\", operands);
1691
      output_asm_insn (\"sld.w 76[ep],  r14\", operands);
1692
      output_asm_insn (\"sld.w 72[ep],  r15\", operands);
1693
      output_asm_insn (\"sld.w 68[ep],  r16\", operands);
1694
      output_asm_insn (\"sld.w 64[ep],  r17\", operands);
1695
      output_asm_insn (\"sld.w 60[ep],  r18\", operands);
1696
      output_asm_insn (\"sld.w 56[ep],  r19\", operands);
1697
      output_asm_insn (\"sld.w 52[ep],  r20\", operands);
1698
      output_asm_insn (\"sld.w 48[ep],  r21\", operands);
1699
      output_asm_insn (\"sld.w 44[ep],  r22\", operands);
1700
      output_asm_insn (\"sld.w 40[ep],  r23\", operands);
1701
      output_asm_insn (\"sld.w 36[ep],  r24\", operands);
1702
      output_asm_insn (\"sld.w 32[ep],  r25\", operands);
1703
      output_asm_insn (\"sld.w 28[ep],  r26\", operands);
1704
      output_asm_insn (\"sld.w 24[ep],  r27\", operands);
1705
      output_asm_insn (\"sld.w 20[ep],  r28\", operands);
1706
      output_asm_insn (\"sld.w 16[ep],  r29\", operands);
1707
      output_asm_insn (\"mov   r1,      ep\", operands);
1708
    }
1709
  else
1710
    {
1711
      output_asm_insn (\"ld.w 116[sp], r31\", operands);
1712
      output_asm_insn (\"ld.w 112[sp], r2\", operands);
1713
      output_asm_insn (\"ld.w 108[sp], gp\", operands);
1714
      output_asm_insn (\"ld.w 104[sp], r6\", operands);
1715
      output_asm_insn (\"ld.w 100[sp], r7\", operands);
1716
      output_asm_insn (\"ld.w 96[sp],  r8\", operands);
1717
      output_asm_insn (\"ld.w 92[sp],  r9\", operands);
1718
      output_asm_insn (\"ld.w 88[sp],  r11\", operands);
1719
      output_asm_insn (\"ld.w 84[sp],  r12\", operands);
1720
      output_asm_insn (\"ld.w 80[sp],  r13\", operands);
1721
      output_asm_insn (\"ld.w 76[sp],  r14\", operands);
1722
      output_asm_insn (\"ld.w 72[sp],  r15\", operands);
1723
      output_asm_insn (\"ld.w 68[sp],  r16\", operands);
1724
      output_asm_insn (\"ld.w 64[sp],  r17\", operands);
1725
      output_asm_insn (\"ld.w 60[sp],  r18\", operands);
1726
      output_asm_insn (\"ld.w 56[sp],  r19\", operands);
1727
      output_asm_insn (\"ld.w 52[sp],  r20\", operands);
1728
      output_asm_insn (\"ld.w 48[sp],  r21\", operands);
1729
      output_asm_insn (\"ld.w 44[sp],  r22\", operands);
1730
      output_asm_insn (\"ld.w 40[sp],  r23\", operands);
1731
      output_asm_insn (\"ld.w 36[sp],  r24\", operands);
1732
      output_asm_insn (\"ld.w 32[sp],  r25\", operands);
1733
      output_asm_insn (\"ld.w 28[sp],  r26\", operands);
1734
      output_asm_insn (\"ld.w 24[sp],  r27\", operands);
1735
      output_asm_insn (\"ld.w 20[sp],  r28\", operands);
1736
      output_asm_insn (\"ld.w 16[sp],  r29\", operands);
1737
    }
1738
  output_asm_insn (\"addi  120, sp, sp\", operands);
1739
  return \"\";
1740
}"
1741
  [(set (attr "length")
1742
        (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1743
                       (const_int 4)
1744
                       (const_int 62)
1745
        ))
1746
   (set_attr "cc" "clobber")])
1747
 
1748
(define_insn "_restore_all_interrupt"
1749
  [(unspec_volatile [(const_int 0)] 1)]
1750
  "TARGET_V850 && ! TARGET_LONG_CALLS"
1751
  "jarl __restore_all_interrupt,r10"
1752
  [(set_attr "length" "4")
1753
   (set_attr "cc" "clobber")])
1754
 
1755
;; Save r6-r9 for a variable argument function
1756
(define_insn "save_r6_r9_v850e"
1757
  [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1758
   (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1759
   (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1760
   (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1761
  ]
1762
  "TARGET_PROLOG_FUNCTION && TARGET_V850E && !TARGET_DISABLE_CALLT"
1763
  "callt ctoff(__callt_save_r6_r9)"
1764
  [(set_attr "length" "2")
1765
   (set_attr "cc" "none")])
1766
 
1767
(define_insn "save_r6_r9"
1768
  [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1769
   (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1770
   (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1771
   (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1772
   (clobber (reg:SI 10))]
1773
  "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS"
1774
  "jarl __save_r6_r9,r10"
1775
  [(set_attr "length" "4")
1776
   (set_attr "cc" "clobber")])
1777
 

powered by: WebSVN 2.1.0

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