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

Subversion Repositories openrisc_me

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

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

Line No. Rev Author Line
1 282 jeremybenn
;; -*- 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, 2008,
5
;;   2009, 2010 Free Software Foundation, Inc.
6
;;   Contributed by Denis Chertykov (chertykov@gmail.com)
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
;;..m..Constant Direct Data memory address.
32
;;  o  Displacement for (mem (plus (reg) (const_int))) operands.
33
;;  p  POST_INC or PRE_DEC address as a pointer (X, Y, Z)
34
;;  r  POST_INC or PRE_DEC address as a register (r26, r28, r30)
35
;;..x..Constant Direct Program memory address.
36
;;  ~  Output 'r' if not AVR_HAVE_JMP_CALL.
37
;;  !  Output 'e' if AVR_HAVE_EIJMP_EICALL.
38
 
39
;; UNSPEC usage:
40
;;  0  Length of a string, see "strlenhi".
41
;;  1  Jump by register pair Z or by table addressed by Z, see "casesi".
42
 
43
(define_constants
44
  [(REG_X       26)
45
   (REG_Y       28)
46
   (REG_Z       30)
47
   (REG_W       24)
48
   (REG_SP      32)
49
   (TMP_REGNO   0)      ; temporary register r0
50
   (ZERO_REGNO  1)      ; zero register r1
51
 
52
   (SREG_ADDR   0x5F)
53
   (RAMPZ_ADDR  0x5B)
54
 
55
   (UNSPEC_STRLEN       0)
56
   (UNSPEC_INDEX_JMP    1)
57
   (UNSPEC_SEI          2)
58
   (UNSPEC_CLI          3)
59
 
60
   (UNSPECV_PROLOGUE_SAVES      0)
61
   (UNSPECV_EPILOGUE_RESTORES   1)
62
   (UNSPECV_WRITE_SP_IRQ_ON     2)
63
   (UNSPECV_WRITE_SP_IRQ_OFF    3)
64
   (UNSPECV_GOTO_RECEIVER       4)])
65
 
66
(include "predicates.md")
67
(include "constraints.md")
68
 
69
;; Condition code settings.
70
(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
71
  (const_string "none"))
72
 
73
(define_attr "type" "branch,branch1,arith,xcall"
74
  (const_string "arith"))
75
 
76
(define_attr "mcu_have_movw" "yes,no"
77
  (const (if_then_else (symbol_ref "AVR_HAVE_MOVW")
78
                       (const_string "yes")
79
                       (const_string "no"))))
80
 
81
(define_attr "mcu_mega" "yes,no"
82
  (const (if_then_else (symbol_ref "AVR_HAVE_JMP_CALL")
83
                       (const_string "yes")
84
                       (const_string "no"))))
85
 
86
 
87
;; The size of instructions in bytes.
88
;; XXX may depend from "cc"
89
 
90
(define_attr "length" ""
91
  (cond [(eq_attr "type" "branch")
92
         (if_then_else (and (ge (minus (pc) (match_dup 0))
93
                                (const_int -63))
94
                            (le (minus (pc) (match_dup 0))
95
                                (const_int 62)))
96
                       (const_int 1)
97
                       (if_then_else (and (ge (minus (pc) (match_dup 0))
98
                                              (const_int -2045))
99
                                          (le (minus (pc) (match_dup 0))
100
                                              (const_int 2045)))
101
                                     (const_int 2)
102
                                     (const_int 3)))
103
         (eq_attr "type" "branch1")
104
         (if_then_else (and (ge (minus (pc) (match_dup 0))
105
                                (const_int -62))
106
                            (le (minus (pc) (match_dup 0))
107
                                (const_int 61)))
108
                       (const_int 2)
109
                       (if_then_else (and (ge (minus (pc) (match_dup 0))
110
                                              (const_int -2044))
111
                                          (le (minus (pc) (match_dup 0))
112
                                              (const_int 2043)))
113
                                     (const_int 3)
114
                                     (const_int 4)))
115
         (eq_attr "type" "xcall")
116
         (if_then_else (eq_attr "mcu_mega" "no")
117
                       (const_int 1)
118
                       (const_int 2))]
119
        (const_int 2)))
120
 
121
;; Define mode iterator
122
(define_mode_iterator QISI [(QI "") (HI "") (SI "")])
123
(define_mode_iterator QIDI [(QI "") (HI "") (SI "") (DI "")])
124
(define_mode_iterator HIDI [(HI "") (SI "") (DI "")])
125
(define_mode_iterator HISI [(HI "") (SI "")])
126
 
127
;;========================================================================
128
;; The following is used by nonlocal_goto and setjmp.
129
;; The receiver pattern will create no instructions since internally
130
;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
131
;; This avoids creating add/sub offsets in frame_pointer save/resore.
132
;; The 'null' receiver also avoids  problems with optimisation
133
;; not recognising incoming jmp and removing code that resets frame_pointer.
134
;; The code derived from builtins.c.
135
 
136
(define_expand "nonlocal_goto_receiver"
137
  [(set (reg:HI REG_Y)
138
        (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
139
  ""
140
  {
141
    emit_move_insn (virtual_stack_vars_rtx,
142
                    gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
143
                                  gen_int_mode (STARTING_FRAME_OFFSET,
144
                                                Pmode)));
145
  /* This might change the hard frame pointer in ways that aren't
146
    apparent to early optimization passes, so force a clobber.  */
147
    emit_clobber (hard_frame_pointer_rtx);
148
    DONE;
149
  })
150
 
151
 
152
;; Defining nonlocal_goto_receiver means we must also define this.
153
;; even though its function is identical to that in builtins.c
154
 
155
(define_expand "nonlocal_goto"
156
  [
157
  (use (match_operand 0 "general_operand"))
158
  (use (match_operand 1 "general_operand"))
159
  (use (match_operand 2 "general_operand"))
160
  (use (match_operand 3 "general_operand"))
161
  ]
162
  ""
163
{
164
  rtx r_label = copy_to_reg (operands[1]);
165
  rtx r_fp = operands[3];
166
  rtx r_sp = operands[2];
167
 
168
  emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
169
 
170
  emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
171
 
172
  emit_move_insn (hard_frame_pointer_rtx, r_fp);
173
  emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
174
 
175
  emit_use (hard_frame_pointer_rtx);
176
  emit_use (stack_pointer_rtx);
177
 
178
  emit_indirect_jump (r_label);
179
 
180
  DONE;
181
})
182
 
183
 
184
(define_insn "*pushqi"
185
  [(set (mem:QI (post_dec (reg:HI REG_SP)))
186
        (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
187
  ""
188
  "@
189
        push %0
190
        push __zero_reg__"
191
  [(set_attr "length" "1,1")])
192
 
193
 
194
(define_insn "*pushhi"
195
  [(set (mem:HI (post_dec (reg:HI REG_SP)))
196
        (match_operand:HI 0 "reg_or_0_operand" "r,L"))]
197
  ""
198
  "@
199
        push %B0\;push %A0
200
        push __zero_reg__\;push __zero_reg__"
201
  [(set_attr "length" "2,2")])
202
 
203
(define_insn "*pushsi"
204
  [(set (mem:SI (post_dec (reg:HI REG_SP)))
205
        (match_operand:SI 0 "reg_or_0_operand" "r,L"))]
206
  ""
207
  "@
208
        push %D0\;push %C0\;push %B0\;push %A0
209
        push __zero_reg__\;push __zero_reg__\;push __zero_reg__\;push __zero_reg__"
210
  [(set_attr "length" "4,4")])
211
 
212
(define_insn "*pushsf"
213
  [(set (mem:SF (post_dec (reg:HI REG_SP)))
214
        (match_operand:SF 0 "register_operand" "r"))]
215
  ""
216
  "push %D0
217
        push %C0
218
        push %B0
219
        push %A0"
220
  [(set_attr "length" "4")])
221
 
222
;;========================================================================
223
;; move byte
224
;; The last alternative (any immediate constant to any register) is
225
;; very expensive.  It should be optimized by peephole2 if a scratch
226
;; register is available, but then that register could just as well be
227
;; allocated for the variable we are loading.  But, most of NO_LD_REGS
228
;; are call-saved registers, and most of LD_REGS are call-used registers,
229
;; so this may still be a win for registers live across function calls.
230
 
231
(define_expand "movqi"
232
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
233
        (match_operand:QI 1 "general_operand" ""))]
234
  ""
235
  "/* One of the ops has to be in a register.  */
236
   if (!register_operand(operand0, QImode)
237
       && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
238
       operands[1] = copy_to_mode_reg(QImode, operand1);
239
  ")
240
 
241
(define_insn "*movqi"
242
  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
243
        (match_operand:QI 1 "general_operand"       "rL,i,rL,Qm,r,q,i"))]
244
  "(register_operand (operands[0],QImode)
245
    || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
246
  "* return output_movqi (insn, operands, NULL);"
247
  [(set_attr "length" "1,1,5,5,1,1,4")
248
   (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
249
 
250
;; This is used in peephole2 to optimize loading immediate constants
251
;; if a scratch register from LD_REGS happens to be available.
252
 
253
(define_insn "*reload_inqi"
254
  [(set (match_operand:QI 0 "register_operand" "=l")
255
        (match_operand:QI 1 "immediate_operand" "i"))
256
   (clobber (match_operand:QI 2 "register_operand" "=&d"))]
257
  "reload_completed"
258
  "ldi %2,lo8(%1)
259
        mov %0,%2"
260
  [(set_attr "length" "2")
261
   (set_attr "cc" "none")])
262
 
263
(define_peephole2
264
  [(match_scratch:QI 2 "d")
265
   (set (match_operand:QI 0 "l_register_operand" "")
266
        (match_operand:QI 1 "immediate_operand" ""))]
267
  "(operands[1] != const0_rtx
268
    && operands[1] != const1_rtx
269
    && operands[1] != constm1_rtx)"
270
  [(parallel [(set (match_dup 0) (match_dup 1))
271
              (clobber (match_dup 2))])]
272
  "")
273
 
274
;;============================================================================
275
;; move word (16 bit)
276
 
277
(define_expand "movhi"
278
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
279
        (match_operand:HI 1 "general_operand"       ""))]
280
  ""
281
  "
282
{
283
   /* One of the ops has to be in a register.  */
284
  if (!register_operand(operand0, HImode)
285
      && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
286
    {
287
      operands[1] = copy_to_mode_reg(HImode, operand1);
288
    }
289
}")
290
 
291
(define_insn "*movhi_sp"
292
  [(set (match_operand:HI 0 "register_operand" "=q,r")
293
        (match_operand:HI 1 "register_operand"  "r,q"))]
294
  "((stack_register_operand(operands[0], HImode) && register_operand (operands[1], HImode))
295
    || (register_operand (operands[0], HImode) && stack_register_operand(operands[1], HImode)))"
296
  "* return output_movhi (insn, operands, NULL);"
297
  [(set_attr "length" "5,2")
298
   (set_attr "cc" "none,none")])
299
 
300
(define_insn "movhi_sp_r_irq_off"
301
  [(set (match_operand:HI 0 "stack_register_operand" "=q")
302
        (unspec_volatile:HI [(match_operand:HI 1 "register_operand"  "r")]
303
                            UNSPECV_WRITE_SP_IRQ_OFF))]
304
  ""
305
  "out __SP_H__, %B1
306
        out __SP_L__, %A1"
307
  [(set_attr "length" "2")
308
   (set_attr "cc" "none")])
309
 
310
(define_insn "movhi_sp_r_irq_on"
311
  [(set (match_operand:HI 0 "stack_register_operand" "=q")
312
        (unspec_volatile:HI [(match_operand:HI 1 "register_operand"  "r")]
313
                            UNSPECV_WRITE_SP_IRQ_ON))]
314
  ""
315
  "cli
316
        out __SP_H__, %B1
317
        sei
318
        out __SP_L__, %A1"
319
  [(set_attr "length" "4")
320
   (set_attr "cc" "none")])
321
 
322
(define_peephole2
323
  [(match_scratch:QI 2 "d")
324
   (set (match_operand:HI 0 "l_register_operand" "")
325
        (match_operand:HI 1 "immediate_operand" ""))]
326
  "(operands[1] != const0_rtx
327
    && operands[1] != constm1_rtx)"
328
  [(parallel [(set (match_dup 0) (match_dup 1))
329
              (clobber (match_dup 2))])]
330
  "")
331
 
332
;; '*' because it is not used in rtl generation, only in above peephole
333
(define_insn "*reload_inhi"
334
  [(set (match_operand:HI 0 "register_operand" "=r")
335
        (match_operand:HI 1 "immediate_operand" "i"))
336
   (clobber (match_operand:QI 2 "register_operand" "=&d"))]
337
  "reload_completed"
338
  "* return output_reload_inhi (insn, operands, NULL);"
339
  [(set_attr "length" "4")
340
   (set_attr "cc" "none")])
341
 
342
(define_insn "*movhi"
343
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
344
        (match_operand:HI 1 "general_operand"       "rL,m,rL,i,i,r,q"))]
345
  "(register_operand (operands[0],HImode)
346
    || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
347
  "* return output_movhi (insn, operands, NULL);"
348
  [(set_attr "length" "2,6,7,2,6,5,2")
349
   (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
350
 
351
(define_peephole2 ; movw
352
  [(set (match_operand:QI 0 "even_register_operand" "")
353
        (match_operand:QI 1 "even_register_operand" ""))
354
   (set (match_operand:QI 2 "odd_register_operand" "")
355
        (match_operand:QI 3 "odd_register_operand" ""))]
356
  "(AVR_HAVE_MOVW
357
    && REGNO (operands[0]) == REGNO (operands[2]) - 1
358
    && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
359
  [(set (match_dup 4) (match_dup 5))]
360
  {
361
    operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
362
    operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
363
  })
364
 
365
(define_peephole2 ; movw_r
366
  [(set (match_operand:QI 0 "odd_register_operand" "")
367
        (match_operand:QI 1 "odd_register_operand" ""))
368
   (set (match_operand:QI 2 "even_register_operand" "")
369
        (match_operand:QI 3 "even_register_operand" ""))]
370
  "(AVR_HAVE_MOVW
371
    && REGNO (operands[2]) == REGNO (operands[0]) - 1
372
    && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
373
  [(set (match_dup 4) (match_dup 5))]
374
  {
375
    operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
376
    operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
377
  })
378
 
379
;;==========================================================================
380
;; move double word (32 bit)
381
 
382
(define_expand "movsi"
383
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
384
        (match_operand:SI 1 "general_operand"  ""))]
385
  ""
386
  "
387
{
388
  /* One of the ops has to be in a register.  */
389
  if (!register_operand (operand0, SImode)
390
      && !(register_operand (operand1, SImode) || const0_rtx == operand1))
391
    {
392
      operands[1] = copy_to_mode_reg (SImode, operand1);
393
    }
394
}")
395
 
396
 
397
 
398
(define_peephole2 ; movsi_lreg_const
399
  [(match_scratch:QI 2 "d")
400
   (set (match_operand:SI 0 "l_register_operand" "")
401
        (match_operand:SI 1 "immediate_operand" ""))
402
   (match_dup 2)]
403
  "(operands[1] != const0_rtx
404
    && operands[1] != constm1_rtx)"
405
  [(parallel [(set (match_dup 0) (match_dup 1))
406
              (clobber (match_dup 2))])]
407
  "")
408
 
409
;; '*' because it is not used in rtl generation.
410
(define_insn "*reload_insi"
411
  [(set (match_operand:SI 0 "register_operand" "=r")
412
        (match_operand:SI 1 "immediate_operand" "i"))
413
   (clobber (match_operand:QI 2 "register_operand" "=&d"))]
414
  "reload_completed"
415
  "* return output_reload_insisf (insn, operands, NULL);"
416
  [(set_attr "length" "8")
417
   (set_attr "cc" "none")])
418
 
419
 
420
(define_insn "*movsi"
421
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
422
        (match_operand:SI 1 "general_operand"       "r,L,Qm,rL,i,i"))]
423
  "(register_operand (operands[0],SImode)
424
    || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
425
  "* return output_movsisf (insn, operands, NULL);"
426
  [(set_attr "length" "4,4,8,9,4,10")
427
   (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
428
 
429
;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
430
;; move floating point numbers (32 bit)
431
 
432
(define_expand "movsf"
433
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
434
        (match_operand:SF 1 "general_operand"  ""))]
435
  ""
436
  "
437
{
438
  /* One of the ops has to be in a register.  */
439
  if (!register_operand (operand1, SFmode)
440
      && !register_operand (operand0, SFmode))
441
    {
442
      operands[1] = copy_to_mode_reg (SFmode, operand1);
443
    }
444
}")
445
 
446
(define_insn "*movsf"
447
  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
448
        (match_operand:SF 1 "general_operand"       "r,G,Qm,r,F,F"))]
449
  "register_operand (operands[0], SFmode)
450
   || register_operand (operands[1], SFmode)"
451
  "* return output_movsisf (insn, operands, NULL);"
452
  [(set_attr "length" "4,4,8,9,4,10")
453
   (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
454
 
455
;;=========================================================================
456
;; move string (like memcpy)
457
;; implement as RTL loop
458
 
459
(define_expand "movmemhi"
460
  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
461
          (match_operand:BLK 1 "memory_operand" ""))
462
          (use (match_operand:HI 2 "const_int_operand" ""))
463
          (use (match_operand:HI 3 "const_int_operand" ""))])]
464
  ""
465
  "{
466
  int prob;
467
  HOST_WIDE_INT count;
468
  enum machine_mode mode;
469
  rtx label = gen_label_rtx ();
470
  rtx loop_reg;
471
  rtx jump;
472
 
473
  /* Copy pointers into new psuedos - they will be changed.  */
474
  rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
475
  rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
476
 
477
  /* Create rtx for tmp register - we use this as scratch.  */
478
  rtx tmp_reg_rtx  = gen_rtx_REG (QImode, TMP_REGNO);
479
 
480
  if (GET_CODE (operands[2]) != CONST_INT)
481
    FAIL;
482
 
483
  count = INTVAL (operands[2]);
484
  if (count <= 0)
485
    FAIL;
486
 
487
  /* Work out branch probability for latter use.  */
488
  prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
489
 
490
  /* See if constant fit 8 bits.  */
491
  mode = (count < 0x100) ? QImode : HImode;
492
  /* Create loop counter register.  */
493
  loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
494
 
495
  /* Now create RTL code for move loop.  */
496
  /* Label at top of loop.  */
497
  emit_label (label);
498
 
499
  /* Move one byte into scratch and inc pointer.  */
500
  emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
501
  emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
502
 
503
  /* Move to mem and inc pointer.  */
504
  emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
505
  emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
506
 
507
  /* Decrement count.  */
508
  emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
509
 
510
  /* Compare with zero and jump if not equal. */
511
  emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
512
                           label);
513
  /* Set jump probability based on loop count.  */
514
  jump = get_last_insn ();
515
  add_reg_note (jump, REG_BR_PROB, GEN_INT (prob));
516
  DONE;
517
}")
518
 
519
;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
520
;; memset (%0, %2, %1)
521
 
522
(define_expand "setmemhi"
523
  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
524
                   (match_operand 2 "const_int_operand" ""))
525
              (use (match_operand:HI 1 "const_int_operand" ""))
526
              (use (match_operand:HI 3 "const_int_operand" "n"))
527
              (clobber (match_scratch:HI 4 ""))
528
              (clobber (match_dup 5))])]
529
  ""
530
  "{
531
  rtx addr0;
532
  int cnt8;
533
  enum machine_mode mode;
534
 
535
  /* If value to set is not zero, use the library routine.  */
536
  if (operands[2] != const0_rtx)
537
    FAIL;
538
 
539
  if (GET_CODE (operands[1]) != CONST_INT)
540
    FAIL;
541
 
542
  cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
543
  mode = cnt8 ? QImode : HImode;
544
  operands[5] = gen_rtx_SCRATCH (mode);
545
  operands[1] = copy_to_mode_reg (mode,
546
                                  gen_int_mode (INTVAL (operands[1]), mode));
547
  addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
548
  operands[0] = gen_rtx_MEM (BLKmode, addr0);
549
}")
550
 
551
(define_insn "*clrmemqi"
552
  [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
553
        (const_int 0))
554
   (use (match_operand:QI 1 "register_operand" "r"))
555
   (use (match_operand:QI 2 "const_int_operand" "n"))
556
   (clobber (match_scratch:HI 3 "=0"))
557
   (clobber (match_scratch:QI 4 "=&1"))]
558
  ""
559
  "st %a0+,__zero_reg__
560
        dec %1
561
        brne .-6"
562
  [(set_attr "length" "3")
563
   (set_attr "cc" "clobber")])
564
 
565
(define_insn "*clrmemhi"
566
  [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
567
        (const_int 0))
568
   (use (match_operand:HI 1 "register_operand" "!w,d"))
569
   (use (match_operand:HI 2 "const_int_operand" "n,n"))
570
   (clobber (match_scratch:HI 3 "=0,0"))
571
   (clobber (match_scratch:HI 4 "=&1,&1"))]
572
  ""
573
  "*{
574
     if (which_alternative==0)
575
       return (AS2 (st,%a0+,__zero_reg__) CR_TAB
576
               AS2 (sbiw,%A1,1) CR_TAB
577
               AS1 (brne,.-6));
578
     else
579
       return (AS2 (st,%a0+,__zero_reg__) CR_TAB
580
               AS2 (subi,%A1,1) CR_TAB
581
               AS2 (sbci,%B1,0) CR_TAB
582
               AS1 (brne,.-8));
583
}"
584
  [(set_attr "length" "3,4")
585
   (set_attr "cc" "clobber,clobber")])
586
 
587
(define_expand "strlenhi"
588
    [(set (match_dup 4)
589
          (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
590
                      (match_operand:QI 2 "const_int_operand" "")
591
                      (match_operand:HI 3 "immediate_operand" "")]
592
                     UNSPEC_STRLEN))
593
     (set (match_dup 4) (plus:HI (match_dup 4)
594
                                 (const_int -1)))
595
     (set (match_operand:HI 0 "register_operand" "")
596
          (minus:HI (match_dup 4)
597
                    (match_dup 5)))]
598
   ""
599
   "{
600
  rtx addr;
601
  if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
602
    FAIL;
603
  addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
604
  operands[1] = gen_rtx_MEM (BLKmode, addr);
605
  operands[5] = addr;
606
  operands[4] = gen_reg_rtx (HImode);
607
}")
608
 
609
(define_insn "*strlenhi"
610
  [(set (match_operand:HI 0 "register_operand" "=e")
611
        (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
612
                    (const_int 0)
613
                    (match_operand:HI 2 "immediate_operand" "i")]
614
                   UNSPEC_STRLEN))]
615
  ""
616
  "ld __tmp_reg__,%a0+
617
        tst __tmp_reg__
618
        brne .-6"
619
  [(set_attr "length" "3")
620
   (set_attr "cc" "clobber")])
621
 
622
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
623
; add bytes
624
 
625
(define_insn "addqi3"
626
  [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
627
        (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
628
                 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
629
  ""
630
  "@
631
        add %0,%2
632
        subi %0,lo8(-(%2))
633
        inc %0
634
        dec %0"
635
  [(set_attr "length" "1,1,1,1")
636
   (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
637
 
638
 
639
(define_expand "addhi3"
640
  [(set (match_operand:HI 0 "register_operand" "")
641
        (plus:HI (match_operand:HI 1 "register_operand" "")
642
                 (match_operand:HI 2 "nonmemory_operand" "")))]
643
  ""
644
  "
645
{
646
  if (GET_CODE (operands[2]) == CONST_INT)
647
    {
648
      short tmp = INTVAL (operands[2]);
649
      operands[2] = GEN_INT(tmp);
650
    }
651
}")
652
 
653
 
654
(define_insn "*addhi3_zero_extend"
655
  [(set (match_operand:HI 0 "register_operand" "=r")
656
        (plus:HI (zero_extend:HI
657
                  (match_operand:QI 1 "register_operand" "r"))
658
                 (match_operand:HI 2 "register_operand" "0")))]
659
  ""
660
  "add %A0,%1
661
        adc %B0,__zero_reg__"
662
  [(set_attr "length" "2")
663
   (set_attr "cc" "set_n")])
664
 
665
(define_insn "*addhi3_zero_extend1"
666
  [(set (match_operand:HI 0 "register_operand" "=r")
667
        (plus:HI (match_operand:HI 1 "register_operand" "%0")
668
                 (zero_extend:HI
669
                  (match_operand:QI 2 "register_operand" "r"))))]
670
  ""
671
  "add %A0,%2
672
        adc %B0,__zero_reg__"
673
  [(set_attr "length" "2")
674
   (set_attr "cc" "set_n")])
675
 
676
(define_insn "*addhi3_sp_R_pc2"
677
  [(set (match_operand:HI 1 "stack_register_operand" "=q")
678
        (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
679
                 (match_operand:HI 0 "avr_sp_immediate_operand" "R")))]
680
  "AVR_2_BYTE_PC"
681
  "*{
682
      if (CONST_INT_P (operands[0]))
683
        {
684
          switch(INTVAL (operands[0]))
685
            {
686
            case -6:
687
              return \"rcall .\" CR_TAB
688
                     \"rcall .\" CR_TAB
689
                     \"rcall .\";
690
            case -5:
691
              return \"rcall .\" CR_TAB
692
                     \"rcall .\" CR_TAB
693
                     \"push __tmp_reg__\";
694
            case -4:
695
              return \"rcall .\" CR_TAB
696
                     \"rcall .\";
697
            case -3:
698
              return \"rcall .\" CR_TAB
699
                     \"push __tmp_reg__\";
700
            case -2:
701
              return \"rcall .\";
702
            case -1:
703
              return \"push __tmp_reg__\";
704
            case 0:
705
              return \"\";
706
            case 1:
707
              return \"pop __tmp_reg__\";
708
            case 2:
709
              return \"pop __tmp_reg__\" CR_TAB
710
                     \"pop __tmp_reg__\";
711
            case 3:
712
              return \"pop __tmp_reg__\" CR_TAB
713
                     \"pop __tmp_reg__\" CR_TAB
714
                     \"pop __tmp_reg__\";
715
            case 4:
716
              return \"pop __tmp_reg__\" CR_TAB
717
                     \"pop __tmp_reg__\" CR_TAB
718
                     \"pop __tmp_reg__\" CR_TAB
719
                     \"pop __tmp_reg__\";
720
            case 5:
721
              return \"pop __tmp_reg__\" CR_TAB
722
                     \"pop __tmp_reg__\" CR_TAB
723
                     \"pop __tmp_reg__\" CR_TAB
724
                     \"pop __tmp_reg__\" CR_TAB
725
                     \"pop __tmp_reg__\";
726
            }
727
        }
728
      return \"bug\";
729
    }"
730
  [(set (attr "length")
731
        (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
732
               (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
733
               (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
734
               (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
735
               (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
736
               (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
737
               (eq (const_int  0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
738
               (eq (const_int  1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
739
               (eq (const_int  2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
740
               (eq (const_int  3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
741
               (eq (const_int  4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
742
               (eq (const_int  5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
743
               (const_int 0)))])
744
 
745
(define_insn "*addhi3_sp_R_pc3"
746
  [(set (match_operand:HI 1 "stack_register_operand" "=q")
747
        (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
748
                 (match_operand:QI 0 "avr_sp_immediate_operand" "R")))]
749
  "AVR_3_BYTE_PC"
750
  "*{
751
      if (CONST_INT_P (operands[0]))
752
        {
753
          switch(INTVAL (operands[0]))
754
            {
755
            case -6:
756
              return \"rcall .\" CR_TAB
757
                     \"rcall .\";
758
            case -5:
759
              return \"rcall .\" CR_TAB
760
                     \"push __tmp_reg__\" CR_TAB
761
                     \"push __tmp_reg__\";
762
            case -4:
763
              return \"rcall .\" CR_TAB
764
                     \"push __tmp_reg__\";
765
            case -3:
766
              return \"rcall .\";
767
            case -2:
768
              return \"push __tmp_reg__\" CR_TAB
769
                     \"push __tmp_reg__\";
770
            case -1:
771
              return \"push __tmp_reg__\";
772
            case 0:
773
              return \"\";
774
            case 1:
775
              return \"pop __tmp_reg__\";
776
            case 2:
777
              return \"pop __tmp_reg__\" CR_TAB
778
                     \"pop __tmp_reg__\";
779
            case 3:
780
              return \"pop __tmp_reg__\" CR_TAB
781
                     \"pop __tmp_reg__\" CR_TAB
782
                     \"pop __tmp_reg__\";
783
            case 4:
784
              return \"pop __tmp_reg__\" CR_TAB
785
                     \"pop __tmp_reg__\" CR_TAB
786
                     \"pop __tmp_reg__\" CR_TAB
787
                     \"pop __tmp_reg__\";
788
            case 5:
789
              return \"pop __tmp_reg__\" CR_TAB
790
                     \"pop __tmp_reg__\" CR_TAB
791
                     \"pop __tmp_reg__\" CR_TAB
792
                     \"pop __tmp_reg__\" CR_TAB
793
                     \"pop __tmp_reg__\";
794
            }
795
        }
796
      return \"bug\";
797
    }"
798
  [(set (attr "length")
799
        (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
800
               (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
801
               (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
802
               (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
803
               (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
804
               (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
805
               (eq (const_int  0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
806
               (eq (const_int  1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
807
               (eq (const_int  2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
808
               (eq (const_int  3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
809
               (eq (const_int  4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
810
               (eq (const_int  5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
811
               (const_int 0)))])
812
 
813
(define_insn "*addhi3"
814
  [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
815
        (plus:HI
816
         (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
817
         (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
818
  ""
819
  "@
820
        add %A0,%A2\;adc %B0,%B2
821
        adiw %A0,%2
822
        sbiw %A0,%n2
823
        subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
824
        sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
825
        sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
826
  [(set_attr "length" "2,1,1,2,3,3")
827
   (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
828
 
829
(define_insn "addsi3"
830
  [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r")
831
          (plus:SI
832
           (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
833
           (match_operand:SI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
834
  ""
835
  "@
836
        add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
837
        adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
838
        sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
839
        subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))
840
        sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
841
        sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
842
  [(set_attr "length" "4,3,3,4,5,5")
843
   (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n")])
844
 
845
(define_insn "*addsi3_zero_extend"
846
  [(set (match_operand:SI 0 "register_operand" "=r")
847
        (plus:SI (zero_extend:SI
848
                  (match_operand:QI 1 "register_operand" "r"))
849
                 (match_operand:SI 2 "register_operand" "0")))]
850
  ""
851
  "add %A0,%1
852
        adc %B0,__zero_reg__
853
        adc %C0,__zero_reg__
854
        adc %D0,__zero_reg__"
855
  [(set_attr "length" "4")
856
   (set_attr "cc" "set_n")])
857
 
858
;-----------------------------------------------------------------------------
859
; sub bytes
860
(define_insn "subqi3"
861
  [(set (match_operand:QI 0 "register_operand" "=r,d")
862
        (minus:QI (match_operand:QI 1 "register_operand" "0,0")
863
                  (match_operand:QI 2 "nonmemory_operand" "r,i")))]
864
  ""
865
  "@
866
        sub %0,%2
867
        subi %0,lo8(%2)"
868
  [(set_attr "length" "1,1")
869
   (set_attr "cc" "set_czn,set_czn")])
870
 
871
(define_insn "subhi3"
872
  [(set (match_operand:HI 0 "register_operand" "=r,d")
873
        (minus:HI (match_operand:HI 1 "register_operand" "0,0")
874
                  (match_operand:HI 2 "nonmemory_operand" "r,i")))]
875
  ""
876
  "@
877
        sub %A0,%A2\;sbc %B0,%B2
878
        subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
879
  [(set_attr "length" "2,2")
880
   (set_attr "cc" "set_czn,set_czn")])
881
 
882
(define_insn "*subhi3_zero_extend1"
883
  [(set (match_operand:HI 0 "register_operand" "=r")
884
        (minus:HI (match_operand:HI 1 "register_operand" "0")
885
                  (zero_extend:HI
886
                   (match_operand:QI 2 "register_operand" "r"))))]
887
  ""
888
  "sub %A0,%2
889
        sbc %B0,__zero_reg__"
890
  [(set_attr "length" "2")
891
   (set_attr "cc" "set_n")])
892
 
893
(define_insn "subsi3"
894
  [(set (match_operand:SI 0 "register_operand" "=r,d")
895
        (minus:SI (match_operand:SI 1 "register_operand" "0,0")
896
                 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
897
  ""
898
  "@
899
        sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
900
        subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
901
  [(set_attr "length" "4,4")
902
   (set_attr "cc" "set_czn,set_czn")])
903
 
904
(define_insn "*subsi3_zero_extend"
905
  [(set (match_operand:SI 0 "register_operand" "=r")
906
        (minus:SI (match_operand:SI 1 "register_operand" "0")
907
                  (zero_extend:SI
908
                   (match_operand:QI 2 "register_operand" "r"))))]
909
  ""
910
  "sub %A0,%2
911
        sbc %B0,__zero_reg__
912
        sbc %C0,__zero_reg__
913
        sbc %D0,__zero_reg__"
914
  [(set_attr "length" "4")
915
   (set_attr "cc" "set_n")])
916
 
917
;******************************************************************************
918
; mul
919
 
920
(define_expand "mulqi3"
921
  [(set (match_operand:QI 0 "register_operand" "")
922
        (mult:QI (match_operand:QI 1 "register_operand" "")
923
                 (match_operand:QI 2 "register_operand" "")))]
924
  ""
925
  "{
926
  if (!AVR_HAVE_MUL)
927
    {
928
      emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
929
      DONE;
930
    }
931
}")
932
 
933
(define_insn "*mulqi3_enh"
934
  [(set (match_operand:QI 0 "register_operand" "=r")
935
        (mult:QI (match_operand:QI 1 "register_operand" "r")
936
                 (match_operand:QI 2 "register_operand" "r")))]
937
  "AVR_HAVE_MUL"
938
  "mul %1,%2
939
        mov %0,r0
940
        clr r1"
941
  [(set_attr "length" "3")
942
   (set_attr "cc" "clobber")])
943
 
944
(define_expand "mulqi3_call"
945
  [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
946
   (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
947
   (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
948
              (clobber (reg:QI 22))])
949
   (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
950
  ""
951
  "")
952
 
953
(define_insn "*mulqi3_call"
954
  [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
955
   (clobber (reg:QI 22))]
956
  "!AVR_HAVE_MUL"
957
  "%~call __mulqi3"
958
  [(set_attr "type" "xcall")
959
   (set_attr "cc" "clobber")])
960
 
961
(define_insn "mulqihi3"
962
  [(set (match_operand:HI 0 "register_operand" "=r")
963
        (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
964
                 (sign_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
965
  "AVR_HAVE_MUL"
966
  "muls %1,%2
967
        movw %0,r0
968
        clr r1"
969
  [(set_attr "length" "3")
970
   (set_attr "cc" "clobber")])
971
 
972
(define_insn "umulqihi3"
973
  [(set (match_operand:HI 0 "register_operand" "=r")
974
        (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
975
                 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
976
  "AVR_HAVE_MUL"
977
  "mul %1,%2
978
        movw %0,r0
979
        clr r1"
980
  [(set_attr "length" "3")
981
   (set_attr "cc" "clobber")])
982
 
983
(define_expand "mulhi3"
984
  [(set (match_operand:HI 0 "register_operand" "")
985
        (mult:HI (match_operand:HI 1 "register_operand" "")
986
                 (match_operand:HI 2 "register_operand" "")))]
987
  ""
988
  "
989
{
990
  if (!AVR_HAVE_MUL)
991
    {
992
      emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
993
      DONE;
994
    }
995
}")
996
 
997
(define_insn "*mulhi3_enh"
998
  [(set (match_operand:HI 0 "register_operand" "=&r")
999
        (mult:HI (match_operand:HI 1 "register_operand" "r")
1000
                 (match_operand:HI 2 "register_operand" "r")))]
1001
  "AVR_HAVE_MUL"
1002
  "mul %A1,%A2
1003
        movw %0,r0
1004
        mul %A1,%B2
1005
        add %B0,r0
1006
        mul %B1,%A2
1007
        add %B0,r0
1008
        clr r1"
1009
  [(set_attr "length" "7")
1010
   (set_attr "cc" "clobber")])
1011
 
1012
(define_expand "mulhi3_call"
1013
  [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
1014
   (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
1015
   (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1016
              (clobber (reg:HI 22))
1017
              (clobber (reg:QI 21))])
1018
   (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
1019
  ""
1020
  "")
1021
 
1022
(define_insn "*mulhi3_call"
1023
  [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1024
   (clobber (reg:HI 22))
1025
   (clobber (reg:QI 21))]
1026
  "!AVR_HAVE_MUL"
1027
  "%~call __mulhi3"
1028
  [(set_attr "type" "xcall")
1029
   (set_attr "cc" "clobber")])
1030
 
1031
;; Operand 2 (reg:SI 18) not clobbered on the enhanced core.
1032
;; All call-used registers clobbered otherwise - normal library call.
1033
(define_expand "mulsi3"
1034
  [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
1035
   (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
1036
   (parallel [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
1037
              (clobber (reg:HI 26))
1038
              (clobber (reg:HI 30))])
1039
   (set (match_operand:SI 0 "register_operand" "") (reg:SI 22))]
1040
  "AVR_HAVE_MUL"
1041
  "")
1042
 
1043
(define_insn "*mulsi3_call"
1044
  [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
1045
   (clobber (reg:HI 26))
1046
   (clobber (reg:HI 30))]
1047
  "AVR_HAVE_MUL"
1048
  "%~call __mulsi3"
1049
  [(set_attr "type" "xcall")
1050
   (set_attr "cc" "clobber")])
1051
 
1052
; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
1053
; divmod
1054
 
1055
;; Generate libgcc.S calls ourselves, because:
1056
;;  - we know exactly which registers are clobbered (for QI and HI
1057
;;    modes, some of the call-used registers are preserved)
1058
;;  - we get both the quotient and the remainder at no extra cost
1059
;;  - we split the patterns only after the first CSE passes because
1060
;;    CSE has problems to operate on hard regs.
1061
;;
1062
(define_insn_and_split "divmodqi4"
1063
  [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
1064
                   (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
1065
                           (match_operand:QI 2 "pseudo_register_operand" "")))
1066
              (set (match_operand:QI 3 "pseudo_register_operand" "")
1067
                   (mod:QI (match_dup 1) (match_dup 2)))
1068
              (clobber (reg:QI 22))
1069
              (clobber (reg:QI 23))
1070
              (clobber (reg:QI 24))
1071
              (clobber (reg:QI 25))])]
1072
  ""
1073
  "this divmodqi4 pattern should have been splitted;"
1074
  ""
1075
  [(set (reg:QI 24) (match_dup 1))
1076
   (set (reg:QI 22) (match_dup 2))
1077
   (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1078
              (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1079
              (clobber (reg:QI 22))
1080
              (clobber (reg:QI 23))])
1081
   (set (match_dup 0) (reg:QI 24))
1082
   (set (match_dup 3) (reg:QI 25))]
1083
  "")
1084
 
1085
(define_insn "*divmodqi4_call"
1086
  [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1087
   (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1088
   (clobber (reg:QI 22))
1089
   (clobber (reg:QI 23))]
1090
  ""
1091
  "%~call __divmodqi4"
1092
  [(set_attr "type" "xcall")
1093
   (set_attr "cc" "clobber")])
1094
 
1095
(define_insn_and_split "udivmodqi4"
1096
 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
1097
                  (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
1098
                           (match_operand:QI 2 "pseudo_register_operand" "")))
1099
             (set (match_operand:QI 3 "pseudo_register_operand" "")
1100
                  (umod:QI (match_dup 1) (match_dup 2)))
1101
             (clobber (reg:QI 22))
1102
             (clobber (reg:QI 23))
1103
             (clobber (reg:QI 24))
1104
             (clobber (reg:QI 25))])]
1105
  ""
1106
  "this udivmodqi4 pattern should have been splitted;"
1107
  ""
1108
  [(set (reg:QI 24) (match_dup 1))
1109
   (set (reg:QI 22) (match_dup 2))
1110
   (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1111
              (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1112
              (clobber (reg:QI 23))])
1113
   (set (match_dup 0) (reg:QI 24))
1114
   (set (match_dup 3) (reg:QI 25))]
1115
  "")
1116
 
1117
(define_insn "*udivmodqi4_call"
1118
  [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1119
   (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1120
   (clobber (reg:QI 23))]
1121
  ""
1122
  "%~call __udivmodqi4"
1123
  [(set_attr "type" "xcall")
1124
   (set_attr "cc" "clobber")])
1125
 
1126
(define_insn_and_split "divmodhi4"
1127
  [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
1128
                   (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
1129
                           (match_operand:HI 2 "pseudo_register_operand" "")))
1130
              (set (match_operand:HI 3 "pseudo_register_operand" "")
1131
                   (mod:HI (match_dup 1) (match_dup 2)))
1132
              (clobber (reg:QI 21))
1133
              (clobber (reg:HI 22))
1134
              (clobber (reg:HI 24))
1135
              (clobber (reg:HI 26))])]
1136
  ""
1137
  "this should have been splitted;"
1138
  ""
1139
  [(set (reg:HI 24) (match_dup 1))
1140
   (set (reg:HI 22) (match_dup 2))
1141
   (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1142
              (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1143
              (clobber (reg:HI 26))
1144
              (clobber (reg:QI 21))])
1145
   (set (match_dup 0) (reg:HI 22))
1146
   (set (match_dup 3) (reg:HI 24))]
1147
  "")
1148
 
1149
(define_insn "*divmodhi4_call"
1150
  [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1151
   (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1152
   (clobber (reg:HI 26))
1153
   (clobber (reg:QI 21))]
1154
  ""
1155
  "%~call __divmodhi4"
1156
  [(set_attr "type" "xcall")
1157
   (set_attr "cc" "clobber")])
1158
 
1159
(define_insn_and_split "udivmodhi4"
1160
  [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
1161
                   (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
1162
                            (match_operand:HI 2 "pseudo_register_operand" "")))
1163
              (set (match_operand:HI 3 "pseudo_register_operand" "")
1164
                   (umod:HI (match_dup 1) (match_dup 2)))
1165
              (clobber (reg:QI 21))
1166
              (clobber (reg:HI 22))
1167
              (clobber (reg:HI 24))
1168
              (clobber (reg:HI 26))])]
1169
  ""
1170
  "this udivmodhi4 pattern should have been splitted.;"
1171
  ""
1172
  [(set (reg:HI 24) (match_dup 1))
1173
   (set (reg:HI 22) (match_dup 2))
1174
   (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1175
              (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1176
              (clobber (reg:HI 26))
1177
              (clobber (reg:QI 21))])
1178
   (set (match_dup 0) (reg:HI 22))
1179
   (set (match_dup 3) (reg:HI 24))]
1180
  "")
1181
 
1182
(define_insn "*udivmodhi4_call"
1183
  [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1184
   (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1185
   (clobber (reg:HI 26))
1186
   (clobber (reg:QI 21))]
1187
  ""
1188
  "%~call __udivmodhi4"
1189
  [(set_attr "type" "xcall")
1190
   (set_attr "cc" "clobber")])
1191
 
1192
(define_insn_and_split "divmodsi4"
1193
  [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
1194
                   (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
1195
                           (match_operand:SI 2 "pseudo_register_operand" "")))
1196
              (set (match_operand:SI 3 "pseudo_register_operand" "")
1197
                   (mod:SI (match_dup 1) (match_dup 2)))
1198
              (clobber (reg:SI 18))
1199
              (clobber (reg:SI 22))
1200
              (clobber (reg:HI 26))
1201
              (clobber (reg:HI 30))])]
1202
  ""
1203
  "this divmodsi4 pattern should have been splitted;"
1204
  ""
1205
  [(set (reg:SI 22) (match_dup 1))
1206
   (set (reg:SI 18) (match_dup 2))
1207
   (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1208
              (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1209
              (clobber (reg:HI 26))
1210
              (clobber (reg:HI 30))])
1211
   (set (match_dup 0) (reg:SI 18))
1212
   (set (match_dup 3) (reg:SI 22))]
1213
  "")
1214
 
1215
(define_insn "*divmodsi4_call"
1216
  [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1217
   (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1218
   (clobber (reg:HI 26))
1219
   (clobber (reg:HI 30))]
1220
  ""
1221
  "%~call __divmodsi4"
1222
  [(set_attr "type" "xcall")
1223
   (set_attr "cc" "clobber")])
1224
 
1225
(define_insn_and_split "udivmodsi4"
1226
  [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
1227
                   (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
1228
                           (match_operand:SI 2 "pseudo_register_operand" "")))
1229
              (set (match_operand:SI 3 "pseudo_register_operand" "")
1230
                   (umod:SI (match_dup 1) (match_dup 2)))
1231
              (clobber (reg:SI 18))
1232
              (clobber (reg:SI 22))
1233
              (clobber (reg:HI 26))
1234
              (clobber (reg:HI 30))])]
1235
  ""
1236
  "this udivmodsi4 pattern should have been splitted;"
1237
  ""
1238
  [(set (reg:SI 22) (match_dup 1))
1239
   (set (reg:SI 18) (match_dup 2))
1240
   (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1241
              (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1242
              (clobber (reg:HI 26))
1243
              (clobber (reg:HI 30))])
1244
   (set (match_dup 0) (reg:SI 18))
1245
   (set (match_dup 3) (reg:SI 22))]
1246
  "")
1247
 
1248
(define_insn "*udivmodsi4_call"
1249
  [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1250
   (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1251
   (clobber (reg:HI 26))
1252
   (clobber (reg:HI 30))]
1253
  ""
1254
  "%~call __udivmodsi4"
1255
  [(set_attr "type" "xcall")
1256
   (set_attr "cc" "clobber")])
1257
 
1258
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
1259
; and
1260
 
1261
(define_insn "andqi3"
1262
  [(set (match_operand:QI 0 "register_operand" "=r,d")
1263
        (and:QI (match_operand:QI 1 "register_operand" "%0,0")
1264
                (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1265
  ""
1266
  "@
1267
        and %0,%2
1268
        andi %0,lo8(%2)"
1269
  [(set_attr "length" "1,1")
1270
   (set_attr "cc" "set_zn,set_zn")])
1271
 
1272
(define_insn "andhi3"
1273
  [(set (match_operand:HI 0 "register_operand" "=r,d,r")
1274
          (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1275
                  (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
1276
   (clobber (match_scratch:QI 3 "=X,X,&d"))]
1277
  ""
1278
{
1279
  if (which_alternative==0)
1280
    return ("and %A0,%A2" CR_TAB
1281
            "and %B0,%B2");
1282
  else if (which_alternative==1)
1283
    {
1284
      if (GET_CODE (operands[2]) == CONST_INT)
1285
        {
1286
          int mask = INTVAL (operands[2]);
1287
          if ((mask & 0xff) != 0xff)
1288
            output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1289
          if ((mask & 0xff00) != 0xff00)
1290
            output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1291
          return "";
1292
        }
1293
        return (AS2 (andi,%A0,lo8(%2)) CR_TAB
1294
                AS2 (andi,%B0,hi8(%2)));
1295
     }
1296
  return (AS2 (ldi,%3,lo8(%2)) CR_TAB
1297
          "and %A0,%3"         CR_TAB
1298
          AS1 (clr,%B0));
1299
}
1300
  [(set_attr "length" "2,2,3")
1301
   (set_attr "cc" "set_n,clobber,set_n")])
1302
 
1303
(define_insn "andsi3"
1304
  [(set (match_operand:SI 0 "register_operand" "=r,d")
1305
        (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1306
                (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1307
  ""
1308
{
1309
  if (which_alternative==0)
1310
    return ("and %0,%2"   CR_TAB
1311
            "and %B0,%B2" CR_TAB
1312
            "and %C0,%C2" CR_TAB
1313
            "and %D0,%D2");
1314
  else if (which_alternative==1)
1315
    {
1316
      if (GET_CODE (operands[2]) == CONST_INT)
1317
        {
1318
          HOST_WIDE_INT mask = INTVAL (operands[2]);
1319
          if ((mask & 0xff) != 0xff)
1320
            output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1321
          if ((mask & 0xff00) != 0xff00)
1322
            output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1323
          if ((mask & 0xff0000L) != 0xff0000L)
1324
            output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
1325
          if ((mask & 0xff000000L) != 0xff000000L)
1326
            output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
1327
          return "";
1328
        }
1329
      return (AS2 (andi, %A0,lo8(%2))  CR_TAB
1330
              AS2 (andi, %B0,hi8(%2)) CR_TAB
1331
              AS2 (andi, %C0,hlo8(%2)) CR_TAB
1332
              AS2 (andi, %D0,hhi8(%2)));
1333
    }
1334
  return "bug";
1335
}
1336
  [(set_attr "length" "4,4")
1337
   (set_attr "cc" "set_n,clobber")])
1338
 
1339
(define_peephole2 ; andi
1340
  [(set (match_operand:QI 0 "d_register_operand" "")
1341
        (and:QI (match_dup 0)
1342
                (match_operand:QI 1 "const_int_operand" "")))
1343
   (set (match_dup 0)
1344
        (and:QI (match_dup 0)
1345
                (match_operand:QI 2 "const_int_operand" "")))]
1346
  ""
1347
  [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1348
  {
1349
    operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
1350
  })
1351
 
1352
;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1353
;; ior
1354
 
1355
(define_insn "iorqi3"
1356
  [(set (match_operand:QI 0 "register_operand" "=r,d")
1357
        (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
1358
                (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1359
  ""
1360
  "@
1361
        or %0,%2
1362
        ori %0,lo8(%2)"
1363
  [(set_attr "length" "1,1")
1364
   (set_attr "cc" "set_zn,set_zn")])
1365
 
1366
(define_insn "iorhi3"
1367
  [(set (match_operand:HI 0 "register_operand" "=r,d")
1368
        (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1369
                (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1370
  ""
1371
{
1372
  if (which_alternative==0)
1373
    return ("or %A0,%A2" CR_TAB
1374
            "or %B0,%B2");
1375
  if (GET_CODE (operands[2]) == CONST_INT)
1376
     {
1377
        int mask = INTVAL (operands[2]);
1378
        if (mask & 0xff)
1379
          output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1380
        if (mask & 0xff00)
1381
          output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1382
        return "";
1383
      }
1384
   return (AS2 (ori,%0,lo8(%2)) CR_TAB
1385
           AS2 (ori,%B0,hi8(%2)));
1386
}
1387
  [(set_attr "length" "2,2")
1388
   (set_attr "cc" "set_n,clobber")])
1389
 
1390
(define_insn "*iorhi3_clobber"
1391
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1392
        (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1393
                (match_operand:HI 2 "immediate_operand" "M,i")))
1394
   (clobber (match_scratch:QI 3 "=&d,&d"))]
1395
  ""
1396
  "@
1397
        ldi %3,lo8(%2)\;or %A0,%3
1398
        ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
1399
  [(set_attr "length" "2,4")
1400
   (set_attr "cc" "clobber,set_n")])
1401
 
1402
(define_insn "iorsi3"
1403
  [(set (match_operand:SI 0 "register_operand"        "=r,d")
1404
        (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1405
                (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1406
  ""
1407
{
1408
  if (which_alternative==0)
1409
    return ("or %0,%2"   CR_TAB
1410
            "or %B0,%B2" CR_TAB
1411
            "or %C0,%C2" CR_TAB
1412
            "or %D0,%D2");
1413
  if (GET_CODE (operands[2]) == CONST_INT)
1414
     {
1415
        HOST_WIDE_INT mask = INTVAL (operands[2]);
1416
        if (mask & 0xff)
1417
          output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1418
        if (mask & 0xff00)
1419
          output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1420
        if (mask & 0xff0000L)
1421
          output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
1422
        if (mask & 0xff000000L)
1423
          output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
1424
        return "";
1425
      }
1426
  return (AS2 (ori, %A0,lo8(%2))  CR_TAB
1427
          AS2 (ori, %B0,hi8(%2)) CR_TAB
1428
          AS2 (ori, %C0,hlo8(%2)) CR_TAB
1429
          AS2 (ori, %D0,hhi8(%2)));
1430
}
1431
  [(set_attr "length" "4,4")
1432
   (set_attr "cc" "set_n,clobber")])
1433
 
1434
(define_insn "*iorsi3_clobber"
1435
  [(set (match_operand:SI 0 "register_operand"        "=r,r")
1436
        (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1437
                (match_operand:SI 2 "immediate_operand" "M,i")))
1438
   (clobber (match_scratch:QI 3 "=&d,&d"))]
1439
  ""
1440
  "@
1441
        ldi %3,lo8(%2)\;or %A0,%3
1442
        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"
1443
  [(set_attr "length" "2,8")
1444
   (set_attr "cc" "clobber,set_n")])
1445
 
1446
;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1447
;; xor
1448
 
1449
(define_insn "xorqi3"
1450
  [(set (match_operand:QI 0 "register_operand" "=r")
1451
        (xor:QI (match_operand:QI 1 "register_operand" "%0")
1452
                (match_operand:QI 2 "register_operand" "r")))]
1453
  ""
1454
  "eor %0,%2"
1455
  [(set_attr "length" "1")
1456
   (set_attr "cc" "set_zn")])
1457
 
1458
(define_insn "xorhi3"
1459
  [(set (match_operand:HI 0 "register_operand" "=r")
1460
        (xor:HI (match_operand:HI 1 "register_operand" "%0")
1461
                (match_operand:HI 2 "register_operand" "r")))]
1462
  ""
1463
  "eor %0,%2
1464
        eor %B0,%B2"
1465
  [(set_attr "length" "2")
1466
   (set_attr "cc" "set_n")])
1467
 
1468
(define_insn "xorsi3"
1469
  [(set (match_operand:SI 0 "register_operand" "=r")
1470
        (xor:SI (match_operand:SI 1 "register_operand" "%0")
1471
                (match_operand:SI 2 "register_operand" "r")))]
1472
  ""
1473
  "eor %0,%2
1474
        eor %B0,%B2
1475
        eor %C0,%C2
1476
        eor %D0,%D2"
1477
  [(set_attr "length" "4")
1478
   (set_attr "cc" "set_n")])
1479
 
1480
;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
1481
;; swap
1482
 
1483
(define_expand "rotlqi3"
1484
  [(set (match_operand:QI 0 "register_operand" "")
1485
        (rotate:QI (match_operand:QI 1 "register_operand" "")
1486
                   (match_operand:QI 2 "const_int_operand" "")))]
1487
  ""
1488
  "
1489
{
1490
  if (!CONST_INT_P (operands[2]) || (INTVAL (operands[2]) != 4))
1491
    FAIL;
1492
}")
1493
 
1494
(define_insn "*rotlqi3_4"
1495
  [(set (match_operand:QI 0 "register_operand" "=r")
1496
        (rotate:QI (match_operand:QI 1 "register_operand" "0")
1497
                   (const_int 4)))]
1498
  ""
1499
  "swap %0"
1500
  [(set_attr "length" "1")
1501
   (set_attr "cc" "none")])
1502
 
1503
;; Split all rotates of HI,SI and DImode registers where rotation is by
1504
;; a whole number of bytes.  The split creates the appropriate moves and
1505
;; considers all overlap situations.  DImode is split before reload.
1506
 
1507
;; HImode does not need scratch.  Use attribute for this constraint.
1508
;; Use QI scratch for DI mode as this is often split into byte sized operands.
1509
 
1510
(define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (HI "X,X,X")])
1511
(define_mode_attr rotsmode [(DI "QI") (SI "HI") (HI "QI")])
1512
 
1513
(define_expand "rotl3"
1514
  [(parallel [(set (match_operand:HIDI 0 "register_operand" "")
1515
                   (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
1516
                                (match_operand:VOID 2 "const_int_operand" "")))
1517
                (clobber (match_operand 3 ""))])]
1518
  ""
1519
  "
1520
{
1521
  if (CONST_INT_P (operands[2]) && 0 == (INTVAL (operands[2]) % 8))
1522
  {
1523
  if (AVR_HAVE_MOVW && 0 == INTVAL (operands[2]) % 16)
1524
    operands[3] = gen_reg_rtx (mode);
1525
  else
1526
    operands[3] = gen_reg_rtx (QImode);
1527
  }
1528
  else
1529
    FAIL;
1530
}")
1531
 
1532
 
1533
;; Overlapping non-HImode registers often (but not always) need a scratch.
1534
;; The best we can do is use early clobber alternative "#&r" so that
1535
;; completely non-overlapping operands dont get a scratch but # so register
1536
;; allocation does not prefer non-overlapping.
1537
 
1538
 
1539
; Split word aligned rotates using scratch that is mode dependent.
1540
(define_insn_and_split "*rotw"
1541
  [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
1542
        (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
1543
                     (match_operand 2 "immediate_operand" "n,n,n")))
1544
   (clobber (match_operand: 3 "register_operand"  "=" ))]
1545
  "(CONST_INT_P (operands[2]) &&
1546
     (0 == (INTVAL (operands[2]) % 16) && AVR_HAVE_MOVW))"
1547
  "#"
1548
  "&& (reload_completed || mode == DImode)"
1549
  [(const_int 0)]
1550
  "avr_rotate_bytes (operands);
1551
  DONE;"
1552
)
1553
 
1554
 
1555
; Split byte aligned rotates using scratch that is always QI mode.
1556
(define_insn_and_split "*rotb"
1557
  [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
1558
        (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
1559
                     (match_operand 2 "immediate_operand" "n,n,n")))
1560
   (clobber (match_operand:QI 3 "register_operand" "=" ))]
1561
  "(CONST_INT_P (operands[2]) &&
1562
     (8 == (INTVAL (operands[2]) % 16)
1563
        || (!AVR_HAVE_MOVW && 0 == (INTVAL (operands[2]) % 16))))"
1564
  "#"
1565
  "&& (reload_completed || mode == DImode)"
1566
  [(const_int 0)]
1567
  "avr_rotate_bytes (operands);
1568
  DONE;"
1569
)
1570
 
1571
 
1572
;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
1573
;; arithmetic shift left
1574
 
1575
(define_expand "ashlqi3"
1576
  [(set (match_operand:QI 0 "register_operand"            "")
1577
        (ashift:QI (match_operand:QI 1 "register_operand" "")
1578
                   (match_operand:QI 2 "general_operand"  "")))]
1579
  ""
1580
  "")
1581
 
1582
(define_split ; ashlqi3_const4
1583
  [(set (match_operand:QI 0 "d_register_operand" "")
1584
        (ashift:QI (match_dup 0)
1585
                   (const_int 4)))]
1586
  ""
1587
  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1588
   (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
1589
  "")
1590
 
1591
(define_split ; ashlqi3_const5
1592
  [(set (match_operand:QI 0 "d_register_operand" "")
1593
        (ashift:QI (match_dup 0)
1594
                   (const_int 5)))]
1595
  ""
1596
  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1597
   (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
1598
   (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
1599
  "")
1600
 
1601
(define_split ; ashlqi3_const6
1602
  [(set (match_operand:QI 0 "d_register_operand" "")
1603
        (ashift:QI (match_dup 0)
1604
                   (const_int 6)))]
1605
  ""
1606
  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1607
   (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
1608
   (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
1609
  "")
1610
 
1611
(define_insn "*ashlqi3"
1612
  [(set (match_operand:QI 0 "register_operand"           "=r,r,r,r,!d,r,r")
1613
        (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1614
                   (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
1615
  ""
1616
  "* return ashlqi3_out (insn, operands, NULL);"
1617
  [(set_attr "length" "5,0,1,2,4,6,9")
1618
   (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1619
 
1620
(define_insn "ashlhi3"
1621
  [(set (match_operand:HI 0 "register_operand"           "=r,r,r,r,r,r,r")
1622
        (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1623
                   (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1624
  ""
1625
  "* return ashlhi3_out (insn, operands, NULL);"
1626
  [(set_attr "length" "6,0,2,2,4,10,10")
1627
   (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1628
 
1629
(define_insn "ashlsi3"
1630
  [(set (match_operand:SI 0 "register_operand"           "=r,r,r,r,r,r,r")
1631
        (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1632
                   (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1633
  ""
1634
  "* return ashlsi3_out (insn, operands, NULL);"
1635
  [(set_attr "length" "8,0,4,4,8,10,12")
1636
   (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1637
 
1638
;; Optimize if a scratch register from LD_REGS happens to be available.
1639
 
1640
(define_peephole2 ; ashlqi3_l_const4
1641
  [(set (match_operand:QI 0 "l_register_operand" "")
1642
        (ashift:QI (match_dup 0)
1643
                   (const_int 4)))
1644
   (match_scratch:QI 1 "d")]
1645
  ""
1646
  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1647
   (set (match_dup 1) (const_int -16))
1648
   (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1649
  "")
1650
 
1651
(define_peephole2 ; ashlqi3_l_const5
1652
  [(set (match_operand:QI 0 "l_register_operand" "")
1653
        (ashift:QI (match_dup 0)
1654
                   (const_int 5)))
1655
   (match_scratch:QI 1 "d")]
1656
  ""
1657
  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1658
   (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
1659
   (set (match_dup 1) (const_int -32))
1660
   (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1661
  "")
1662
 
1663
(define_peephole2 ; ashlqi3_l_const6
1664
  [(set (match_operand:QI 0 "l_register_operand" "")
1665
        (ashift:QI (match_dup 0)
1666
                   (const_int 6)))
1667
   (match_scratch:QI 1 "d")]
1668
  ""
1669
  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1670
   (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
1671
   (set (match_dup 1) (const_int -64))
1672
   (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1673
  "")
1674
 
1675
(define_peephole2
1676
  [(match_scratch:QI 3 "d")
1677
   (set (match_operand:HI 0 "register_operand" "")
1678
        (ashift:HI (match_operand:HI 1 "register_operand" "")
1679
                   (match_operand:QI 2 "const_int_operand" "")))]
1680
  ""
1681
  [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
1682
              (clobber (match_dup 3))])]
1683
  "")
1684
 
1685
(define_insn "*ashlhi3_const"
1686
  [(set (match_operand:HI 0 "register_operand"            "=r,r,r,r,r")
1687
        (ashift:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1688
                   (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1689
   (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1690
  "reload_completed"
1691
  "* return ashlhi3_out (insn, operands, NULL);"
1692
  [(set_attr "length" "0,2,2,4,10")
1693
   (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
1694
 
1695
(define_peephole2
1696
  [(match_scratch:QI 3 "d")
1697
   (set (match_operand:SI 0 "register_operand" "")
1698
        (ashift:SI (match_operand:SI 1 "register_operand" "")
1699
                   (match_operand:QI 2 "const_int_operand" "")))]
1700
  ""
1701
  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1702
              (clobber (match_dup 3))])]
1703
  "")
1704
 
1705
(define_insn "*ashlsi3_const"
1706
  [(set (match_operand:SI 0 "register_operand"            "=r,r,r,r")
1707
        (ashift:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1708
                   (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1709
   (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1710
  "reload_completed"
1711
  "* return ashlsi3_out (insn, operands, NULL);"
1712
  [(set_attr "length" "0,4,4,10")
1713
   (set_attr "cc" "none,set_n,clobber,clobber")])
1714
 
1715
;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1716
;; arithmetic shift right
1717
 
1718
(define_insn "ashrqi3"
1719
  [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
1720
        (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
1721
                     (match_operand:QI 2 "general_operand"  "r,L,P,K,n,Qm")))]
1722
  ""
1723
  "* return ashrqi3_out (insn, operands, NULL);"
1724
  [(set_attr "length" "5,0,1,2,5,9")
1725
   (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")])
1726
 
1727
(define_insn "ashrhi3"
1728
  [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
1729
        (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1730
                     (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1731
  ""
1732
  "* return ashrhi3_out (insn, operands, NULL);"
1733
  [(set_attr "length" "6,0,2,4,4,10,10")
1734
   (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1735
 
1736
(define_insn "ashrsi3"
1737
  [(set (match_operand:SI 0 "register_operand"             "=r,r,r,r,r,r,r")
1738
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1739
                     (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1740
  ""
1741
  "* return ashrsi3_out (insn, operands, NULL);"
1742
  [(set_attr "length" "8,0,4,6,8,10,12")
1743
   (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1744
 
1745
;; Optimize if a scratch register from LD_REGS happens to be available.
1746
 
1747
(define_peephole2
1748
  [(match_scratch:QI 3 "d")
1749
   (set (match_operand:HI 0 "register_operand" "")
1750
        (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
1751
                     (match_operand:QI 2 "const_int_operand" "")))]
1752
  ""
1753
  [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
1754
              (clobber (match_dup 3))])]
1755
  "")
1756
 
1757
(define_insn "*ashrhi3_const"
1758
  [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
1759
        (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1760
                     (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1761
   (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1762
  "reload_completed"
1763
  "* return ashrhi3_out (insn, operands, NULL);"
1764
  [(set_attr "length" "0,2,4,4,10")
1765
   (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
1766
 
1767
(define_peephole2
1768
  [(match_scratch:QI 3 "d")
1769
   (set (match_operand:SI 0 "register_operand" "")
1770
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1771
                     (match_operand:QI 2 "const_int_operand" "")))]
1772
  ""
1773
  [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
1774
              (clobber (match_dup 3))])]
1775
  "")
1776
 
1777
(define_insn "*ashrsi3_const"
1778
  [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
1779
        (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1780
                     (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1781
   (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1782
  "reload_completed"
1783
  "* return ashrsi3_out (insn, operands, NULL);"
1784
  [(set_attr "length" "0,4,4,10")
1785
   (set_attr "cc" "none,clobber,set_n,clobber")])
1786
 
1787
;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1788
;; logical shift right
1789
 
1790
(define_expand "lshrqi3"
1791
  [(set (match_operand:QI 0 "register_operand"              "")
1792
        (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
1793
                     (match_operand:QI 2 "general_operand"  "")))]
1794
  ""
1795
  "")
1796
 
1797
(define_split   ; lshrqi3_const4
1798
  [(set (match_operand:QI 0 "d_register_operand" "")
1799
        (lshiftrt:QI (match_dup 0)
1800
                     (const_int 4)))]
1801
  ""
1802
  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1803
   (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
1804
  "")
1805
 
1806
(define_split   ; lshrqi3_const5
1807
  [(set (match_operand:QI 0 "d_register_operand" "")
1808
        (lshiftrt:QI (match_dup 0)
1809
                     (const_int 5)))]
1810
  ""
1811
  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1812
   (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
1813
   (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
1814
  "")
1815
 
1816
(define_split   ; lshrqi3_const6
1817
  [(set (match_operand:QI 0 "d_register_operand" "")
1818
        (lshiftrt:QI (match_dup 0)
1819
                     (const_int 6)))]
1820
  ""
1821
  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1822
   (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
1823
   (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
1824
  "")
1825
 
1826
(define_insn "*lshrqi3"
1827
  [(set (match_operand:QI 0 "register_operand"             "=r,r,r,r,!d,r,r")
1828
        (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1829
                     (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
1830
  ""
1831
  "* return lshrqi3_out (insn, operands, NULL);"
1832
  [(set_attr "length" "5,0,1,2,4,6,9")
1833
   (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1834
 
1835
(define_insn "lshrhi3"
1836
  [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
1837
        (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1838
                     (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1839
  ""
1840
  "* return lshrhi3_out (insn, operands, NULL);"
1841
  [(set_attr "length" "6,0,2,2,4,10,10")
1842
   (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1843
 
1844
(define_insn "lshrsi3"
1845
  [(set (match_operand:SI 0 "register_operand"             "=r,r,r,r,r,r,r")
1846
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1847
                     (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1848
  ""
1849
  "* return lshrsi3_out (insn, operands, NULL);"
1850
  [(set_attr "length" "8,0,4,4,8,10,12")
1851
   (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1852
 
1853
;; Optimize if a scratch register from LD_REGS happens to be available.
1854
 
1855
(define_peephole2 ; lshrqi3_l_const4
1856
  [(set (match_operand:QI 0 "l_register_operand" "")
1857
        (lshiftrt:QI (match_dup 0)
1858
                     (const_int 4)))
1859
   (match_scratch:QI 1 "d")]
1860
  ""
1861
  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1862
   (set (match_dup 1) (const_int 15))
1863
   (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1864
  "")
1865
 
1866
(define_peephole2 ; lshrqi3_l_const5
1867
  [(set (match_operand:QI 0 "l_register_operand" "")
1868
        (lshiftrt:QI (match_dup 0)
1869
                     (const_int 5)))
1870
   (match_scratch:QI 1 "d")]
1871
  ""
1872
  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1873
   (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
1874
   (set (match_dup 1) (const_int 7))
1875
   (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1876
  "")
1877
 
1878
(define_peephole2 ; lshrqi3_l_const6
1879
  [(set (match_operand:QI 0 "l_register_operand" "")
1880
        (lshiftrt:QI (match_dup 0)
1881
                     (const_int 6)))
1882
   (match_scratch:QI 1 "d")]
1883
  ""
1884
  [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1885
   (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
1886
   (set (match_dup 1) (const_int 3))
1887
   (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1888
  "")
1889
 
1890
(define_peephole2
1891
  [(match_scratch:QI 3 "d")
1892
   (set (match_operand:HI 0 "register_operand" "")
1893
        (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
1894
                     (match_operand:QI 2 "const_int_operand" "")))]
1895
  ""
1896
  [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
1897
              (clobber (match_dup 3))])]
1898
  "")
1899
 
1900
(define_insn "*lshrhi3_const"
1901
  [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
1902
        (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1903
                     (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1904
   (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1905
  "reload_completed"
1906
  "* return lshrhi3_out (insn, operands, NULL);"
1907
  [(set_attr "length" "0,2,2,4,10")
1908
   (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
1909
 
1910
(define_peephole2
1911
  [(match_scratch:QI 3 "d")
1912
   (set (match_operand:SI 0 "register_operand" "")
1913
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1914
                     (match_operand:QI 2 "const_int_operand" "")))]
1915
  ""
1916
  [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
1917
              (clobber (match_dup 3))])]
1918
  "")
1919
 
1920
(define_insn "*lshrsi3_const"
1921
  [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
1922
        (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1923
                     (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1924
   (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1925
  "reload_completed"
1926
  "* return lshrsi3_out (insn, operands, NULL);"
1927
  [(set_attr "length" "0,4,4,10")
1928
   (set_attr "cc" "none,clobber,clobber,clobber")])
1929
 
1930
;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
1931
;; abs
1932
 
1933
(define_insn "absqi2"
1934
  [(set (match_operand:QI 0 "register_operand" "=r")
1935
        (abs:QI (match_operand:QI 1 "register_operand" "0")))]
1936
  ""
1937
  "sbrc %0,7
1938
        neg %0"
1939
  [(set_attr "length" "2")
1940
   (set_attr "cc" "clobber")])
1941
 
1942
 
1943
(define_insn "abssf2"
1944
  [(set (match_operand:SF 0 "register_operand" "=d,r")
1945
        (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
1946
  ""
1947
  "@
1948
        andi %D0,0x7f
1949
        clt\;bld %D0,7"
1950
  [(set_attr "length" "1,2")
1951
   (set_attr "cc" "set_n,clobber")])
1952
 
1953
;; 0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x
1954
;; neg
1955
 
1956
(define_insn "negqi2"
1957
  [(set (match_operand:QI 0 "register_operand" "=r")
1958
        (neg:QI (match_operand:QI 1 "register_operand" "0")))]
1959
  ""
1960
  "neg %0"
1961
  [(set_attr "length" "1")
1962
   (set_attr "cc" "set_zn")])
1963
 
1964
(define_insn "neghi2"
1965
  [(set (match_operand:HI 0 "register_operand"       "=!d,r,&r")
1966
        (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
1967
  ""
1968
  "@
1969
        com %B0\;neg %A0\;sbci %B0,lo8(-1)
1970
        com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
1971
        clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
1972
  [(set_attr "length" "3,4,4")
1973
   (set_attr "cc" "set_czn,set_n,set_czn")])
1974
 
1975
(define_insn "negsi2"
1976
  [(set (match_operand:SI 0 "register_operand"       "=!d,r,&r")
1977
        (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
1978
  ""
1979
  "@
1980
        com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
1981
        com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
1982
        clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
1983
  [(set_attr_alternative "length"
1984
                         [(const_int 7)
1985
                          (const_int 8)
1986
                          (if_then_else (eq_attr "mcu_have_movw" "yes")
1987
                                        (const_int 7)
1988
                                        (const_int 8))])
1989
   (set_attr "cc" "set_czn,set_n,set_czn")])
1990
 
1991
(define_insn "negsf2"
1992
  [(set (match_operand:SF 0 "register_operand" "=d,r")
1993
        (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
1994
  ""
1995
  "@
1996
        subi %D0,0x80
1997
        bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
1998
  [(set_attr "length" "1,4")
1999
   (set_attr "cc" "set_n,set_n")])
2000
 
2001
;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2002
;; not
2003
 
2004
(define_insn "one_cmplqi2"
2005
  [(set (match_operand:QI 0 "register_operand" "=r")
2006
        (not:QI (match_operand:QI 1 "register_operand" "0")))]
2007
  ""
2008
  "com %0"
2009
  [(set_attr "length" "1")
2010
   (set_attr "cc" "set_czn")])
2011
 
2012
(define_insn "one_cmplhi2"
2013
  [(set (match_operand:HI 0 "register_operand" "=r")
2014
        (not:HI (match_operand:HI 1 "register_operand" "0")))]
2015
  ""
2016
  "com %0
2017
        com %B0"
2018
  [(set_attr "length" "2")
2019
   (set_attr "cc" "set_n")])
2020
 
2021
(define_insn "one_cmplsi2"
2022
  [(set (match_operand:SI 0 "register_operand" "=r")
2023
        (not:SI (match_operand:SI 1 "register_operand" "0")))]
2024
  ""
2025
  "com %0
2026
        com %B0
2027
        com %C0
2028
        com %D0"
2029
  [(set_attr "length" "4")
2030
   (set_attr "cc" "set_n")])
2031
 
2032
;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2033
;; sign extend
2034
 
2035
(define_insn "extendqihi2"
2036
  [(set (match_operand:HI 0 "register_operand" "=r,r")
2037
        (sign_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
2038
  ""
2039
  "@
2040
        clr %B0\;sbrc %0,7\;com %B0
2041
        mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
2042
  [(set_attr "length" "3,4")
2043
   (set_attr "cc" "set_n,set_n")])
2044
 
2045
(define_insn "extendqisi2"
2046
  [(set (match_operand:SI 0 "register_operand" "=r,r")
2047
        (sign_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
2048
  ""
2049
  "@
2050
        clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
2051
        mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
2052
  [(set_attr "length" "5,6")
2053
   (set_attr "cc" "set_n,set_n")])
2054
 
2055
(define_insn "extendhisi2"
2056
  [(set (match_operand:SI 0 "register_operand"               "=r,&r")
2057
        (sign_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
2058
  ""
2059
  "@
2060
        clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
2061
        {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
2062
  [(set_attr_alternative "length"
2063
                         [(const_int 4)
2064
                          (if_then_else (eq_attr "mcu_have_movw" "yes")
2065
                                        (const_int 5)
2066
                                        (const_int 6))])
2067
   (set_attr "cc" "set_n,set_n")])
2068
 
2069
;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2070
;; zero extend
2071
 
2072
(define_insn_and_split "zero_extendqihi2"
2073
  [(set (match_operand:HI 0 "register_operand" "=r")
2074
        (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
2075
  ""
2076
  "#"
2077
  "reload_completed"
2078
  [(set (match_dup 2) (match_dup 1))
2079
   (set (match_dup 3) (const_int 0))]
2080
  "unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
2081
   unsigned int high_off = subreg_highpart_offset (QImode, HImode);
2082
 
2083
   operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
2084
   operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
2085
  ")
2086
 
2087
(define_insn_and_split "zero_extendqisi2"
2088
  [(set (match_operand:SI 0 "register_operand" "=r")
2089
        (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2090
  ""
2091
  "#"
2092
  "reload_completed"
2093
  [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
2094
   (set (match_dup 3) (const_int 0))]
2095
  "unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2096
   unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2097
 
2098
   operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2099
   operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2100
  ")
2101
 
2102
(define_insn_and_split "zero_extendhisi2"
2103
  [(set (match_operand:SI 0 "register_operand" "=r")
2104
        (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2105
  ""
2106
  "#"
2107
  "reload_completed"
2108
  [(set (match_dup 2) (match_dup 1))
2109
   (set (match_dup 3) (const_int 0))]
2110
  "unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2111
   unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2112
 
2113
   operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2114
   operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2115
  ")
2116
 
2117
(define_insn_and_split "zero_extendqidi2"
2118
  [(set (match_operand:DI 0 "register_operand" "=r")
2119
        (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
2120
  ""
2121
  "#"
2122
  "reload_completed"
2123
  [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2124
   (set (match_dup 3) (const_int 0))]
2125
  "unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2126
   unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2127
 
2128
   operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2129
   operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2130
  ")
2131
 
2132
(define_insn_and_split "zero_extendhidi2"
2133
  [(set (match_operand:DI 0 "register_operand" "=r")
2134
        (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
2135
  ""
2136
  "#"
2137
  "reload_completed"
2138
  [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2139
   (set (match_dup 3) (const_int 0))]
2140
  "unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2141
   unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2142
 
2143
   operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2144
   operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2145
  ")
2146
 
2147
(define_insn_and_split "zero_extendsidi2"
2148
  [(set (match_operand:DI 0 "register_operand" "=r")
2149
        (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2150
  ""
2151
  "#"
2152
  "reload_completed"
2153
  [(set (match_dup 2) (match_dup 1))
2154
   (set (match_dup 3) (const_int 0))]
2155
  "unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2156
   unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2157
 
2158
   operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2159
   operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2160
  ")
2161
 
2162
;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
2163
;; compare
2164
 
2165
; Optimize negated tests into reverse compare if overflow is undefined.
2166
(define_insn "*negated_tstqi"
2167
  [(set (cc0)
2168
        (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
2169
                 (const_int 0)))]
2170
  "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2171
  "cp __zero_reg__,%0"
2172
  [(set_attr "cc" "compare")
2173
   (set_attr "length" "1")])
2174
 
2175
(define_insn "*reversed_tstqi"
2176
  [(set (cc0)
2177
        (compare (const_int 0)
2178
                 (match_operand:QI 0 "register_operand" "r")))]
2179
  ""
2180
  "cp __zero_reg__,%0"
2181
[(set_attr "cc" "compare")
2182
 (set_attr "length" "2")])
2183
 
2184
(define_insn "*negated_tsthi"
2185
  [(set (cc0)
2186
        (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
2187
                 (const_int 0)))]
2188
  "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2189
  "cp __zero_reg__,%A0
2190
        cpc __zero_reg__,%B0"
2191
[(set_attr "cc" "compare")
2192
 (set_attr "length" "2")])
2193
 
2194
;; Leave here the clobber used by the cmphi pattern for simplicity, even
2195
;; though it is unused, because this pattern is synthesized by avr_reorg.
2196
(define_insn "*reversed_tsthi"
2197
  [(set (cc0)
2198
        (compare (const_int 0)
2199
                 (match_operand:HI 0 "register_operand" "r")))
2200
   (clobber (match_scratch:QI 1 "=X"))]
2201
  ""
2202
  "cp __zero_reg__,%A0
2203
        cpc __zero_reg__,%B0"
2204
[(set_attr "cc" "compare")
2205
 (set_attr "length" "2")])
2206
 
2207
(define_insn "*negated_tstsi"
2208
  [(set (cc0)
2209
        (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
2210
                 (const_int 0)))]
2211
  "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2212
  "cp __zero_reg__,%A0
2213
        cpc __zero_reg__,%B0
2214
        cpc __zero_reg__,%C0
2215
        cpc __zero_reg__,%D0"
2216
  [(set_attr "cc" "compare")
2217
   (set_attr "length" "4")])
2218
 
2219
(define_insn "*reversed_tstsi"
2220
  [(set (cc0)
2221
        (compare (const_int 0)
2222
                 (match_operand:SI 0 "register_operand" "r")))
2223
   (clobber (match_scratch:QI 1 "=X"))]
2224
  ""
2225
  "cp __zero_reg__,%A0
2226
        cpc __zero_reg__,%B0
2227
        cpc __zero_reg__,%C0
2228
        cpc __zero_reg__,%D0"
2229
  [(set_attr "cc" "compare")
2230
   (set_attr "length" "4")])
2231
 
2232
 
2233
(define_insn "*cmpqi"
2234
  [(set (cc0)
2235
        (compare (match_operand:QI 0 "register_operand"  "r,r,d")
2236
                 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
2237
  ""
2238
  "@
2239
        tst %0
2240
        cp %0,%1
2241
        cpi %0,lo8(%1)"
2242
  [(set_attr "cc" "compare,compare,compare")
2243
   (set_attr "length" "1,1,1")])
2244
 
2245
(define_insn "*cmpqi_sign_extend"
2246
  [(set (cc0)
2247
        (compare (sign_extend:HI
2248
                  (match_operand:QI 0 "register_operand"  "d"))
2249
                 (match_operand:HI 1 "const_int_operand" "n")))]
2250
  "INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) <= 127"
2251
  "cpi %0,lo8(%1)"
2252
  [(set_attr "cc" "compare")
2253
   (set_attr "length" "1")])
2254
 
2255
(define_insn "*cmphi"
2256
  [(set (cc0)
2257
        (compare (match_operand:HI 0 "register_operand"  "!w,r,r,d,d,r,r")
2258
                 (match_operand:HI 1 "nonmemory_operand" "L,L,r,M,i,M,i")))
2259
   (clobber (match_scratch:QI 2 "=X,X,X,X,&d,&d,&d"))]
2260
  ""
2261
  "*{
2262
  switch (which_alternative)
2263
    {
2264
    case 0: case 1:
2265
      return out_tsthi (insn, operands[0], NULL);
2266
 
2267
    case 2:
2268
      return (AS2 (cp,%A0,%A1) CR_TAB
2269
              AS2 (cpc,%B0,%B1));
2270
    case 3:
2271
      if (reg_unused_after (insn, operands[0])
2272
          && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
2273
          && test_hard_reg_class (ADDW_REGS, operands[0]))
2274
        return AS2 (sbiw,%0,%1);
2275
       else
2276
        return (AS2 (cpi,%0,%1) CR_TAB
2277
                AS2 (cpc,%B0,__zero_reg__));
2278
    case 4:
2279
      if (reg_unused_after (insn, operands[0]))
2280
        return (AS2 (subi,%0,lo8(%1))  CR_TAB
2281
                AS2 (sbci,%B0,hi8(%1)));
2282
      else
2283
        return (AS2 (ldi, %2,hi8(%1))  CR_TAB
2284
                AS2 (cpi, %A0,lo8(%1)) CR_TAB
2285
                AS2 (cpc, %B0,%2));
2286
   case 5:
2287
      return (AS2 (ldi, %2,lo8(%1))  CR_TAB
2288
              AS2 (cp, %A0,%2) CR_TAB
2289
              AS2 (cpc, %B0,__zero_reg__));
2290
 
2291
   case 6:
2292
      return (AS2 (ldi, %2,lo8(%1))  CR_TAB
2293
              AS2 (cp, %A0,%2)       CR_TAB
2294
              AS2 (ldi, %2,hi8(%1)) CR_TAB
2295
              AS2 (cpc, %B0,%2));
2296
    }
2297
  return \"bug\";
2298
}"
2299
  [(set_attr "cc" "compare,compare,compare,compare,compare,compare,compare")
2300
   (set_attr "length" "1,2,2,2,3,3,4")])
2301
 
2302
 
2303
(define_insn "*cmpsi"
2304
  [(set (cc0)
2305
        (compare (match_operand:SI 0 "register_operand"  "r,r,d,d,r,r")
2306
                 (match_operand:SI 1 "nonmemory_operand" "L,r,M,i,M,i")))
2307
   (clobber (match_scratch:QI 2 "=X,X,X,&d,&d,&d"))]
2308
  ""
2309
  "*{
2310
  switch (which_alternative)
2311
    {
2312
    case 0:
2313
      return out_tstsi (insn, operands[0], NULL);
2314
 
2315
    case 1:
2316
      return (AS2 (cp,%A0,%A1) CR_TAB
2317
              AS2 (cpc,%B0,%B1) CR_TAB
2318
              AS2 (cpc,%C0,%C1) CR_TAB
2319
              AS2 (cpc,%D0,%D1));
2320
    case 2:
2321
      if (reg_unused_after (insn, operands[0])
2322
          && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
2323
          && test_hard_reg_class (ADDW_REGS, operands[0]))
2324
        return (AS2 (sbiw,%0,%1) CR_TAB
2325
                AS2 (cpc,%C0,__zero_reg__) CR_TAB
2326
                AS2 (cpc,%D0,__zero_reg__));
2327
      else
2328
        return (AS2 (cpi,%A0,lo8(%1))  CR_TAB
2329
                AS2 (cpc,%B0,__zero_reg__) CR_TAB
2330
                AS2 (cpc,%C0,__zero_reg__) CR_TAB
2331
                AS2 (cpc,%D0,__zero_reg__));
2332
    case 3:
2333
      if (reg_unused_after (insn, operands[0]))
2334
        return (AS2 (subi,%A0,lo8(%1))  CR_TAB
2335
                AS2 (sbci,%B0,hi8(%1))  CR_TAB
2336
                AS2 (sbci,%C0,hlo8(%1))  CR_TAB
2337
                AS2 (sbci,%D0,hhi8(%1)));
2338
      else
2339
       return (AS2 (cpi, %A0,lo8(%1))   CR_TAB
2340
               AS2 (ldi, %2,hi8(%1))  CR_TAB
2341
               AS2 (cpc, %B0,%2)       CR_TAB
2342
               AS2 (ldi, %2,hlo8(%1))  CR_TAB
2343
               AS2 (cpc, %C0,%2)       CR_TAB
2344
               AS2 (ldi, %2,hhi8(%1)) CR_TAB
2345
               AS2 (cpc, %D0,%2));
2346
    case 4:
2347
        return (AS2 (ldi,%2,lo8(%1))        CR_TAB
2348
                AS2 (cp,%A0,%2)            CR_TAB
2349
                AS2 (cpc,%B0,__zero_reg__) CR_TAB
2350
                AS2 (cpc,%C0,__zero_reg__) CR_TAB
2351
                AS2 (cpc,%D0,__zero_reg__));
2352
    case 5:
2353
       return (AS2 (ldi, %2,lo8(%1))   CR_TAB
2354
               AS2 (cp, %A0,%2)        CR_TAB
2355
               AS2 (ldi, %2,hi8(%1))  CR_TAB
2356
               AS2 (cpc, %B0,%2)       CR_TAB
2357
               AS2 (ldi, %2,hlo8(%1))  CR_TAB
2358
               AS2 (cpc, %C0,%2)       CR_TAB
2359
               AS2 (ldi, %2,hhi8(%1)) CR_TAB
2360
               AS2 (cpc, %D0,%2));
2361
    }
2362
  return \"bug\";
2363
}"
2364
  [(set_attr "cc" "compare,compare,compare,compare,compare,compare")
2365
   (set_attr "length" "4,4,4,7,5,8")])
2366
 
2367
 
2368
;; ----------------------------------------------------------------------
2369
;; JUMP INSTRUCTIONS
2370
;; ----------------------------------------------------------------------
2371
;; Conditional jump instructions
2372
 
2373
(define_expand "cbranchsi4"
2374
  [(parallel [(set (cc0)
2375
                   (compare (match_operand:SI 1 "register_operand" "")
2376
                            (match_operand:SI 2 "nonmemory_operand" "")))
2377
              (clobber (match_scratch:QI 4 ""))])
2378
   (set (pc)
2379
        (if_then_else
2380
              (match_operator 0 "ordered_comparison_operator" [(cc0)
2381
                                                               (const_int 0)])
2382
              (label_ref (match_operand 3 "" ""))
2383
              (pc)))]
2384
 "")
2385
 
2386
(define_expand "cbranchhi4"
2387
  [(parallel [(set (cc0)
2388
                   (compare (match_operand:HI 1 "register_operand" "")
2389
                            (match_operand:HI 2 "nonmemory_operand" "")))
2390
              (clobber (match_scratch:QI 4 ""))])
2391
   (set (pc)
2392
        (if_then_else
2393
              (match_operator 0 "ordered_comparison_operator" [(cc0)
2394
                                                               (const_int 0)])
2395
              (label_ref (match_operand 3 "" ""))
2396
              (pc)))]
2397
 "")
2398
 
2399
(define_expand "cbranchqi4"
2400
  [(set (cc0)
2401
        (compare (match_operand:QI 1 "register_operand" "")
2402
                 (match_operand:QI 2 "nonmemory_operand" "")))
2403
   (set (pc)
2404
        (if_then_else
2405
              (match_operator 0 "ordered_comparison_operator" [(cc0)
2406
                                                               (const_int 0)])
2407
              (label_ref (match_operand 3 "" ""))
2408
              (pc)))]
2409
 "")
2410
 
2411
 
2412
;; Test a single bit in a QI/HI/SImode register.
2413
;; Combine will create zero extract patterns for single bit tests.
2414
;; permit any mode in source pattern by using VOIDmode.
2415
 
2416
(define_insn "*sbrx_branch"
2417
  [(set (pc)
2418
        (if_then_else
2419
         (match_operator 0 "eqne_operator"
2420
                         [(zero_extract:QIDI
2421
                           (match_operand:VOID 1 "register_operand" "r")
2422
                           (const_int 1)
2423
                           (match_operand 2 "const_int_operand" "n"))
2424
                          (const_int 0)])
2425
         (label_ref (match_operand 3 "" ""))
2426
         (pc)))]
2427
  ""
2428
  "* return avr_out_sbxx_branch (insn, operands);"
2429
  [(set (attr "length")
2430
        (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2431
                           (le (minus (pc) (match_dup 3)) (const_int 2046)))
2432
                      (const_int 2)
2433
                      (if_then_else (eq_attr "mcu_mega" "no")
2434
                                    (const_int 2)
2435
                                    (const_int 4))))
2436
   (set_attr "cc" "clobber")])
2437
 
2438
;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
2439
;; or for old peepholes.
2440
;; Fixme - bitwise Mask will not work for DImode
2441
 
2442
(define_insn "*sbrx_and_branch"
2443
  [(set (pc)
2444
        (if_then_else
2445
         (match_operator 0 "eqne_operator"
2446
                         [(and:QISI
2447
                           (match_operand:QISI 1 "register_operand" "r")
2448
                           (match_operand:QISI 2 "single_one_operand" "n"))
2449
                          (const_int 0)])
2450
         (label_ref (match_operand 3 "" ""))
2451
         (pc)))]
2452
  ""
2453
{
2454
    HOST_WIDE_INT bitnumber;
2455
    bitnumber = exact_log2 (GET_MODE_MASK (mode) & INTVAL (operands[2]));
2456
    operands[2] = GEN_INT (bitnumber);
2457
    return avr_out_sbxx_branch (insn, operands);
2458
}
2459
  [(set (attr "length")
2460
        (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2461
                           (le (minus (pc) (match_dup 3)) (const_int 2046)))
2462
                      (const_int 2)
2463
                      (if_then_else (eq_attr "mcu_mega" "no")
2464
                                    (const_int 2)
2465
                                    (const_int 4))))
2466
   (set_attr "cc" "clobber")])
2467
 
2468
;; Convert sign tests to bit 7/15/31 tests that match the above insns.
2469
(define_peephole2
2470
  [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
2471
                       (const_int 0)))
2472
   (set (pc) (if_then_else (ge (cc0) (const_int 0))
2473
                           (label_ref (match_operand 1 "" ""))
2474
                           (pc)))]
2475
  ""
2476
  [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
2477
                                                (const_int 1)
2478
                                                (const_int 7))
2479
                               (const_int 0))
2480
                           (label_ref (match_dup 1))
2481
                           (pc)))]
2482
  "")
2483
 
2484
(define_peephole2
2485
  [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
2486
                       (const_int 0)))
2487
   (set (pc) (if_then_else (lt (cc0) (const_int 0))
2488
                           (label_ref (match_operand 1 "" ""))
2489
                           (pc)))]
2490
  ""
2491
  [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
2492
                                                (const_int 1)
2493
                                                (const_int 7))
2494
                               (const_int 0))
2495
                           (label_ref (match_dup 1))
2496
                           (pc)))]
2497
  "")
2498
 
2499
(define_peephole2
2500
  [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
2501
                                  (const_int 0)))
2502
              (clobber (match_operand:HI 2 ""))])
2503
   (set (pc) (if_then_else (ge (cc0) (const_int 0))
2504
                           (label_ref (match_operand 1 "" ""))
2505
                           (pc)))]
2506
  ""
2507
  [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
2508
                               (const_int 0))
2509
                           (label_ref (match_dup 1))
2510
                           (pc)))]
2511
  "")
2512
 
2513
(define_peephole2
2514
  [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
2515
                                  (const_int 0)))
2516
              (clobber (match_operand:HI 2 ""))])
2517
   (set (pc) (if_then_else (lt (cc0) (const_int 0))
2518
                           (label_ref (match_operand 1 "" ""))
2519
                           (pc)))]
2520
  ""
2521
  [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
2522
                               (const_int 0))
2523
                           (label_ref (match_dup 1))
2524
                           (pc)))]
2525
  "")
2526
 
2527
(define_peephole2
2528
  [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
2529
                                  (const_int 0)))
2530
              (clobber (match_operand:SI 2 ""))])
2531
   (set (pc) (if_then_else (ge (cc0) (const_int 0))
2532
                           (label_ref (match_operand 1 "" ""))
2533
                           (pc)))]
2534
  ""
2535
  [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
2536
                               (const_int 0))
2537
                           (label_ref (match_dup 1))
2538
                           (pc)))]
2539
  "operands[2] = GEN_INT (-2147483647 - 1);")
2540
 
2541
(define_peephole2
2542
  [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
2543
                                  (const_int 0)))
2544
              (clobber (match_operand:SI 2 ""))])
2545
   (set (pc) (if_then_else (lt (cc0) (const_int 0))
2546
                           (label_ref (match_operand 1 "" ""))
2547
                           (pc)))]
2548
  ""
2549
  [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
2550
                               (const_int 0))
2551
                           (label_ref (match_dup 1))
2552
                           (pc)))]
2553
  "operands[2] = GEN_INT (-2147483647 - 1);")
2554
 
2555
;; ************************************************************************
2556
;; Implementation of conditional jumps here.
2557
;;  Compare with 0 (test) jumps
2558
;; ************************************************************************
2559
 
2560
(define_insn "branch"
2561
  [(set (pc)
2562
        (if_then_else (match_operator 1 "simple_comparison_operator"
2563
                        [(cc0)
2564
                         (const_int 0)])
2565
                      (label_ref (match_operand 0 "" ""))
2566
                      (pc)))]
2567
  ""
2568
  "*
2569
   return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2570
  [(set_attr "type" "branch")
2571
   (set_attr "cc" "clobber")])
2572
 
2573
;; ****************************************************************
2574
;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
2575
;; Convert them all to proper jumps.
2576
;; ****************************************************************/
2577
 
2578
(define_insn "difficult_branch"
2579
  [(set (pc)
2580
        (if_then_else (match_operator 1 "difficult_comparison_operator"
2581
                        [(cc0)
2582
                         (const_int 0)])
2583
                      (label_ref (match_operand 0 "" ""))
2584
                      (pc)))]
2585
  ""
2586
  "*
2587
   return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2588
  [(set_attr "type" "branch1")
2589
   (set_attr "cc" "clobber")])
2590
 
2591
;; revers branch
2592
 
2593
(define_insn "rvbranch"
2594
  [(set (pc)
2595
        (if_then_else (match_operator 1 "simple_comparison_operator"
2596
                        [(cc0)
2597
                         (const_int 0)])
2598
                      (pc)
2599
                      (label_ref (match_operand 0 "" ""))))]
2600
  ""
2601
  "*
2602
   return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2603
  [(set_attr "type" "branch1")
2604
   (set_attr "cc" "clobber")])
2605
 
2606
(define_insn "difficult_rvbranch"
2607
  [(set (pc)
2608
        (if_then_else (match_operator 1 "difficult_comparison_operator"
2609
                        [(cc0)
2610
                         (const_int 0)])
2611
                      (pc)
2612
                      (label_ref (match_operand 0 "" ""))))]
2613
  ""
2614
  "*
2615
   return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2616
  [(set_attr "type" "branch")
2617
   (set_attr "cc" "clobber")])
2618
 
2619
;; **************************************************************************
2620
;; Unconditional and other jump instructions.
2621
 
2622
(define_insn "jump"
2623
  [(set (pc)
2624
        (label_ref (match_operand 0 "" "")))]
2625
  ""
2626
  "*{
2627
  if (AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1)
2628
    return AS1 (jmp,%x0);
2629
  return AS1 (rjmp,%x0);
2630
}"
2631
  [(set (attr "length")
2632
        (if_then_else (match_operand 0 "symbol_ref_operand" "")
2633
                (if_then_else (eq_attr "mcu_mega" "no")
2634
                              (const_int 1)
2635
                              (const_int 2))
2636
                (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
2637
                                   (le (minus (pc) (match_dup 0)) (const_int 2047)))
2638
                              (const_int 1)
2639
                              (const_int 2))))
2640
   (set_attr "cc" "none")])
2641
 
2642
;; call
2643
 
2644
(define_expand "call"
2645
  [(call (match_operand:HI 0 "call_insn_operand" "")
2646
         (match_operand:HI 1 "general_operand" ""))]
2647
  ;; Operand 1 not used on the AVR.
2648
  ""
2649
  "")
2650
 
2651
;; call value
2652
 
2653
(define_expand "call_value"
2654
  [(set (match_operand 0 "register_operand" "")
2655
        (call (match_operand:HI 1 "call_insn_operand" "")
2656
              (match_operand:HI 2 "general_operand" "")))]
2657
  ;; Operand 2 not used on the AVR.
2658
  ""
2659
  "")
2660
 
2661
(define_insn "call_insn"
2662
  [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "!z,*r,s,n"))
2663
         (match_operand:HI 1 "general_operand" "X,X,X,X"))]
2664
;; We don't need in saving Z register because r30,r31 is a call used registers
2665
  ;; Operand 1 not used on the AVR.
2666
  "(register_operand (operands[0], HImode) || CONSTANT_P (operands[0]))"
2667
  "*{
2668
  if (which_alternative==0)
2669
     return \"%!icall\";
2670
  else if (which_alternative==1)
2671
    {
2672
      if (AVR_HAVE_MOVW)
2673
        return (AS2 (movw, r30, %0) CR_TAB
2674
               \"%!icall\");
2675
      else
2676
        return (AS2 (mov, r30, %A0) CR_TAB
2677
                AS2 (mov, r31, %B0) CR_TAB
2678
                \"%!icall\");
2679
    }
2680
  else if (which_alternative==2)
2681
    return AS1(%~call,%x0);
2682
  return (AS2 (ldi,r30,lo8(%0)) CR_TAB
2683
          AS2 (ldi,r31,hi8(%0)) CR_TAB
2684
          \"%!icall\");
2685
}"
2686
  [(set_attr "cc" "clobber,clobber,clobber,clobber")
2687
   (set_attr_alternative "length"
2688
                         [(const_int 1)
2689
                          (if_then_else (eq_attr "mcu_have_movw" "yes")
2690
                                        (const_int 2)
2691
                                        (const_int 3))
2692
                          (if_then_else (eq_attr "mcu_mega" "yes")
2693
                                        (const_int 2)
2694
                                        (const_int 1))
2695
                          (const_int 3)])])
2696
 
2697
(define_insn "call_value_insn"
2698
  [(set (match_operand 0 "register_operand" "=r,r,r,r")
2699
        (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "!z,*r,s,n"))
2700
;; We don't need in saving Z register because r30,r31 is a call used registers
2701
              (match_operand:HI 2 "general_operand" "X,X,X,X")))]
2702
  ;; Operand 2 not used on the AVR.
2703
  "(register_operand (operands[0], VOIDmode) || CONSTANT_P (operands[0]))"
2704
  "*{
2705
  if (which_alternative==0)
2706
     return \"%!icall\";
2707
  else if (which_alternative==1)
2708
    {
2709
      if (AVR_HAVE_MOVW)
2710
        return (AS2 (movw, r30, %1) CR_TAB
2711
                \"%!icall\");
2712
      else
2713
        return (AS2 (mov, r30, %A1) CR_TAB
2714
                AS2 (mov, r31, %B1) CR_TAB
2715
                \"%!icall\");
2716
    }
2717
  else if (which_alternative==2)
2718
    return AS1(%~call,%x1);
2719
  return (AS2 (ldi, r30, lo8(%1)) CR_TAB
2720
          AS2 (ldi, r31, hi8(%1)) CR_TAB
2721
          \"%!icall\");
2722
}"
2723
  [(set_attr "cc" "clobber,clobber,clobber,clobber")
2724
   (set_attr_alternative "length"
2725
                         [(const_int 1)
2726
                          (if_then_else (eq_attr "mcu_have_movw" "yes")
2727
                                        (const_int 2)
2728
                                        (const_int 3))
2729
                          (if_then_else (eq_attr "mcu_mega" "yes")
2730
                                        (const_int 2)
2731
                                        (const_int 1))
2732
                          (const_int 3)])])
2733
 
2734
(define_insn "nop"
2735
  [(const_int 0)]
2736
  ""
2737
  "nop"
2738
  [(set_attr "cc" "none")
2739
   (set_attr "length" "1")])
2740
 
2741
; indirect jump
2742
 
2743
(define_expand "indirect_jump"
2744
  [(set (pc) (match_operand:HI 0 "nonmemory_operand" ""))]
2745
  ""
2746
  " if ((!AVR_HAVE_JMP_CALL) && !register_operand(operand0, HImode))
2747
    {
2748
      operands[0] = copy_to_mode_reg(HImode, operand0);
2749
    }"
2750
)
2751
 
2752
; indirect jump
2753
(define_insn "*jcindirect_jump"
2754
  [(set (pc) (match_operand:HI 0 "immediate_operand" "i"))]
2755
  ""
2756
  "@
2757
        %~jmp %x0"
2758
  [(set_attr "length" "2")
2759
   (set_attr "cc" "none")])
2760
 
2761
;;
2762
(define_insn "*njcindirect_jump"
2763
  [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
2764
  "!AVR_HAVE_EIJMP_EICALL"
2765
  "@
2766
        ijmp
2767
        push %A0\;push %B0\;ret"
2768
  [(set_attr "length" "1,3")
2769
   (set_attr "cc" "none,none")])
2770
 
2771
(define_insn "*indirect_jump_avr6"
2772
  [(set (pc) (match_operand:HI 0 "register_operand" "z"))]
2773
  "AVR_HAVE_EIJMP_EICALL"
2774
  "eijmp"
2775
  [(set_attr "length" "1")
2776
   (set_attr "cc" "none")])
2777
 
2778
;; table jump
2779
 
2780
;; Table made from "rjmp" instructions for <=8K devices.
2781
(define_insn "*tablejump_rjmp"
2782
  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
2783
                        UNSPEC_INDEX_JMP))
2784
   (use (label_ref (match_operand 1 "" "")))
2785
   (clobber (match_dup 0))]
2786
  "(!AVR_HAVE_JMP_CALL) && (!AVR_HAVE_EIJMP_EICALL)"
2787
  "@
2788
        ijmp
2789
        push %A0\;push %B0\;ret"
2790
  [(set_attr "length" "1,3")
2791
   (set_attr "cc" "none,none")])
2792
 
2793
;; Not a prologue, but similar idea - move the common piece of code to libgcc.
2794
(define_insn "*tablejump_lib"
2795
  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2796
                        UNSPEC_INDEX_JMP))
2797
   (use (label_ref (match_operand 1 "" "")))
2798
   (clobber (match_dup 0))]
2799
  "AVR_HAVE_JMP_CALL && TARGET_CALL_PROLOGUES"
2800
  "%~jmp __tablejump2__"
2801
  [(set_attr "length" "2")
2802
   (set_attr "cc" "clobber")])
2803
 
2804
(define_insn "*tablejump_enh"
2805
  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2806
                        UNSPEC_INDEX_JMP))
2807
   (use (label_ref (match_operand 1 "" "")))
2808
   (clobber (match_dup 0))]
2809
  "AVR_HAVE_JMP_CALL && AVR_HAVE_LPMX"
2810
  "lsl r30
2811
        rol r31
2812
        lpm __tmp_reg__,Z+
2813
        lpm r31,Z
2814
        mov r30,__tmp_reg__
2815
        %!ijmp"
2816
  [(set_attr "length" "6")
2817
   (set_attr "cc" "clobber")])
2818
 
2819
(define_insn "*tablejump"
2820
  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2821
                        UNSPEC_INDEX_JMP))
2822
   (use (label_ref (match_operand 1 "" "")))
2823
   (clobber (match_dup 0))]
2824
  "AVR_HAVE_JMP_CALL && !AVR_HAVE_EIJMP_EICALL"
2825
  "lsl r30
2826
        rol r31
2827
        lpm
2828
        inc r30
2829
        push r0
2830
        lpm
2831
        push r0
2832
        ret"
2833
  [(set_attr "length" "8")
2834
   (set_attr "cc" "clobber")])
2835
 
2836
(define_expand "casesi"
2837
  [(set (match_dup 6)
2838
        (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
2839
                  (match_operand:HI 1 "register_operand" "")))
2840
   (parallel [(set (cc0)
2841
                   (compare (match_dup 6)
2842
                            (match_operand:HI 2 "register_operand" "")))
2843
              (clobber (match_scratch:QI 9 ""))])
2844
 
2845
   (set (pc)
2846
        (if_then_else (gtu (cc0)
2847
                           (const_int 0))
2848
                      (label_ref (match_operand 4 "" ""))
2849
                      (pc)))
2850
 
2851
   (set (match_dup 6)
2852
        (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
2853
 
2854
   (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
2855
              (use (label_ref (match_dup 3)))
2856
              (clobber (match_dup 6))])]
2857
  ""
2858
  "
2859
{
2860
  operands[6] = gen_reg_rtx (HImode);
2861
}")
2862
 
2863
 
2864
;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2865
;; This instruction sets Z flag
2866
 
2867
(define_insn "sez"
2868
  [(set (cc0) (const_int 0))]
2869
  ""
2870
  "sez"
2871
  [(set_attr "length" "1")
2872
   (set_attr "cc" "compare")])
2873
 
2874
;; Clear/set/test a single bit in I/O address space.
2875
 
2876
(define_insn "*cbi"
2877
  [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2878
        (and:QI (mem:QI (match_dup 0))
2879
                (match_operand:QI 1 "single_zero_operand" "n")))]
2880
  "(optimize > 0)"
2881
{
2882
  operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
2883
  return AS2 (cbi,%m0-0x20,%2);
2884
}
2885
  [(set_attr "length" "1")
2886
   (set_attr "cc" "none")])
2887
 
2888
(define_insn "*sbi"
2889
  [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2890
        (ior:QI (mem:QI (match_dup 0))
2891
                (match_operand:QI 1 "single_one_operand" "n")))]
2892
  "(optimize > 0)"
2893
{
2894
  operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
2895
  return AS2 (sbi,%m0-0x20,%2);
2896
}
2897
  [(set_attr "length" "1")
2898
   (set_attr "cc" "none")])
2899
 
2900
;; Lower half of the I/O space - use sbic/sbis directly.
2901
(define_insn "*sbix_branch"
2902
  [(set (pc)
2903
        (if_then_else
2904
         (match_operator 0 "eqne_operator"
2905
                         [(zero_extract:HI
2906
                           (mem:QI (match_operand 1 "low_io_address_operand" "n"))
2907
                           (const_int 1)
2908
                           (match_operand 2 "const_int_operand" "n"))
2909
                          (const_int 0)])
2910
         (label_ref (match_operand 3 "" ""))
2911
         (pc)))]
2912
  "(optimize > 0)"
2913
  "* return avr_out_sbxx_branch (insn, operands);"
2914
  [(set (attr "length")
2915
        (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2916
                           (le (minus (pc) (match_dup 3)) (const_int 2046)))
2917
                      (const_int 2)
2918
                      (if_then_else (eq_attr "mcu_mega" "no")
2919
                                    (const_int 2)
2920
                                    (const_int 4))))
2921
   (set_attr "cc" "clobber")])
2922
 
2923
;; Tests of bit 7 are pessimized to sign tests, so we need this too...
2924
(define_insn "*sbix_branch_bit7"
2925
  [(set (pc)
2926
        (if_then_else
2927
         (match_operator 0 "gelt_operator"
2928
                         [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
2929
                          (const_int 0)])
2930
         (label_ref (match_operand 2 "" ""))
2931
         (pc)))]
2932
  "(optimize > 0)"
2933
{
2934
  operands[3] = operands[2];
2935
  operands[2] = GEN_INT (7);
2936
  return avr_out_sbxx_branch (insn, operands);
2937
}
2938
  [(set (attr "length")
2939
        (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2940
                           (le (minus (pc) (match_dup 2)) (const_int 2046)))
2941
                      (const_int 2)
2942
                      (if_then_else (eq_attr "mcu_mega" "no")
2943
                                    (const_int 2)
2944
                                    (const_int 4))))
2945
   (set_attr "cc" "clobber")])
2946
 
2947
;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
2948
(define_insn "*sbix_branch_tmp"
2949
  [(set (pc)
2950
        (if_then_else
2951
         (match_operator 0 "eqne_operator"
2952
                         [(zero_extract:HI
2953
                           (mem:QI (match_operand 1 "high_io_address_operand" "n"))
2954
                           (const_int 1)
2955
                           (match_operand 2 "const_int_operand" "n"))
2956
                          (const_int 0)])
2957
         (label_ref (match_operand 3 "" ""))
2958
         (pc)))]
2959
  "(optimize > 0)"
2960
  "* return avr_out_sbxx_branch (insn, operands);"
2961
  [(set (attr "length")
2962
        (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2963
                           (le (minus (pc) (match_dup 3)) (const_int 2045)))
2964
                      (const_int 3)
2965
                      (if_then_else (eq_attr "mcu_mega" "no")
2966
                                    (const_int 3)
2967
                                    (const_int 5))))
2968
   (set_attr "cc" "clobber")])
2969
 
2970
(define_insn "*sbix_branch_tmp_bit7"
2971
  [(set (pc)
2972
        (if_then_else
2973
         (match_operator 0 "gelt_operator"
2974
                         [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
2975
                          (const_int 0)])
2976
         (label_ref (match_operand 2 "" ""))
2977
         (pc)))]
2978
  "(optimize > 0)"
2979
{
2980
  operands[3] = operands[2];
2981
  operands[2] = GEN_INT (7);
2982
  return avr_out_sbxx_branch (insn, operands);
2983
}
2984
  [(set (attr "length")
2985
        (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2986
                           (le (minus (pc) (match_dup 2)) (const_int 2045)))
2987
                      (const_int 3)
2988
                      (if_then_else (eq_attr "mcu_mega" "no")
2989
                                    (const_int 3)
2990
                                    (const_int 5))))
2991
   (set_attr "cc" "clobber")])
2992
 
2993
;; ************************* Peepholes ********************************
2994
 
2995
(define_peephole
2996
  [(set (match_operand:SI 0 "d_register_operand" "")
2997
        (plus:SI (match_dup 0)
2998
                 (const_int -1)))
2999
   (parallel
3000
    [(set (cc0)
3001
          (compare (match_dup 0)
3002
                   (const_int -1)))
3003
     (clobber (match_operand:QI 1 "d_register_operand" ""))])
3004
   (set (pc)
3005
        (if_then_else (ne (cc0) (const_int 0))
3006
                      (label_ref (match_operand 2 "" ""))
3007
                      (pc)))]
3008
  ""
3009
  "*
3010
{
3011
  CC_STATUS_INIT;
3012
  if (test_hard_reg_class (ADDW_REGS, operands[0]))
3013
    output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
3014
                     AS2 (sbc,%C0,__zero_reg__) CR_TAB
3015
                     AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3016
  else
3017
    output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3018
                     AS2 (sbc,%B0,__zero_reg__) CR_TAB
3019
                     AS2 (sbc,%C0,__zero_reg__) CR_TAB
3020
                     AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3021
  switch (avr_jump_mode (operands[2],insn))
3022
  {
3023
    case 1:
3024
      return AS1 (brcc,%2);
3025
    case 2:
3026
      return (AS1 (brcs,.+2) CR_TAB
3027
              AS1 (rjmp,%2));
3028
  }
3029
  return (AS1 (brcs,.+4) CR_TAB
3030
          AS1 (jmp,%2));
3031
}")
3032
 
3033
(define_peephole
3034
  [(set (match_operand:HI 0 "d_register_operand" "")
3035
        (plus:HI (match_dup 0)
3036
                 (const_int -1)))
3037
   (parallel
3038
    [(set (cc0)
3039
          (compare (match_dup 0)
3040
                   (const_int 65535)))
3041
     (clobber (match_operand:QI 1 "d_register_operand" ""))])
3042
   (set (pc)
3043
        (if_then_else (ne (cc0) (const_int 0))
3044
                      (label_ref (match_operand 2 "" ""))
3045
                      (pc)))]
3046
  ""
3047
  "*
3048
{
3049
  CC_STATUS_INIT;
3050
  if (test_hard_reg_class (ADDW_REGS, operands[0]))
3051
    output_asm_insn (AS2 (sbiw,%0,1), operands);
3052
  else
3053
    output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3054
                     AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
3055
  switch (avr_jump_mode (operands[2],insn))
3056
  {
3057
    case 1:
3058
      return AS1 (brcc,%2);
3059
    case 2:
3060
      return (AS1 (brcs,.+2) CR_TAB
3061
              AS1 (rjmp,%2));
3062
  }
3063
  return (AS1 (brcs,.+4) CR_TAB
3064
          AS1 (jmp,%2));
3065
}")
3066
 
3067
(define_peephole
3068
  [(set (match_operand:QI 0 "d_register_operand" "")
3069
        (plus:QI (match_dup 0)
3070
                 (const_int -1)))
3071
   (set (cc0)
3072
        (compare (match_dup 0)
3073
                 (const_int -1)))
3074
   (set (pc)
3075
        (if_then_else (ne (cc0) (const_int 0))
3076
                      (label_ref (match_operand 1 "" ""))
3077
                      (pc)))]
3078
  ""
3079
  "*
3080
{
3081
  CC_STATUS_INIT;
3082
  cc_status.value1 = operands[0];
3083
  cc_status.flags |= CC_OVERFLOW_UNUSABLE;
3084
  output_asm_insn (AS2 (subi,%A0,1), operands);
3085
  switch (avr_jump_mode (operands[1],insn))
3086
  {
3087
    case 1:
3088
      return AS1 (brcc,%1);
3089
    case 2:
3090
      return (AS1 (brcs,.+2) CR_TAB
3091
              AS1 (rjmp,%1));
3092
  }
3093
  return (AS1 (brcs,.+4) CR_TAB
3094
          AS1 (jmp,%1));
3095
}")
3096
 
3097
(define_peephole
3098
  [(set (cc0)
3099
        (compare (match_operand:QI 0 "register_operand" "")
3100
                 (const_int 0)))
3101
   (set (pc)
3102
        (if_then_else (eq (cc0) (const_int 0))
3103
                      (label_ref (match_operand 1 "" ""))
3104
                      (pc)))]
3105
  "jump_over_one_insn_p (insn, operands[1])"
3106
  "cpse %0,__zero_reg__")
3107
 
3108
(define_peephole
3109
  [(set (cc0)
3110
        (compare (match_operand:QI 0 "register_operand" "")
3111
                 (match_operand:QI 1 "register_operand" "")))
3112
   (set (pc)
3113
        (if_then_else (eq (cc0) (const_int 0))
3114
                      (label_ref (match_operand 2 "" ""))
3115
                      (pc)))]
3116
  "jump_over_one_insn_p (insn, operands[2])"
3117
  "cpse %0,%1")
3118
 
3119
;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
3120
;;prologue/epilogue support instructions
3121
 
3122
(define_insn "popqi"
3123
  [(set (match_operand:QI 0 "register_operand" "=r")
3124
        (mem:QI (post_inc (reg:HI REG_SP))))]
3125
  ""
3126
  "pop %0"
3127
  [(set_attr "cc" "none")
3128
   (set_attr "length" "1")])
3129
 
3130
(define_insn "pophi"
3131
  [(set (match_operand:HI 0 "register_operand" "=r")
3132
        (mem:HI (post_inc (reg:HI REG_SP))))]
3133
  ""
3134
  "pop %A0\;pop %B0"
3135
  [(set_attr "cc" "none")
3136
   (set_attr "length" "2")])
3137
 
3138
;; Enable Interrupts
3139
(define_insn "enable_interrupt"
3140
  [(unspec [(const_int 0)] UNSPEC_SEI)]
3141
  ""
3142
  "sei"
3143
  [(set_attr "length" "1")
3144
  (set_attr "cc" "none")
3145
  ])
3146
 
3147
;; Disable Interrupts
3148
(define_insn "disable_interrupt"
3149
  [(unspec [(const_int 0)] UNSPEC_CLI)]
3150
  ""
3151
  "cli"
3152
  [(set_attr "length" "1")
3153
  (set_attr "cc" "none")
3154
  ])
3155
 
3156
;;  Library prologue saves
3157
(define_insn "call_prologue_saves"
3158
  [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
3159
   (match_operand:HI 0 "immediate_operand" "")
3160
   (set (reg:HI REG_SP) (minus:HI
3161
                           (reg:HI REG_SP)
3162
                           (match_operand:HI 1 "immediate_operand" "")))
3163
   (use (reg:HI REG_X))
3164
   (clobber (reg:HI REG_Z))]
3165
  ""
3166
  "ldi r30,lo8(gs(1f))
3167
        ldi r31,hi8(gs(1f))
3168
        %~jmp __prologue_saves__+((18 - %0) * 2)
3169
1:"
3170
  [(set_attr_alternative "length"
3171
                         [(if_then_else (eq_attr "mcu_mega" "yes")
3172
                                        (const_int 6)
3173
                                        (const_int 5))])
3174
  (set_attr "cc" "clobber")
3175
  ])
3176
 
3177
;  epilogue  restores using library
3178
(define_insn "epilogue_restores"
3179
  [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
3180
   (set (reg:HI REG_Y ) (plus:HI
3181
                           (reg:HI REG_Y)
3182
                           (match_operand:HI 0 "immediate_operand" "")))
3183
   (set (reg:HI REG_SP) (reg:HI REG_Y))
3184
   (clobber  (reg:QI REG_Z))]
3185
  ""
3186
  "ldi r30, lo8(%0)
3187
        %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
3188
  [(set_attr_alternative "length"
3189
                         [(if_then_else (eq_attr "mcu_mega" "yes")
3190
                                        (const_int 3)
3191
                                        (const_int 2))])
3192
  (set_attr "cc" "clobber")
3193
  ])
3194
 
3195
; return
3196
(define_insn "return"
3197
  [(return)]
3198
  "reload_completed && avr_simple_epilogue ()"
3199
  "ret"
3200
  [(set_attr "cc" "none")
3201
   (set_attr "length" "1")])
3202
 
3203
(define_insn "return_from_epilogue"
3204
  [(return)]
3205
  "(reload_completed
3206
    && cfun->machine
3207
    && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
3208
    && !cfun->machine->is_naked)"
3209
  "ret"
3210
  [(set_attr "cc" "none")
3211
   (set_attr "length" "1")])
3212
 
3213
(define_insn "return_from_interrupt_epilogue"
3214
  [(return)]
3215
  "(reload_completed
3216
    && cfun->machine
3217
    && (cfun->machine->is_interrupt || cfun->machine->is_signal)
3218
    && !cfun->machine->is_naked)"
3219
  "reti"
3220
  [(set_attr "cc" "none")
3221
   (set_attr "length" "1")])
3222
 
3223
(define_insn "return_from_naked_epilogue"
3224
  [(return)]
3225
  "(reload_completed
3226
    && cfun->machine
3227
    && cfun->machine->is_naked)"
3228
  ""
3229
  [(set_attr "cc" "none")
3230
   (set_attr "length" "0")])
3231
 
3232
(define_expand "prologue"
3233
  [(const_int 0)]
3234
  ""
3235
  "
3236
  {
3237
    expand_prologue ();
3238
    DONE;
3239
  }")
3240
 
3241
(define_expand "epilogue"
3242
  [(const_int 0)]
3243
  ""
3244
  "
3245
  {
3246
    expand_epilogue ();
3247
    DONE;
3248
  }")

powered by: WebSVN 2.1.0

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