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

Subversion Repositories scarts

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

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

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