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

Subversion Repositories openrisc_me

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

Details | Compare with Previous | View Log

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