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/] [vax/] [vax.md] - Blame information for rev 282

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 282 jeremybenn
;; Machine description for GNU compiler, VAX Version
2
;; Copyright (C) 1987, 1988, 1991, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
3
;; 2002, 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
4
 
5
;; This file is part of GCC.
6
 
7
;; GCC is free software; you can redistribute it and/or modify
8
;; it under the terms of the GNU General Public License as published by
9
;; the Free Software Foundation; either version 3, or (at your option)
10
;; any later version.
11
 
12
;; GCC is distributed in the hope that it will be useful,
13
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
;; GNU General Public License for more details.
16
 
17
;; You should have received a copy of the GNU General Public License
18
;; along with GCC; see the file COPYING3.  If not see
19
;; .
20
 
21
 
22
;;- Instruction patterns.  When multiple patterns apply,
23
;;- the first one in the file is chosen.
24
;;-
25
;;- See file "rtl.def" for documentation on define_insn, match_*, et al.
26
;;-
27
;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
28
;;- updates for most instructions.
29
 
30
;; UNSPEC_VOLATILE usage:
31
 
32
(define_constants
33
  [(VUNSPEC_BLOCKAGE 0)     ; `blockage' insn to prevent scheduling across an
34
                            ; insn in the code.
35
   (VUNSPEC_SYNC_ISTREAM 1) ; sequence of insns to sync the I-stream
36
   (VAX_AP_REGNUM 12)       ; Register 12 contains the argument pointer
37
   (VAX_FP_REGNUM 13)       ; Register 13 contains the frame pointer
38
   (VAX_SP_REGNUM 14)       ; Register 14 contains the stack pointer
39
   (VAX_PC_REGNUM 15)       ; Register 15 contains the program counter
40
  ]
41
)
42
 
43
;; Integer modes supported on VAX, with a mapping from machine mode
44
;; to mnemonic suffix.  DImode is always a special case.
45
(define_mode_iterator VAXint [QI HI SI])
46
(define_mode_iterator VAXintQH [QI HI])
47
(define_mode_iterator VAXintQHSD [QI HI SI DI])
48
(define_mode_attr  isfx [(QI "b") (HI "w") (SI "l") (DI "q")])
49
 
50
;; Similar for float modes supported on VAX.
51
(define_mode_iterator VAXfp [SF DF])
52
(define_mode_attr  fsfx [(SF "f") (DF "%#")])
53
 
54
;; Some output patterns want integer immediates with a prefix...
55
(define_mode_attr  iprefx [(QI "B") (HI "H") (SI "N")])
56
 
57
;;
58
(include "constraints.md")
59
(include "predicates.md")
60
 
61
(define_insn "*cmp"
62
  [(set (cc0)
63
        (compare (match_operand:VAXint 0 "nonimmediate_operand" "nrmT,nrmT")
64
                 (match_operand:VAXint 1 "general_operand" "I,nrmT")))]
65
  ""
66
  "@
67
   tst %0
68
   cmp %0,%1")
69
 
70
(define_insn "*cmp"
71
  [(set (cc0)
72
        (compare (match_operand:VAXfp 0 "general_operand" "gF,gF")
73
                 (match_operand:VAXfp 1 "general_operand" "G,gF")))]
74
  ""
75
  "@
76
   tst %0
77
   cmp %0,%1")
78
 
79
(define_insn "*bit"
80
  [(set (cc0)
81
        (compare (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT")
82
                             (match_operand:VAXint 1 "general_operand" "nrmT"))
83
                 (const_int 0)))]
84
  ""
85
  "bit %0,%1")
86
 
87
;; The VAX has no sCOND insns.  It does have add/subtract with carry
88
;; which could be used to implement the sltu and sgeu patterns.  However,
89
;; to do this properly requires a complete rewrite of the compare insns
90
;; to keep them together with the sltu/sgeu insns until after the
91
;; reload pass is complete.  The previous implementation didn't do this
92
;; and has been deleted.
93
 
94
 
95
(define_insn "mov"
96
  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
97
        (match_operand:VAXfp 1 "general_operand" "G,gF"))]
98
  ""
99
  "@
100
   clr %0
101
   mov %1,%0")
102
 
103
;; Some VAXen don't support this instruction.
104
;;(define_insn "movti"
105
;;  [(set (match_operand:TI 0 "general_operand" "=g")
106
;;      (match_operand:TI 1 "general_operand" "g"))]
107
;;  ""
108
;;  "movh %1,%0")
109
 
110
(define_insn "movdi"
111
  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
112
        (match_operand:DI 1 "general_operand" "g"))]
113
  ""
114
  "* return vax_output_int_move (insn, operands, DImode);")
115
 
116
;; The VAX move instructions have space-time tradeoffs.  On a MicroVAX
117
;; register-register mov instructions take 3 bytes and 2 CPU cycles.  clrl
118
;; takes 2 bytes and 3 cycles.  mov from constant to register takes 2 cycles
119
;; if the constant is smaller than 4 bytes, 3 cycles for a longword
120
;; constant.  movz, mneg, and mcom are as fast as mov, so movzwl is faster
121
;; than movl for positive constants that fit in 16 bits but not 6 bits.  cvt
122
;; instructions take 4 cycles.  inc takes 3 cycles.  The machine description
123
;; is willing to trade 1 byte for 1 cycle (clrl instead of movl $0; cvtwl
124
;; instead of movl).
125
 
126
;; Cycle counts for other models may vary (on a VAX 750 they are similar,
127
;; but on a VAX 9000 most move and add instructions with one constant
128
;; operand take 1 cycle).
129
 
130
;;  Loads of constants between 64 and 128 used to be done with
131
;; "addl3 $63,#,dst" but this is slower than movzbl and takes as much space.
132
 
133
(define_expand "movsi"
134
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
135
        (match_operand:SI 1 "general_operand" ""))]
136
  ""
137
  "
138
{
139
#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
140
  if (flag_pic
141
      && GET_CODE (operands[1]) == CONST
142
      && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF
143
      && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (operands[1], 0), 0)))
144
    {
145
      rtx symbol_ref = XEXP (XEXP (operands[1], 0), 0);
146
      rtx const_int = XEXP (XEXP (operands[1], 0), 1);
147
      rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
148
      emit_move_insn (temp, symbol_ref);
149
      emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, const_int));
150
      DONE;
151
    }
152
#endif
153
}")
154
 
155
(define_insn "movsi_2"
156
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
157
        (match_operand:SI 1 "nonsymbolic_operand" "nrmT"))]
158
  ""
159
  "* return vax_output_int_move (insn, operands, SImode);")
160
 
161
(define_insn "mov"
162
  [(set (match_operand:VAXintQH 0 "nonimmediate_operand" "=g")
163
        (match_operand:VAXintQH 1 "general_operand" "g"))]
164
  ""
165
  "* return vax_output_int_move (insn, operands, mode);")
166
 
167
(define_insn "movstricthi"
168
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+g"))
169
        (match_operand:HI 1 "general_operand" "g"))]
170
  ""
171
  "*
172
{
173
  if (CONST_INT_P (operands[1]))
174
    {
175
      int i = INTVAL (operands[1]);
176
      if (i == 0)
177
        return \"clrw %0\";
178
      else if ((unsigned int)i < 64)
179
        return \"movw %1,%0\";
180
      else if ((unsigned int)~i < 64)
181
        return \"mcomw %H1,%0\";
182
      else if ((unsigned int)i < 256)
183
        return \"movzbw %1,%0\";
184
    }
185
  return \"movw %1,%0\";
186
}")
187
 
188
(define_insn "movstrictqi"
189
  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+g"))
190
        (match_operand:QI 1 "general_operand" "g"))]
191
  ""
192
  "*
193
{
194
  if (CONST_INT_P (operands[1]))
195
    {
196
      int i = INTVAL (operands[1]);
197
      if (i == 0)
198
        return \"clrb %0\";
199
      else if ((unsigned int)~i < 64)
200
        return \"mcomb %B1,%0\";
201
    }
202
  return \"movb %1,%0\";
203
}")
204
 
205
;; This is here to accept 4 arguments and pass the first 3 along
206
;; to the movmemhi1 pattern that really does the work.
207
(define_expand "movmemhi"
208
  [(set (match_operand:BLK 0 "general_operand" "=g")
209
        (match_operand:BLK 1 "general_operand" "g"))
210
   (use (match_operand:HI 2 "general_operand" "g"))
211
   (match_operand 3 "" "")]
212
  ""
213
  "
214
{
215
  emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2]));
216
  DONE;
217
}")
218
 
219
;; The definition of this insn does not really explain what it does,
220
;; but it should suffice
221
;; that anything generated as this insn will be recognized as one
222
;; and that it won't successfully combine with anything.
223
 
224
(define_insn "movmemhi1"
225
  [(set (match_operand:BLK 0 "memory_operand" "=o")
226
        (match_operand:BLK 1 "memory_operand" "o"))
227
   (use (match_operand:HI 2 "general_operand" "g"))
228
   (clobber (reg:SI 0))
229
   (clobber (reg:SI 1))
230
   (clobber (reg:SI 2))
231
   (clobber (reg:SI 3))
232
   (clobber (reg:SI 4))
233
   (clobber (reg:SI 5))]
234
  ""
235
  "movc3 %2,%1,%0")
236
 
237
;; Extension and truncation insns.
238
 
239
(define_insn "truncsiqi2"
240
  [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
241
        (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))]
242
  ""
243
  "cvtlb %1,%0")
244
 
245
(define_insn "truncsihi2"
246
  [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
247
        (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))]
248
  ""
249
  "cvtlw %1,%0")
250
 
251
(define_insn "trunchiqi2"
252
  [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
253
        (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))]
254
  ""
255
  "cvtwb %1,%0")
256
 
257
(define_insn "extendhisi2"
258
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
259
        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
260
  ""
261
  "cvtwl %1,%0")
262
 
263
(define_insn "extendqihi2"
264
  [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
265
        (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
266
  ""
267
  "cvtbw %1,%0")
268
 
269
(define_insn "extendqisi2"
270
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
271
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
272
  ""
273
  "cvtbl %1,%0")
274
 
275
(define_insn "extendsfdf2"
276
  [(set (match_operand:DF 0 "nonimmediate_operand" "=g")
277
        (float_extend:DF (match_operand:SF 1 "general_operand" "gF")))]
278
  ""
279
  "cvtf%# %1,%0")
280
 
281
(define_insn "truncdfsf2"
282
  [(set (match_operand:SF 0 "nonimmediate_operand" "=g")
283
        (float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))]
284
  ""
285
  "cvt%#f %1,%0")
286
 
287
(define_insn "zero_extendhisi2"
288
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
289
        (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
290
  ""
291
  "movzwl %1,%0")
292
 
293
(define_insn "zero_extendqihi2"
294
  [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
295
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
296
  ""
297
  "movzbw %1,%0")
298
 
299
(define_insn "zero_extendqisi2"
300
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
301
        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
302
  ""
303
  "movzbl %1,%0")
304
 
305
;; Fix-to-float conversion insns.
306
 
307
(define_insn "float2"
308
  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
309
        (float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g")))]
310
  ""
311
  "cvt %1,%0")
312
 
313
;; Float-to-fix conversion insns.
314
 
315
(define_insn "fix_trunc2"
316
  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
317
        (fix:VAXint (fix:VAXfp (match_operand:VAXfp 1 "general_operand" "gF"))))]
318
  ""
319
  "cvt %1,%0")
320
 
321
;;- All kinds of add instructions.
322
 
323
(define_insn "add3"
324
  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
325
        (plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
326
                    (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))]
327
  ""
328
  "@
329
   add2 %2,%0
330
   add2 %1,%0
331
   add3 %1,%2,%0")
332
 
333
(define_insn "pushlclsymreg"
334
  [(set (match_operand:SI 0 "push_operand" "=g")
335
        (plus:SI (match_operand:SI 1 "register_operand" "%r")
336
                 (match_operand:SI 2 "local_symbolic_operand" "i")))]
337
  "flag_pic"
338
  "pushab %a2[%1]")
339
 
340
(define_insn "pushextsymreg"
341
  [(set (match_operand:SI 0 "push_operand" "=g")
342
        (plus:SI (match_operand:SI 1 "register_operand" "%r")
343
                 (match_operand:SI 2 "external_symbolic_operand" "i")))]
344
  "flag_pic"
345
  "pushab %a2[%1]")
346
 
347
(define_insn "movlclsymreg"
348
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
349
        (plus:SI (match_operand:SI 1 "register_operand" "%r")
350
                 (match_operand:SI 2 "local_symbolic_operand" "i")))]
351
  "flag_pic"
352
  "movab %a2[%1],%0")
353
 
354
(define_insn "movextsymreg"
355
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
356
        (plus:SI (match_operand:SI 1 "register_operand" "%r")
357
                 (match_operand:SI 2 "external_symbolic_operand" "i")))]
358
  "flag_pic"
359
  "movab %a2[%1],%0")
360
 
361
(define_insn "add3"
362
  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
363
        (plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")
364
                    (match_operand:VAXint 2 "general_operand" "nrmT")))]
365
  ""
366
  "* return vax_output_int_add (insn, operands, mode);")
367
 
368
(define_expand "adddi3"
369
  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
370
        (plus:DI (match_operand:DI 1 "general_operand" "g")
371
                 (match_operand:DI 2 "general_operand" "g")))]
372
  "!reload_in_progress"
373
  "vax_expand_addsub_di_operands (operands, PLUS); DONE;")
374
 
375
(define_insn "adcdi3"
376
  [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr")
377
        (plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0")
378
                 (match_operand:DI 2 "general_addsub_di_operand" "nRr")))]
379
  "TARGET_QMATH"
380
  "* return vax_output_int_add (insn, operands, DImode);")
381
 
382
;; The add-with-carry (adwc) instruction only accepts two operands.
383
(define_insn "adddi3_old"
384
  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>")
385
        (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>")
386
                 (match_operand:DI 2 "general_operand" "Fsro,Fs")))]
387
  "!TARGET_QMATH"
388
  "* return vax_output_int_add (insn, operands, DImode);")
389
 
390
;;- All kinds of subtract instructions.
391
 
392
(define_insn "sub3"
393
  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
394
        (minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
395
                     (match_operand:VAXfp 2 "general_operand" "gF,gF")))]
396
  ""
397
  "@
398
   sub2 %2,%0
399
   sub3 %2,%1,%0")
400
 
401
(define_insn "sub3"
402
  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
403
        (minus:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
404
                     (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))]
405
  ""
406
  "@
407
   sub2 %2,%0
408
   sub3 %2,%1,%0")
409
 
410
(define_expand "subdi3"
411
  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
412
        (minus:DI (match_operand:DI 1 "general_operand" "g")
413
                  (match_operand:DI 2 "general_operand" "g")))]
414
  "!reload_in_progress"
415
  "vax_expand_addsub_di_operands (operands, MINUS); DONE;")
416
 
417
(define_insn "sbcdi3"
418
  [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,=Rr")
419
        (minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I")
420
                  (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr")))]
421
  "TARGET_QMATH"
422
  "* return vax_output_int_subtract (insn, operands, DImode);")
423
 
424
;; The subtract-with-carry (sbwc) instruction only takes two operands.
425
(define_insn "subdi3_old"
426
  [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>")
427
        (minus:DI (match_operand:DI 1 "general_operand" "0,or>")
428
                  (match_operand:DI 2 "general_operand" "Fsor,Fs")))]
429
  "!TARGET_QMATH"
430
  "* return vax_output_int_subtract (insn, operands, DImode);")
431
 
432
;;- Multiply instructions.
433
 
434
(define_insn "mul3"
435
  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
436
        (mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
437
                    (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))]
438
  ""
439
  "@
440
   mul2 %2,%0
441
   mul2 %1,%0
442
   mul3 %1,%2,%0")
443
 
444
(define_insn "mul3"
445
  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
446
        (mult:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
447
                    (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
448
  ""
449
  "@
450
   mul2 %2,%0
451
   mul2 %1,%0
452
   mul3 %1,%2,%0")
453
 
454
(define_insn "mulsidi3"
455
  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
456
        (mult:DI (sign_extend:DI
457
                  (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
458
                 (sign_extend:DI
459
                  (match_operand:SI 2 "nonimmediate_operand" "nrmT"))))]
460
  ""
461
  "emul %1,%2,$0,%0")
462
 
463
(define_insn ""
464
  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
465
        (plus:DI
466
         (mult:DI (sign_extend:DI
467
                   (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
468
                  (sign_extend:DI
469
                   (match_operand:SI 2 "nonimmediate_operand" "nrmT")))
470
         (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g"))))]
471
  ""
472
  "emul %1,%2,%3,%0")
473
 
474
;; 'F' constraint means type CONST_DOUBLE
475
(define_insn ""
476
  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
477
        (plus:DI
478
         (mult:DI (sign_extend:DI
479
                   (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
480
                  (sign_extend:DI
481
                   (match_operand:SI 2 "nonimmediate_operand" "nrmT")))
482
         (match_operand:DI 3 "immediate_operand" "F")))]
483
  "GET_CODE (operands[3]) == CONST_DOUBLE
484
    && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)"
485
  "*
486
{
487
  if (CONST_DOUBLE_HIGH (operands[3]))
488
    operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[3]));
489
  return \"emul %1,%2,%3,%0\";
490
}")
491
 
492
;;- Divide instructions.
493
 
494
(define_insn "div3"
495
  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
496
        (div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
497
                   (match_operand:VAXfp 2 "general_operand" "gF,gF")))]
498
  ""
499
  "@
500
   div2 %2,%0
501
   div3 %2,%1,%0")
502
 
503
(define_insn "div3"
504
  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
505
        (div:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
506
                   (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))]
507
  ""
508
  "@
509
   div2 %2,%0
510
   div3 %2,%1,%0")
511
 
512
;This is left out because it is very slow;
513
;we are better off programming around the "lack" of this insn.
514
;(define_insn "divmoddisi4"
515
;  [(set (match_operand:SI 0 "general_operand" "=g")
516
;       (div:SI (match_operand:DI 1 "general_operand" "g")
517
;               (match_operand:SI 2 "general_operand" "g")))
518
;   (set (match_operand:SI 3 "general_operand" "=g")
519
;       (mod:SI (match_operand:DI 1 "general_operand" "g")
520
;               (match_operand:SI 2 "general_operand" "g")))]
521
;  ""
522
;  "ediv %2,%1,%0,%3")
523
 
524
;; Bit-and on the VAX is done with a clear-bits insn.
525
(define_expand "and3"
526
  [(set (match_operand:VAXint 0 "nonimmediate_operand" "")
527
        (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" ""))
528
                   (match_operand:VAXint 2 "general_operand" "")))]
529
  ""
530
  "
531
{
532
  rtx op1 = operands[1];
533
 
534
  /* If there is a constant argument, complement that one.  */
535
  if (CONST_INT_P (operands[2]) && ! CONST_INT_P (op1))
536
    {
537
      operands[1] = operands[2];
538
      operands[2] = op1;
539
      op1 = operands[1];
540
    }
541
 
542
  if (CONST_INT_P (op1))
543
    operands[1] = GEN_INT (~INTVAL (op1));
544
  else
545
    operands[1] = expand_unop (mode, one_cmpl_optab, op1, 0, 1);
546
}")
547
 
548
(define_insn "*and"
549
  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
550
        (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT,nrmT"))
551
                    (match_operand:VAXint 2 "general_operand" "0,nrmT")))]
552
  ""
553
  "@
554
   bic2 %1,%0
555
   bic3 %1,%2,%0")
556
 
557
;; The following used to be needed because constant propagation can
558
;; create them starting from the bic insn patterns above.  This is no
559
;; longer a problem.  However, having these patterns allows optimization
560
;; opportunities in combine.c.
561
 
562
(define_insn "*and_const_int"
563
  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
564
        (and:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
565
                   (match_operand:VAXint 2 "const_int_operand" "n,n")))]
566
  ""
567
  "@
568
   bic2 %2,%0
569
   bic3 %2,%1,%0")
570
 
571
 
572
;;- Bit set instructions.
573
 
574
(define_insn "ior3"
575
  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
576
        (ior:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
577
                   (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
578
  ""
579
  "@
580
   bis2 %2,%0
581
   bis2 %1,%0
582
   bis3 %2,%1,%0")
583
 
584
;;- xor instructions.
585
 
586
(define_insn "xor3"
587
  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
588
        (xor:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
589
                   (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
590
  ""
591
  "@
592
   xor2 %2,%0
593
   xor2 %1,%0
594
   xor3 %2,%1,%0")
595
 
596
 
597
(define_insn "neg2"
598
  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
599
        (neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF")))]
600
  ""
601
  "mneg %1,%0")
602
 
603
(define_insn "neg2"
604
  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
605
        (neg:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))]
606
  ""
607
  "mneg %1,%0")
608
 
609
(define_insn "one_cmpl2"
610
  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
611
        (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))]
612
  ""
613
  "mcom %1,%0")
614
 
615
 
616
;; Arithmetic right shift on the VAX works by negating the shift count,
617
;; then emitting a right shift with the shift count negated.  This means
618
;; that all actual shift counts in the RTL will be positive.  This
619
;; prevents converting shifts to ZERO_EXTRACTs with negative positions,
620
;; which isn't valid.
621
(define_expand "ashrsi3"
622
  [(set (match_operand:SI 0 "general_operand" "=g")
623
        (ashiftrt:SI (match_operand:SI 1 "general_operand" "g")
624
                   (match_operand:QI 2 "general_operand" "g")))]
625
  ""
626
  "
627
{
628
  if (! CONST_INT_P(operands[2]))
629
    operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
630
}")
631
 
632
(define_insn ""
633
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
634
        (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
635
                     (match_operand:QI 2 "const_int_operand" "n")))]
636
  ""
637
  "ashl $%n2,%1,%0")
638
 
639
(define_insn ""
640
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
641
        (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
642
                     (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
643
  ""
644
  "ashl %2,%1,%0")
645
 
646
(define_insn "ashlsi3"
647
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
648
        (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
649
                   (match_operand:QI 2 "general_operand" "g")))]
650
  ""
651
  "*
652
{
653
  if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1]))
654
    return \"addl2 %0,%0\";
655
  if (REG_P (operands[1]) && CONST_INT_P (operands[2]))
656
    {
657
      int i = INTVAL (operands[2]);
658
      if (i == 1)
659
        return \"addl3 %1,%1,%0\";
660
      if (i == 2 && !optimize_size)
661
        {
662
          if (push_operand (operands[0], SImode))
663
            return \"pushal 0[%1]\";
664
          return \"moval 0[%1],%0\";
665
        }
666
      if (i == 3 && !optimize_size)
667
        {
668
          if (push_operand (operands[0], SImode))
669
            return \"pushaq 0[%1]\";
670
          return \"movaq 0[%1],%0\";
671
        }
672
    }
673
  return \"ashl %2,%1,%0\";
674
}")
675
 
676
;; Arithmetic right shift on the VAX works by negating the shift count.
677
(define_expand "ashrdi3"
678
  [(set (match_operand:DI 0 "general_operand" "=g")
679
        (ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
680
                     (match_operand:QI 2 "general_operand" "g")))]
681
  ""
682
  "
683
{
684
  operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
685
}")
686
 
687
(define_insn "ashldi3"
688
  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
689
        (ashift:DI (match_operand:DI 1 "general_operand" "g")
690
                   (match_operand:QI 2 "general_operand" "g")))]
691
  ""
692
  "ashq %2,%1,%0")
693
 
694
(define_insn ""
695
  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
696
        (ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
697
                     (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
698
  ""
699
  "ashq %2,%1,%0")
700
 
701
;; We used to have expand_shift handle logical right shifts by using extzv,
702
;; but this make it very difficult to do lshrdi3.  Since the VAX is the
703
;; only machine with this kludge, it's better to just do this with a
704
;; define_expand and remove that case from expand_shift.
705
 
706
(define_expand "lshrsi3"
707
  [(set (match_dup 3)
708
        (minus:QI (const_int 32)
709
                  (match_dup 4)))
710
   (set (match_operand:SI 0 "nonimmediate_operand" "=g")
711
        (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
712
                         (match_dup 3)
713
                         (match_operand:SI 2 "register_operand" "g")))]
714
  ""
715
  "
716
{
717
  operands[3] = gen_reg_rtx (QImode);
718
  operands[4] = gen_lowpart (QImode, operands[2]);
719
}")
720
 
721
;; Rotate right on the VAX works by negating the shift count.
722
(define_expand "rotrsi3"
723
  [(set (match_operand:SI 0 "general_operand" "=g")
724
        (rotatert:SI (match_operand:SI 1 "general_operand" "g")
725
                     (match_operand:QI 2 "general_operand" "g")))]
726
  ""
727
  "
728
{
729
  if (! CONST_INT_P (operands[2]))
730
    operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
731
}")
732
 
733
(define_insn "rotlsi3"
734
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
735
        (rotate:SI (match_operand:SI 1 "general_operand" "nrmT")
736
                   (match_operand:QI 2 "general_operand" "g")))]
737
  ""
738
  "rotl %2,%1,%0")
739
 
740
(define_insn ""
741
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
742
        (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
743
                     (match_operand:QI 2 "const_int_operand" "n")))]
744
  ""
745
  "rotl %R2,%1,%0")
746
 
747
(define_insn ""
748
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
749
        (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
750
                     (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
751
  ""
752
  "rotl %2,%1,%0")
753
 
754
;This insn is probably slower than a multiply and an add.
755
;(define_insn ""
756
;  [(set (match_operand:SI 0 "general_operand" "=g")
757
;       (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g")
758
;                         (match_operand:SI 2 "general_operand" "g"))
759
;                (match_operand:SI 3 "general_operand" "g")))]
760
;  ""
761
;  "index %1,$0x80000000,$0x7fffffff,%3,%2,%0")
762
 
763
;; Special cases of bit-field insns which we should
764
;; recognize in preference to the general case.
765
;; These handle aligned 8-bit and 16-bit fields,
766
;; which can usually be done with move instructions.
767
 
768
(define_insn ""
769
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+ro")
770
                         (match_operand:QI 1 "const_int_operand" "n")
771
                         (match_operand:SI 2 "const_int_operand" "n"))
772
        (match_operand:SI 3 "general_operand" "g"))]
773
   "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
774
   && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
775
   && (REG_P (operands[0])
776
       || ! mode_dependent_address_p (XEXP (operands[0], 0)))"
777
  "*
778
{
779
  if (REG_P (operands[0]))
780
    {
781
      if (INTVAL (operands[2]) != 0)
782
        return \"insv %3,%2,%1,%0\";
783
    }
784
  else
785
    operands[0]
786
      = adjust_address (operands[0],
787
                        INTVAL (operands[1]) == 8 ? QImode : HImode,
788
                        INTVAL (operands[2]) / 8);
789
 
790
  CC_STATUS_INIT;
791
  if (INTVAL (operands[1]) == 8)
792
    return \"movb %3,%0\";
793
  return \"movw %3,%0\";
794
}")
795
 
796
(define_insn ""
797
  [(set (match_operand:SI 0 "nonimmediate_operand" "=&g")
798
        (zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
799
                         (match_operand:QI 2 "const_int_operand" "n")
800
                         (match_operand:SI 3 "const_int_operand" "n")))]
801
  "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
802
   && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
803
   && (REG_P (operands[1])
804
       || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
805
  "*
806
{
807
  if (REG_P (operands[1]))
808
    {
809
      if (INTVAL (operands[3]) != 0)
810
        return \"extzv %3,%2,%1,%0\";
811
    }
812
  else
813
    operands[1]
814
      = adjust_address (operands[1],
815
                        INTVAL (operands[2]) == 8 ? QImode : HImode,
816
                        INTVAL (operands[3]) / 8);
817
 
818
  if (INTVAL (operands[2]) == 8)
819
    return \"movzbl %1,%0\";
820
  return \"movzwl %1,%0\";
821
}")
822
 
823
(define_insn ""
824
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
825
        (sign_extract:SI (match_operand:SI 1 "register_operand" "ro")
826
                         (match_operand:QI 2 "const_int_operand" "n")
827
                         (match_operand:SI 3 "const_int_operand" "n")))]
828
  "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
829
   && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
830
   && (REG_P (operands[1])
831
       || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
832
  "*
833
{
834
  if (REG_P (operands[1]))
835
    {
836
      if (INTVAL (operands[3]) != 0)
837
        return \"extv %3,%2,%1,%0\";
838
    }
839
  else
840
    operands[1]
841
      = adjust_address (operands[1],
842
                        INTVAL (operands[2]) == 8 ? QImode : HImode,
843
                        INTVAL (operands[3]) / 8);
844
 
845
  if (INTVAL (operands[2]) == 8)
846
    return \"cvtbl %1,%0\";
847
  return \"cvtwl %1,%0\";
848
}")
849
 
850
;; Register-only SImode cases of bit-field insns.
851
 
852
(define_insn ""
853
  [(set (cc0)
854
        (compare
855
         (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
856
                          (match_operand:QI 1 "general_operand" "g")
857
                          (match_operand:SI 2 "general_operand" "nrmT"))
858
         (match_operand:SI 3 "general_operand" "nrmT")))]
859
  ""
860
  "cmpv %2,%1,%0,%3")
861
 
862
(define_insn ""
863
  [(set (cc0)
864
        (compare
865
         (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
866
                          (match_operand:QI 1 "general_operand" "g")
867
                          (match_operand:SI 2 "general_operand" "nrmT"))
868
         (match_operand:SI 3 "general_operand" "nrmT")))]
869
  ""
870
  "cmpzv %2,%1,%0,%3")
871
 
872
;; When the field position and size are constant and the destination
873
;; is a register, extv and extzv are much slower than a rotate followed
874
;; by a bicl or sign extension.  Because we might end up choosing ext[z]v
875
;; anyway, we can't allow immediate values for the primary source operand.
876
 
877
(define_insn ""
878
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
879
        (sign_extract:SI (match_operand:SI 1 "register_operand" "ro")
880
                         (match_operand:QI 2 "general_operand" "g")
881
                         (match_operand:SI 3 "general_operand" "nrmT")))]
882
  ""
883
  "*
884
{
885
  if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
886
      || ! REG_P (operands[0])
887
      || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16))
888
    return \"extv %3,%2,%1,%0\";
889
  if (INTVAL (operands[2]) == 8)
890
    return \"rotl %R3,%1,%0\;cvtbl %0,%0\";
891
  return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
892
}")
893
 
894
(define_insn ""
895
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
896
        (zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
897
                         (match_operand:QI 2 "general_operand" "g")
898
                         (match_operand:SI 3 "general_operand" "nrmT")))]
899
  ""
900
  "*
901
{
902
  if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
903
      || ! REG_P (operands[0]))
904
    return \"extzv %3,%2,%1,%0\";
905
  if (INTVAL (operands[2]) == 8)
906
    return \"rotl %R3,%1,%0\;movzbl %0,%0\";
907
  if (INTVAL (operands[2]) == 16)
908
    return \"rotl %R3,%1,%0\;movzwl %0,%0\";
909
  if (INTVAL (operands[3]) & 31)
910
    return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
911
  if (rtx_equal_p (operands[0], operands[1]))
912
    return \"bicl2 %M2,%0\";
913
  return \"bicl3 %M2,%1,%0\";
914
}")
915
 
916
;; Non-register cases.
917
;; nonimmediate_operand is used to make sure that mode-ambiguous cases
918
;; don't match these (and therefore match the cases above instead).
919
 
920
(define_insn ""
921
  [(set (cc0)
922
        (compare
923
         (sign_extract:SI (match_operand:QI 0 "memory_operand" "m")
924
                          (match_operand:QI 1 "general_operand" "g")
925
                          (match_operand:SI 2 "general_operand" "nrmT"))
926
         (match_operand:SI 3 "general_operand" "nrmT")))]
927
  ""
928
  "cmpv %2,%1,%0,%3")
929
 
930
(define_insn ""
931
  [(set (cc0)
932
        (compare
933
         (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm")
934
                          (match_operand:QI 1 "general_operand" "g")
935
                          (match_operand:SI 2 "general_operand" "nrmT"))
936
         (match_operand:SI 3 "general_operand" "nrmT")))]
937
  ""
938
  "cmpzv %2,%1,%0,%3")
939
 
940
(define_insn "extv"
941
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
942
        (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
943
                         (match_operand:QI 2 "general_operand" "g")
944
                         (match_operand:SI 3 "general_operand" "nrmT")))]
945
  ""
946
  "*
947
{
948
  if (!REG_P (operands[0]) || !CONST_INT_P (operands[2])
949
      || !CONST_INT_P (operands[3])
950
      || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)
951
      || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
952
      || side_effects_p (operands[1])
953
      || (MEM_P (operands[1])
954
          && mode_dependent_address_p (XEXP (operands[1], 0))))
955
    return \"extv %3,%2,%1,%0\";
956
  if (INTVAL (operands[2]) == 8)
957
    return \"rotl %R3,%1,%0\;cvtbl %0,%0\";
958
  return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
959
}")
960
 
961
(define_expand "extzv"
962
  [(set (match_operand:SI 0 "general_operand" "")
963
        (zero_extract:SI (match_operand:SI 1 "general_operand" "")
964
                         (match_operand:QI 2 "general_operand" "")
965
                         (match_operand:SI 3 "general_operand" "")))]
966
  ""
967
  "")
968
 
969
(define_insn ""
970
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
971
        (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
972
                         (match_operand:QI 2 "general_operand" "g")
973
                         (match_operand:SI 3 "general_operand" "nrmT")))]
974
  ""
975
  "*
976
{
977
  if (!REG_P (operands[0]) || !CONST_INT_P (operands[2])
978
      || !CONST_INT_P (operands[3])
979
      || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
980
      || side_effects_p (operands[1])
981
      || (MEM_P (operands[1])
982
          && mode_dependent_address_p (XEXP (operands[1], 0))))
983
    return \"extzv %3,%2,%1,%0\";
984
  if (INTVAL (operands[2]) == 8)
985
    return \"rotl %R3,%1,%0\;movzbl %0,%0\";
986
  if (INTVAL (operands[2]) == 16)
987
    return \"rotl %R3,%1,%0\;movzwl %0,%0\";
988
  if (MEM_P (operands[1])
989
      && GET_CODE (XEXP (operands[1], 0)) == PLUS
990
      && REG_P (XEXP (XEXP (operands[1], 0), 0))
991
      && CONST_INT_P (XEXP (XEXP (operands[1], 0), 1))
992
      && CONST_INT_P (operands[2])
993
      && CONST_INT_P (operands[3]))
994
    {
995
      HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[1], 0), 1));
996
      HOST_WIDE_INT l = INTVAL (operands[2]);
997
      HOST_WIDE_INT v = INTVAL (operands[3]);
998
      if ((o & 3) && (o & 3) * 8 + v + l <= 32)
999
        {
1000
          rtx tmp;
1001
          tmp = XEXP (XEXP (operands[1], 0), 0);
1002
          if (o & ~3)
1003
            tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3));
1004
          operands[1] = gen_rtx_MEM (QImode, tmp);
1005
          operands[3] = GEN_INT (v + (o & 3) * 8);
1006
        }
1007
      if (optimize_size)
1008
        return \"extzv %3,%2,%1,%0\";
1009
    }
1010
  return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
1011
}")
1012
 
1013
(define_expand "insv"
1014
  [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
1015
                         (match_operand:QI 1 "general_operand" "")
1016
                         (match_operand:SI 2 "general_operand" ""))
1017
        (match_operand:SI 3 "general_operand" ""))]
1018
  ""
1019
  "")
1020
 
1021
(define_insn ""
1022
  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+g")
1023
                         (match_operand:QI 1 "general_operand" "g")
1024
                         (match_operand:SI 2 "general_operand" "nrmT"))
1025
        (match_operand:SI 3 "general_operand" "nrmT"))]
1026
  ""
1027
  "*
1028
{
1029
  if (MEM_P (operands[0])
1030
      && GET_CODE (XEXP (operands[0], 0)) == PLUS
1031
      && REG_P (XEXP (XEXP (operands[0], 0), 0))
1032
      && CONST_INT_P (XEXP (XEXP (operands[0], 0), 1))
1033
      && CONST_INT_P (operands[1])
1034
      && CONST_INT_P (operands[2]))
1035
    {
1036
      HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[0], 0), 1));
1037
      HOST_WIDE_INT v = INTVAL (operands[2]);
1038
      HOST_WIDE_INT l = INTVAL (operands[1]);
1039
      if ((o & 3) && (o & 3) * 8 + v + l <= 32)
1040
        {
1041
          rtx tmp;
1042
          tmp = XEXP (XEXP (operands[0], 0), 0);
1043
          if (o & ~3)
1044
            tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3));
1045
          operands[0] = gen_rtx_MEM (QImode, tmp);
1046
          operands[2] = GEN_INT (v + (o & 3) * 8);
1047
        }
1048
    }
1049
  return \"insv %3,%2,%1,%0\";
1050
}")
1051
 
1052
(define_insn ""
1053
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1054
                         (match_operand:QI 1 "general_operand" "g")
1055
                         (match_operand:SI 2 "general_operand" "nrmT"))
1056
        (match_operand:SI 3 "general_operand" "nrmT"))]
1057
  ""
1058
  "insv %3,%2,%1,%0")
1059
 
1060
;; Unconditional jump
1061
(define_insn "jump"
1062
  [(set (pc)
1063
        (label_ref (match_operand 0 "" "")))]
1064
  ""
1065
  "jbr %l0")
1066
 
1067
;; Conditional jumps
1068
 
1069
(define_expand "cbranch4"
1070
  [(set (cc0)
1071
        (compare (match_operand:VAXint 1 "nonimmediate_operand" "")
1072
                 (match_operand:VAXint 2 "general_operand" "")))
1073
   (set (pc)
1074
        (if_then_else
1075
              (match_operator 0 "ordered_comparison_operator" [(cc0)
1076
                                                               (const_int 0)])
1077
              (label_ref (match_operand 3 "" ""))
1078
              (pc)))]
1079
 "")
1080
 
1081
(define_expand "cbranch4"
1082
  [(set (cc0)
1083
        (compare (match_operand:VAXfp 1 "general_operand" "")
1084
                 (match_operand:VAXfp 2 "general_operand" "")))
1085
   (set (pc)
1086
        (if_then_else
1087
              (match_operator 0 "ordered_comparison_operator" [(cc0)
1088
                                                               (const_int 0)])
1089
              (label_ref (match_operand 3 "" ""))
1090
              (pc)))]
1091
 "")
1092
 
1093
(define_insn "*branch"
1094
  [(set (pc)
1095
        (if_then_else (match_operator 0 "ordered_comparison_operator"
1096
                                      [(cc0)
1097
                                       (const_int 0)])
1098
                      (label_ref (match_operand 1 "" ""))
1099
                      (pc)))]
1100
  ""
1101
  "j%c0 %l1")
1102
 
1103
;; Recognize reversed jumps.
1104
(define_insn "*branch_reversed"
1105
  [(set (pc)
1106
        (if_then_else (match_operator 0 "ordered_comparison_operator"
1107
                                      [(cc0)
1108
                                       (const_int 0)])
1109
                      (pc)
1110
                      (label_ref (match_operand 1 "" ""))))]
1111
  ""
1112
  "j%C0 %l1") ; %C0 negates condition
1113
 
1114
;; Recognize jbs, jlbs, jbc and jlbc instructions.  Note that the operand
1115
;; of jlbs and jlbc insns are SImode in the hardware.  However, if it is
1116
;; memory, we use QImode in the insn.  So we can't use those instructions
1117
;; for mode-dependent addresses.
1118
 
1119
(define_insn ""
1120
  [(set (pc)
1121
        (if_then_else
1122
         (ne (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
1123
                              (const_int 1)
1124
                              (match_operand:SI 1 "general_operand" "I,nrmT"))
1125
             (const_int 0))
1126
         (label_ref (match_operand 2 "" ""))
1127
         (pc)))]
1128
  ""
1129
  "@
1130
   jlbs %0,%l2
1131
   jbs %1,%0,%l2")
1132
 
1133
(define_insn ""
1134
  [(set (pc)
1135
        (if_then_else
1136
         (eq (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
1137
                              (const_int 1)
1138
                              (match_operand:SI 1 "general_operand" "I,nrmT"))
1139
             (const_int 0))
1140
         (label_ref (match_operand 2 "" ""))
1141
         (pc)))]
1142
  ""
1143
  "@
1144
   jlbc %0,%l2
1145
   jbc %1,%0,%l2")
1146
 
1147
(define_insn ""
1148
  [(set (pc)
1149
        (if_then_else
1150
         (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1151
                              (const_int 1)
1152
                              (match_operand:SI 1 "general_operand" "I,nrmT"))
1153
             (const_int 0))
1154
         (label_ref (match_operand 2 "" ""))
1155
         (pc)))]
1156
  ""
1157
  "@
1158
   jlbs %0,%l2
1159
   jbs %1,%0,%l2")
1160
 
1161
(define_insn ""
1162
  [(set (pc)
1163
        (if_then_else
1164
         (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1165
                              (const_int 1)
1166
                              (match_operand:SI 1 "general_operand" "I,nrmT"))
1167
             (const_int 0))
1168
         (label_ref (match_operand 2 "" ""))
1169
         (pc)))]
1170
  ""
1171
  "@
1172
   jlbc %0,%l2
1173
   jbc %1,%0,%l2")
1174
 
1175
;; Subtract-and-jump and Add-and-jump insns.
1176
;; These are not used when output is for the Unix assembler
1177
;; because it does not know how to modify them to reach far.
1178
 
1179
;; Normal sob insns.
1180
 
1181
(define_insn ""
1182
  [(set (pc)
1183
        (if_then_else
1184
         (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1185
                      (const_int -1))
1186
             (const_int 0))
1187
         (label_ref (match_operand 1 "" ""))
1188
         (pc)))
1189
   (set (match_dup 0)
1190
        (plus:SI (match_dup 0)
1191
                 (const_int -1)))]
1192
  "!TARGET_UNIX_ASM"
1193
  "jsobgtr %0,%l1")
1194
 
1195
(define_insn ""
1196
  [(set (pc)
1197
        (if_then_else
1198
         (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1199
                      (const_int -1))
1200
             (const_int 0))
1201
         (label_ref (match_operand 1 "" ""))
1202
         (pc)))
1203
   (set (match_dup 0)
1204
        (plus:SI (match_dup 0)
1205
                 (const_int -1)))]
1206
  "!TARGET_UNIX_ASM"
1207
  "jsobgeq %0,%l1")
1208
 
1209
;; Normal aob insns.  Define a version for when operands[1] is a constant.
1210
(define_insn ""
1211
  [(set (pc)
1212
        (if_then_else
1213
         (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1214
                      (const_int 1))
1215
             (match_operand:SI 1 "general_operand" "nrmT"))
1216
         (label_ref (match_operand 2 "" ""))
1217
         (pc)))
1218
   (set (match_dup 0)
1219
        (plus:SI (match_dup 0)
1220
                 (const_int 1)))]
1221
  "!TARGET_UNIX_ASM"
1222
  "jaoblss %1,%0,%l2")
1223
 
1224
(define_insn ""
1225
  [(set (pc)
1226
        (if_then_else
1227
         (lt (match_operand:SI 0 "nonimmediate_operand" "+g")
1228
             (match_operand:SI 1 "general_operand" "nrmT"))
1229
         (label_ref (match_operand 2 "" ""))
1230
         (pc)))
1231
   (set (match_dup 0)
1232
        (plus:SI (match_dup 0)
1233
                 (const_int 1)))]
1234
  "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
1235
  "jaoblss %P1,%0,%l2")
1236
 
1237
(define_insn ""
1238
  [(set (pc)
1239
        (if_then_else
1240
         (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1241
                      (const_int 1))
1242
             (match_operand:SI 1 "general_operand" "nrmT"))
1243
         (label_ref (match_operand 2 "" ""))
1244
         (pc)))
1245
   (set (match_dup 0)
1246
        (plus:SI (match_dup 0)
1247
                 (const_int 1)))]
1248
  "!TARGET_UNIX_ASM"
1249
  "jaobleq %1,%0,%l2")
1250
 
1251
(define_insn ""
1252
  [(set (pc)
1253
        (if_then_else
1254
         (le (match_operand:SI 0 "nonimmediate_operand" "+g")
1255
             (match_operand:SI 1 "general_operand" "nrmT"))
1256
         (label_ref (match_operand 2 "" ""))
1257
         (pc)))
1258
   (set (match_dup 0)
1259
        (plus:SI (match_dup 0)
1260
                 (const_int 1)))]
1261
  "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
1262
  "jaobleq %P1,%0,%l2")
1263
 
1264
;; Something like a sob insn, but compares against -1.
1265
;; This finds `while (foo--)' which was changed to `while (--foo != -1)'.
1266
 
1267
(define_insn ""
1268
  [(set (pc)
1269
        (if_then_else
1270
         (ne (match_operand:SI 0 "nonimmediate_operand" "+g")
1271
             (const_int 0))
1272
         (label_ref (match_operand 1 "" ""))
1273
         (pc)))
1274
   (set (match_dup 0)
1275
        (plus:SI (match_dup 0)
1276
                 (const_int -1)))]
1277
  ""
1278
  "decl %0\;jgequ %l1")
1279
 
1280
(define_expand "call_pop"
1281
  [(parallel [(call (match_operand:QI 0 "memory_operand" "")
1282
                    (match_operand:SI 1 "const_int_operand" ""))
1283
              (set (reg:SI VAX_SP_REGNUM)
1284
                   (plus:SI (reg:SI VAX_SP_REGNUM)
1285
                            (match_operand:SI 3 "immediate_operand" "")))])]
1286
  ""
1287
{
1288
  gcc_assert (INTVAL (operands[3]) <= 255 * 4 && INTVAL (operands[3]) % 4 == 0);
1289
 
1290
  /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size
1291
     during EH unwinding.  We must include the argument count pushed by
1292
     the calls instruction.  */
1293
  operands[1] = GEN_INT (INTVAL (operands[3]) + 4);
1294
})
1295
 
1296
(define_insn "*call_pop"
1297
  [(call (match_operand:QI 0 "memory_operand" "m")
1298
         (match_operand:SI 1 "const_int_operand" "n"))
1299
   (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM)
1300
                                        (match_operand:SI 2 "immediate_operand" "i")))]
1301
  ""
1302
{
1303
  operands[1] = GEN_INT ((INTVAL (operands[1]) - 4) / 4);
1304
  return "calls %1,%0";
1305
})
1306
 
1307
(define_expand "call_value_pop"
1308
  [(parallel [(set (match_operand 0 "" "")
1309
                   (call (match_operand:QI 1 "memory_operand" "")
1310
                         (match_operand:SI 2 "const_int_operand" "")))
1311
              (set (reg:SI VAX_SP_REGNUM)
1312
                   (plus:SI (reg:SI VAX_SP_REGNUM)
1313
                            (match_operand:SI 4 "immediate_operand" "")))])]
1314
  ""
1315
{
1316
  gcc_assert (INTVAL (operands[4]) <= 255 * 4 && INTVAL (operands[4]) % 4 == 0);
1317
 
1318
  /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size
1319
     during EH unwinding.  We must include the argument count pushed by
1320
     the calls instruction.  */
1321
  operands[2] = GEN_INT (INTVAL (operands[4]) + 4);
1322
})
1323
 
1324
(define_insn "*call_value_pop"
1325
  [(set (match_operand 0 "" "")
1326
        (call (match_operand:QI 1 "memory_operand" "m")
1327
              (match_operand:SI 2 "const_int_operand" "n")))
1328
   (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM)
1329
                                        (match_operand:SI 3 "immediate_operand" "i")))]
1330
  ""
1331
  "*
1332
{
1333
  operands[2] = GEN_INT ((INTVAL (operands[2]) - 4) / 4);
1334
  return \"calls %2,%1\";
1335
}")
1336
 
1337
(define_expand "call"
1338
  [(call (match_operand:QI 0 "memory_operand" "")
1339
      (match_operand:SI 1 "const_int_operand" ""))]
1340
  ""
1341
  "
1342
{
1343
  /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size
1344
     during EH unwinding.  We must include the argument count pushed by
1345
     the calls instruction.  */
1346
  operands[1] = GEN_INT (INTVAL (operands[1]) + 4);
1347
}")
1348
 
1349
(define_insn "*call"
1350
   [(call (match_operand:QI 0 "memory_operand" "m")
1351
       (match_operand:SI 1 "const_int_operand" ""))]
1352
  ""
1353
  "calls $0,%0")
1354
 
1355
(define_expand "call_value"
1356
  [(set (match_operand 0 "" "")
1357
      (call (match_operand:QI 1 "memory_operand" "")
1358
            (match_operand:SI 2 "const_int_operand" "")))]
1359
  ""
1360
  "
1361
{
1362
  /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size
1363
     during EH unwinding.  We must include the argument count pushed by
1364
     the calls instruction.  */
1365
  operands[2] = GEN_INT (INTVAL (operands[2]) + 4);
1366
}")
1367
 
1368
(define_insn "*call_value"
1369
  [(set (match_operand 0 "" "")
1370
        (call (match_operand:QI 1 "memory_operand" "m")
1371
              (match_operand:SI 2 "const_int_operand" "")))]
1372
  ""
1373
  "calls $0,%1")
1374
 
1375
;; Call subroutine returning any type.
1376
 
1377
(define_expand "untyped_call"
1378
  [(parallel [(call (match_operand 0 "" "")
1379
              (const_int 0))
1380
              (match_operand 1 "" "")
1381
              (match_operand 2 "" "")])]
1382
  ""
1383
  "
1384
{
1385
  int i;
1386
 
1387
  emit_call_insn (gen_call_pop (operands[0], const0_rtx, NULL, const0_rtx));
1388
 
1389
  for (i = 0; i < XVECLEN (operands[2], 0); i++)
1390
    {
1391
      rtx set = XVECEXP (operands[2], 0, i);
1392
      emit_move_insn (SET_DEST (set), SET_SRC (set));
1393
    }
1394
 
1395
  /* The optimizer does not know that the call sets the function value
1396
     registers we stored in the result block.  We avoid problems by
1397
     claiming that all hard registers are used and clobbered at this
1398
     point.  */
1399
  emit_insn (gen_blockage ());
1400
 
1401
  DONE;
1402
}")
1403
 
1404
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1405
;; all of memory.  This blocks insns from being moved across this point.
1406
 
1407
(define_insn "blockage"
1408
  [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
1409
  ""
1410
  "")
1411
 
1412
(define_insn "return"
1413
  [(return)]
1414
  ""
1415
  "ret")
1416
 
1417
(define_expand "epilogue"
1418
  [(return)]
1419
  ""
1420
  "
1421
{
1422
  emit_jump_insn (gen_return ());
1423
  DONE;
1424
}")
1425
 
1426
(define_insn "nop"
1427
  [(const_int 0)]
1428
  ""
1429
  "nop")
1430
 
1431
;; This had a wider constraint once, and it had trouble.
1432
;; If you are tempted to try `g', please don't--it's not worth
1433
;; the risk we will reopen the same bug.
1434
(define_insn "indirect_jump"
1435
  [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1436
  ""
1437
  "jmp (%0)")
1438
 
1439
;; This is here to accept 5 arguments (as passed by expand_end_case)
1440
;; and pass the first 4 along to the casesi1 pattern that really does
1441
;; the actual casesi work.  We emit a jump here to the default label
1442
;; _before_ the casesi so that we can be sure that the casesi never
1443
;; drops through.
1444
;; This is suboptimal perhaps, but so is much of the rest of this
1445
;; machine description.  For what it's worth, HPPA uses the same trick.
1446
;;
1447
;; operand 0 is index
1448
;; operand 1 is the minimum bound (a const_int)
1449
;; operand 2 is the maximum bound - minimum bound + 1 (also a const_int)
1450
;; operand 3 is CODE_LABEL for the table;
1451
;; operand 4 is the CODE_LABEL to go to if index out of range (ie. default).
1452
;;
1453
;; We emit:
1454
;;      i = index - minimum_bound
1455
;;      if (i > (maximum_bound - minimum_bound + 1) goto default;
1456
;;      casesi (i, 0, table);
1457
;;
1458
(define_expand "casesi"
1459
  [(match_operand:SI 0 "general_operand" "")
1460
   (match_operand:SI 1 "general_operand" "")
1461
   (match_operand:SI 2 "general_operand" "")
1462
   (match_operand 3 "" "")
1463
   (match_operand 4 "" "")]
1464
  ""
1465
{
1466
  rtx test;
1467
 
1468
  /* i = index - minimum_bound;
1469
     But only if the lower bound is not already zero.  */
1470
  if (operands[1] != const0_rtx)
1471
    {
1472
      rtx index = gen_reg_rtx (SImode);
1473
      emit_insn (gen_addsi3 (index,
1474
                             operands[0],
1475
                             GEN_INT (-INTVAL (operands[1]))));
1476
      operands[0] = index;
1477
    }
1478
 
1479
  /* if (i > (maximum_bound - minimum_bound + 1)) goto default;  */
1480
  test = gen_rtx_fmt_ee (GTU, VOIDmode, operands[0], operands[2]);
1481
  emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
1482
 
1483
  /* casesi (i, 0, table);  */
1484
  emit_jump_insn (gen_casesi1 (operands[0], operands[2], operands[3]));
1485
  DONE;
1486
})
1487
 
1488
;; This insn is a bit of a lier.  It actually falls through if no case
1489
;; matches.  But, we prevent that from ever happening by emitting a jump
1490
;; before this, see the define_expand above.
1491
(define_insn "casesi1"
1492
  [(match_operand:SI 1 "const_int_operand" "n")
1493
   (set (pc)
1494
        (plus:SI (sign_extend:SI
1495
                  (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "nrmT")
1496
                                            (const_int 2))
1497
                          (pc))))
1498
                 (label_ref:SI (match_operand 2 "" ""))))]
1499
  ""
1500
  "casel %0,$0,%1")
1501
 
1502
(define_insn "pushextsym"
1503
  [(set (match_operand:SI 0 "push_operand" "=g")
1504
        (match_operand:SI 1 "external_symbolic_operand" "i"))]
1505
  ""
1506
  "pushab %a1")
1507
 
1508
(define_insn "movextsym"
1509
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1510
        (match_operand:SI 1 "external_symbolic_operand" "i"))]
1511
  ""
1512
  "movab %a1,%0")
1513
 
1514
(define_insn "pushlclsym"
1515
  [(set (match_operand:SI 0 "push_operand" "=g")
1516
        (match_operand:SI 1 "local_symbolic_operand" "i"))]
1517
  ""
1518
  "pushab %a1")
1519
 
1520
(define_insn "movlclsym"
1521
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1522
        (match_operand:SI 1 "local_symbolic_operand" "i"))]
1523
  ""
1524
  "movab %a1,%0")
1525
 
1526
;;- load or push effective address
1527
;; These come after the move and add/sub patterns
1528
;; because we don't want pushl $1 turned into pushad 1.
1529
;; or addl3 r1,r2,r3 turned into movab 0(r1)[r2],r3.
1530
 
1531
;; It does not work to use constraints to distinguish pushes from moves,
1532
;; because < matches any autodecrement, not just a push.
1533
 
1534
(define_insn "pushaddr"
1535
  [(set (match_operand:SI 0 "push_operand" "=g")
1536
        (match_operand:VAXintQHSD 1 "address_operand" "p"))]
1537
  ""
1538
  "pusha %a1")
1539
 
1540
(define_insn "movaddr"
1541
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1542
        (match_operand:VAXintQHSD 1 "address_operand" "p"))]
1543
  ""
1544
  "mova %a1,%0")
1545
 
1546
(define_insn "pushaddr"
1547
  [(set (match_operand:SI 0 "push_operand" "=g")
1548
        (match_operand:VAXfp 1 "address_operand" "p"))]
1549
  ""
1550
  "pusha %a1")
1551
 
1552
(define_insn "movaddr"
1553
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1554
        (match_operand:VAXfp 1 "address_operand" "p"))]
1555
  ""
1556
  "mova %a1,%0")
1557
 
1558
;; These used to be peepholes, but it is more straightforward to do them
1559
;; as single insns.  However, we must force the output to be a register
1560
;; if it is not an offsettable address so that we know that we can assign
1561
;; to it twice.
1562
 
1563
;; If we had a good way of evaluating the relative costs, these could be
1564
;; machine-independent.
1565
 
1566
;; Optimize   extzv ...,z;    andl2 ...,z
1567
;; or         ashl ...,z;     andl2 ...,z
1568
;; with other operands constant.  This is what the combiner converts the
1569
;; above sequences to before attempting to recognize the new insn.
1570
 
1571
(define_insn ""
1572
  [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
1573
        (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
1574
                             (match_operand:QI 2 "const_int_operand" "n"))
1575
                (match_operand:SI 3 "const_int_operand" "n")))]
1576
  "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0"
1577
  "*
1578
{
1579
  unsigned long mask1 = INTVAL (operands[3]);
1580
  unsigned long mask2 = (1 << (32 - INTVAL (operands[2]))) - 1;
1581
 
1582
  if ((mask1 & mask2) != mask1)
1583
    operands[3] = GEN_INT (mask1 & mask2);
1584
 
1585
  return \"rotl %R2,%1,%0\;bicl2 %N3,%0\";
1586
}")
1587
 
1588
;; left-shift and mask
1589
;; The only case where `ashl' is better is if the mask only turns off
1590
;; bits that the ashl would anyways, in which case it should have been
1591
;; optimized away.
1592
 
1593
(define_insn ""
1594
  [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
1595
        (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
1596
                           (match_operand:QI 2 "const_int_operand" "n"))
1597
                (match_operand:SI 3 "const_int_operand" "n")))]
1598
  ""
1599
  "*
1600
{
1601
  operands[3]
1602
    = GEN_INT (INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1));
1603
  return \"rotl %2,%1,%0\;bicl2 %N3,%0\";
1604
}")
1605
 
1606
;; Instruction sequence to sync the VAX instruction stream.
1607
(define_insn "sync_istream"
1608
  [(unspec_volatile [(const_int 0)] VUNSPEC_SYNC_ISTREAM)]
1609
  ""
1610
  "movpsl -(%|sp)\;pushal 1(%|pc)\;rei")
1611
 
1612
(define_expand "nonlocal_goto"
1613
  [(use (match_operand 0 "general_operand" ""))
1614
   (use (match_operand 1 "general_operand" ""))
1615
   (use (match_operand 2 "general_operand" ""))
1616
   (use (match_operand 3 "general_operand" ""))]
1617
  ""
1618
{
1619
  rtx lab = operands[1];
1620
  rtx stack = operands[2];
1621
  rtx fp = operands[3];
1622
 
1623
  emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1624
  emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
1625
 
1626
  emit_move_insn (hard_frame_pointer_rtx, fp);
1627
  emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
1628
 
1629
  emit_use (hard_frame_pointer_rtx);
1630
  emit_use (stack_pointer_rtx);
1631
 
1632
  /* We'll convert this to direct jump via a peephole optimization.  */
1633
  emit_indirect_jump (copy_to_reg (lab));
1634
  emit_barrier ();
1635
  DONE;
1636
})

powered by: WebSVN 2.1.0

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