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

Subversion Repositories openrisc_me

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

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

Line No. Rev Author Line
1 38 julius
;; -*- Mode: Scheme -*-
2
;;   Machine description for GNU compiler,
3
;;   for ATMEL AVR micro controllers.
4
;;   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
5
;;   Free Software Foundation, Inc.
6
;;   Contributed by Denis Chertykov (denisc@overta.ru)
7
 
8
;; This file is part of GCC.
9
 
10
;; GCC is free software; you can redistribute it and/or modify
11
;; it under the terms of the GNU General Public License as published by
12
;; the Free Software Foundation; either version 3, or (at your option)
13
;; any later version.
14
 
15
;; GCC is distributed in the hope that it will be useful,
16
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
;; GNU General Public License for more details.
19
 
20
;; You should have received a copy of the GNU General Public License
21
;; along with GCC; see the file COPYING3.  If not see
22
;; .
23
 
24
;; Special characters after '%':
25
;;  A  No effect (add 0).
26
;;  B  Add 1 to REG number, MEM address or CONST_INT.
27
;;  C  Add 2.
28
;;  D  Add 3.
29
;;  j  Branch condition.
30
;;  k  Reverse branch condition.
31
;;  o  Displacement for (mem (plus (reg) (const_int))) operands.
32
;;  p  POST_INC or PRE_DEC address as a pointer (X, Y, Z)
33
;;  r  POST_INC or PRE_DEC address as a register (r26, r28, r30)
34
;;  ~  Output 'r' if not AVR_MEGA.
35
 
36
;; UNSPEC usage:
37
;;  0  Length of a string, see "strlenhi".
38
;;  1  Jump by register pair Z or by table addressed by Z, see "casesi".
39
 
40
(define_constants
41
  [(REG_X       26)
42
   (REG_Y       28)
43
   (REG_Z       30)
44
   (REG_W       24)
45
   (REG_SP      32)
46
   (TMP_REGNO   0)      ; temporary register r0
47
   (ZERO_REGNO  1)      ; zero register r1
48
   (UNSPEC_STRLEN       0)
49
   (UNSPEC_INDEX_JMP    1)])
50
 
51
(include "predicates.md")
52
(include "constraints.md")
53
 
54
;; Condition code settings.
55
(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
56
  (const_string "none"))
57
 
58
(define_attr "type" "branch,branch1,arith,xcall"
59
  (const_string "arith"))
60
 
61
(define_attr "mcu_have_movw" "yes,no"
62
  (const (if_then_else (symbol_ref "AVR_HAVE_MOVW")
63
                       (const_string "yes")
64
                       (const_string "no"))))
65
 
66
(define_attr "mcu_mega" "yes,no"
67
  (const (if_then_else (symbol_ref "AVR_MEGA")
68
                       (const_string "yes")
69
                       (const_string "no"))))
70
 
71
 
72
;; The size of instructions in bytes.
73
;; XXX may depend from "cc"
74
 
75
(define_attr "length" ""
76
  (cond [(eq_attr "type" "branch")
77
         (if_then_else (and (ge (minus (pc) (match_dup 0))
78
                                (const_int -63))
79
                            (le (minus (pc) (match_dup 0))
80
                                (const_int 62)))
81
                       (const_int 1)
82
                       (if_then_else (and (ge (minus (pc) (match_dup 0))
83
                                              (const_int -2045))
84
                                          (le (minus (pc) (match_dup 0))
85
                                              (const_int 2045)))
86
                                     (const_int 2)
87
                                     (const_int 3)))
88
         (eq_attr "type" "branch1")
89
         (if_then_else (and (ge (minus (pc) (match_dup 0))
90
                                (const_int -62))
91
                            (le (minus (pc) (match_dup 0))
92
                                (const_int 61)))
93
                       (const_int 2)
94
                       (if_then_else (and (ge (minus (pc) (match_dup 0))
95
                                              (const_int -2044))
96
                                          (le (minus (pc) (match_dup 0))
97
                                              (const_int 2043)))
98
                                     (const_int 3)
99
                                     (const_int 4)))
100
         (eq_attr "type" "xcall")
101
         (if_then_else (eq_attr "mcu_mega" "no")
102
                       (const_int 1)
103
                       (const_int 2))]
104
        (const_int 2)))
105
 
106
(define_insn "*pop1"
107
  [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 1)))]
108
  ""
109
  "pop __tmp_reg__"
110
  [(set_attr "length" "1")])
111
 
112
(define_insn "*pop2"
113
  [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 2)))]
114
  ""
115
  "pop __tmp_reg__
116
        pop __tmp_reg__"
117
  [(set_attr "length" "2")])
118
 
119
(define_insn "*pop3"
120
  [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 3)))]
121
  ""
122
  "pop __tmp_reg__
123
        pop __tmp_reg__
124
        pop __tmp_reg__"
125
  [(set_attr "length" "3")])
126
 
127
(define_insn "*pop4"
128
  [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 4)))]
129
  ""
130
  "pop __tmp_reg__
131
        pop __tmp_reg__
132
        pop __tmp_reg__
133
        pop __tmp_reg__"
134
  [(set_attr "length" "4")])
135
 
136
(define_insn "*pop5"
137
  [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 5)))]
138
  ""
139
  "pop __tmp_reg__
140
        pop __tmp_reg__
141
        pop __tmp_reg__
142
        pop __tmp_reg__
143
        pop __tmp_reg__"
144
  [(set_attr "length" "5")])
145
 
146
(define_insn "*pushqi"
147
  [(set (mem:QI (post_dec (reg:HI 32)))
148
        (match_operand:QI 0 "nonmemory_operand" "r,L"))]
149
  "(operands[0] == const0_rtx || register_operand (operands[0], QImode))"
150
  "@
151
        push %0
152
        push __zero_reg__"
153
  [(set_attr "length" "1,1")])
154
 
155
 
156
(define_insn "*pushhi"
157
  [(set (mem:HI (post_dec (reg:HI 32)))
158
        (match_operand:HI 0 "nonmemory_operand" "r,L"))]
159
  "(operands[0] == const0_rtx || register_operand (operands[0], HImode))"
160
  "@
161
        push %B0\;push %A0
162
        push __zero_reg__\;push __zero_reg__"
163
  [(set_attr "length" "2,2")])
164
 
165
(define_insn "*pushsi"
166
  [(set (mem:SI (post_dec (reg:HI 32)))
167
        (match_operand:SI 0 "nonmemory_operand" "r,L"))]
168
  "(operands[0] == const0_rtx || register_operand (operands[0], SImode))"
169
  "@
170
        push %D0\;push %C0\;push %B0\;push %A0
171
        push __zero_reg__\;push __zero_reg__\;push __zero_reg__\;push __zero_reg__"
172
  [(set_attr "length" "4,4")])
173
 
174
(define_insn "*pushsf"
175
  [(set (mem:SF (post_dec (reg:HI 32)))
176
        (match_operand:SF 0 "register_operand" "r"))]
177
  ""
178
  "push %D0
179
        push %C0
180
        push %B0
181
        push %A0"
182
  [(set_attr "length" "4")])
183
 
184
;;========================================================================
185
;; move byte
186
;; The last alternative (any immediate constant to any register) is
187
;; very expensive.  It should be optimized by peephole2 if a scratch
188
;; register is available, but then that register could just as well be
189
;; allocated for the variable we are loading.  But, most of NO_LD_REGS
190
;; are call-saved registers, and most of LD_REGS are call-used registers,
191
;; so this may still be a win for registers live across function calls.
192
 
193
(define_expand "movqi"
194
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
195
        (match_operand:QI 1 "general_operand" ""))]
196
  ""
197
  "/* One of the ops has to be in a register.  */
198
   if (!register_operand(operand0, QImode)
199
       && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
200
       operands[1] = copy_to_mode_reg(QImode, operand1);
201
  ")
202
 
203
(define_insn "*movqi"
204
  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
205
        (match_operand:QI 1 "general_operand"       "r,i,rL,Qm,r,q,i"))]
206
  "(register_operand (operands[0],QImode)
207
    || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
208
  "* return output_movqi (insn, operands, NULL);"
209
  [(set_attr "length" "1,1,5,5,1,1,4")
210
   (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
211
 
212
;; This is used in peephole2 to optimize loading immediate constants
213
;; if a scratch register from LD_REGS happens to be available.
214
 
215
(define_insn "*reload_inqi"
216
  [(set (match_operand:QI 0 "register_operand" "=l")
217
        (match_operand:QI 1 "immediate_operand" "i"))
218
   (clobber (match_operand:QI 2 "register_operand" "=&d"))]
219
  "reload_completed"
220
  "ldi %2,lo8(%1)
221
        mov %0,%2"
222
  [(set_attr "length" "2")
223
   (set_attr "cc" "none")])
224
 
225
(define_peephole2
226
  [(match_scratch:QI 2 "d")
227
   (set (match_operand:QI 0 "l_register_operand" "")
228
        (match_operand:QI 1 "immediate_operand" ""))]
229
  "(operands[1] != const0_rtx
230
    && operands[1] != const1_rtx
231
    && operands[1] != constm1_rtx)"
232
  [(parallel [(set (match_dup 0) (match_dup 1))
233
              (clobber (match_dup 2))])]
234
  "if (!avr_peep2_scratch_safe (operands[2]))
235
     FAIL;")
236
 
237
;;============================================================================
238
;; move word (16 bit)
239
 
240
(define_expand "movhi"
241
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
242
        (match_operand:HI 1 "general_operand"       ""))]
243
  ""
244
  "
245
{
246
   /* One of the ops has to be in a register.  */
247
  if (!register_operand(operand0, HImode)
248
      && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
249
    {
250
      operands[1] = copy_to_mode_reg(HImode, operand1);
251
    }
252
}")
253
 
254
 
255
(define_peephole2
256
  [(match_scratch:QI 2 "d")
257
   (set (match_operand:HI 0 "l_register_operand" "")
258
        (match_operand:HI 1 "immediate_operand" ""))]
259
  "(operands[1] != const0_rtx
260
    && operands[1] != constm1_rtx)"
261
  [(parallel [(set (match_dup 0) (match_dup 1))
262
              (clobber (match_dup 2))])]
263
  "if (!avr_peep2_scratch_safe (operands[2]))
264
     FAIL;")
265
 
266
;; '*' because it is not used in rtl generation, only in above peephole
267
(define_insn "*reload_inhi"
268
  [(set (match_operand:HI 0 "register_operand" "=r")
269
        (match_operand:HI 1 "immediate_operand" "i"))
270
   (clobber (match_operand:QI 2 "register_operand" "=&d"))]
271
  "reload_completed"
272
  "* return output_reload_inhi (insn, operands, NULL);"
273
  [(set_attr "length" "4")
274
   (set_attr "cc" "none")])
275
 
276
(define_insn "*movhi"
277
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
278
        (match_operand:HI 1 "general_operand"       "r,m,rL,i,i,r,q"))]
279
  "(register_operand (operands[0],HImode)
280
    || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
281
  "* return output_movhi (insn, operands, NULL);"
282
  [(set_attr "length" "2,6,7,2,6,5,2")
283
   (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
284
 
285
;;==========================================================================
286
;; move double word (32 bit)
287
 
288
(define_expand "movsi"
289
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
290
        (match_operand:SI 1 "general_operand"  ""))]
291
  ""
292
  "
293
{
294
  /* One of the ops has to be in a register.  */
295
  if (!register_operand (operand0, SImode)
296
      && !(register_operand (operand1, SImode) || const0_rtx == operand1))
297
    {
298
      operands[1] = copy_to_mode_reg (SImode, operand1);
299
    }
300
}")
301
 
302
 
303
 
304
(define_peephole2
305
  [(match_scratch:QI 2 "d")
306
   (set (match_operand:SI 0 "l_register_operand" "")
307
        (match_operand:SI 1 "immediate_operand" ""))]
308
  "(operands[1] != const0_rtx
309
    && operands[1] != constm1_rtx)"
310
  [(parallel [(set (match_dup 0) (match_dup 1))
311
              (clobber (match_dup 2))])]
312
  "if (!avr_peep2_scratch_safe (operands[2]))
313
     FAIL;")
314
 
315
;; '*' because it is not used in rtl generation.
316
(define_insn "*reload_insi"
317
  [(set (match_operand:SI 0 "register_operand" "=r")
318
        (match_operand:SI 1 "immediate_operand" "i"))
319
   (clobber (match_operand:QI 2 "register_operand" "=&d"))]
320
  "reload_completed"
321
  "* return output_reload_insisf (insn, operands, NULL);"
322
  [(set_attr "length" "8")
323
   (set_attr "cc" "none")])
324
 
325
 
326
(define_insn "*movsi"
327
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
328
        (match_operand:SI 1 "general_operand"       "r,L,Qm,rL,i,i"))]
329
  "(register_operand (operands[0],SImode)
330
    || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
331
  "* return output_movsisf (insn, operands, NULL);"
332
  [(set_attr "length" "4,4,8,9,4,10")
333
   (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
334
 
335
;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
336
;; move floating point numbers (32 bit)
337
 
338
(define_expand "movsf"
339
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
340
        (match_operand:SF 1 "general_operand"  ""))]
341
  ""
342
  "
343
{
344
  /* One of the ops has to be in a register.  */
345
  if (!register_operand (operand1, SFmode)
346
      && !register_operand (operand0, SFmode))
347
    {
348
      operands[1] = copy_to_mode_reg (SFmode, operand1);
349
    }
350
}")
351
 
352
(define_insn "*movsf"
353
  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
354
        (match_operand:SF 1 "general_operand"       "r,G,Qm,r,F,F"))]
355
  "register_operand (operands[0], SFmode)
356
   || register_operand (operands[1], SFmode)"
357
  "* return output_movsisf (insn, operands, NULL);"
358
  [(set_attr "length" "4,4,8,9,4,10")
359
   (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
360
 
361
;;=========================================================================
362
;; move string (like memcpy)
363
;; implement as RTL loop
364
 
365
(define_expand "movmemhi"
366
  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
367
          (match_operand:BLK 1 "memory_operand" ""))
368
          (use (match_operand:HI 2 "const_int_operand" ""))
369
          (use (match_operand:HI 3 "const_int_operand" ""))])]
370
  ""
371
  "{
372
  int prob;
373
  HOST_WIDE_INT count;
374
  enum machine_mode mode;
375
  rtx label = gen_label_rtx ();
376
  rtx loop_reg;
377
  rtx jump;
378
 
379
  /* Copy pointers into new psuedos - they will be changed.  */
380
  rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
381
  rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
382
 
383
  /* Create rtx for tmp register - we use this as scratch.  */
384
  rtx tmp_reg_rtx  = gen_rtx_REG (QImode, TMP_REGNO);
385
 
386
  if (GET_CODE (operands[2]) != CONST_INT)
387
    FAIL;
388
 
389
  count = INTVAL (operands[2]);
390
  if (count <= 0)
391
    FAIL;
392
 
393
  /* Work out branch probability for latter use.  */
394
  prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
395
 
396
  /* See if constant fit 8 bits.  */
397
  mode = (count < 0x100) ? QImode : HImode;
398
  /* Create loop counter register.  */
399
  loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
400
 
401
  /* Now create RTL code for move loop.  */
402
  /* Label at top of loop.  */
403
  emit_label (label);
404
 
405
  /* Move one byte into scratch and inc pointer.  */
406
  emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
407
  emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
408
 
409
  /* Move to mem and inc pointer.  */
410
  emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
411
  emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
412
 
413
  /* Decrement count.  */
414
  emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
415
 
416
  /* Compare with zero and jump if not equal. */
417
  emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
418
                           label);
419
  /* Set jump probability based on loop count.  */
420
  jump = get_last_insn ();
421
  REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB,
422
                    GEN_INT (prob),
423
                    REG_NOTES (jump));
424
  DONE;
425
}")
426
 
427
;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
428
;; memset (%0, %2, %1)
429
 
430
(define_expand "setmemhi"
431
  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
432
                   (match_operand 2 "const_int_operand" ""))
433
              (use (match_operand:HI 1 "const_int_operand" ""))
434
              (use (match_operand:HI 3 "const_int_operand" "n"))
435
              (clobber (match_scratch:HI 4 ""))
436
              (clobber (match_dup 5))])]
437
  ""
438
  "{
439
  rtx addr0;
440
  int cnt8;
441
  enum machine_mode mode;
442
 
443
  /* If value to set is not zero, use the library routine.  */
444
  if (operands[2] != const0_rtx)
445
    FAIL;
446
 
447
  if (GET_CODE (operands[1]) != CONST_INT)
448
    FAIL;
449
 
450
  cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
451
  mode = cnt8 ? QImode : HImode;
452
  operands[5] = gen_rtx_SCRATCH (mode);
453
  operands[1] = copy_to_mode_reg (mode,
454
                                  gen_int_mode (INTVAL (operands[1]), mode));
455
  addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
456
  operands[0] = gen_rtx_MEM (BLKmode, addr0);
457
}")
458
 
459
(define_insn "*clrmemqi"
460
  [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
461
        (const_int 0))
462
   (use (match_operand:QI 1 "register_operand" "r"))
463
   (use (match_operand:QI 2 "const_int_operand" "n"))
464
   (clobber (match_scratch:HI 3 "=0"))
465
   (clobber (match_scratch:QI 4 "=&1"))]
466
  ""
467
  "st %a0+,__zero_reg__
468
        dec %1
469
        brne .-6"
470
  [(set_attr "length" "3")
471
   (set_attr "cc" "clobber")])
472
 
473
(define_insn "*clrmemhi"
474
  [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
475
        (const_int 0))
476
   (use (match_operand:HI 1 "register_operand" "!w,d"))
477
   (use (match_operand:HI 2 "const_int_operand" "n,n"))
478
   (clobber (match_scratch:HI 3 "=0,0"))
479
   (clobber (match_scratch:HI 4 "=&1,&1"))]
480
  ""
481
  "*{
482
     if (which_alternative==0)
483
       return (AS2 (st,%a0+,__zero_reg__) CR_TAB
484
               AS2 (sbiw,%A1,1) CR_TAB
485
               AS1 (brne,.-6));
486
     else
487
       return (AS2 (st,%a0+,__zero_reg__) CR_TAB
488
               AS2 (subi,%A1,1) CR_TAB
489
               AS2 (sbci,%B1,0) CR_TAB
490
               AS1 (brne,.-8));
491
}"
492
  [(set_attr "length" "3,4")
493
   (set_attr "cc" "clobber,clobber")])
494
 
495
(define_expand "strlenhi"
496
    [(set (match_dup 4)
497
          (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
498
                      (match_operand:QI 2 "const_int_operand" "")
499
                      (match_operand:HI 3 "immediate_operand" "")]
500
                     UNSPEC_STRLEN))
501
     (set (match_dup 4) (plus:HI (match_dup 4)
502
                                 (const_int -1)))
503
     (set (match_operand:HI 0 "register_operand" "")
504
          (minus:HI (match_dup 4)
505
                    (match_dup 5)))]
506
   ""
507
   "{
508
  rtx addr;
509
  if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
510
    FAIL;
511
  addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
512
  operands[1] = gen_rtx_MEM (BLKmode, addr);
513
  operands[5] = addr;
514
  operands[4] = gen_reg_rtx (HImode);
515
}")
516
 
517
(define_insn "*strlenhi"
518
  [(set (match_operand:HI 0 "register_operand" "=e")
519
        (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
520
                    (const_int 0)
521
                    (match_operand:HI 2 "immediate_operand" "i")]
522
                   UNSPEC_STRLEN))]
523
  ""
524
  "ld __tmp_reg__,%a0+
525
        tst __tmp_reg__
526
        brne .-6"
527
  [(set_attr "length" "3")
528
   (set_attr "cc" "clobber")])
529
 
530
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
531
; add bytes
532
 
533
(define_insn "addqi3"
534
  [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
535
        (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
536
                 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
537
  ""
538
  "@
539
        add %0,%2
540
        subi %0,lo8(-(%2))
541
        inc %0
542
        dec %0"
543
  [(set_attr "length" "1,1,1,1")
544
   (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
545
 
546
 
547
(define_expand "addhi3"
548
  [(set (match_operand:HI 0 "register_operand" "")
549
        (plus:HI (match_operand:HI 1 "register_operand" "")
550
                 (match_operand:HI 2 "nonmemory_operand" "")))]
551
  ""
552
  "
553
{
554
  if (GET_CODE (operands[2]) == CONST_INT)
555
    {
556
      short tmp = INTVAL (operands[2]);
557
      operands[2] = GEN_INT(tmp);
558
    }
559
}")
560
 
561
 
562
(define_insn "*addhi3_zero_extend"
563
  [(set (match_operand:HI 0 "register_operand" "=r")
564
        (plus:HI (zero_extend:HI
565
                  (match_operand:QI 1 "register_operand" "r"))
566
                 (match_operand:HI 2 "register_operand" "0")))]
567
  ""
568
  "add %A0,%1
569
        adc %B0,__zero_reg__"
570
  [(set_attr "length" "2")
571
   (set_attr "cc" "set_n")])
572
 
573
(define_insn "*addhi3_zero_extend1"
574
  [(set (match_operand:HI 0 "register_operand" "=r")
575
        (plus:HI (match_operand:HI 1 "register_operand" "%0")
576
                 (zero_extend:HI
577
                  (match_operand:QI 2 "register_operand" "r"))))]
578
  ""
579
  "add %A0,%2
580
        adc %B0,__zero_reg__"
581
  [(set_attr "length" "2")
582
   (set_attr "cc" "set_n")])
583
 
584
(define_insn "*addhi3_zero_extend2"
585
  [(set (match_operand:HI 0 "register_operand" "=r")
586
        (plus:HI
587
         (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
588
         (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
589
  ""
590
  "add %0,%2
591
        mov %B0,__zero_reg__
592
        adc %B0,__zero_reg__"
593
  [(set_attr "length" "3")
594
   (set_attr "cc" "set_n")])
595
 
596
(define_insn "*addhi3"
597
  [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
598
        (plus:HI
599
         (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
600
         (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
601
  ""
602
  "@
603
        add %A0,%A2\;adc %B0,%B2
604
        adiw %A0,%2
605
        sbiw %A0,%n2
606
        subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
607
        sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
608
        sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
609
  [(set_attr "length" "2,1,1,2,3,3")
610
   (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
611
 
612
(define_insn "addsi3"
613
  [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r")
614
          (plus:SI
615
           (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
616
           (match_operand:SI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
617
  ""
618
  "@
619
        add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
620
        adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
621
        sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
622
        subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))
623
        sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
624
        sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
625
  [(set_attr "length" "4,3,3,4,5,5")
626
   (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n")])
627
 
628
(define_insn "*addsi3_zero_extend"
629
  [(set (match_operand:SI 0 "register_operand" "=r")
630
        (plus:SI (zero_extend:SI
631
                  (match_operand:QI 1 "register_operand" "r"))
632
                 (match_operand:SI 2 "register_operand" "0")))]
633
  ""
634
  "add %A0,%1
635
        adc %B0,__zero_reg__
636
        adc %C0,__zero_reg__
637
        adc %D0,__zero_reg__"
638
  [(set_attr "length" "4")
639
   (set_attr "cc" "set_n")])
640
 
641
;-----------------------------------------------------------------------------
642
; sub bytes
643
(define_insn "subqi3"
644
  [(set (match_operand:QI 0 "register_operand" "=r,d")
645
        (minus:QI (match_operand:QI 1 "register_operand" "0,0")
646
                  (match_operand:QI 2 "nonmemory_operand" "r,i")))]
647
  ""
648
  "@
649
        sub %0,%2
650
        subi %0,lo8(%2)"
651
  [(set_attr "length" "1,1")
652
   (set_attr "cc" "set_czn,set_czn")])
653
 
654
(define_insn "subhi3"
655
  [(set (match_operand:HI 0 "register_operand" "=r,d")
656
        (minus:HI (match_operand:HI 1 "register_operand" "0,0")
657
                  (match_operand:HI 2 "nonmemory_operand" "r,i")))]
658
  ""
659
  "@
660
        sub %A0,%A2\;sbc %B0,%B2
661
        subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
662
  [(set_attr "length" "2,2")
663
   (set_attr "cc" "set_czn,set_czn")])
664
 
665
(define_insn "*subhi3_zero_extend1"
666
  [(set (match_operand:HI 0 "register_operand" "=r")
667
        (minus:HI (match_operand:HI 1 "register_operand" "0")
668
                  (zero_extend:HI
669
                   (match_operand:QI 2 "register_operand" "r"))))]
670
  ""
671
  "sub %A0,%2
672
        sbc %B0,__zero_reg__"
673
  [(set_attr "length" "2")
674
   (set_attr "cc" "set_n")])
675
 
676
(define_insn "subsi3"
677
  [(set (match_operand:SI 0 "register_operand" "=r,d")
678
        (minus:SI (match_operand:SI 1 "register_operand" "0,0")
679
                 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
680
  ""
681
  "@
682
        sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
683
        subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
684
  [(set_attr "length" "4,4")
685
   (set_attr "cc" "set_czn,set_czn")])
686
 
687
(define_insn "*subsi3_zero_extend"
688
  [(set (match_operand:SI 0 "register_operand" "=r")
689
        (minus:SI (match_operand:SI 1 "register_operand" "0")
690
                  (zero_extend:SI
691
                   (match_operand:QI 2 "register_operand" "r"))))]
692
  ""
693
  "sub %A0,%2
694
        sbc %B0,__zero_reg__
695
        sbc %C0,__zero_reg__
696
        sbc %D0,__zero_reg__"
697
  [(set_attr "length" "4")
698
   (set_attr "cc" "set_n")])
699
 
700
;******************************************************************************
701
; mul
702
 
703
(define_expand "mulqi3"
704
  [(set (match_operand:QI 0 "register_operand" "")
705
        (mult:QI (match_operand:QI 1 "register_operand" "")
706
                 (match_operand:QI 2 "register_operand" "")))]
707
  ""
708
  "{
709
  if (!AVR_ENHANCED)
710
    {
711
      emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
712
      DONE;
713
    }
714
}")
715
 
716
(define_insn "*mulqi3_enh"
717
  [(set (match_operand:QI 0 "register_operand" "=r")
718
        (mult:QI (match_operand:QI 1 "register_operand" "r")
719
                 (match_operand:QI 2 "register_operand" "r")))]
720
  "AVR_ENHANCED"
721
  "mul %1,%2
722
        mov %0,r0
723
        clr r1"
724
  [(set_attr "length" "3")
725
   (set_attr "cc" "clobber")])
726
 
727
(define_expand "mulqi3_call"
728
  [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
729
   (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
730
   (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
731
              (clobber (reg:QI 22))])
732
   (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
733
  ""
734
  "")
735
 
736
(define_insn "*mulqi3_call"
737
  [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
738
   (clobber (reg:QI 22))]
739
  "!AVR_ENHANCED"
740
  "%~call __mulqi3"
741
  [(set_attr "type" "xcall")
742
   (set_attr "cc" "clobber")])
743
 
744
(define_insn "mulqihi3"
745
  [(set (match_operand:HI 0 "register_operand" "=r")
746
        (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
747
                 (sign_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
748
  "AVR_ENHANCED"
749
  "muls %1,%2
750
        movw %0,r0
751
        clr r1"
752
  [(set_attr "length" "3")
753
   (set_attr "cc" "clobber")])
754
 
755
(define_insn "umulqihi3"
756
  [(set (match_operand:HI 0 "register_operand" "=r")
757
        (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
758
                 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
759
  "AVR_ENHANCED"
760
  "mul %1,%2
761
        movw %0,r0
762
        clr r1"
763
  [(set_attr "length" "3")
764
   (set_attr "cc" "clobber")])
765
 
766
(define_expand "mulhi3"
767
  [(set (match_operand:HI 0 "register_operand" "")
768
        (mult:HI (match_operand:HI 1 "register_operand" "")
769
                 (match_operand:HI 2 "register_operand" "")))]
770
  ""
771
  "
772
{
773
  if (!AVR_ENHANCED)
774
    {
775
      emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
776
      DONE;
777
    }
778
}")
779
 
780
(define_insn "*mulhi3_enh"
781
  [(set (match_operand:HI 0 "register_operand" "=&r")
782
        (mult:HI (match_operand:HI 1 "register_operand" "r")
783
                 (match_operand:HI 2 "register_operand" "r")))]
784
  "AVR_ENHANCED"
785
  "mul %A1,%A2
786
        movw %0,r0
787
        mul %A1,%B2
788
        add %B0,r0
789
        mul %B1,%A2
790
        add %B0,r0
791
        clr r1"
792
  [(set_attr "length" "7")
793
   (set_attr "cc" "clobber")])
794
 
795
(define_expand "mulhi3_call"
796
  [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
797
   (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
798
   (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
799
              (clobber (reg:HI 22))
800
              (clobber (reg:QI 21))])
801
   (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
802
  ""
803
  "")
804
 
805
(define_insn "*mulhi3_call"
806
  [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
807
   (clobber (reg:HI 22))
808
   (clobber (reg:QI 21))]
809
  "!AVR_ENHANCED"
810
  "%~call __mulhi3"
811
  [(set_attr "type" "xcall")
812
   (set_attr "cc" "clobber")])
813
 
814
;; Operand 2 (reg:SI 18) not clobbered on the enhanced core.
815
;; All call-used registers clobbered otherwise - normal library call.
816
(define_expand "mulsi3"
817
  [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
818
   (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
819
   (parallel [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
820
              (clobber (reg:HI 26))
821
              (clobber (reg:HI 30))])
822
   (set (match_operand:SI 0 "register_operand" "") (reg:SI 22))]
823
  "AVR_ENHANCED"
824
  "")
825
 
826
(define_insn "*mulsi3_call"
827
  [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
828
   (clobber (reg:HI 26))
829
   (clobber (reg:HI 30))]
830
  "AVR_ENHANCED"
831
  "%~call __mulsi3"
832
  [(set_attr "type" "xcall")
833
   (set_attr "cc" "clobber")])
834
 
835
; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
836
; divmod
837
 
838
;; Generate libgcc.S calls ourselves, because:
839
;;  - we know exactly which registers are clobbered (for QI and HI
840
;;    modes, some of the call-used registers are preserved)
841
;;  - we get both the quotient and the remainder at no extra cost
842
 
843
(define_expand "divmodqi4"
844
  [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
845
   (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
846
   (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
847
              (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
848
              (clobber (reg:QI 22))
849
              (clobber (reg:QI 23))])
850
   (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))
851
   (set (match_operand:QI 3 "register_operand" "") (reg:QI 25))]
852
  ""
853
  "")
854
 
855
(define_insn "*divmodqi4_call"
856
  [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
857
   (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
858
   (clobber (reg:QI 22))
859
   (clobber (reg:QI 23))]
860
  ""
861
  "%~call __divmodqi4"
862
  [(set_attr "type" "xcall")
863
   (set_attr "cc" "clobber")])
864
 
865
(define_expand "udivmodqi4"
866
  [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
867
   (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
868
   (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
869
              (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
870
              (clobber (reg:QI 23))])
871
   (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))
872
   (set (match_operand:QI 3 "register_operand" "") (reg:QI 25))]
873
  ""
874
  "")
875
 
876
(define_insn "*udivmodqi4_call"
877
  [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
878
   (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
879
   (clobber (reg:QI 23))]
880
  ""
881
  "%~call __udivmodqi4"
882
  [(set_attr "type" "xcall")
883
   (set_attr "cc" "clobber")])
884
 
885
(define_expand "divmodhi4"
886
  [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
887
   (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
888
   (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
889
              (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
890
              (clobber (reg:HI 26))
891
              (clobber (reg:QI 21))])
892
   (set (match_operand:HI 0 "register_operand" "") (reg:HI 22))
893
   (set (match_operand:HI 3 "register_operand" "") (reg:HI 24))]
894
  ""
895
  "")
896
 
897
(define_insn "*divmodhi4_call"
898
  [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
899
   (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
900
   (clobber (reg:HI 26))
901
   (clobber (reg:QI 21))]
902
  ""
903
  "%~call __divmodhi4"
904
  [(set_attr "type" "xcall")
905
   (set_attr "cc" "clobber")])
906
 
907
(define_expand "udivmodhi4"
908
  [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
909
   (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
910
   (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
911
              (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
912
              (clobber (reg:HI 26))
913
              (clobber (reg:QI 21))])
914
   (set (match_operand:HI 0 "register_operand" "") (reg:HI 22))
915
   (set (match_operand:HI 3 "register_operand" "") (reg:HI 24))]
916
  ""
917
  "")
918
 
919
(define_insn "*udivmodhi4_call"
920
  [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
921
   (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
922
   (clobber (reg:HI 26))
923
   (clobber (reg:QI 21))]
924
  ""
925
  "%~call __udivmodhi4"
926
  [(set_attr "type" "xcall")
927
   (set_attr "cc" "clobber")])
928
 
929
(define_expand "divmodsi4"
930
  [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
931
   (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
932
   (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
933
              (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
934
              (clobber (reg:HI 26))
935
              (clobber (reg:HI 30))])
936
   (set (match_operand:SI 0 "register_operand" "") (reg:SI 18))
937
   (set (match_operand:SI 3 "register_operand" "") (reg:SI 22))]
938
  ""
939
  "")
940
 
941
(define_insn "*divmodsi4_call"
942
  [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
943
   (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
944
   (clobber (reg:HI 26))
945
   (clobber (reg:HI 30))]
946
  ""
947
  "%~call __divmodsi4"
948
  [(set_attr "type" "xcall")
949
   (set_attr "cc" "clobber")])
950
 
951
(define_expand "udivmodsi4"
952
  [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
953
   (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
954
   (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
955
              (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
956
              (clobber (reg:HI 26))
957
              (clobber (reg:HI 30))])
958
   (set (match_operand:SI 0 "register_operand" "") (reg:SI 18))
959
   (set (match_operand:SI 3 "register_operand" "") (reg:SI 22))]
960
  ""
961
  "")
962
 
963
(define_insn "*udivmodsi4_call"
964
  [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
965
   (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
966
   (clobber (reg:HI 26))
967
   (clobber (reg:HI 30))]
968
  ""
969
  "%~call __udivmodsi4"
970
  [(set_attr "type" "xcall")
971
   (set_attr "cc" "clobber")])
972
 
973
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
974
; and
975
 
976
(define_insn "andqi3"
977
  [(set (match_operand:QI 0 "register_operand" "=r,d")
978
        (and:QI (match_operand:QI 1 "register_operand" "%0,0")
979
                (match_operand:QI 2 "nonmemory_operand" "r,i")))]
980
  ""
981
  "@
982
        and %0,%2
983
        andi %0,lo8(%2)"
984
  [(set_attr "length" "1,1")
985
   (set_attr "cc" "set_zn,set_zn")])
986
 
987
(define_insn "andhi3"
988
  [(set (match_operand:HI 0 "register_operand" "=r,d,r")
989
          (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
990
                  (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
991
   (clobber (match_scratch:QI 3 "=X,X,&d"))]
992
  ""
993
  "*{
994
  if (which_alternative==0)
995
    return (AS2 (and,%A0,%A2) CR_TAB
996
            AS2 (and,%B0,%B2));
997
  else if (which_alternative==1)
998
    {
999
      if (GET_CODE (operands[2]) == CONST_INT)
1000
        {
1001
          int mask = INTVAL (operands[2]);
1002
          if ((mask & 0xff) != 0xff)
1003
            output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1004
          if ((mask & 0xff00) != 0xff00)
1005
            output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1006
          return \"\";
1007
        }
1008
        return (AS2 (andi,%A0,lo8(%2)) CR_TAB
1009
                AS2 (andi,%B0,hi8(%2)));
1010
     }
1011
  return (AS2 (ldi,%3,lo8(%2)) CR_TAB
1012
          AS2 (and,%A0,%3)     CR_TAB
1013
          AS1 (clr,%B0));
1014
}"
1015
  [(set_attr "length" "2,2,3")
1016
   (set_attr "cc" "set_n,clobber,set_n")])
1017
 
1018
(define_insn "andsi3"
1019
  [(set (match_operand:SI 0 "register_operand" "=r,d")
1020
        (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1021
                (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1022
  ""
1023
  "*{
1024
  if (which_alternative==0)
1025
    return (AS2 (and, %0,%2)   CR_TAB
1026
            AS2 (and, %B0,%B2) CR_TAB
1027
            AS2 (and, %C0,%C2) CR_TAB
1028
            AS2 (and, %D0,%D2));
1029
  else if (which_alternative==1)
1030
    {
1031
      if (GET_CODE (operands[2]) == CONST_INT)
1032
        {
1033
          HOST_WIDE_INT mask = INTVAL (operands[2]);
1034
          if ((mask & 0xff) != 0xff)
1035
            output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1036
          if ((mask & 0xff00) != 0xff00)
1037
            output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1038
          if ((mask & 0xff0000L) != 0xff0000L)
1039
            output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
1040
          if ((mask & 0xff000000L) != 0xff000000L)
1041
            output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
1042
          return \"\";
1043
        }
1044
      return (AS2 (andi, %A0,lo8(%2))  CR_TAB
1045
              AS2 (andi, %B0,hi8(%2)) CR_TAB
1046
              AS2 (andi, %C0,hlo8(%2)) CR_TAB
1047
              AS2 (andi, %D0,hhi8(%2)));
1048
    }
1049
  return \"bug\";
1050
}"
1051
  [(set_attr "length" "4,4")
1052
   (set_attr "cc" "set_n,set_n")])
1053
 
1054
;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1055
;; ior
1056
 
1057
(define_insn "iorqi3"
1058
  [(set (match_operand:QI 0 "register_operand" "=r,d")
1059
        (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
1060
                (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1061
  ""
1062
  "@
1063
        or %0,%2
1064
        ori %0,lo8(%2)"
1065
  [(set_attr "length" "1,1")
1066
   (set_attr "cc" "set_zn,set_zn")])
1067
 
1068
(define_insn "iorhi3"
1069
  [(set (match_operand:HI 0 "register_operand" "=r,d")
1070
        (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1071
                (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1072
  ""
1073
  "*{
1074
  if (which_alternative==0)
1075
    return (AS2 (or,%A0,%A2) CR_TAB
1076
            AS2 (or,%B0,%B2));
1077
  if (GET_CODE (operands[2]) == CONST_INT)
1078
     {
1079
        int mask = INTVAL (operands[2]);
1080
        if (mask & 0xff)
1081
          output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1082
        if (mask & 0xff00)
1083
          output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1084
        return \"\";
1085
      }
1086
   return (AS2 (ori,%0,lo8(%2)) CR_TAB
1087
           AS2 (ori,%B0,hi8(%2)));
1088
}"
1089
  [(set_attr "length" "2,2")
1090
   (set_attr "cc" "set_n,clobber")])
1091
 
1092
(define_insn "*iorhi3_clobber"
1093
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1094
        (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1095
                (match_operand:HI 2 "immediate_operand" "M,i")))
1096
   (clobber (match_scratch:QI 3 "=&d,&d"))]
1097
  ""
1098
  "@
1099
        ldi %3,lo8(%2)\;or %A0,%3
1100
        ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
1101
  [(set_attr "length" "2,4")
1102
   (set_attr "cc" "clobber,set_n")])
1103
 
1104
(define_insn "iorsi3"
1105
  [(set (match_operand:SI 0 "register_operand"        "=r,d")
1106
        (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1107
                (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1108
  ""
1109
  "*{
1110
  if (which_alternative==0)
1111
    return (AS2 (or, %0,%2)   CR_TAB
1112
            AS2 (or, %B0,%B2) CR_TAB
1113
            AS2 (or, %C0,%C2) CR_TAB
1114
            AS2 (or, %D0,%D2));
1115
  if (GET_CODE (operands[2]) == CONST_INT)
1116
     {
1117
        HOST_WIDE_INT mask = INTVAL (operands[2]);
1118
        if (mask & 0xff)
1119
          output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1120
        if (mask & 0xff00)
1121
          output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1122
        if (mask & 0xff0000L)
1123
          output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
1124
        if (mask & 0xff000000L)
1125
          output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
1126
        return \"\";
1127
      }
1128
  return (AS2 (ori, %A0,lo8(%2))  CR_TAB
1129
          AS2 (ori, %B0,hi8(%2)) CR_TAB
1130
          AS2 (ori, %C0,hlo8(%2)) CR_TAB
1131
          AS2 (ori, %D0,hhi8(%2)));
1132
}"
1133
  [(set_attr "length" "4,4")
1134
   (set_attr "cc" "set_n,clobber")])
1135
 
1136
(define_insn "*iorsi3_clobber"
1137
  [(set (match_operand:SI 0 "register_operand"        "=r,r")
1138
        (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1139
                (match_operand:SI 2 "immediate_operand" "M,i")))
1140
   (clobber (match_scratch:QI 3 "=&d,&d"))]
1141
  ""
1142
  "@
1143
        ldi %3,lo8(%2)\;or %A0,%3
1144
        ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3\;ldi %3,hlo8(%2)\;or %C0,%3\;ldi %3,hhi8(%2)\;or %D0,%3"
1145
  [(set_attr "length" "2,8")
1146
   (set_attr "cc" "clobber,set_n")])
1147
 
1148
;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1149
;; xor
1150
 
1151
(define_insn "xorqi3"
1152
  [(set (match_operand:QI 0 "register_operand" "=r")
1153
        (xor:QI (match_operand:QI 1 "register_operand" "%0")
1154
                (match_operand:QI 2 "register_operand" "r")))]
1155
  ""
1156
  "eor %0,%2"
1157
  [(set_attr "length" "1")
1158
   (set_attr "cc" "set_zn")])
1159
 
1160
(define_insn "xorhi3"
1161
  [(set (match_operand:HI 0 "register_operand" "=r")
1162
        (xor:HI (match_operand:HI 1 "register_operand" "%0")
1163
                (match_operand:HI 2 "register_operand" "r")))]
1164
  ""
1165
  "eor %0,%2
1166
        eor %B0,%B2"
1167
  [(set_attr "length" "2")
1168
   (set_attr "cc" "set_n")])
1169
 
1170
(define_insn "xorsi3"
1171
  [(set (match_operand:SI 0 "register_operand" "=r")
1172
        (xor:SI (match_operand:SI 1 "register_operand" "%0")
1173
                (match_operand:SI 2 "register_operand" "r")))]
1174
  ""
1175
  "eor %0,%2
1176
        eor %B0,%B2
1177
        eor %C0,%C2
1178
        eor %D0,%D2"
1179
  [(set_attr "length" "4")
1180
   (set_attr "cc" "set_n")])
1181
 
1182
;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
1183
;; arithmetic shift left
1184
 
1185
(define_insn "ashlqi3"
1186
  [(set (match_operand:QI 0 "register_operand"           "=r,r,r,r,!d,r,r")
1187
        (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1188
                   (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
1189
  ""
1190
  "* return ashlqi3_out (insn, operands, NULL);"
1191
  [(set_attr "length" "5,0,1,2,4,6,9")
1192
   (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1193
 
1194
(define_insn "ashlhi3"
1195
  [(set (match_operand:HI 0 "register_operand"           "=r,r,r,r,r,r,r")
1196
        (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1197
                   (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1198
  ""
1199
  "* return ashlhi3_out (insn, operands, NULL);"
1200
  [(set_attr "length" "6,0,2,2,4,10,10")
1201
   (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1202
 
1203
(define_insn "ashlsi3"
1204
  [(set (match_operand:SI 0 "register_operand"           "=r,r,r,r,r,r,r")
1205
        (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1206
                   (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1207
  ""
1208
  "* return ashlsi3_out (insn, operands, NULL);"
1209
  [(set_attr "length" "8,0,4,4,8,10,12")
1210
   (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1211
 
1212
;; Optimize if a scratch register from LD_REGS happens to be available.
1213
 
1214
(define_peephole2
1215
  [(match_scratch:QI 3 "d")
1216
   (set (match_operand:HI 0 "register_operand" "")
1217
        (ashift:HI (match_operand:HI 1 "register_operand" "")
1218
                   (match_operand:QI 2 "const_int_operand" "")))]
1219
  ""
1220
  [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
1221
              (clobber (match_dup 3))])]
1222
  "if (!avr_peep2_scratch_safe (operands[3]))
1223
     FAIL;")
1224
 
1225
(define_insn "*ashlhi3_const"
1226
  [(set (match_operand:HI 0 "register_operand"            "=r,r,r,r,r")
1227
        (ashift:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1228
                   (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1229
   (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1230
  "reload_completed"
1231
  "* return ashlhi3_out (insn, operands, NULL);"
1232
  [(set_attr "length" "0,2,2,4,10")
1233
   (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
1234
 
1235
(define_peephole2
1236
  [(match_scratch:QI 3 "d")
1237
   (set (match_operand:SI 0 "register_operand" "")
1238
        (ashift:SI (match_operand:SI 1 "register_operand" "")
1239
                   (match_operand:QI 2 "const_int_operand" "")))]
1240
  ""
1241
  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1242
              (clobber (match_dup 3))])]
1243
  "if (!avr_peep2_scratch_safe (operands[3]))
1244
     FAIL;")
1245
 
1246
(define_insn "*ashlsi3_const"
1247
  [(set (match_operand:SI 0 "register_operand"            "=r,r,r,r")
1248
        (ashift:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1249
                   (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1250
   (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1251
  "reload_completed"
1252
  "* return ashlsi3_out (insn, operands, NULL);"
1253
  [(set_attr "length" "0,4,4,10")
1254
   (set_attr "cc" "none,set_n,clobber,clobber")])
1255
 
1256
;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1257
;; arithmetic shift right
1258
 
1259
(define_insn "ashrqi3"
1260
  [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
1261
        (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
1262
                     (match_operand:QI 2 "general_operand"  "r,L,P,K,n,Qm")))]
1263
  ""
1264
  "* return ashrqi3_out (insn, operands, NULL);"
1265
  [(set_attr "length" "5,0,1,2,5,9")
1266
   (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")])
1267
 
1268
(define_insn "ashrhi3"
1269
  [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
1270
        (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1271
                     (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1272
  ""
1273
  "* return ashrhi3_out (insn, operands, NULL);"
1274
  [(set_attr "length" "6,0,2,4,4,10,10")
1275
   (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1276
 
1277
(define_insn "ashrsi3"
1278
  [(set (match_operand:SI 0 "register_operand"             "=r,r,r,r,r,r,r")
1279
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1280
                     (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1281
  ""
1282
  "* return ashrsi3_out (insn, operands, NULL);"
1283
  [(set_attr "length" "8,0,4,6,8,10,12")
1284
   (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1285
 
1286
;; Optimize if a scratch register from LD_REGS happens to be available.
1287
 
1288
(define_peephole2
1289
  [(match_scratch:QI 3 "d")
1290
   (set (match_operand:HI 0 "register_operand" "")
1291
        (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
1292
                     (match_operand:QI 2 "const_int_operand" "")))]
1293
  ""
1294
  [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
1295
              (clobber (match_dup 3))])]
1296
  "if (!avr_peep2_scratch_safe (operands[3]))
1297
     FAIL;")
1298
 
1299
(define_insn "*ashrhi3_const"
1300
  [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
1301
        (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1302
                     (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1303
   (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1304
  "reload_completed"
1305
  "* return ashrhi3_out (insn, operands, NULL);"
1306
  [(set_attr "length" "0,2,4,4,10")
1307
   (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
1308
 
1309
(define_peephole2
1310
  [(match_scratch:QI 3 "d")
1311
   (set (match_operand:SI 0 "register_operand" "")
1312
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1313
                     (match_operand:QI 2 "const_int_operand" "")))]
1314
  ""
1315
  [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
1316
              (clobber (match_dup 3))])]
1317
  "if (!avr_peep2_scratch_safe (operands[3]))
1318
     FAIL;")
1319
 
1320
(define_insn "*ashrsi3_const"
1321
  [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
1322
        (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1323
                     (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1324
   (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1325
  "reload_completed"
1326
  "* return ashrsi3_out (insn, operands, NULL);"
1327
  [(set_attr "length" "0,4,4,10")
1328
   (set_attr "cc" "none,clobber,set_n,clobber")])
1329
 
1330
;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1331
;; logical shift right
1332
 
1333
(define_insn "lshrqi3"
1334
  [(set (match_operand:QI 0 "register_operand"             "=r,r,r,r,!d,r,r")
1335
        (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1336
                     (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
1337
  ""
1338
  "* return lshrqi3_out (insn, operands, NULL);"
1339
  [(set_attr "length" "5,0,1,2,4,6,9")
1340
   (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1341
 
1342
(define_insn "lshrhi3"
1343
  [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
1344
        (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1345
                     (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1346
  ""
1347
  "* return lshrhi3_out (insn, operands, NULL);"
1348
  [(set_attr "length" "6,0,2,2,4,10,10")
1349
   (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1350
 
1351
(define_insn "lshrsi3"
1352
  [(set (match_operand:SI 0 "register_operand"             "=r,r,r,r,r,r,r")
1353
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1354
                     (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1355
  ""
1356
  "* return lshrsi3_out (insn, operands, NULL);"
1357
  [(set_attr "length" "8,0,4,4,8,10,12")
1358
   (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1359
 
1360
;; Optimize if a scratch register from LD_REGS happens to be available.
1361
 
1362
(define_peephole2
1363
  [(match_scratch:QI 3 "d")
1364
   (set (match_operand:HI 0 "register_operand" "")
1365
        (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
1366
                     (match_operand:QI 2 "const_int_operand" "")))]
1367
  ""
1368
  [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
1369
              (clobber (match_dup 3))])]
1370
  "if (!avr_peep2_scratch_safe (operands[3]))
1371
     FAIL;")
1372
 
1373
(define_insn "*lshrhi3_const"
1374
  [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
1375
        (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1376
                     (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1377
   (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1378
  "reload_completed"
1379
  "* return lshrhi3_out (insn, operands, NULL);"
1380
  [(set_attr "length" "0,2,2,4,10")
1381
   (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
1382
 
1383
(define_peephole2
1384
  [(match_scratch:QI 3 "d")
1385
   (set (match_operand:SI 0 "register_operand" "")
1386
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1387
                     (match_operand:QI 2 "const_int_operand" "")))]
1388
  ""
1389
  [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
1390
              (clobber (match_dup 3))])]
1391
  "if (!avr_peep2_scratch_safe (operands[3]))
1392
     FAIL;")
1393
 
1394
(define_insn "*lshrsi3_const"
1395
  [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
1396
        (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1397
                     (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1398
   (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1399
  "reload_completed"
1400
  "* return lshrsi3_out (insn, operands, NULL);"
1401
  [(set_attr "length" "0,4,4,10")
1402
   (set_attr "cc" "none,clobber,clobber,clobber")])
1403
 
1404
;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
1405
;; abs
1406
 
1407
(define_insn "absqi2"
1408
  [(set (match_operand:QI 0 "register_operand" "=r")
1409
        (abs:QI (match_operand:QI 1 "register_operand" "0")))]
1410
  ""
1411
  "sbrc %0,7
1412
        neg %0"
1413
  [(set_attr "length" "2")
1414
   (set_attr "cc" "clobber")])
1415
 
1416
 
1417
(define_insn "abssf2"
1418
  [(set (match_operand:SF 0 "register_operand" "=d,r")
1419
        (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
1420
  ""
1421
  "@
1422
        andi %D0,0x7f
1423
        clt\;bld %D0,7"
1424
  [(set_attr "length" "1,2")
1425
   (set_attr "cc" "set_n,clobber")])
1426
 
1427
;; 0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x
1428
;; neg
1429
 
1430
(define_insn "negqi2"
1431
  [(set (match_operand:QI 0 "register_operand" "=r")
1432
        (neg:QI (match_operand:QI 1 "register_operand" "0")))]
1433
  ""
1434
  "neg %0"
1435
  [(set_attr "length" "1")
1436
   (set_attr "cc" "set_zn")])
1437
 
1438
(define_insn "neghi2"
1439
  [(set (match_operand:HI 0 "register_operand"       "=!d,r,&r")
1440
        (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
1441
  ""
1442
  "@
1443
        com %B0\;neg %A0\;sbci %B0,lo8(-1)
1444
        com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
1445
        clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
1446
  [(set_attr "length" "3,4,4")
1447
   (set_attr "cc" "set_czn,set_n,set_czn")])
1448
 
1449
(define_insn "negsi2"
1450
  [(set (match_operand:SI 0 "register_operand"       "=!d,r,&r")
1451
        (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
1452
  ""
1453
  "@
1454
        com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
1455
        com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
1456
        clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
1457
  [(set_attr_alternative "length"
1458
                         [(const_int 7)
1459
                          (const_int 8)
1460
                          (if_then_else (eq_attr "mcu_have_movw" "yes")
1461
                                        (const_int 7)
1462
                                        (const_int 8))])
1463
   (set_attr "cc" "set_czn,set_n,set_czn")])
1464
 
1465
(define_insn "negsf2"
1466
  [(set (match_operand:SF 0 "register_operand" "=d,r")
1467
        (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
1468
  ""
1469
  "@
1470
        subi %D0,0x80
1471
        bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
1472
  [(set_attr "length" "1,4")
1473
   (set_attr "cc" "set_n,set_n")])
1474
 
1475
;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1476
;; not
1477
 
1478
(define_insn "one_cmplqi2"
1479
  [(set (match_operand:QI 0 "register_operand" "=r")
1480
        (not:QI (match_operand:QI 1 "register_operand" "0")))]
1481
  ""
1482
  "com %0"
1483
  [(set_attr "length" "1")
1484
   (set_attr "cc" "set_czn")])
1485
 
1486
(define_insn "one_cmplhi2"
1487
  [(set (match_operand:HI 0 "register_operand" "=r")
1488
        (not:HI (match_operand:HI 1 "register_operand" "0")))]
1489
  ""
1490
  "com %0
1491
        com %B0"
1492
  [(set_attr "length" "2")
1493
   (set_attr "cc" "set_n")])
1494
 
1495
(define_insn "one_cmplsi2"
1496
  [(set (match_operand:SI 0 "register_operand" "=r")
1497
        (not:SI (match_operand:SI 1 "register_operand" "0")))]
1498
  ""
1499
  "com %0
1500
        com %B0
1501
        com %C0
1502
        com %D0"
1503
  [(set_attr "length" "4")
1504
   (set_attr "cc" "set_n")])
1505
 
1506
;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1507
;; sign extend
1508
 
1509
(define_insn "extendqihi2"
1510
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1511
        (sign_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
1512
  ""
1513
  "@
1514
        clr %B0\;sbrc %0,7\;com %B0
1515
        mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
1516
  [(set_attr "length" "3,4")
1517
   (set_attr "cc" "set_n,set_n")])
1518
 
1519
(define_insn "extendqisi2"
1520
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1521
        (sign_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
1522
  ""
1523
  "@
1524
        clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
1525
        mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
1526
  [(set_attr "length" "5,6")
1527
   (set_attr "cc" "set_n,set_n")])
1528
 
1529
(define_insn "extendhisi2"
1530
  [(set (match_operand:SI 0 "register_operand"               "=r,&r")
1531
        (sign_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
1532
  ""
1533
  "@
1534
        clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
1535
        {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
1536
  [(set_attr_alternative "length"
1537
                         [(const_int 4)
1538
                          (if_then_else (eq_attr "mcu_have_movw" "yes")
1539
                                        (const_int 5)
1540
                                        (const_int 6))])
1541
   (set_attr "cc" "set_n,set_n")])
1542
 
1543
;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1544
;; zero extend
1545
 
1546
(define_insn "zero_extendqihi2"
1547
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1548
        (zero_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
1549
  ""
1550
  "@
1551
        clr %B0
1552
        mov %A0,%A1\;clr %B0"
1553
  [(set_attr "length" "1,2")
1554
   (set_attr "cc" "set_n,set_n")])
1555
 
1556
(define_insn "zero_extendqisi2"
1557
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1558
        (zero_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
1559
  ""
1560
  "@
1561
        clr %B0\;clr %C0\;clr %D0
1562
        mov %A0,%A1\;clr %B0\;clr %C0\;clr %D0"
1563
  [(set_attr "length" "3,4")
1564
   (set_attr "cc" "set_n,set_n")])
1565
 
1566
(define_insn "zero_extendhisi2"
1567
  [(set (match_operand:SI 0 "register_operand" "=r,&r")
1568
        (zero_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
1569
  ""
1570
  "@
1571
        clr %C0\;clr %D0
1572
        {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;clr %D0"
1573
  [(set_attr_alternative "length"
1574
                         [(const_int 2)
1575
                          (if_then_else (eq_attr "mcu_have_movw" "yes")
1576
                                        (const_int 3)
1577
                                        (const_int 4))])
1578
   (set_attr "cc" "set_n,set_n")])
1579
 
1580
;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
1581
;; compare
1582
 
1583
(define_insn "tstqi"
1584
  [(set (cc0)
1585
        (match_operand:QI 0 "register_operand" "r"))]
1586
  ""
1587
  "tst %0"
1588
  [(set_attr "cc" "compare")
1589
   (set_attr "length" "1")])
1590
 
1591
(define_insn "*negated_tstqi"
1592
  [(set (cc0)
1593
        (neg:QI (match_operand:QI 0 "register_operand" "r")))]
1594
  ""
1595
  "cp __zero_reg__,%0"
1596
  [(set_attr "cc" "compare")
1597
   (set_attr "length" "1")])
1598
 
1599
(define_insn "tsthi"
1600
  [(set (cc0)
1601
        (match_operand:HI 0 "register_operand" "!w,r"))]
1602
  ""
1603
  "* return out_tsthi (insn,NULL);"
1604
[(set_attr "cc" "compare,compare")
1605
 (set_attr "length" "1,2")])
1606
 
1607
(define_insn "*negated_tsthi"
1608
  [(set (cc0)
1609
        (neg:HI (match_operand:HI 0 "register_operand" "r")))]
1610
  ""
1611
  "cp __zero_reg__,%A0
1612
        cpc __zero_reg__,%B0"
1613
[(set_attr "cc" "compare")
1614
 (set_attr "length" "2")])
1615
 
1616
(define_insn "tstsi"
1617
  [(set (cc0)
1618
        (match_operand:SI 0 "register_operand" "r"))]
1619
  ""
1620
  "* return out_tstsi (insn,NULL);"
1621
  [(set_attr "cc" "compare")
1622
   (set_attr "length" "4")])
1623
 
1624
(define_insn "*negated_tstsi"
1625
  [(set (cc0)
1626
        (neg:SI (match_operand:SI 0 "register_operand" "r")))]
1627
  ""
1628
  "cp __zero_reg__,%A0
1629
        cpc __zero_reg__,%B0
1630
        cpc __zero_reg__,%C0
1631
        cpc __zero_reg__,%D0"
1632
  [(set_attr "cc" "compare")
1633
   (set_attr "length" "4")])
1634
 
1635
 
1636
(define_insn "cmpqi"
1637
  [(set (cc0)
1638
        (compare (match_operand:QI 0 "register_operand"  "r,d")
1639
                 (match_operand:QI 1 "nonmemory_operand" "r,i")))]
1640
  ""
1641
  "@
1642
        cp %0,%1
1643
        cpi %0,lo8(%1)"
1644
  [(set_attr "cc" "compare,compare")
1645
   (set_attr "length" "1,1")])
1646
 
1647
(define_insn "*cmpqi_sign_extend"
1648
  [(set (cc0)
1649
        (compare (sign_extend:HI
1650
                  (match_operand:QI 0 "register_operand"  "d"))
1651
                 (match_operand:HI 1 "const_int_operand" "n")))]
1652
  "INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) <= 127"
1653
  "cpi %0,lo8(%1)"
1654
  [(set_attr "cc" "compare")
1655
   (set_attr "length" "1")])
1656
 
1657
(define_insn "cmphi"
1658
  [(set (cc0)
1659
        (compare (match_operand:HI 0 "register_operand"  "r,d,d,r,r")
1660
                 (match_operand:HI 1 "nonmemory_operand" "r,M,i,M,i")))
1661
   (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
1662
  ""
1663
  "*{
1664
  switch (which_alternative)
1665
    {
1666
    case 0:
1667
      return (AS2 (cp,%A0,%A1) CR_TAB
1668
              AS2 (cpc,%B0,%B1));
1669
    case 1:
1670
      if (reg_unused_after (insn, operands[0])
1671
          && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
1672
          && test_hard_reg_class (ADDW_REGS, operands[0]))
1673
        return AS2 (sbiw,%0,%1);
1674
       else
1675
        return (AS2 (cpi,%0,%1) CR_TAB
1676
                AS2 (cpc,%B0,__zero_reg__));
1677
    case 2:
1678
      if (reg_unused_after (insn, operands[0]))
1679
        return (AS2 (subi,%0,lo8(%1))  CR_TAB
1680
                AS2 (sbci,%B0,hi8(%1)));
1681
      else
1682
        return (AS2 (ldi, %2,hi8(%1))  CR_TAB
1683
                AS2 (cpi, %A0,lo8(%1)) CR_TAB
1684
                AS2 (cpc, %B0,%2));
1685
   case 3:
1686
      return (AS2 (ldi, %2,lo8(%1))  CR_TAB
1687
              AS2 (cp, %A0,%2) CR_TAB
1688
              AS2 (cpc, %B0,__zero_reg__));
1689
 
1690
   case 4:
1691
      return (AS2 (ldi, %2,lo8(%1))  CR_TAB
1692
              AS2 (cp, %A0,%2)       CR_TAB
1693
              AS2 (ldi, %2,hi8(%1)) CR_TAB
1694
              AS2 (cpc, %B0,%2));
1695
    }
1696
  return \"bug\";
1697
}"
1698
  [(set_attr "cc" "compare,compare,compare,compare,compare")
1699
   (set_attr "length" "2,2,3,3,4")])
1700
 
1701
 
1702
(define_insn "cmpsi"
1703
  [(set (cc0)
1704
        (compare (match_operand:SI 0 "register_operand"  "r,d,d,r,r")
1705
                 (match_operand:SI 1 "nonmemory_operand" "r,M,i,M,i")))
1706
   (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
1707
  ""
1708
  "*{
1709
  switch (which_alternative)
1710
    {
1711
    case 0:
1712
      return (AS2 (cp,%A0,%A1) CR_TAB
1713
              AS2 (cpc,%B0,%B1) CR_TAB
1714
              AS2 (cpc,%C0,%C1) CR_TAB
1715
              AS2 (cpc,%D0,%D1));
1716
    case 1:
1717
      if (reg_unused_after (insn, operands[0])
1718
          && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
1719
          && test_hard_reg_class (ADDW_REGS, operands[0]))
1720
        return (AS2 (sbiw,%0,%1) CR_TAB
1721
                AS2 (cpc,%C0,__zero_reg__) CR_TAB
1722
                AS2 (cpc,%D0,__zero_reg__));
1723
      else
1724
        return (AS2 (cpi,%A0,lo8(%1))  CR_TAB
1725
                AS2 (cpc,%B0,__zero_reg__) CR_TAB
1726
                AS2 (cpc,%C0,__zero_reg__) CR_TAB
1727
                AS2 (cpc,%D0,__zero_reg__));
1728
    case 2:
1729
      if (reg_unused_after (insn, operands[0]))
1730
        return (AS2 (subi,%A0,lo8(%1))  CR_TAB
1731
                AS2 (sbci,%B0,hi8(%1))  CR_TAB
1732
                AS2 (sbci,%C0,hlo8(%1))  CR_TAB
1733
                AS2 (sbci,%D0,hhi8(%1)));
1734
      else
1735
       return (AS2 (cpi, %A0,lo8(%1))   CR_TAB
1736
               AS2 (ldi, %2,hi8(%1))  CR_TAB
1737
               AS2 (cpc, %B0,%2)       CR_TAB
1738
               AS2 (ldi, %2,hlo8(%1))  CR_TAB
1739
               AS2 (cpc, %C0,%2)       CR_TAB
1740
               AS2 (ldi, %2,hhi8(%1)) CR_TAB
1741
               AS2 (cpc, %D0,%2));
1742
    case 3:
1743
        return (AS2 (ldi,%2,lo8(%1))        CR_TAB
1744
                AS2 (cp,%A0,%2)            CR_TAB
1745
                AS2 (cpc,%B0,__zero_reg__) CR_TAB
1746
                AS2 (cpc,%C0,__zero_reg__) CR_TAB
1747
                AS2 (cpc,%D0,__zero_reg__));
1748
    case 4:
1749
       return (AS2 (ldi, %2,lo8(%1))   CR_TAB
1750
               AS2 (cp, %A0,%2)        CR_TAB
1751
               AS2 (ldi, %2,hi8(%1))  CR_TAB
1752
               AS2 (cpc, %B0,%2)       CR_TAB
1753
               AS2 (ldi, %2,hlo8(%1))  CR_TAB
1754
               AS2 (cpc, %C0,%2)       CR_TAB
1755
               AS2 (ldi, %2,hhi8(%1)) CR_TAB
1756
               AS2 (cpc, %D0,%2));
1757
    }
1758
  return \"bug\";
1759
}"
1760
  [(set_attr "cc" "compare,compare,compare,compare,compare")
1761
   (set_attr "length" "4,4,7,5,8")])
1762
 
1763
;; ----------------------------------------------------------------------
1764
;; JUMP INSTRUCTIONS
1765
;; ----------------------------------------------------------------------
1766
;; Conditional jump instructions
1767
 
1768
(define_expand "beq"
1769
  [(set (pc)
1770
        (if_then_else (eq (cc0) (const_int 0))
1771
                      (label_ref (match_operand 0 "" ""))
1772
                      (pc)))]
1773
  ""
1774
  "")
1775
 
1776
(define_expand "bne"
1777
  [(set (pc)
1778
        (if_then_else (ne (cc0) (const_int 0))
1779
                      (label_ref (match_operand 0 "" ""))
1780
                      (pc)))]
1781
  ""
1782
  "")
1783
 
1784
(define_expand "bge"
1785
  [(set (pc)
1786
        (if_then_else (ge (cc0) (const_int 0))
1787
                      (label_ref (match_operand 0 "" ""))
1788
                      (pc)))]
1789
  ""
1790
  "")
1791
 
1792
(define_expand "bgeu"
1793
  [(set (pc)
1794
        (if_then_else (geu (cc0) (const_int 0))
1795
                      (label_ref (match_operand 0 "" ""))
1796
                      (pc)))]
1797
  ""
1798
  "")
1799
 
1800
(define_expand "blt"
1801
  [(set (pc)
1802
        (if_then_else (lt (cc0) (const_int 0))
1803
                      (label_ref (match_operand 0 "" ""))
1804
                      (pc)))]
1805
  ""
1806
  "")
1807
 
1808
(define_expand "bltu"
1809
  [(set (pc)
1810
        (if_then_else (ltu (cc0) (const_int 0))
1811
                      (label_ref (match_operand 0 "" ""))
1812
                      (pc)))]
1813
  ""
1814
  "")
1815
 
1816
 
1817
 
1818
/****************************************************************
1819
 AVR not have following conditional jumps: LE,LEU,GT,GTU.
1820
 Convert them all to proper jumps.
1821
*****************************************************************/
1822
 
1823
(define_expand "ble"
1824
  [(set (pc)
1825
        (if_then_else (le (cc0) (const_int 0))
1826
                      (label_ref (match_operand 0 "" ""))
1827
                      (pc)))]
1828
  ""
1829
  "")
1830
 
1831
(define_expand "bleu"
1832
  [(set (pc)
1833
        (if_then_else (leu (cc0) (const_int 0))
1834
                      (label_ref (match_operand 0 "" ""))
1835
                      (pc)))]
1836
  ""
1837
  "")
1838
 
1839
(define_expand "bgt"
1840
  [(set (pc)
1841
        (if_then_else (gt (cc0) (const_int 0))
1842
                      (label_ref (match_operand 0 "" ""))
1843
                      (pc)))]
1844
  ""
1845
  "")
1846
 
1847
(define_expand "bgtu"
1848
  [(set (pc)
1849
        (if_then_else (gtu (cc0) (const_int 0))
1850
                      (label_ref (match_operand 0 "" ""))
1851
                      (pc)))]
1852
  ""
1853
  "")
1854
 
1855
;; Test a single bit in a QI/HI/SImode register.
1856
(define_insn "*sbrx_branch"
1857
  [(set (pc)
1858
        (if_then_else
1859
         (match_operator 0 "eqne_operator"
1860
                         [(zero_extract
1861
                           (match_operand:QI 1 "register_operand" "r")
1862
                           (const_int 1)
1863
                           (match_operand 2 "const_int_operand" "n"))
1864
                          (const_int 0)])
1865
         (label_ref (match_operand 3 "" ""))
1866
         (pc)))]
1867
  ""
1868
  "* return avr_out_sbxx_branch (insn, operands);"
1869
  [(set (attr "length")
1870
        (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
1871
                           (le (minus (pc) (match_dup 3)) (const_int 2046)))
1872
                      (const_int 2)
1873
                      (if_then_else (eq_attr "mcu_mega" "no")
1874
                                    (const_int 2)
1875
                                    (const_int 4))))
1876
   (set_attr "cc" "clobber")])
1877
 
1878
(define_insn "*sbrx_and_branchhi"
1879
  [(set (pc)
1880
        (if_then_else
1881
         (match_operator 0 "eqne_operator"
1882
                         [(and:HI
1883
                           (match_operand:HI 1 "register_operand" "r")
1884
                           (match_operand:HI 2 "single_one_operand" "n"))
1885
                          (const_int 0)])
1886
         (label_ref (match_operand 3 "" ""))
1887
         (pc)))]
1888
  ""
1889
  "* return avr_out_sbxx_branch (insn, operands);"
1890
  [(set (attr "length")
1891
        (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
1892
                           (le (minus (pc) (match_dup 3)) (const_int 2046)))
1893
                      (const_int 2)
1894
                      (if_then_else (eq_attr "mcu_mega" "no")
1895
                                    (const_int 2)
1896
                                    (const_int 4))))
1897
   (set_attr "cc" "clobber")])
1898
 
1899
(define_insn "*sbrx_and_branchsi"
1900
  [(set (pc)
1901
        (if_then_else
1902
         (match_operator 0 "eqne_operator"
1903
                         [(and:SI
1904
                           (match_operand:SI 1 "register_operand" "r")
1905
                           (match_operand:SI 2 "single_one_operand" "n"))
1906
                          (const_int 0)])
1907
         (label_ref (match_operand 3 "" ""))
1908
         (pc)))]
1909
  ""
1910
  "* return avr_out_sbxx_branch (insn, operands);"
1911
  [(set (attr "length")
1912
        (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
1913
                           (le (minus (pc) (match_dup 3)) (const_int 2046)))
1914
                      (const_int 2)
1915
                      (if_then_else (eq_attr "mcu_mega" "no")
1916
                                    (const_int 2)
1917
                                    (const_int 4))))
1918
   (set_attr "cc" "clobber")])
1919
 
1920
;; Convert sign tests to bit 7/15/31 tests that match the above insns.
1921
(define_peephole2
1922
  [(set (cc0) (match_operand:QI 0 "register_operand" ""))
1923
   (set (pc) (if_then_else (ge (cc0) (const_int 0))
1924
                           (label_ref (match_operand 1 "" ""))
1925
                           (pc)))]
1926
  ""
1927
  [(set (pc) (if_then_else (eq (zero_extract (match_dup 0)
1928
                                             (const_int 1)
1929
                                             (const_int 7))
1930
                               (const_int 0))
1931
                           (label_ref (match_dup 1))
1932
                           (pc)))]
1933
  "")
1934
 
1935
(define_peephole2
1936
  [(set (cc0) (match_operand:QI 0 "register_operand" ""))
1937
   (set (pc) (if_then_else (lt (cc0) (const_int 0))
1938
                           (label_ref (match_operand 1 "" ""))
1939
                           (pc)))]
1940
  ""
1941
  [(set (pc) (if_then_else (ne (zero_extract (match_dup 0)
1942
                                             (const_int 1)
1943
                                             (const_int 7))
1944
                               (const_int 0))
1945
                           (label_ref (match_dup 1))
1946
                           (pc)))]
1947
  "")
1948
 
1949
(define_peephole2
1950
  [(set (cc0) (match_operand:HI 0 "register_operand" ""))
1951
   (set (pc) (if_then_else (ge (cc0) (const_int 0))
1952
                           (label_ref (match_operand 1 "" ""))
1953
                           (pc)))]
1954
  ""
1955
  [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
1956
                               (const_int 0))
1957
                           (label_ref (match_dup 1))
1958
                           (pc)))]
1959
  "")
1960
 
1961
(define_peephole2
1962
  [(set (cc0) (match_operand:HI 0 "register_operand" ""))
1963
   (set (pc) (if_then_else (lt (cc0) (const_int 0))
1964
                           (label_ref (match_operand 1 "" ""))
1965
                           (pc)))]
1966
  ""
1967
  [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
1968
                               (const_int 0))
1969
                           (label_ref (match_dup 1))
1970
                           (pc)))]
1971
  "")
1972
 
1973
(define_peephole2
1974
  [(set (cc0) (match_operand:SI 0 "register_operand" ""))
1975
   (set (pc) (if_then_else (ge (cc0) (const_int 0))
1976
                           (label_ref (match_operand 1 "" ""))
1977
                           (pc)))]
1978
  ""
1979
  [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
1980
                               (const_int 0))
1981
                           (label_ref (match_dup 1))
1982
                           (pc)))]
1983
  "operands[2] = GEN_INT (-2147483647 - 1);")
1984
 
1985
(define_peephole2
1986
  [(set (cc0) (match_operand:SI 0 "register_operand" ""))
1987
   (set (pc) (if_then_else (lt (cc0) (const_int 0))
1988
                           (label_ref (match_operand 1 "" ""))
1989
                           (pc)))]
1990
  ""
1991
  [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
1992
                               (const_int 0))
1993
                           (label_ref (match_dup 1))
1994
                           (pc)))]
1995
  "operands[2] = GEN_INT (-2147483647 - 1);")
1996
 
1997
;; ************************************************************************
1998
;; Implementation of conditional jumps here.
1999
;;  Compare with 0 (test) jumps
2000
;; ************************************************************************
2001
 
2002
(define_insn "branch"
2003
  [(set (pc)
2004
        (if_then_else (match_operator 1 "simple_comparison_operator"
2005
                        [(cc0)
2006
                         (const_int 0)])
2007
                      (label_ref (match_operand 0 "" ""))
2008
                      (pc)))]
2009
  ""
2010
  "*
2011
   return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2012
  [(set_attr "type" "branch")
2013
   (set_attr "cc" "clobber")])
2014
 
2015
(define_insn "difficult_branch"
2016
  [(set (pc)
2017
        (if_then_else (match_operator 1 "difficult_comparison_operator"
2018
                        [(cc0)
2019
                         (const_int 0)])
2020
                      (label_ref (match_operand 0 "" ""))
2021
                      (pc)))]
2022
  ""
2023
  "*
2024
   return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2025
  [(set_attr "type" "branch1")
2026
   (set_attr "cc" "clobber")])
2027
 
2028
;; revers branch
2029
 
2030
(define_insn "rvbranch"
2031
  [(set (pc)
2032
        (if_then_else (match_operator 1 "simple_comparison_operator"
2033
                        [(cc0)
2034
                         (const_int 0)])
2035
                      (pc)
2036
                      (label_ref (match_operand 0 "" ""))))]
2037
  ""
2038
  "*
2039
   return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2040
  [(set_attr "type" "branch1")
2041
   (set_attr "cc" "clobber")])
2042
 
2043
(define_insn "difficult_rvbranch"
2044
  [(set (pc)
2045
        (if_then_else (match_operator 1 "difficult_comparison_operator"
2046
                        [(cc0)
2047
                         (const_int 0)])
2048
                      (pc)
2049
                      (label_ref (match_operand 0 "" ""))))]
2050
  ""
2051
  "*
2052
   return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2053
  [(set_attr "type" "branch")
2054
   (set_attr "cc" "clobber")])
2055
 
2056
;; **************************************************************************
2057
;; Unconditional and other jump instructions.
2058
 
2059
(define_insn "jump"
2060
  [(set (pc)
2061
        (label_ref (match_operand 0 "" "")))]
2062
  ""
2063
  "*{
2064
  if (AVR_MEGA && get_attr_length (insn) != 1)
2065
    return AS1 (jmp,%0);
2066
  return AS1 (rjmp,%0);
2067
}"
2068
  [(set (attr "length")
2069
        (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
2070
                           (le (minus (pc) (match_dup 0)) (const_int 2047)))
2071
                      (const_int 1)
2072
                      (const_int 2)))
2073
   (set_attr "cc" "none")])
2074
 
2075
;; call
2076
 
2077
(define_expand "call"
2078
  [(call (match_operand:HI 0 "call_insn_operand" "")
2079
         (match_operand:HI 1 "general_operand" ""))]
2080
  ;; Operand 1 not used on the AVR.
2081
  ""
2082
  "")
2083
 
2084
;; call value
2085
 
2086
(define_expand "call_value"
2087
  [(set (match_operand 0 "register_operand" "")
2088
        (call (match_operand:HI 1 "call_insn_operand" "")
2089
              (match_operand:HI 2 "general_operand" "")))]
2090
  ;; Operand 2 not used on the AVR.
2091
  ""
2092
  "")
2093
 
2094
(define_insn "call_insn"
2095
  [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "!z,*r,s,n"))
2096
         (match_operand:HI 1 "general_operand" "X,X,X,X"))]
2097
;; We don't need in saving Z register because r30,r31 is a call used registers
2098
  ;; Operand 1 not used on the AVR.
2099
  "(register_operand (operands[0], HImode) || CONSTANT_P (operands[0]))"
2100
  "*{
2101
  if (which_alternative==0)
2102
     return \"icall\";
2103
  else if (which_alternative==1)
2104
    {
2105
      if (AVR_HAVE_MOVW)
2106
        return (AS2 (movw, r30, %0) CR_TAB
2107
                \"icall\");
2108
      else
2109
        return (AS2 (mov, r30, %A0) CR_TAB
2110
                AS2 (mov, r31, %B0) CR_TAB
2111
                \"icall\");
2112
    }
2113
  else if (which_alternative==2)
2114
    return AS1(%~call,%c0);
2115
  return (AS2 (ldi,r30,lo8(%0)) CR_TAB
2116
          AS2 (ldi,r31,hi8(%0)) CR_TAB
2117
          \"icall\");
2118
}"
2119
  [(set_attr "cc" "clobber,clobber,clobber,clobber")
2120
   (set_attr_alternative "length"
2121
                         [(const_int 1)
2122
                          (if_then_else (eq_attr "mcu_have_movw" "yes")
2123
                                        (const_int 2)
2124
                                        (const_int 3))
2125
                          (if_then_else (eq_attr "mcu_mega" "yes")
2126
                                        (const_int 2)
2127
                                        (const_int 1))
2128
                          (const_int 3)])])
2129
 
2130
(define_insn "call_value_insn"
2131
  [(set (match_operand 0 "register_operand" "=r,r,r,r")
2132
        (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "!z,*r,s,n"))
2133
;; We don't need in saving Z register because r30,r31 is a call used registers
2134
              (match_operand:HI 2 "general_operand" "X,X,X,X")))]
2135
  ;; Operand 2 not used on the AVR.
2136
  "(register_operand (operands[0], VOIDmode) || CONSTANT_P (operands[0]))"
2137
  "*{
2138
  if (which_alternative==0)
2139
     return \"icall\";
2140
  else if (which_alternative==1)
2141
    {
2142
      if (AVR_HAVE_MOVW)
2143
        return (AS2 (movw, r30, %1) CR_TAB
2144
                \"icall\");
2145
      else
2146
        return (AS2 (mov, r30, %A1) CR_TAB
2147
                AS2 (mov, r31, %B1) CR_TAB
2148
                \"icall\");
2149
    }
2150
  else if (which_alternative==2)
2151
    return AS1(%~call,%c1);
2152
  return (AS2 (ldi, r30, lo8(%1)) CR_TAB
2153
          AS2 (ldi, r31, hi8(%1)) CR_TAB
2154
          \"icall\");
2155
}"
2156
  [(set_attr "cc" "clobber,clobber,clobber,clobber")
2157
   (set_attr_alternative "length"
2158
                         [(const_int 1)
2159
                          (if_then_else (eq_attr "mcu_have_movw" "yes")
2160
                                        (const_int 2)
2161
                                        (const_int 3))
2162
                          (if_then_else (eq_attr "mcu_mega" "yes")
2163
                                        (const_int 2)
2164
                                        (const_int 1))
2165
                          (const_int 3)])])
2166
 
2167
(define_insn "return"
2168
  [(return)]
2169
  "reload_completed && avr_simple_epilogue ()"
2170
  "ret"
2171
  [(set_attr "cc" "none")
2172
   (set_attr "length" "1")])
2173
 
2174
(define_insn "nop"
2175
  [(const_int 0)]
2176
  ""
2177
  "nop"
2178
  [(set_attr "cc" "none")
2179
   (set_attr "length" "1")])
2180
 
2181
; indirect jump
2182
(define_insn "indirect_jump"
2183
  [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
2184
  ""
2185
  "@
2186
        ijmp
2187
        push %A0\;push %B0\;ret"
2188
  [(set_attr "length" "1,3")
2189
   (set_attr "cc" "none,none")])
2190
 
2191
;; table jump
2192
 
2193
;; Table made from "rjmp" instructions for <=8K devices.
2194
(define_insn "*tablejump_rjmp"
2195
  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
2196
                        UNSPEC_INDEX_JMP))
2197
   (use (label_ref (match_operand 1 "" "")))
2198
   (clobber (match_dup 0))]
2199
  "!AVR_MEGA"
2200
  "@
2201
        ijmp
2202
        push %A0\;push %B0\;ret"
2203
  [(set_attr "length" "1,3")
2204
   (set_attr "cc" "none,none")])
2205
 
2206
;; Not a prologue, but similar idea - move the common piece of code to libgcc.
2207
(define_insn "*tablejump_lib"
2208
  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2209
                        UNSPEC_INDEX_JMP))
2210
   (use (label_ref (match_operand 1 "" "")))
2211
   (clobber (match_dup 0))]
2212
  "AVR_MEGA && TARGET_CALL_PROLOGUES"
2213
  "jmp __tablejump2__"
2214
  [(set_attr "length" "2")
2215
   (set_attr "cc" "clobber")])
2216
 
2217
(define_insn "*tablejump_enh"
2218
  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2219
                        UNSPEC_INDEX_JMP))
2220
   (use (label_ref (match_operand 1 "" "")))
2221
   (clobber (match_dup 0))]
2222
  "AVR_MEGA && AVR_ENHANCED"
2223
  "lsl r30
2224
        rol r31
2225
        lpm __tmp_reg__,Z+
2226
        lpm r31,Z
2227
        mov r30,__tmp_reg__
2228
        ijmp"
2229
  [(set_attr "length" "6")
2230
   (set_attr "cc" "clobber")])
2231
 
2232
(define_insn "*tablejump"
2233
  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2234
                        UNSPEC_INDEX_JMP))
2235
   (use (label_ref (match_operand 1 "" "")))
2236
   (clobber (match_dup 0))]
2237
  "AVR_MEGA"
2238
  "lsl r30
2239
        rol r31
2240
        lpm
2241
        inc r30
2242
        push r0
2243
        lpm
2244
        push r0
2245
        ret"
2246
  [(set_attr "length" "8")
2247
   (set_attr "cc" "clobber")])
2248
 
2249
(define_expand "casesi"
2250
  [(set (match_dup 6)
2251
        (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
2252
                  (match_operand:HI 1 "register_operand" "")))
2253
   (parallel [(set (cc0)
2254
                   (compare (match_dup 6)
2255
                            (match_operand:HI 2 "register_operand" "")))
2256
              (clobber (match_scratch:QI 9 ""))])
2257
 
2258
   (set (pc)
2259
        (if_then_else (gtu (cc0)
2260
                           (const_int 0))
2261
                      (label_ref (match_operand 4 "" ""))
2262
                      (pc)))
2263
 
2264
   (set (match_dup 6)
2265
        (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
2266
 
2267
   (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
2268
              (use (label_ref (match_dup 3)))
2269
              (clobber (match_dup 6))])]
2270
  ""
2271
  "
2272
{
2273
  operands[6] = gen_reg_rtx (HImode);
2274
}")
2275
 
2276
 
2277
;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2278
;; This instruction sets Z flag
2279
 
2280
(define_insn "sez"
2281
  [(set (cc0) (const_int 0))]
2282
  ""
2283
  "sez"
2284
  [(set_attr "length" "1")
2285
   (set_attr "cc" "compare")])
2286
 
2287
;; Clear/set/test a single bit in I/O address space.
2288
 
2289
(define_insn "*cbi"
2290
  [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2291
        (and:QI (mem:QI (match_dup 0))
2292
                (match_operand:QI 1 "single_zero_operand" "n")))]
2293
  "(optimize > 0)"
2294
{
2295
  operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
2296
  return AS2 (cbi,%0-0x20,%2);
2297
}
2298
  [(set_attr "length" "1")
2299
   (set_attr "cc" "none")])
2300
 
2301
(define_insn "*sbi"
2302
  [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2303
        (ior:QI (mem:QI (match_dup 0))
2304
                (match_operand:QI 1 "single_one_operand" "n")))]
2305
  "(optimize > 0)"
2306
{
2307
  operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
2308
  return AS2 (sbi,%0-0x20,%2);
2309
}
2310
  [(set_attr "length" "1")
2311
   (set_attr "cc" "none")])
2312
 
2313
;; Lower half of the I/O space - use sbic/sbis directly.
2314
(define_insn "*sbix_branch"
2315
  [(set (pc)
2316
        (if_then_else
2317
         (match_operator 0 "eqne_operator"
2318
                         [(zero_extract
2319
                           (mem:QI (match_operand 1 "low_io_address_operand" "n"))
2320
                           (const_int 1)
2321
                           (match_operand 2 "const_int_operand" "n"))
2322
                          (const_int 0)])
2323
         (label_ref (match_operand 3 "" ""))
2324
         (pc)))]
2325
  "(optimize > 0)"
2326
  "* return avr_out_sbxx_branch (insn, operands);"
2327
  [(set (attr "length")
2328
        (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2329
                           (le (minus (pc) (match_dup 3)) (const_int 2046)))
2330
                      (const_int 2)
2331
                      (if_then_else (eq_attr "mcu_mega" "no")
2332
                                    (const_int 2)
2333
                                    (const_int 4))))
2334
   (set_attr "cc" "clobber")])
2335
 
2336
;; Tests of bit 7 are pessimized to sign tests, so we need this too...
2337
(define_insn "*sbix_branch_bit7"
2338
  [(set (pc)
2339
        (if_then_else
2340
         (match_operator 0 "gelt_operator"
2341
                         [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
2342
                          (const_int 0)])
2343
         (label_ref (match_operand 2 "" ""))
2344
         (pc)))]
2345
  "(optimize > 0)"
2346
{
2347
  operands[3] = operands[2];
2348
  operands[2] = GEN_INT (7);
2349
  return avr_out_sbxx_branch (insn, operands);
2350
}
2351
  [(set (attr "length")
2352
        (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2353
                           (le (minus (pc) (match_dup 2)) (const_int 2046)))
2354
                      (const_int 2)
2355
                      (if_then_else (eq_attr "mcu_mega" "no")
2356
                                    (const_int 2)
2357
                                    (const_int 4))))
2358
   (set_attr "cc" "clobber")])
2359
 
2360
;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
2361
(define_insn "*sbix_branch_tmp"
2362
  [(set (pc)
2363
        (if_then_else
2364
         (match_operator 0 "eqne_operator"
2365
                         [(zero_extract
2366
                           (mem:QI (match_operand 1 "high_io_address_operand" "n"))
2367
                           (const_int 1)
2368
                           (match_operand 2 "const_int_operand" "n"))
2369
                          (const_int 0)])
2370
         (label_ref (match_operand 3 "" ""))
2371
         (pc)))]
2372
  "(optimize > 0)"
2373
  "* return avr_out_sbxx_branch (insn, operands);"
2374
  [(set (attr "length")
2375
        (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2376
                           (le (minus (pc) (match_dup 3)) (const_int 2045)))
2377
                      (const_int 3)
2378
                      (if_then_else (eq_attr "mcu_mega" "no")
2379
                                    (const_int 3)
2380
                                    (const_int 5))))
2381
   (set_attr "cc" "clobber")])
2382
 
2383
(define_insn "*sbix_branch_tmp_bit7"
2384
  [(set (pc)
2385
        (if_then_else
2386
         (match_operator 0 "gelt_operator"
2387
                         [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
2388
                          (const_int 0)])
2389
         (label_ref (match_operand 2 "" ""))
2390
         (pc)))]
2391
  "(optimize > 0)"
2392
{
2393
  operands[3] = operands[2];
2394
  operands[2] = GEN_INT (7);
2395
  return avr_out_sbxx_branch (insn, operands);
2396
}
2397
  [(set (attr "length")
2398
        (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2399
                           (le (minus (pc) (match_dup 2)) (const_int 2045)))
2400
                      (const_int 3)
2401
                      (if_then_else (eq_attr "mcu_mega" "no")
2402
                                    (const_int 3)
2403
                                    (const_int 5))))
2404
   (set_attr "cc" "clobber")])
2405
 
2406
;; ************************* Peepholes ********************************
2407
 
2408
(define_peephole
2409
  [(set (match_operand:SI 0 "d_register_operand" "")
2410
        (plus:SI (match_dup 0)
2411
                 (const_int -1)))
2412
   (parallel
2413
    [(set (cc0)
2414
          (compare (match_dup 0)
2415
                   (const_int -1)))
2416
     (clobber (match_operand:QI 1 "d_register_operand" ""))])
2417
   (set (pc)
2418
        (if_then_else (ne (cc0) (const_int 0))
2419
                      (label_ref (match_operand 2 "" ""))
2420
                      (pc)))]
2421
  ""
2422
  "*
2423
{
2424
  CC_STATUS_INIT;
2425
  if (test_hard_reg_class (ADDW_REGS, operands[0]))
2426
    output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
2427
                     AS2 (sbc,%C0,__zero_reg__) CR_TAB
2428
                     AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
2429
  else
2430
    output_asm_insn (AS2 (subi,%A0,1) CR_TAB
2431
                     AS2 (sbc,%B0,__zero_reg__) CR_TAB
2432
                     AS2 (sbc,%C0,__zero_reg__) CR_TAB
2433
                     AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
2434
  switch (avr_jump_mode (operands[2],insn))
2435
  {
2436
    case 1:
2437
      return AS1 (brcc,%2);
2438
    case 2:
2439
      return (AS1 (brcs,.+2) CR_TAB
2440
              AS1 (rjmp,%2));
2441
  }
2442
  return (AS1 (brcs,.+4) CR_TAB
2443
          AS1 (jmp,%2));
2444
}")
2445
 
2446
(define_peephole
2447
  [(set (match_operand:HI 0 "d_register_operand" "")
2448
        (plus:HI (match_dup 0)
2449
                 (const_int -1)))
2450
   (parallel
2451
    [(set (cc0)
2452
          (compare (match_dup 0)
2453
                   (const_int 65535)))
2454
     (clobber (match_operand:QI 1 "d_register_operand" ""))])
2455
   (set (pc)
2456
        (if_then_else (ne (cc0) (const_int 0))
2457
                      (label_ref (match_operand 2 "" ""))
2458
                      (pc)))]
2459
  ""
2460
  "*
2461
{
2462
  CC_STATUS_INIT;
2463
  if (test_hard_reg_class (ADDW_REGS, operands[0]))
2464
    output_asm_insn (AS2 (sbiw,%0,1), operands);
2465
  else
2466
    output_asm_insn (AS2 (subi,%A0,1) CR_TAB
2467
                     AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
2468
  switch (avr_jump_mode (operands[2],insn))
2469
  {
2470
    case 1:
2471
      return AS1 (brcc,%2);
2472
    case 2:
2473
      return (AS1 (brcs,.+2) CR_TAB
2474
              AS1 (rjmp,%2));
2475
  }
2476
  return (AS1 (brcs,.+4) CR_TAB
2477
          AS1 (jmp,%2));
2478
}")
2479
 
2480
(define_peephole
2481
  [(set (match_operand:QI 0 "d_register_operand" "")
2482
        (plus:QI (match_dup 0)
2483
                 (const_int -1)))
2484
   (set (cc0)
2485
        (compare (match_dup 0)
2486
                 (const_int -1)))
2487
   (set (pc)
2488
        (if_then_else (ne (cc0) (const_int 0))
2489
                      (label_ref (match_operand 1 "" ""))
2490
                      (pc)))]
2491
  ""
2492
  "*
2493
{
2494
  CC_STATUS_INIT;
2495
  cc_status.value1 = operands[0];
2496
  cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2497
  output_asm_insn (AS2 (subi,%A0,1), operands);
2498
  switch (avr_jump_mode (operands[1],insn))
2499
  {
2500
    case 1:
2501
      return AS1 (brcc,%1);
2502
    case 2:
2503
      return (AS1 (brcs,.+2) CR_TAB
2504
              AS1 (rjmp,%1));
2505
  }
2506
  return (AS1 (brcs,.+4) CR_TAB
2507
          AS1 (jmp,%1));
2508
}")
2509
 
2510
(define_peephole
2511
  [(set (cc0) (match_operand:QI 0 "register_operand" ""))
2512
   (set (pc)
2513
        (if_then_else (eq (cc0) (const_int 0))
2514
                      (label_ref (match_operand 1 "" ""))
2515
                      (pc)))]
2516
  "jump_over_one_insn_p (insn, operands[1])"
2517
  "cpse %0,__zero_reg__")
2518
 
2519
(define_peephole
2520
  [(set (cc0)
2521
        (compare (match_operand:QI 0 "register_operand" "")
2522
                 (match_operand:QI 1 "register_operand" "")))
2523
   (set (pc)
2524
        (if_then_else (eq (cc0) (const_int 0))
2525
                      (label_ref (match_operand 2 "" ""))
2526
                      (pc)))]
2527
  "jump_over_one_insn_p (insn, operands[2])"
2528
  "cpse %0,%1")

powered by: WebSVN 2.1.0

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