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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [config/] [pdp11/] [pdp11.md] - Blame information for rev 154

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
;;- Machine description for the pdp11 for GNU C compiler
2
;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2004, 2005
3
;; 2007 Free Software Foundation, Inc.
4
;; Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
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
 
23
;; HI is 16 bit
24
;; QI is 8 bit
25
 
26
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27
 
28
;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
29
;;- updates for most instructions.
30
 
31
;;- Operand classes for the register allocator:
32
 
33
;; Compare instructions.
34
 
35
;; currently we only support df floats, which saves us quite some
36
;; hassle switching the FP mode!
37
;; we assume that CPU is always in long float mode, and
38
;; 16 bit integer mode - currently, the prologue for main does this,
39
;; but maybe we should just set up a NEW crt0 properly,
40
;; -- and what about signal handling code?
41
;; (we don't even let sf floats in the register file, so
42
;; we only should have to worry about truncating and widening
43
;; when going to memory)
44
 
45
;; abort() call by g++ - must define libfunc for cmp_optab
46
;; and ucmp_optab for mode SImode, because we don't have that!!!
47
;; - yet since no libfunc is there, we abort ()
48
 
49
;; The only thing that remains to be done then is output
50
;; the floats in a way the assembler can handle it (and
51
;; if you're really into it, use a PDP11 float emulation
52
;; library to do floating point constant folding - but
53
;; I guess you'll get reasonable results even when not
54
;; doing this)
55
;; the last thing to do is fix the UPDATE_CC macro to check
56
;; for floating point condition codes, and set cc_status
57
;; properly, also setting the CC_IN_FCCR flag.
58
 
59
;; define attributes
60
;; currently type is only fpu or arith or unknown, maybe branch later ?
61
;; default is arith
62
(define_attr "type" "unknown,arith,fp" (const_string "arith"))
63
 
64
;; length default is 1 word each
65
(define_attr "length" "" (const_int 1))
66
 
67
;; a user's asm statement
68
(define_asm_attributes
69
  [(set_attr "type" "unknown")
70
; all bets are off how long it is - make it 256, forces long jumps
71
; whenever jumping around it !!!
72
   (set_attr "length" "256")])
73
 
74
;; define function units
75
 
76
;; arithmetic - values here immediately when next insn issued
77
;; or does it mean the number of cycles after this insn was issued?
78
;; how do I say that fpu insns use cpu also? (pre-interaction phase)
79
 
80
;(define_function_unit "cpu" 1 1 (eq_attr "type" "arith") 0 0)
81
;(define_function_unit "fpu" 1 1 (eq_attr "type" "fp") 0 0)
82
 
83
;; compare
84
(define_insn "cmpdf"
85
  [(set (cc0)
86
        (compare (match_operand:DF 0 "general_operand" "fR,Q,F")
87
                 (match_operand:DF 1 "register_operand" "a,a,a")))]
88
  "TARGET_FPU"
89
  "*
90
{
91
  cc_status.flags = CC_IN_FPU;
92
  return \"{cmpd|cmpf} %0, %1\;cfcc\";
93
}"
94
  [(set_attr "length" "2,3,6")])
95
 
96
;; a bit of brain damage, maybe inline later -
97
;; problem is - gcc seems to NEED SImode because
98
;; of the cmp weirdness - maybe change gcc to handle this?
99
 
100
(define_expand "cmpsi"
101
  [(set (reg:SI 0)
102
        (match_operand:SI 0 "general_operand" "g"))
103
   (set (reg:SI 2)
104
        (match_operand:SI 1 "general_operand" "g"))
105
   (parallel [(set (cc0)
106
                   (compare (reg:SI 0)
107
                            (reg:SI 2)))
108
              (clobber (reg:SI 0))])]
109
  "0" ;; disable for test
110
  "")
111
 
112
;; check for next insn for branch code - does this still
113
;; work in gcc 2.* ?
114
 
115
(define_insn ""
116
  [(set (cc0)
117
        (compare (reg:SI 0)
118
                 (reg:SI 2)))
119
   (clobber (reg:SI 0))]
120
  ""
121
  "*
122
{
123
  rtx br_insn = NEXT_INSN (insn);
124
  RTX_CODE br_code;
125
 
126
  gcc_assert (GET_CODE (br_insn) == JUMP_INSN);
127
  br_code =  GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
128
 
129
  switch(br_code)
130
  {
131
    case GEU:
132
    case LTU:
133
    case GTU:
134
    case LEU:
135
 
136
      return \"jsr pc, ___ucmpsi\;cmp $1,r0\";
137
 
138
    case GE:
139
    case LT:
140
    case GT:
141
    case LE:
142
    case EQ:
143
    case NE:
144
 
145
      return \"jsr pc, ___cmpsi\;tst r0\";
146
 
147
    default:
148
 
149
      gcc_unreachable ();
150
  }
151
}"
152
  [(set_attr "length" "4")])
153
 
154
 
155
(define_insn "cmphi"
156
  [(set (cc0)
157
        (compare (match_operand:HI 0 "general_operand" "rR,rR,Qi,Qi")
158
                 (match_operand:HI 1 "general_operand" "rR,Qi,rR,Qi")))]
159
  ""
160
  "cmp %0,%1"
161
  [(set_attr "length" "1,2,2,3")])
162
 
163
(define_insn "cmpqi"
164
  [(set (cc0)
165
        (compare (match_operand:QI 0 "general_operand" "rR,rR,Qi,Qi")
166
                 (match_operand:QI 1 "general_operand" "rR,Qi,rR,Qi")))]
167
  ""
168
  "cmpb %0,%1"
169
  [(set_attr "length" "1,2,2,3")])
170
 
171
 
172
;; We have to have this because cse can optimize the previous pattern
173
;; into this one.
174
 
175
(define_insn "tstdf"
176
  [(set (cc0)
177
        (match_operand:DF 0 "general_operand" "fR,Q"))]
178
  "TARGET_FPU"
179
  "*
180
{
181
  cc_status.flags = CC_IN_FPU;
182
  return \"{tstd|tstf} %0\;cfcc\";
183
}"
184
  [(set_attr "length" "2,3")])
185
 
186
 
187
(define_expand "tstsi"
188
  [(set (reg:SI 0)
189
        (match_operand:SI 0 "general_operand" "g"))
190
   (parallel [(set (cc0)
191
                   (reg:SI 0))
192
              (clobber (reg:SI 0))])]
193
  "0" ;; disable for test
194
  "")
195
 
196
(define_insn ""
197
  [(set (cc0)
198
        (reg:SI 0))
199
   (clobber (reg:SI 0))]
200
  ""
201
  "jsr pc, ___tstsi\;tst r0"
202
  [(set_attr "length" "3")])
203
 
204
 
205
(define_insn "tsthi"
206
  [(set (cc0)
207
        (match_operand:HI 0 "general_operand" "rR,Q"))]
208
  ""
209
  "tst %0"
210
  [(set_attr "length" "1,2")])
211
 
212
(define_insn "tstqi"
213
  [(set (cc0)
214
        (match_operand:QI 0 "general_operand" "rR,Q"))]
215
  ""
216
  "tstb %0"
217
  [(set_attr "length" "1,2")])
218
 
219
;; sob instruction - we need an assembler which can make this instruction
220
;; valid under _all_ circumstances!
221
 
222
(define_insn ""
223
  [(set (pc)
224
        (if_then_else
225
         (ne (plus:HI (match_operand:HI 0 "register_operand" "+r")
226
                      (const_int -1))
227
             (const_int 0))
228
         (label_ref (match_operand 1 "" ""))
229
         (pc)))
230
   (set (match_dup 0)
231
        (plus:HI (match_dup 0)
232
                 (const_int -1)))]
233
  "TARGET_40_PLUS"
234
  "*
235
{
236
 static int labelcount = 0;
237
 static char buf[1000];
238
 
239
 if (get_attr_length (insn) == 1)
240
    return \"sob %0, %l1\";
241
 
242
 /* emulate sob */
243
 output_asm_insn (\"dec %0\", operands);
244
 
245
 sprintf (buf, \"bge LONG_SOB%d\", labelcount);
246
 output_asm_insn (buf, NULL);
247
 
248
 output_asm_insn (\"jmp %l1\", operands);
249
 
250
 sprintf (buf, \"LONG_SOB%d:\", labelcount++);
251
 output_asm_insn (buf, NULL);
252
 
253
 return \"\";
254
}"
255
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
256
                                                       (pc))
257
                                                (const_int -256))
258
                                           (ge (minus (match_dup 0)
259
                                                       (pc))
260
                                                (const_int 0)))
261
                                      (const_int 4)
262
                                      (const_int 1)))])
263
 
264
;; These control RTL generation for conditional jump insns
265
;; and match them for register allocation.
266
 
267
;; problem with too short jump distance! we need an assembler which can
268
;; make this valid for all jump distances!
269
;; e.g. gas!
270
 
271
;; these must be changed to check for CC_IN_FCCR if float is to be
272
;; enabled
273
 
274
(define_insn "beq"
275
  [(set (pc)
276
        (if_then_else (eq (cc0)
277
                          (const_int 0))
278
                      (label_ref (match_operand 0 "" ""))
279
                      (pc)))]
280
  ""
281
  "* return output_jump(\"beq\", \"bne\", get_attr_length(insn));"
282
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
283
                                                      (pc))
284
                                               (const_int -128))
285
                                           (ge (minus (match_dup 0)
286
                                                      (pc))
287
                                               (const_int 128)))
288
                                      (const_int 3)
289
                                      (const_int 1)))])
290
 
291
 
292
(define_insn "bne"
293
  [(set (pc)
294
        (if_then_else (ne (cc0)
295
                          (const_int 0))
296
                      (label_ref (match_operand 0 "" ""))
297
                      (pc)))]
298
  ""
299
  "* return output_jump(\"bne\", \"beq\", get_attr_length(insn));"
300
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
301
                                                      (pc))
302
                                               (const_int -128))
303
                                           (ge (minus (match_dup 0)
304
                                                      (pc))
305
                                               (const_int 128)))
306
                                      (const_int 3)
307
                                      (const_int 1)))])
308
 
309
(define_insn "bgt"
310
  [(set (pc)
311
        (if_then_else (gt (cc0)
312
                          (const_int 0))
313
                      (label_ref (match_operand 0 "" ""))
314
                      (pc)))]
315
  ""
316
  "* return output_jump(\"bgt\", \"ble\", get_attr_length(insn));"
317
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
318
                                                      (pc))
319
                                               (const_int -128))
320
                                           (ge (minus (match_dup 0)
321
                                                      (pc))
322
                                               (const_int 128)))
323
                                      (const_int 3)
324
                                      (const_int 1)))])
325
 
326
(define_insn "bgtu"
327
  [(set (pc)
328
        (if_then_else (gtu (cc0)
329
                           (const_int 0))
330
                      (label_ref (match_operand 0 "" ""))
331
                      (pc)))]
332
  ""
333
  "* return output_jump(\"bhi\", \"blos\", get_attr_length(insn));"
334
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
335
                                                      (pc))
336
                                               (const_int -128))
337
                                           (ge (minus (match_dup 0)
338
                                                      (pc))
339
                                               (const_int 128)))
340
                                      (const_int 3)
341
                                      (const_int 1)))])
342
 
343
(define_insn "blt"
344
  [(set (pc)
345
        (if_then_else (lt (cc0)
346
                          (const_int 0))
347
                      (label_ref (match_operand 0 "" ""))
348
                      (pc)))]
349
  ""
350
  "* return output_jump(\"blt\", \"bge\", get_attr_length(insn));"
351
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
352
                                                      (pc))
353
                                               (const_int -128))
354
                                           (ge (minus (match_dup 0)
355
                                                      (pc))
356
                                               (const_int 128)))
357
                                      (const_int 3)
358
                                      (const_int 1)))])
359
 
360
 
361
(define_insn "bltu"
362
  [(set (pc)
363
        (if_then_else (ltu (cc0)
364
                           (const_int 0))
365
                      (label_ref (match_operand 0 "" ""))
366
                      (pc)))]
367
  ""
368
  "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));"
369
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
370
                                                      (pc))
371
                                               (const_int -128))
372
                                           (ge (minus (match_dup 0)
373
                                                      (pc))
374
                                               (const_int 128)))
375
                                      (const_int 3)
376
                                      (const_int 1)))])
377
 
378
(define_insn "bge"
379
  [(set (pc)
380
        (if_then_else (ge (cc0)
381
                          (const_int 0))
382
                      (label_ref (match_operand 0 "" ""))
383
                      (pc)))]
384
  ""
385
  "* return output_jump(\"bge\", \"blt\", get_attr_length(insn));"
386
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
387
                                                      (pc))
388
                                               (const_int -128))
389
                                           (ge (minus (match_dup 0)
390
                                                      (pc))
391
                                               (const_int 128)))
392
                                      (const_int 3)
393
                                      (const_int 1)))])
394
 
395
(define_insn "bgeu"
396
  [(set (pc)
397
        (if_then_else (geu (cc0)
398
                           (const_int 0))
399
                      (label_ref (match_operand 0 "" ""))
400
                      (pc)))]
401
  ""
402
  "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));"
403
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
404
                                                      (pc))
405
                                               (const_int -128))
406
                                           (ge (minus (match_dup 0)
407
                                                      (pc))
408
                                               (const_int 128)))
409
                                      (const_int 3)
410
                                      (const_int 1)))])
411
 
412
(define_insn "ble"
413
  [(set (pc)
414
        (if_then_else (le (cc0)
415
                          (const_int 0))
416
                      (label_ref (match_operand 0 "" ""))
417
                      (pc)))]
418
  ""
419
  "* return output_jump(\"ble\", \"bgt\", get_attr_length(insn));"
420
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
421
                                                      (pc))
422
                                               (const_int -128))
423
                                           (ge (minus (match_dup 0)
424
                                                      (pc))
425
                                               (const_int 128)))
426
                                      (const_int 3)
427
                                      (const_int 1)))])
428
 
429
(define_insn "bleu"
430
  [(set (pc)
431
        (if_then_else (leu (cc0)
432
                           (const_int 0))
433
                      (label_ref (match_operand 0 "" ""))
434
                      (pc)))]
435
  ""
436
  "* return output_jump(\"blos\", \"bhi\", get_attr_length(insn));"
437
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
438
                                                      (pc))
439
                                               (const_int -128))
440
                                           (ge (minus (match_dup 0)
441
                                                      (pc))
442
                                               (const_int 128)))
443
                                      (const_int 3)
444
                                      (const_int 1)))])
445
 
446
 
447
;; These match inverted jump insns for register allocation.
448
 
449
(define_insn ""
450
  [(set (pc)
451
        (if_then_else (eq (cc0)
452
                          (const_int 0))
453
                      (pc)
454
                      (label_ref (match_operand 0 "" ""))))]
455
  ""
456
  "* return output_jump(\"bne\", \"beq\", get_attr_length(insn));"
457
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
458
                                                      (pc))
459
                                               (const_int -128))
460
                                           (ge (minus (match_dup 0)
461
                                                      (pc))
462
                                               (const_int 128)))
463
                                      (const_int 3)
464
                                      (const_int 1)))])
465
 
466
(define_insn ""
467
  [(set (pc)
468
        (if_then_else (ne (cc0)
469
                          (const_int 0))
470
                      (pc)
471
                      (label_ref (match_operand 0 "" ""))))]
472
  ""
473
  "* return output_jump(\"beq\", \"bne\", get_attr_length(insn));"
474
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
475
                                                      (pc))
476
                                               (const_int -128))
477
                                           (ge (minus (match_dup 0)
478
                                                      (pc))
479
                                               (const_int 128)))
480
                                      (const_int 3)
481
                                      (const_int 1)))])
482
 
483
(define_insn ""
484
  [(set (pc)
485
        (if_then_else (gt (cc0)
486
                          (const_int 0))
487
                      (pc)
488
                      (label_ref (match_operand 0 "" ""))))]
489
  ""
490
  "* return output_jump(\"ble\", \"bgt\", get_attr_length(insn));"
491
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
492
                                                      (pc))
493
                                               (const_int -128))
494
                                           (ge (minus (match_dup 0)
495
                                                      (pc))
496
                                               (const_int 128)))
497
                                      (const_int 3)
498
                                      (const_int 1)))])
499
 
500
(define_insn ""
501
  [(set (pc)
502
        (if_then_else (gtu (cc0)
503
                           (const_int 0))
504
                      (pc)
505
                      (label_ref (match_operand 0 "" ""))))]
506
  ""
507
  "* return output_jump(\"blos\", \"bhi\", get_attr_length(insn));"
508
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
509
                                                      (pc))
510
                                               (const_int -128))
511
                                           (ge (minus (match_dup 0)
512
                                                      (pc))
513
                                               (const_int 128)))
514
                                      (const_int 3)
515
                                      (const_int 1)))])
516
 
517
(define_insn ""
518
  [(set (pc)
519
        (if_then_else (lt (cc0)
520
                          (const_int 0))
521
                      (pc)
522
                      (label_ref (match_operand 0 "" ""))))]
523
  ""
524
  "* return output_jump(\"bge\", \"blt\", get_attr_length(insn));"
525
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
526
                                                      (pc))
527
                                               (const_int -128))
528
                                           (ge (minus (match_dup 0)
529
                                                      (pc))
530
                                               (const_int 128)))
531
                                      (const_int 3)
532
                                      (const_int 1)))])
533
 
534
(define_insn ""
535
  [(set (pc)
536
        (if_then_else (ltu (cc0)
537
                           (const_int 0))
538
                      (pc)
539
                      (label_ref (match_operand 0 "" ""))))]
540
  ""
541
  "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));"
542
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
543
                                                      (pc))
544
                                               (const_int -128))
545
                                           (ge (minus (match_dup 0)
546
                                                      (pc))
547
                                               (const_int 128)))
548
                                      (const_int 3)
549
                                      (const_int 1)))])
550
 
551
(define_insn ""
552
  [(set (pc)
553
        (if_then_else (ge (cc0)
554
                          (const_int 0))
555
                      (pc)
556
                      (label_ref (match_operand 0 "" ""))))]
557
  ""
558
  "* return output_jump(\"blt\", \"bge\", get_attr_length(insn));"
559
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
560
                                                      (pc))
561
                                               (const_int -128))
562
                                           (ge (minus (match_dup 0)
563
                                                      (pc))
564
                                               (const_int 128)))
565
                                      (const_int 3)
566
                                      (const_int 1)))])
567
 
568
(define_insn ""
569
  [(set (pc)
570
        (if_then_else (geu (cc0)
571
                           (const_int 0))
572
                      (pc)
573
                      (label_ref (match_operand 0 "" ""))))]
574
  ""
575
  "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));"
576
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
577
                                                      (pc))
578
                                               (const_int -128))
579
                                           (ge (minus (match_dup 0)
580
                                                      (pc))
581
                                               (const_int 128)))
582
                                      (const_int 3)
583
                                      (const_int 1)))])
584
 
585
(define_insn ""
586
  [(set (pc)
587
        (if_then_else (le (cc0)
588
                          (const_int 0))
589
                      (pc)
590
                      (label_ref (match_operand 0 "" ""))))]
591
  ""
592
  "* return output_jump(\"bgt\", \"ble\", get_attr_length(insn));"
593
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
594
                                                      (pc))
595
                                               (const_int -128))
596
                                           (ge (minus (match_dup 0)
597
                                                      (pc))
598
                                               (const_int 128)))
599
                                      (const_int 3)
600
                                      (const_int 1)))])
601
 
602
(define_insn ""
603
  [(set (pc)
604
        (if_then_else (leu (cc0)
605
                           (const_int 0))
606
                      (pc)
607
                      (label_ref (match_operand 0 "" ""))))]
608
  ""
609
  "* return output_jump(\"bhi\", \"blos\", get_attr_length(insn));"
610
  [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
611
                                                      (pc))
612
                                               (const_int -128))
613
                                           (ge (minus (match_dup 0)
614
                                                      (pc))
615
                                               (const_int 128)))
616
                                      (const_int 3)
617
                                      (const_int 1)))])
618
 
619
;; Move instructions
620
 
621
(define_insn "movdi"
622
  [(set (match_operand:DI 0 "general_operand" "=g,rm,o")
623
        (match_operand:DI 1 "general_operand" "m,r,a"))]
624
  ""
625
  "* return output_move_quad (operands);"
626
;; what's the mose expensive code - say twice movsi = 16
627
  [(set_attr "length" "16,16,16")])
628
 
629
(define_insn "movsi"
630
  [(set (match_operand:SI 0 "general_operand" "=r,r,r,rm,m")
631
        (match_operand:SI 1 "general_operand" "rN,IJ,K,m,r"))]
632
  ""
633
  "* return output_move_double (operands);"
634
;; what's the most expensive code ? - I think 8!
635
;; we could split it up and make several sub-cases...
636
  [(set_attr "length" "2,3,4,8,8")])
637
 
638
(define_insn "movhi"
639
  [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
640
        (match_operand:HI 1 "general_operand" "rRN,Qi,rRN,Qi"))]
641
  ""
642
  "*
643
{
644
  if (operands[1] == const0_rtx)
645
    return \"clr %0\";
646
 
647
  return \"mov %1, %0\";
648
}"
649
  [(set_attr "length" "1,2,2,3")])
650
 
651
(define_insn "movqi"
652
  [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
653
        (match_operand:QI 1 "general_operand" "g"))]
654
  ""
655
  "*
656
{
657
  if (operands[1] == const0_rtx)
658
    return \"clrb %0\";
659
 
660
  return \"movb %1, %0\";
661
}"
662
  [(set_attr "length" "1")])
663
 
664
;; do we have to supply all these moves? e.g. to
665
;; NO_LOAD_FPU_REGs ?
666
(define_insn "movdf"
667
  [(set (match_operand:DF 0 "general_operand" "=a,fR,a,Q,m")
668
        (match_operand:DF 1 "general_operand" "fFR,a,Q,a,m"))]
669
  ""
670
  "* if (which_alternative ==0)
671
       return \"ldd %1, %0\";
672
     else if (which_alternative == 1)
673
       return \"std %1, %0\";
674
     else
675
       return output_move_quad (operands); "
676
;; just a guess..
677
  [(set_attr "length" "1,1,5,5,16")])
678
 
679
(define_insn "movsf"
680
  [(set (match_operand:SF 0 "general_operand" "=g,r,g")
681
        (match_operand:SF 1 "general_operand" "r,rmF,g"))]
682
  "TARGET_FPU"
683
  "* return output_move_double (operands);"
684
  [(set_attr "length" "8,8,8")])
685
 
686
;; maybe fiddle a bit with move_ratio, then
687
;; let constraints only accept a register ...
688
 
689
(define_expand "movmemhi"
690
  [(parallel [(set (match_operand:BLK 0 "general_operand" "=g,g")
691
                   (match_operand:BLK 1 "general_operand" "g,g"))
692
              (use (match_operand:HI 2 "arith_operand" "n,&mr"))
693
              (use (match_operand:HI 3 "immediate_operand" "i,i"))
694
              (clobber (match_scratch:HI 4 "=&r,X"))
695
              (clobber (match_dup 5))
696
              (clobber (match_dup 6))
697
              (clobber (match_dup 2))])]
698
  "(TARGET_BCOPY_BUILTIN)"
699
  "
700
{
701
  operands[0]
702
    = replace_equiv_address (operands[0],
703
                             copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
704
  operands[1]
705
    = replace_equiv_address (operands[1],
706
                             copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
707
 
708
  operands[5] = XEXP (operands[0], 0);
709
  operands[6] = XEXP (operands[1], 0);
710
}")
711
 
712
 
713
(define_insn "" ; "movmemhi"
714
  [(set (mem:BLK (match_operand:HI 0 "general_operand" "=r,r"))
715
        (mem:BLK (match_operand:HI 1 "general_operand" "r,r")))
716
   (use (match_operand:HI 2 "arith_operand" "n,&r"))
717
   (use (match_operand:HI 3 "immediate_operand" "i,i"))
718
   (clobber (match_scratch:HI 4 "=&r,X"))
719
   (clobber (match_dup 0))
720
   (clobber (match_dup 1))
721
   (clobber (match_dup 2))]
722
  "(TARGET_BCOPY_BUILTIN)"
723
  "* return output_block_move (operands);"
724
;;; just a guess
725
  [(set_attr "length" "40")])
726
 
727
 
728
 
729
;;- truncation instructions
730
 
731
(define_insn  "truncdfsf2"
732
  [(set (match_operand:SF 0 "general_operand" "=r,R,Q")
733
        (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a,a")))]
734
  "TARGET_FPU"
735
  "* if (which_alternative ==0)
736
     {
737
       output_asm_insn(\"{stcdf|movfo} %1, -(sp)\", operands);
738
       output_asm_insn(\"mov (sp)+, %0\", operands);
739
       operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+1);
740
       output_asm_insn(\"mov (sp)+, %0\", operands);
741
       return \"\";
742
     }
743
     else if (which_alternative == 1)
744
       return \"{stcdf|movfo} %1, %0\";
745
     else
746
       return \"{stcdf|movfo} %1, %0\";
747
  "
748
  [(set_attr "length" "3,1,2")])
749
 
750
 
751
(define_expand "truncsihi2"
752
  [(set (match_operand:HI 0 "general_operand" "=g")
753
        (subreg:HI
754
          (match_operand:SI 1 "general_operand" "or")
755
          0))]
756
  ""
757
  "")
758
 
759
 
760
;;- zero extension instructions
761
 
762
(define_insn "zero_extendqihi2"
763
  [(set (match_operand:HI 0 "general_operand" "=r")
764
        (zero_extend:HI (match_operand:QI 1 "general_operand" "0")))]
765
  ""
766
  "bic $0177400, %0"
767
  [(set_attr "length" "2")])
768
 
769
(define_expand "zero_extendhisi2"
770
  [(set (subreg:HI
771
          (match_dup 0)
772
          2)
773
        (match_operand:HI 1 "register_operand" "r"))
774
   (set (subreg:HI
775
          (match_operand:SI 0 "register_operand" "=r")
776
          0)
777
        (const_int 0))]
778
  ""
779
  "/* operands[1] = make_safe_from (operands[1], operands[0]); */")
780
 
781
 
782
;;- sign extension instructions
783
 
784
(define_insn "extendsfdf2"
785
  [(set (match_operand:DF 0 "register_operand" "=a,a,a")
786
        (float_extend:DF (match_operand:SF 1 "general_operand" "r,R,Q")))]
787
  "TARGET_FPU"
788
  "@
789
   mov %1, -(sp)\;{ldcfd|movof} (sp)+,%0
790
   {ldcfd|movof} %1, %0
791
   {ldcfd|movof} %1, %0"
792
  [(set_attr "length" "2,1,2")])
793
 
794
;; does movb sign extend in register-to-register move?
795
(define_insn "extendqihi2"
796
  [(set (match_operand:HI 0 "register_operand" "=r,r")
797
        (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))]
798
  ""
799
  "movb %1, %0"
800
  [(set_attr "length" "1,2")])
801
 
802
(define_insn "extendqisi2"
803
  [(set (match_operand:SI 0 "register_operand" "=r,r")
804
        (sign_extend:SI (match_operand:QI 1 "general_operand" "rR,Q")))]
805
  "TARGET_40_PLUS"
806
  "*
807
{
808
  rtx latehalf[2];
809
 
810
  /* make register pair available */
811
  latehalf[0] = operands[0];
812
  operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+ 1);
813
 
814
  output_asm_insn(\"movb %1, %0\", operands);
815
  output_asm_insn(\"sxt %0\", latehalf);
816
 
817
  return \"\";
818
}"
819
  [(set_attr "length" "2,3")])
820
 
821
;; maybe we have to use define_expand to say that we have the instruction,
822
;; unconditionally, and then match dependent on CPU type:
823
 
824
(define_expand "extendhisi2"
825
  [(set (match_operand:SI 0 "general_operand" "=g")
826
        (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))]
827
  ""
828
  "")
829
 
830
(define_insn "" ; "extendhisi2"
831
  [(set (match_operand:SI 0 "general_operand" "=o,<,r")
832
        (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g")))]
833
  "TARGET_40_PLUS"
834
  "*
835
{
836
  rtx latehalf[2];
837
 
838
  /* we don't want to mess with auto increment */
839
 
840
  switch (which_alternative)
841
  {
842
    case 0:
843
 
844
      latehalf[0] = operands[0];
845
      operands[0] = adjust_address(operands[0], HImode, 2);
846
 
847
      output_asm_insn(\"mov %1, %0\", operands);
848
      output_asm_insn(\"sxt %0\", latehalf);
849
 
850
      return \"\";
851
 
852
    case 1:
853
 
854
      /* - auto-decrement - right direction ;-) */
855
      output_asm_insn(\"mov %1, %0\", operands);
856
      output_asm_insn(\"sxt %0\", operands);
857
 
858
      return \"\";
859
 
860
    case 2:
861
 
862
      /* make register pair available */
863
      latehalf[0] = operands[0];
864
      operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
865
 
866
      output_asm_insn(\"mov %1, %0\", operands);
867
      output_asm_insn(\"sxt %0\", latehalf);
868
 
869
      return \"\";
870
 
871
    default:
872
 
873
      gcc_unreachable ();
874
  }
875
}"
876
  [(set_attr "length" "5,3,3")])
877
 
878
 
879
(define_insn ""
880
  [(set (match_operand:SI 0 "register_operand" "=r")
881
        (sign_extend:SI (match_operand:HI 1 "general_operand" "0")))]
882
  "(! TARGET_40_PLUS)"
883
  "*
884
{
885
  static int count = 0;
886
  char buf[100];
887
  rtx lateoperands[2];
888
 
889
  lateoperands[0] = operands[0];
890
  operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
891
 
892
  output_asm_insn(\"tst %0\", operands);
893
  sprintf(buf, \"bge extendhisi%d\", count);
894
  output_asm_insn(buf, NULL);
895
  output_asm_insn(\"mov -1, %0\", lateoperands);
896
  sprintf(buf, \"bne extendhisi%d\", count+1);
897
  output_asm_insn(buf, NULL);
898
  sprintf(buf, \"\\nextendhisi%d:\", count);
899
  output_asm_insn(buf, NULL);
900
  output_asm_insn(\"clr %0\", lateoperands);
901
  sprintf(buf, \"\\nextendhisi%d:\", count+1);
902
  output_asm_insn(buf, NULL);
903
 
904
  count += 2;
905
 
906
  return \"\";
907
}"
908
  [(set_attr "length" "6")])
909
 
910
;; make float to int and vice versa
911
;; using the cc_status.flag field we could probably cut down
912
;; on seti and setl
913
;; assume that we are normally in double and integer mode -
914
;; what do pdp library routines do to fpu mode ?
915
 
916
(define_insn "floatsidf2"
917
  [(set (match_operand:DF 0 "register_operand" "=a,a,a")
918
        (float:DF (match_operand:SI 1 "general_operand" "r,R,Q")))]
919
  "TARGET_FPU"
920
  "* if (which_alternative ==0)
921
     {
922
       rtx latehalf[2];
923
 
924
       latehalf[0] = NULL;
925
       latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
926
       output_asm_insn(\"mov %1, -(sp)\", latehalf);
927
       output_asm_insn(\"mov %1, -(sp)\", operands);
928
 
929
       output_asm_insn(\"setl\", operands);
930
       output_asm_insn(\"{ldcld|movif} (sp)+, %0\", operands);
931
       output_asm_insn(\"seti\", operands);
932
       return \"\";
933
     }
934
     else if (which_alternative == 1)
935
       return \"setl\;{ldcld|movif} %1, %0\;seti\";
936
     else
937
       return \"setl\;{ldcld|movif} %1, %0\;seti\";
938
  "
939
  [(set_attr "length" "5,3,4")])
940
 
941
(define_insn "floathidf2"
942
  [(set (match_operand:DF 0 "register_operand" "=a,a")
943
        (float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))]
944
  "TARGET_FPU"
945
  "{ldcid|movif} %1, %0"
946
  [(set_attr "length" "1,2")])
947
 
948
;; cut float to int
949
(define_insn "fix_truncdfsi2"
950
  [(set (match_operand:SI 0 "general_operand" "=r,R,Q")
951
        (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a,a"))))]
952
  "TARGET_FPU"
953
  "* if (which_alternative ==0)
954
     {
955
       output_asm_insn(\"setl\", operands);
956
       output_asm_insn(\"{stcdl|movfi} %1, -(sp)\", operands);
957
       output_asm_insn(\"seti\", operands);
958
       output_asm_insn(\"mov (sp)+, %0\", operands);
959
       operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
960
       output_asm_insn(\"mov (sp)+, %0\", operands);
961
       return \"\";
962
     }
963
     else if (which_alternative == 1)
964
       return \"setl\;{stcdl|movfi} %1, %0\;seti\";
965
     else
966
       return \"setl\;{stcdl|movfi} %1, %0\;seti\";
967
  "
968
  [(set_attr "length" "5,3,4")])
969
 
970
(define_insn "fix_truncdfhi2"
971
  [(set (match_operand:HI 0 "general_operand" "=rR,Q")
972
        (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))]
973
  "TARGET_FPU"
974
  "{stcdi|movfi} %1, %0"
975
  [(set_attr "length" "1,2")])
976
 
977
 
978
;;- arithmetic instructions
979
;;- add instructions
980
 
981
(define_insn "adddf3"
982
  [(set (match_operand:DF 0 "register_operand" "=a,a,a")
983
        (plus:DF (match_operand:DF 1 "register_operand" "%0,0,0")
984
                 (match_operand:DF 2 "general_operand" "fR,Q,F")))]
985
  "TARGET_FPU"
986
  "{addd|addf} %2, %0"
987
  [(set_attr "length" "1,2,5")])
988
 
989
(define_insn "addsi3"
990
  [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
991
        (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
992
                 (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))]
993
  ""
994
  "*
995
{ /* Here we trust that operands don't overlap
996
 
997
     or is lateoperands the low word?? - looks like it! */
998
 
999
  rtx lateoperands[3];
1000
 
1001
  lateoperands[0] = operands[0];
1002
 
1003
  if (REG_P (operands[0]))
1004
    operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1005
  else
1006
    operands[0] = adjust_address (operands[0], HImode, 2);
1007
 
1008
  if (! CONSTANT_P(operands[2]))
1009
  {
1010
    lateoperands[2] = operands[2];
1011
 
1012
    if (REG_P (operands[2]))
1013
      operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1014
    else
1015
      operands[2] = adjust_address (operands[2], HImode, 2);
1016
 
1017
    output_asm_insn (\"add %2, %0\", operands);
1018
    output_asm_insn (\"adc %0\", lateoperands);
1019
    output_asm_insn (\"add %2, %0\", lateoperands);
1020
    return \"\";
1021
  }
1022
 
1023
  lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
1024
  operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1025
 
1026
  if (INTVAL(operands[2]))
1027
  {
1028
    output_asm_insn (\"add %2, %0\", operands);
1029
    output_asm_insn (\"adc %0\", lateoperands);
1030
  }
1031
 
1032
  if (INTVAL(lateoperands[2]))
1033
    output_asm_insn (\"add %2, %0\", lateoperands);
1034
 
1035
  return \"\";
1036
}"
1037
  [(set_attr "length" "3,5,6,8,3,1,5,5,3,8")])
1038
 
1039
(define_insn "addhi3"
1040
  [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1041
        (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
1042
                 (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
1043
  ""
1044
  "*
1045
{
1046
  if (GET_CODE (operands[2]) == CONST_INT)
1047
    {
1048
      if (INTVAL(operands[2]) == 1)
1049
        return \"inc %0\";
1050
      else if (INTVAL(operands[2]) == -1)
1051
        return \"dec %0\";
1052
    }
1053
 
1054
  return \"add %2, %0\";
1055
}"
1056
  [(set_attr "length" "1,2,2,3")])
1057
 
1058
(define_insn "addqi3"
1059
  [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1060
        (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
1061
                 (match_operand:QI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
1062
  ""
1063
  "*
1064
{
1065
  if (GET_CODE (operands[2]) == CONST_INT)
1066
    {
1067
      if (INTVAL(operands[2]) == 1)
1068
        return \"incb %0\";
1069
      else if (INTVAL(operands[2]) == -1)
1070
        return \"decb %0\";
1071
    }
1072
 
1073
  return \"add %2, %0\";
1074
}"
1075
  [(set_attr "length" "1,2,2,3")])
1076
 
1077
 
1078
;;- subtract instructions
1079
;; we don't have to care for constant second
1080
;; args, since they are canonical plus:xx now!
1081
;; also for minus:DF ??
1082
 
1083
(define_insn "subdf3"
1084
  [(set (match_operand:DF 0 "register_operand" "=a,a")
1085
        (minus:DF (match_operand:DF 1 "register_operand" "0,0")
1086
                  (match_operand:DF 2 "general_operand" "fR,Q")))]
1087
  "TARGET_FPU"
1088
  "{subd|subf} %2, %0"
1089
  [(set_attr "length" "1,2")])
1090
 
1091
(define_insn "subsi3"
1092
  [(set (match_operand:SI 0 "general_operand" "=r,r,o,o")
1093
        (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0")
1094
                  (match_operand:SI 2 "general_operand" "r,o,r,o")))]
1095
  ""
1096
  "*
1097
{ /* Here we trust that operands don't overlap
1098
 
1099
     or is lateoperands the low word?? - looks like it! */
1100
 
1101
  rtx lateoperands[3];
1102
 
1103
  lateoperands[0] = operands[0];
1104
 
1105
  if (REG_P (operands[0]))
1106
    operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1107
  else
1108
    operands[0] = adjust_address (operands[0], HImode, 2);
1109
 
1110
  lateoperands[2] = operands[2];
1111
 
1112
  if (REG_P (operands[2]))
1113
    operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1114
  else
1115
    operands[2] = adjust_address (operands[2], HImode, 2);
1116
 
1117
  output_asm_insn (\"sub %2, %0\", operands);
1118
  output_asm_insn (\"sbc %0\", lateoperands);
1119
  output_asm_insn (\"sub %2, %0\", lateoperands);
1120
  return \"\";
1121
}"
1122
;; offsettable memory addresses always are expensive!!!
1123
  [(set_attr "length" "3,5,6,8")])
1124
 
1125
(define_insn "subhi3"
1126
  [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1127
        (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
1128
                  (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
1129
  ""
1130
  "*
1131
{
1132
  gcc_assert (GET_CODE (operands[2]) != CONST_INT);
1133
 
1134
  return \"sub %2, %0\";
1135
}"
1136
  [(set_attr "length" "1,2,2,3")])
1137
 
1138
(define_insn "subqi3"
1139
  [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1140
        (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
1141
                  (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
1142
  ""
1143
  "*
1144
{
1145
  gcc_assert (GET_CODE (operands[2]) != CONST_INT);
1146
 
1147
  return \"sub %2, %0\";
1148
}"
1149
  [(set_attr "length" "1,2,2,3")])
1150
 
1151
;;;;- and instructions
1152
;; Bit-and on the pdp (like on the VAX) is done with a clear-bits insn.
1153
 
1154
(define_insn "andsi3"
1155
  [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
1156
        (and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
1157
                (not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))]
1158
  ""
1159
  "*
1160
{ /* Here we trust that operands don't overlap
1161
 
1162
     or is lateoperands the low word?? - looks like it! */
1163
 
1164
  rtx lateoperands[3];
1165
 
1166
  lateoperands[0] = operands[0];
1167
 
1168
  if (REG_P (operands[0]))
1169
    operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1170
  else
1171
    operands[0] = adjust_address (operands[0], HImode, 2);
1172
 
1173
  if (! CONSTANT_P(operands[2]))
1174
  {
1175
    lateoperands[2] = operands[2];
1176
 
1177
    if (REG_P (operands[2]))
1178
      operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1179
    else
1180
      operands[2] = adjust_address (operands[2], HImode, 2);
1181
 
1182
    output_asm_insn (\"bic %2, %0\", operands);
1183
    output_asm_insn (\"bic %2, %0\", lateoperands);
1184
    return \"\";
1185
  }
1186
 
1187
  lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
1188
  operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1189
 
1190
  /* these have different lengths, so we should have
1191
     different constraints! */
1192
  if (INTVAL(operands[2]))
1193
    output_asm_insn (\"bic %2, %0\", operands);
1194
 
1195
  if (INTVAL(lateoperands[2]))
1196
    output_asm_insn (\"bic %2, %0\", lateoperands);
1197
 
1198
  return \"\";
1199
}"
1200
  [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
1201
 
1202
(define_insn "andhi3"
1203
  [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1204
        (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
1205
                (not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))]
1206
  ""
1207
  "bic %2, %0"
1208
  [(set_attr "length" "1,2,2,3")])
1209
 
1210
(define_insn "andqi3"
1211
  [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1212
        (and:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
1213
                (not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))]
1214
  ""
1215
  "bicb %2, %0"
1216
  [(set_attr "length" "1,2,2,3")])
1217
 
1218
;;- Bit set (inclusive or) instructions
1219
(define_insn "iorsi3"
1220
  [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
1221
        (ior:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
1222
                  (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))]
1223
  ""
1224
  "*
1225
{ /* Here we trust that operands don't overlap
1226
 
1227
     or is lateoperands the low word?? - looks like it! */
1228
 
1229
  rtx lateoperands[3];
1230
 
1231
  lateoperands[0] = operands[0];
1232
 
1233
  if (REG_P (operands[0]))
1234
    operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1235
  else
1236
    operands[0] = adjust_address (operands[0], HImode, 2);
1237
 
1238
  if (! CONSTANT_P(operands[2]))
1239
    {
1240
      lateoperands[2] = operands[2];
1241
 
1242
      if (REG_P (operands[2]))
1243
        operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1244
      else
1245
        operands[2] = adjust_address (operands[2], HImode, 2);
1246
 
1247
      output_asm_insn (\"bis %2, %0\", operands);
1248
      output_asm_insn (\"bis %2, %0\", lateoperands);
1249
      return \"\";
1250
    }
1251
 
1252
  lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
1253
  operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1254
 
1255
  /* these have different lengths, so we should have
1256
     different constraints! */
1257
  if (INTVAL(operands[2]))
1258
    output_asm_insn (\"bis %2, %0\", operands);
1259
 
1260
  if (INTVAL(lateoperands[2]))
1261
    output_asm_insn (\"bis %2, %0\", lateoperands);
1262
 
1263
  return \"\";
1264
}"
1265
  [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
1266
 
1267
(define_insn "iorhi3"
1268
  [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1269
        (ior:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
1270
                (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
1271
  ""
1272
  "bis %2, %0"
1273
  [(set_attr "length" "1,2,2,3")])
1274
 
1275
(define_insn "iorqi3"
1276
  [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1277
        (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
1278
                (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
1279
  ""
1280
  "bisb %2, %0")
1281
 
1282
;;- xor instructions
1283
(define_insn "xorsi3"
1284
  [(set (match_operand:SI 0 "register_operand" "=r")
1285
        (xor:SI (match_operand:SI 1 "register_operand" "%0")
1286
                (match_operand:SI 2 "arith_operand" "r")))]
1287
  "TARGET_40_PLUS"
1288
  "*
1289
{ /* Here we trust that operands don't overlap */
1290
 
1291
  rtx lateoperands[3];
1292
 
1293
  lateoperands[0] = operands[0];
1294
  operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1295
 
1296
  if (REG_P(operands[2]))
1297
    {
1298
      lateoperands[2] = operands[2];
1299
      operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1300
 
1301
      output_asm_insn (\"xor %2, %0\", operands);
1302
      output_asm_insn (\"xor %2, %0\", lateoperands);
1303
 
1304
      return \"\";
1305
    }
1306
 
1307
}"
1308
  [(set_attr "length" "2")])
1309
 
1310
(define_insn "xorhi3"
1311
  [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1312
        (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
1313
                (match_operand:HI 2 "register_operand" "r,r")))]
1314
  "TARGET_40_PLUS"
1315
  "xor %2, %0"
1316
  [(set_attr "length" "1,2")])
1317
 
1318
;;- one complement instructions
1319
 
1320
(define_insn "one_cmplhi2"
1321
  [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1322
        (not:HI (match_operand:HI 1 "general_operand" "0,0")))]
1323
  ""
1324
  "com %0"
1325
  [(set_attr "length" "1,2")])
1326
 
1327
(define_insn "one_cmplqi2"
1328
  [(set (match_operand:QI 0 "general_operand" "=rR,rR")
1329
        (not:QI (match_operand:QI 1 "general_operand" "0,g")))]
1330
  ""
1331
  "@
1332
  comb %0
1333
  movb %1, %0\; comb %0"
1334
  [(set_attr "length" "1,2")])
1335
 
1336
;;- arithmetic shift instructions
1337
(define_insn "ashlsi3"
1338
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1339
        (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
1340
                   (match_operand:HI 2 "general_operand" "rR,Qi")))]
1341
  "TARGET_45"
1342
  "ashc %2,%0"
1343
  [(set_attr "length" "1,2")])
1344
 
1345
;; Arithmetic right shift on the pdp works by negating the shift count.
1346
(define_expand "ashrsi3"
1347
  [(set (match_operand:SI 0 "register_operand" "=r")
1348
        (ashift:SI (match_operand:SI 1 "register_operand" "0")
1349
                   (match_operand:HI 2 "general_operand" "g")))]
1350
  ""
1351
  "
1352
{
1353
  operands[2] = negate_rtx (HImode, operands[2]);
1354
}")
1355
 
1356
;; define asl aslb asr asrb - ashc missing!
1357
 
1358
;; asl
1359
(define_insn ""
1360
  [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1361
        (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1362
                   (const_int 1)))]
1363
  ""
1364
  "asl %0"
1365
  [(set_attr "length" "1,2")])
1366
 
1367
;; and another possibility for asr is << -1
1368
;; might cause problems since -1 can also be encoded as 65535!
1369
;; not in gcc2 ???
1370
 
1371
;; asr
1372
(define_insn ""
1373
  [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1374
        (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1375
                   (const_int -1)))]
1376
  ""
1377
  "asr %0"
1378
  [(set_attr "length" "1,2")])
1379
 
1380
;; lsr
1381
(define_insn ""
1382
  [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1383
        (lshiftrt:HI (match_operand:HI 1 "general_operand" "0,0")
1384
                   (const_int 1)))]
1385
  ""
1386
  "clc\;ror %0"
1387
  [(set_attr "length" "1,2")])
1388
 
1389
(define_insn "lshrsi3"
1390
  [(set (match_operand:SI 0 "register_operand" "=r")
1391
        (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1392
                   (const_int 1)))]
1393
  ""
1394
{
1395
 
1396
  rtx lateoperands[2];
1397
 
1398
  lateoperands[0] = operands[0];
1399
  operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1400
 
1401
  lateoperands[1] = operands[1];
1402
  operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
1403
 
1404
  output_asm_insn (\"clc\", operands);
1405
  output_asm_insn (\"ror %0\", lateoperands);
1406
  output_asm_insn (\"ror %0\", operands);
1407
 
1408
  return \"\";
1409
}
1410
  [(set_attr "length" "5")])
1411
 
1412
;; shift is by arbitrary count is expensive,
1413
;; shift by one cheap - so let's do that, if
1414
;; space doesn't matter
1415
(define_insn ""
1416
  [(set (match_operand:HI 0 "general_operand" "=r")
1417
        (ashift:HI (match_operand:HI 1 "general_operand" "0")
1418
                   (match_operand:HI 2 "expand_shift_operand" "O")))]
1419
  "! optimize_size"
1420
  "*
1421
{
1422
  register int i;
1423
 
1424
  for (i = 1; i <= abs(INTVAL(operands[2])); i++)
1425
    if (INTVAL(operands[2]) < 0)
1426
      output_asm_insn(\"asr %0\", operands);
1427
    else
1428
      output_asm_insn(\"asl %0\", operands);
1429
 
1430
  return \"\";
1431
}"
1432
;; longest is 4
1433
  [(set (attr "length") (const_int 4))])
1434
 
1435
;; aslb
1436
(define_insn ""
1437
  [(set (match_operand:QI 0 "general_operand" "=r,o")
1438
        (ashift:QI (match_operand:QI 1 "general_operand" "0,0")
1439
                   (match_operand:HI 2 "const_immediate_operand" "n,n")))]
1440
  ""
1441
  "*
1442
{ /* allowing predec or post_inc is possible, but hairy! */
1443
  int i, cnt;
1444
 
1445
  cnt = INTVAL(operands[2]) & 0x0007;
1446
 
1447
  for (i=0 ; i < cnt ; i++)
1448
       output_asm_insn(\"aslb %0\", operands);
1449
 
1450
  return \"\";
1451
}"
1452
;; set attribute length ( match_dup 2 & 7 ) *(1 or 2) !!!
1453
  [(set_attr_alternative "length"
1454
                         [(const_int 7)
1455
                          (const_int 14)])])
1456
 
1457
;;; asr
1458
;(define_insn ""
1459
;  [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1460
;       (ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0")
1461
;                    (const_int 1)))]
1462
;  ""
1463
;  "asr %0"
1464
;  [(set_attr "length" "1,2")])
1465
 
1466
;; asrb
1467
(define_insn ""
1468
  [(set (match_operand:QI 0 "general_operand" "=r,o")
1469
        (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0")
1470
                     (match_operand:HI 2 "const_immediate_operand" "n,n")))]
1471
  ""
1472
  "*
1473
{ /* allowing predec or post_inc is possible, but hairy! */
1474
  int i, cnt;
1475
 
1476
  cnt = INTVAL(operands[2]) & 0x0007;
1477
 
1478
  for (i=0 ; i < cnt ; i++)
1479
       output_asm_insn(\"asrb %0\", operands);
1480
 
1481
  return \"\";
1482
}"
1483
  [(set_attr_alternative "length"
1484
                         [(const_int 7)
1485
                          (const_int 14)])])
1486
 
1487
;; the following is invalid - too complex!!! - just say 14 !!!
1488
;  [(set (attr "length") (plus (and (match_dup 2)
1489
;                                   (const_int 7))
1490
;                              (and (match_dup 2)
1491
;                                   (const_int 7))))])
1492
 
1493
 
1494
 
1495
;; can we get +-1 in the next pattern? should
1496
;; have been caught by previous patterns!
1497
 
1498
(define_insn "ashlhi3"
1499
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1500
        (ashift:HI (match_operand:HI 1 "register_operand" "0,0")
1501
                   (match_operand:HI 2 "general_operand" "rR,Qi")))]
1502
  ""
1503
  "*
1504
{
1505
  if (GET_CODE(operands[2]) == CONST_INT)
1506
    {
1507
      if (INTVAL(operands[2]) == 1)
1508
        return \"asl %0\";
1509
      else if (INTVAL(operands[2]) == -1)
1510
        return \"asr %0\";
1511
    }
1512
 
1513
  return \"ash %2,%0\";
1514
}"
1515
  [(set_attr "length" "1,2")])
1516
 
1517
;; Arithmetic right shift on the pdp works by negating the shift count.
1518
(define_expand "ashrhi3"
1519
  [(set (match_operand:HI 0 "register_operand" "=r")
1520
        (ashift:HI (match_operand:HI 1 "register_operand" "0")
1521
                   (match_operand:HI 2 "general_operand" "g")))]
1522
  ""
1523
  "
1524
{
1525
  operands[2] = negate_rtx (HImode, operands[2]);
1526
}")
1527
 
1528
;;;;- logical shift instructions
1529
;;(define_insn "lshrsi3"
1530
;;  [(set (match_operand:HI 0 "register_operand" "=r")
1531
;;      (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
1532
;;                   (match_operand:HI 2 "arith_operand" "rI")))]
1533
;;  ""
1534
;;  "srl %0,%2")
1535
 
1536
;; absolute
1537
 
1538
(define_insn "absdf2"
1539
  [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1540
        (abs:DF (match_operand:DF 1 "general_operand" "0,0")))]
1541
  "TARGET_FPU"
1542
  "{absd|absf} %0"
1543
  [(set_attr "length" "1,2")])
1544
 
1545
(define_insn "abshi2"
1546
  [(set (match_operand:HI 0 "general_operand" "=r,o")
1547
        (abs:HI (match_operand:HI 1 "general_operand" "0,0")))]
1548
  "TARGET_ABSHI_BUILTIN"
1549
  "*
1550
{
1551
  static int count = 0;
1552
  char buf[200];
1553
 
1554
  output_asm_insn(\"tst %0\", operands);
1555
  sprintf(buf, \"bge abshi%d\", count);
1556
  output_asm_insn(buf, NULL);
1557
  output_asm_insn(\"neg %0\", operands);
1558
  sprintf(buf, \"\\nabshi%d:\", count++);
1559
  output_asm_insn(buf, NULL);
1560
 
1561
  return \"\";
1562
}"
1563
  [(set_attr "length" "3,5")])
1564
 
1565
 
1566
;; define expand abshi - is much better !!! - but
1567
;; will it be optimized into an abshi2 ?
1568
;; it will leave better code, because the tsthi might be
1569
;; optimized away!!
1570
; -- just a thought - don't have time to check
1571
;
1572
;(define_expand "abshi2"
1573
;  [(match_operand:HI 0 "general_operand" "")
1574
;   (match_operand:HI 1 "general_operand" "")]
1575
;  ""
1576
;  "
1577
;{
1578
;  rtx label = gen_label_rtx ();
1579
;
1580
;  /* do I need this? */
1581
;  do_pending_stack_adjust ();
1582
;
1583
;  emit_move_insn (operands[0], operands[1]);
1584
;
1585
;  emit_insn (gen_tsthi (operands[0]));
1586
;  emit_insn (gen_bge (label1));
1587
;
1588
;  emit_insn (gen_neghi(operands[0], operands[0])
1589
;
1590
;  emit_barrier ();
1591
;
1592
;  emit_label (label);
1593
;
1594
;  /* allow REG_NOTES to be set on last insn (labels don't have enough
1595
;     fields, and can't be used for REG_NOTES anyway).  */
1596
;  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
1597
;  DONE;
1598
;}")
1599
 
1600
;; negate insns
1601
 
1602
(define_insn "negdf2"
1603
  [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1604
        (neg:DF (match_operand:DF 1 "register_operand" "0,0")))]
1605
  "TARGET_FPU"
1606
  "{negd|negf} %0"
1607
  [(set_attr "length" "1,2")])
1608
 
1609
(define_insn "negsi2"
1610
  [(set (match_operand:SI 0 "register_operand" "=r")
1611
        (neg:SI (match_operand:SI 1 "general_operand" "0")))]
1612
  ""
1613
{
1614
 
1615
  rtx lateoperands[2];
1616
 
1617
  lateoperands[0] = operands[0];
1618
  operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1619
 
1620
  lateoperands[1] = operands[1];
1621
  operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
1622
 
1623
  output_asm_insn (\"com %0\", operands);
1624
  output_asm_insn (\"com %0\", lateoperands);
1625
  output_asm_insn (\"inc %0\", operands);
1626
  output_asm_insn (\"adc %0\", lateoperands);
1627
 
1628
  return \"\";
1629
}
1630
  [(set_attr "length" "5")])
1631
 
1632
(define_insn "neghi2"
1633
  [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1634
        (neg:HI (match_operand:HI 1 "general_operand" "0,0")))]
1635
  ""
1636
  "neg %0"
1637
  [(set_attr "length" "1,2")])
1638
 
1639
(define_insn "negqi2"
1640
  [(set (match_operand:QI 0 "general_operand" "=rR,Q")
1641
        (neg:QI (match_operand:QI 1 "general_operand" "0,0")))]
1642
  ""
1643
  "negb %0"
1644
  [(set_attr "length" "1,2")])
1645
 
1646
 
1647
;; Unconditional and other jump instructions
1648
(define_insn "jump"
1649
  [(set (pc)
1650
        (label_ref (match_operand 0 "" "")))]
1651
  ""
1652
  "jmp %l0"
1653
  [(set_attr "length" "2")])
1654
 
1655
(define_insn ""
1656
  [(set (pc)
1657
    (label_ref (match_operand 0 "" "")))
1658
   (clobber (const_int 1))]
1659
  ""
1660
  "jmp %l0"
1661
  [(set_attr "length" "2")])
1662
 
1663
(define_insn "tablejump"
1664
  [(set (pc) (match_operand:HI 0 "general_operand" "rR,Q"))
1665
   (use (label_ref (match_operand 1 "" "")))]
1666
  ""
1667
  "jmp %0"
1668
  [(set_attr "length" "1,2")])
1669
 
1670
;; indirect jump - let's be conservative!
1671
;; allow only register_operand, even though we could also
1672
;; allow labels etc.
1673
 
1674
(define_insn "indirect_jump"
1675
  [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
1676
  ""
1677
  "jmp (%0)")
1678
 
1679
;;- jump to subroutine
1680
 
1681
(define_insn "call"
1682
  [(call (match_operand:HI 0 "general_operand" "rR,Q")
1683
         (match_operand:HI 1 "general_operand" "g,g"))
1684
;;   (use (reg:HI 0)) what was that ???
1685
  ]
1686
  ;;- Don't use operand 1 for most machines.
1687
  ""
1688
  "jsr pc, %0"
1689
  [(set_attr "length" "1,2")])
1690
 
1691
;;- jump to subroutine
1692
(define_insn "call_value"
1693
  [(set (match_operand 0 "" "")
1694
        (call (match_operand:HI 1 "general_operand" "rR,Q")
1695
              (match_operand:HI 2 "general_operand" "g,g")))
1696
;;   (use (reg:HI 0)) - what was that ????
1697
  ]
1698
  ;;- Don't use operand 2 for most machines.
1699
  ""
1700
  "jsr pc, %1"
1701
  [(set_attr "length" "1,2")])
1702
 
1703
;;- nop instruction
1704
(define_insn "nop"
1705
  [(const_int 0)]
1706
  ""
1707
  "nop")
1708
 
1709
 
1710
;;- multiply
1711
 
1712
(define_insn "muldf3"
1713
  [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1714
        (mult:DF (match_operand:DF 1 "register_operand" "%0,0,0")
1715
                 (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1716
  "TARGET_FPU"
1717
  "{muld|mulf} %2, %0"
1718
  [(set_attr "length" "1,2,5")])
1719
 
1720
;; 16 bit result multiply:
1721
;; currently we multiply only into odd registers, so we don't use two
1722
;; registers - but this is a bit inefficient at times. If we define
1723
;; a register class for each register, then we can specify properly
1724
;; which register need which scratch register ....
1725
 
1726
(define_insn "mulhi3"
1727
  [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs
1728
        (mult:HI (match_operand:HI 1 "register_operand" "%0,0")
1729
                 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1730
  "TARGET_45"
1731
  "mul %2, %0"
1732
  [(set_attr "length" "1,2")])
1733
 
1734
;; 32 bit result
1735
(define_expand "mulhisi3"
1736
  [(set (match_dup 3)
1737
        (match_operand:HI 1 "general_operand" "g,g"))
1738
   (set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1739
        (mult:SI (truncate:HI
1740
                  (match_dup 0))
1741
                 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1742
  "TARGET_45"
1743
  "operands[3] = gen_lowpart(HImode, operands[1]);")
1744
 
1745
(define_insn ""
1746
  [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1747
        (mult:SI (truncate:HI
1748
                  (match_operand:SI 1 "register_operand" "%0,0"))
1749
                 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1750
  "TARGET_45"
1751
  "mul %2, %0"
1752
  [(set_attr "length" "1,2")])
1753
 
1754
;(define_insn "mulhisi3"
1755
;  [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1756
;       (mult:SI (truncate:HI
1757
;                  (match_operand:SI 1 "register_operand" "%0,0"))
1758
;                (match_operand:HI 2 "general_operand" "rR,Qi")))]
1759
;  "TARGET_45"
1760
;  "mul %2, %0"
1761
;  [(set_attr "length" "1,2")])
1762
 
1763
;;- divide
1764
(define_insn "divdf3"
1765
  [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1766
        (div:DF (match_operand:DF 1 "register_operand" "0,0,0")
1767
                (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1768
  "TARGET_FPU"
1769
  "{divd|divf} %2, %0"
1770
  [(set_attr "length" "1,2,5")])
1771
 
1772
 
1773
(define_expand "divhi3"
1774
  [(set (subreg:HI (match_dup 1) 0)
1775
        (div:HI (match_operand:SI 1 "general_operand" "0")
1776
                (match_operand:HI 2 "general_operand" "g")))
1777
   (set (match_operand:HI 0 "general_operand" "=r")
1778
        (subreg:HI (match_dup 1) 0))]
1779
  "TARGET_45"
1780
  "")
1781
 
1782
(define_insn ""
1783
  [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1784
        (div:HI (match_operand:SI 1 "general_operand" "0")
1785
                (match_operand:HI 2 "general_operand" "g")))]
1786
  "TARGET_45"
1787
  "div %2,%0"
1788
  [(set_attr "length" "2")])
1789
 
1790
(define_expand "modhi3"
1791
  [(set (subreg:HI (match_dup 1) 2)
1792
        (mod:HI (match_operand:SI 1 "general_operand" "0")
1793
                (match_operand:HI 2 "general_operand" "g")))
1794
   (set (match_operand:HI 0 "general_operand" "=r")
1795
        (subreg:HI (match_dup 1) 2))]
1796
  "TARGET_45"
1797
  "")
1798
 
1799
(define_insn ""
1800
  [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 2)
1801
        (mod:HI (match_operand:SI 1 "general_operand" "0")
1802
                (match_operand:HI 2 "general_operand" "g")))]
1803
  "TARGET_45"
1804
  "div %2,%0"
1805
  [(set_attr "length" "2")])
1806
 
1807
;(define_expand "divmodhi4"
1808
;  [(parallel [(set (subreg:HI (match_dup 1) 0)
1809
;                  (div:HI (match_operand:SI 1 "general_operand" "0")
1810
;                          (match_operand:HI 2 "general_operand" "g")))
1811
;              (set (subreg:HI (match_dup 1) 2)
1812
;                  (mod:HI (match_dup 1)
1813
;                          (match_dup 2)))])
1814
;   (set (match_operand:HI 3 "general_operand" "=r")
1815
;        (subreg:HI (match_dup 1) 2))
1816
;   (set (match_operand:HI 0 "general_operand" "=r")
1817
;        (subreg:HI (match_dup 1) 0))]
1818
;  "TARGET_45"
1819
;  "")
1820
;
1821
;(define_insn ""
1822
;  [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1823
;                  (div:HI (match_operand:SI 1 "general_operand" "0")
1824
;                          (match_operand:HI 2 "general_operand" "g")))
1825
;   (set (subreg:HI (match_dup 0) 2)
1826
;                  (mod:HI (match_dup 1)
1827
;                          (match_dup 2)))]
1828
;  "TARGET_45"
1829
;  "div %2, %0")
1830
;
1831
 
1832
;; is rotate doing the right thing to be included here ????

powered by: WebSVN 2.1.0

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