annotate gcc/config/avr/avr.md @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 ;; Machine description for GNU compiler,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 ;; for ATMEL AVR micro controllers.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3 ;; Copyright (C) 1998-2018 Free Software Foundation, Inc.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
4 ;; Contributed by Denis Chertykov (chertykov@gmail.com)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 ;; This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 ;; GCC is free software; you can redistribute it and/or modify
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 ;; it under the terms of the GNU General Public License as published by
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 ;; the Free Software Foundation; either version 3, or (at your option)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 ;; any later version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 ;; GCC is distributed in the hope that it will be useful,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 ;; GNU General Public License for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 ;; You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 ;; along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 ;; <http://www.gnu.org/licenses/>.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 ;; Special characters after '%':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 ;; A No effect (add 0).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 ;; B Add 1 to REG number, MEM address or CONST_INT.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 ;; C Add 2.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 ;; D Add 3.
111
kono
parents: 67
diff changeset
27 ;; E reg number in XEXP(x, 0).
kono
parents: 67
diff changeset
28 ;; F Add 1 to reg number.
kono
parents: 67
diff changeset
29 ;; I reg number in XEXP(XEXP(x, 0), 0).
kono
parents: 67
diff changeset
30 ;; J Add 1 to reg number.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 ;; j Branch condition.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 ;; k Reverse branch condition.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
33 ;;..m..Constant Direct Data memory address.
111
kono
parents: 67
diff changeset
34 ;; i Print the SFR address quivalent of a CONST_INT or a CONST_INT
kono
parents: 67
diff changeset
35 ;; RAM address. The resulting address is suitable to be used in IN/OUT.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 ;; o Displacement for (mem (plus (reg) (const_int))) operands.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30)
111
kono
parents: 67
diff changeset
39 ;; r Print a REG without the register prefix 'r'.
kono
parents: 67
diff changeset
40 ;; T/T Print operand suitable for BLD/BST instruction, i.e. register and
kono
parents: 67
diff changeset
41 ;; bit number. This gets 2 operands: The first %T gets a REG_P and
kono
parents: 67
diff changeset
42 ;; just cashes the operand for the next %T. The second %T gets
kono
parents: 67
diff changeset
43 ;; a CONST_INT that represents a bit position.
kono
parents: 67
diff changeset
44 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
kono
parents: 67
diff changeset
45 ;; "%T0%T1" it will print "r19,5".
kono
parents: 67
diff changeset
46 ;; Notice that you must not write a comma between %T0 and %T1.
kono
parents: 67
diff changeset
47 ;; T/t Similar to above, but don't print the comma and the bit number.
kono
parents: 67
diff changeset
48 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
kono
parents: 67
diff changeset
49 ;; "%T0%t1" it will print "r19".
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
50 ;;..x..Constant Direct Program memory address.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53
111
kono
parents: 67
diff changeset
54
kono
parents: 67
diff changeset
55 (define_constants
kono
parents: 67
diff changeset
56 [(REG_X 26)
kono
parents: 67
diff changeset
57 (REG_Y 28)
kono
parents: 67
diff changeset
58 (REG_Z 30)
kono
parents: 67
diff changeset
59 (REG_W 24)
kono
parents: 67
diff changeset
60 (REG_SP 32)
kono
parents: 67
diff changeset
61 (LPM_REGNO 0) ; implicit target register of LPM
kono
parents: 67
diff changeset
62 (TMP_REGNO 0) ; temporary register r0
kono
parents: 67
diff changeset
63 (ZERO_REGNO 1) ; zero register r1
kono
parents: 67
diff changeset
64 ])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 (define_constants
111
kono
parents: 67
diff changeset
67 [(TMP_REGNO_TINY 16) ; r16 is temp register for AVR_TINY
kono
parents: 67
diff changeset
68 (ZERO_REGNO_TINY 17) ; r17 is zero register for AVR_TINY
kono
parents: 67
diff changeset
69 ])
kono
parents: 67
diff changeset
70
kono
parents: 67
diff changeset
71 (define_c_enum "unspec"
kono
parents: 67
diff changeset
72 [UNSPEC_STRLEN
kono
parents: 67
diff changeset
73 UNSPEC_MOVMEM
kono
parents: 67
diff changeset
74 UNSPEC_INDEX_JMP
kono
parents: 67
diff changeset
75 UNSPEC_FMUL
kono
parents: 67
diff changeset
76 UNSPEC_FMULS
kono
parents: 67
diff changeset
77 UNSPEC_FMULSU
kono
parents: 67
diff changeset
78 UNSPEC_COPYSIGN
kono
parents: 67
diff changeset
79 UNSPEC_IDENTITY
kono
parents: 67
diff changeset
80 UNSPEC_INSERT_BITS
kono
parents: 67
diff changeset
81 UNSPEC_ROUND
kono
parents: 67
diff changeset
82 ])
kono
parents: 67
diff changeset
83
kono
parents: 67
diff changeset
84 (define_c_enum "unspecv"
kono
parents: 67
diff changeset
85 [UNSPECV_PROLOGUE_SAVES
kono
parents: 67
diff changeset
86 UNSPECV_EPILOGUE_RESTORES
kono
parents: 67
diff changeset
87 UNSPECV_WRITE_SP
kono
parents: 67
diff changeset
88 UNSPECV_GASISR
kono
parents: 67
diff changeset
89 UNSPECV_GOTO_RECEIVER
kono
parents: 67
diff changeset
90 UNSPECV_ENABLE_IRQS
kono
parents: 67
diff changeset
91 UNSPECV_MEMORY_BARRIER
kono
parents: 67
diff changeset
92 UNSPECV_NOP
kono
parents: 67
diff changeset
93 UNSPECV_SLEEP
kono
parents: 67
diff changeset
94 UNSPECV_WDR
kono
parents: 67
diff changeset
95 UNSPECV_DELAY_CYCLES
kono
parents: 67
diff changeset
96 ])
kono
parents: 67
diff changeset
97
kono
parents: 67
diff changeset
98 ;; Chunk numbers for __gcc_isr are hard-coded in GAS.
kono
parents: 67
diff changeset
99 (define_constants
kono
parents: 67
diff changeset
100 [(GASISR_Prologue 1)
kono
parents: 67
diff changeset
101 (GASISR_Epilogue 2)
kono
parents: 67
diff changeset
102 (GASISR_Done 0)
kono
parents: 67
diff changeset
103 ])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 (include "predicates.md")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 (include "constraints.md")
111
kono
parents: 67
diff changeset
107
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 ;; Condition code settings.
111
kono
parents: 67
diff changeset
109 (define_attr "cc" "none,set_czn,set_zn,set_vzn,set_n,compare,clobber,
kono
parents: 67
diff changeset
110 plus,ldi"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 (const_string "none"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 (define_attr "type" "branch,branch1,arith,xcall"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 (const_string "arith"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 ;; The size of instructions in bytes.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 ;; XXX may depend from "cc"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 (define_attr "length" ""
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 (cond [(eq_attr "type" "branch")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 (if_then_else (and (ge (minus (pc) (match_dup 0))
111
kono
parents: 67
diff changeset
122 (const_int -62))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 (le (minus (pc) (match_dup 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 (const_int 62)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 (const_int 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 (if_then_else (and (ge (minus (pc) (match_dup 0))
111
kono
parents: 67
diff changeset
127 (const_int -2044))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 (le (minus (pc) (match_dup 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 (const_int 2045)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 (const_int 2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 (const_int 3)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 (eq_attr "type" "branch1")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 (if_then_else (and (ge (minus (pc) (match_dup 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 (const_int -62))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 (le (minus (pc) (match_dup 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 (const_int 61)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 (const_int 2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 (if_then_else (and (ge (minus (pc) (match_dup 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 (const_int -2044))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 (le (minus (pc) (match_dup 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 (const_int 2043)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 (const_int 3)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 (const_int 4)))
111
kono
parents: 67
diff changeset
144 (eq_attr "type" "xcall")
kono
parents: 67
diff changeset
145 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
kono
parents: 67
diff changeset
146 (const_int 1)
kono
parents: 67
diff changeset
147 (const_int 2))]
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 (const_int 2)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149
111
kono
parents: 67
diff changeset
150 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
kono
parents: 67
diff changeset
151 ;; Following insn attribute tells if and how the adjustment has to be
kono
parents: 67
diff changeset
152 ;; done:
kono
parents: 67
diff changeset
153 ;; no No adjustment needed; attribute "length" is fine.
kono
parents: 67
diff changeset
154 ;; Otherwise do special processing depending on the attribute.
kono
parents: 67
diff changeset
155
kono
parents: 67
diff changeset
156 (define_attr "adjust_len"
kono
parents: 67
diff changeset
157 "out_bitop, plus, addto_sp, sext,
kono
parents: 67
diff changeset
158 tsthi, tstpsi, tstsi, compare, compare64, call,
kono
parents: 67
diff changeset
159 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
kono
parents: 67
diff changeset
160 ufract, sfract, round,
kono
parents: 67
diff changeset
161 xload, movmem,
kono
parents: 67
diff changeset
162 ashlqi, ashrqi, lshrqi,
kono
parents: 67
diff changeset
163 ashlhi, ashrhi, lshrhi,
kono
parents: 67
diff changeset
164 ashlsi, ashrsi, lshrsi,
kono
parents: 67
diff changeset
165 ashlpsi, ashrpsi, lshrpsi,
kono
parents: 67
diff changeset
166 insert_bits, insv_notbit, insv_notbit_0, insv_notbit_7,
kono
parents: 67
diff changeset
167 no"
kono
parents: 67
diff changeset
168 (const_string "no"))
kono
parents: 67
diff changeset
169
kono
parents: 67
diff changeset
170 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
kono
parents: 67
diff changeset
171
kono
parents: 67
diff changeset
172 ;; mov : ISA has no MOVW movw : ISA has MOVW
kono
parents: 67
diff changeset
173 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
kono
parents: 67
diff changeset
174 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
kono
parents: 67
diff changeset
175 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
kono
parents: 67
diff changeset
176 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
kono
parents: 67
diff changeset
177 ;; no_xmega: non-XMEGA core xmega : XMEGA core
kono
parents: 67
diff changeset
178 ;; no_tiny: non-TINY core tiny : TINY core
kono
parents: 67
diff changeset
179
kono
parents: 67
diff changeset
180 (define_attr "isa"
kono
parents: 67
diff changeset
181 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega, no_tiny,tiny,
kono
parents: 67
diff changeset
182 standard"
kono
parents: 67
diff changeset
183 (const_string "standard"))
kono
parents: 67
diff changeset
184
kono
parents: 67
diff changeset
185 (define_attr "enabled" ""
kono
parents: 67
diff changeset
186 (cond [(eq_attr "isa" "standard")
kono
parents: 67
diff changeset
187 (const_int 1)
kono
parents: 67
diff changeset
188
kono
parents: 67
diff changeset
189 (and (eq_attr "isa" "mov")
kono
parents: 67
diff changeset
190 (match_test "!AVR_HAVE_MOVW"))
kono
parents: 67
diff changeset
191 (const_int 1)
kono
parents: 67
diff changeset
192
kono
parents: 67
diff changeset
193 (and (eq_attr "isa" "movw")
kono
parents: 67
diff changeset
194 (match_test "AVR_HAVE_MOVW"))
kono
parents: 67
diff changeset
195 (const_int 1)
kono
parents: 67
diff changeset
196
kono
parents: 67
diff changeset
197 (and (eq_attr "isa" "rjmp")
kono
parents: 67
diff changeset
198 (match_test "!AVR_HAVE_JMP_CALL"))
kono
parents: 67
diff changeset
199 (const_int 1)
kono
parents: 67
diff changeset
200
kono
parents: 67
diff changeset
201 (and (eq_attr "isa" "jmp")
kono
parents: 67
diff changeset
202 (match_test "AVR_HAVE_JMP_CALL"))
kono
parents: 67
diff changeset
203 (const_int 1)
kono
parents: 67
diff changeset
204
kono
parents: 67
diff changeset
205 (and (eq_attr "isa" "ijmp")
kono
parents: 67
diff changeset
206 (match_test "!AVR_HAVE_EIJMP_EICALL"))
kono
parents: 67
diff changeset
207 (const_int 1)
kono
parents: 67
diff changeset
208
kono
parents: 67
diff changeset
209 (and (eq_attr "isa" "eijmp")
kono
parents: 67
diff changeset
210 (match_test "AVR_HAVE_EIJMP_EICALL"))
kono
parents: 67
diff changeset
211 (const_int 1)
kono
parents: 67
diff changeset
212
kono
parents: 67
diff changeset
213 (and (eq_attr "isa" "lpm")
kono
parents: 67
diff changeset
214 (match_test "!AVR_HAVE_LPMX"))
kono
parents: 67
diff changeset
215 (const_int 1)
kono
parents: 67
diff changeset
216
kono
parents: 67
diff changeset
217 (and (eq_attr "isa" "lpmx")
kono
parents: 67
diff changeset
218 (match_test "AVR_HAVE_LPMX"))
kono
parents: 67
diff changeset
219 (const_int 1)
kono
parents: 67
diff changeset
220
kono
parents: 67
diff changeset
221 (and (eq_attr "isa" "elpm")
kono
parents: 67
diff changeset
222 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
kono
parents: 67
diff changeset
223 (const_int 1)
kono
parents: 67
diff changeset
224
kono
parents: 67
diff changeset
225 (and (eq_attr "isa" "elpmx")
kono
parents: 67
diff changeset
226 (match_test "AVR_HAVE_ELPMX"))
kono
parents: 67
diff changeset
227 (const_int 1)
kono
parents: 67
diff changeset
228
kono
parents: 67
diff changeset
229 (and (eq_attr "isa" "xmega")
kono
parents: 67
diff changeset
230 (match_test "AVR_XMEGA"))
kono
parents: 67
diff changeset
231 (const_int 1)
kono
parents: 67
diff changeset
232
kono
parents: 67
diff changeset
233 (and (eq_attr "isa" "tiny")
kono
parents: 67
diff changeset
234 (match_test "AVR_TINY"))
kono
parents: 67
diff changeset
235 (const_int 1)
kono
parents: 67
diff changeset
236
kono
parents: 67
diff changeset
237 (and (eq_attr "isa" "no_xmega")
kono
parents: 67
diff changeset
238 (match_test "!AVR_XMEGA"))
kono
parents: 67
diff changeset
239 (const_int 1)
kono
parents: 67
diff changeset
240
kono
parents: 67
diff changeset
241 (and (eq_attr "isa" "no_tiny")
kono
parents: 67
diff changeset
242 (match_test "!AVR_TINY"))
kono
parents: 67
diff changeset
243 (const_int 1)
kono
parents: 67
diff changeset
244
kono
parents: 67
diff changeset
245 ] (const_int 0)))
kono
parents: 67
diff changeset
246
kono
parents: 67
diff changeset
247
kono
parents: 67
diff changeset
248 ;; Define mode iterators
kono
parents: 67
diff changeset
249 (define_mode_iterator QIHI [QI HI])
kono
parents: 67
diff changeset
250 (define_mode_iterator QIHI2 [QI HI])
kono
parents: 67
diff changeset
251 (define_mode_iterator QISI [QI HI PSI SI])
kono
parents: 67
diff changeset
252 (define_mode_iterator QIDI [QI HI PSI SI DI])
kono
parents: 67
diff changeset
253 (define_mode_iterator HISI [HI PSI SI])
kono
parents: 67
diff changeset
254
kono
parents: 67
diff changeset
255 (define_mode_iterator ALL1 [QI QQ UQQ])
kono
parents: 67
diff changeset
256 (define_mode_iterator ALL2 [HI HQ UHQ HA UHA])
kono
parents: 67
diff changeset
257 (define_mode_iterator ALL4 [SI SQ USQ SA USA])
kono
parents: 67
diff changeset
258
kono
parents: 67
diff changeset
259 ;; All supported move-modes
kono
parents: 67
diff changeset
260 (define_mode_iterator MOVMODE [QI QQ UQQ
kono
parents: 67
diff changeset
261 HI HQ UHQ HA UHA
kono
parents: 67
diff changeset
262 SI SQ USQ SA USA
kono
parents: 67
diff changeset
263 SF PSI])
kono
parents: 67
diff changeset
264
kono
parents: 67
diff changeset
265 ;; Supported ordered modes that are 2, 3, 4 bytes wide
kono
parents: 67
diff changeset
266 (define_mode_iterator ORDERED234 [HI SI PSI
kono
parents: 67
diff changeset
267 HQ UHQ HA UHA
kono
parents: 67
diff changeset
268 SQ USQ SA USA])
kono
parents: 67
diff changeset
269
kono
parents: 67
diff changeset
270 ;; Post-reload split of 3, 4 bytes wide moves.
kono
parents: 67
diff changeset
271 (define_mode_iterator SPLIT34 [SI SF PSI
kono
parents: 67
diff changeset
272 SQ USQ SA USA])
kono
parents: 67
diff changeset
273
kono
parents: 67
diff changeset
274 ;; Define code iterators
kono
parents: 67
diff changeset
275 ;; Define two incarnations so that we can build the cross product.
kono
parents: 67
diff changeset
276 (define_code_iterator any_extend [sign_extend zero_extend])
kono
parents: 67
diff changeset
277 (define_code_iterator any_extend2 [sign_extend zero_extend])
kono
parents: 67
diff changeset
278 (define_code_iterator any_extract [sign_extract zero_extract])
kono
parents: 67
diff changeset
279 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
kono
parents: 67
diff changeset
280
kono
parents: 67
diff changeset
281 (define_code_iterator bitop [xor ior and])
kono
parents: 67
diff changeset
282 (define_code_iterator xior [xor ior])
kono
parents: 67
diff changeset
283 (define_code_iterator eqne [eq ne])
kono
parents: 67
diff changeset
284
kono
parents: 67
diff changeset
285 (define_code_iterator ss_addsub [ss_plus ss_minus])
kono
parents: 67
diff changeset
286 (define_code_iterator us_addsub [us_plus us_minus])
kono
parents: 67
diff changeset
287 (define_code_iterator ss_abs_neg [ss_abs ss_neg])
kono
parents: 67
diff changeset
288
kono
parents: 67
diff changeset
289 ;; Define code attributes
kono
parents: 67
diff changeset
290 (define_code_attr extend_su
kono
parents: 67
diff changeset
291 [(sign_extend "s")
kono
parents: 67
diff changeset
292 (zero_extend "u")])
kono
parents: 67
diff changeset
293
kono
parents: 67
diff changeset
294 (define_code_attr extend_u
kono
parents: 67
diff changeset
295 [(sign_extend "")
kono
parents: 67
diff changeset
296 (zero_extend "u")])
kono
parents: 67
diff changeset
297
kono
parents: 67
diff changeset
298 (define_code_attr extend_s
kono
parents: 67
diff changeset
299 [(sign_extend "s")
kono
parents: 67
diff changeset
300 (zero_extend "")])
kono
parents: 67
diff changeset
301
kono
parents: 67
diff changeset
302 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
kono
parents: 67
diff changeset
303 (define_code_attr mul_r_d
kono
parents: 67
diff changeset
304 [(zero_extend "r")
kono
parents: 67
diff changeset
305 (sign_extend "d")])
kono
parents: 67
diff changeset
306
kono
parents: 67
diff changeset
307 (define_code_attr abelian
kono
parents: 67
diff changeset
308 [(ss_minus "") (us_minus "")
kono
parents: 67
diff changeset
309 (ss_plus "%") (us_plus "%")])
kono
parents: 67
diff changeset
310
kono
parents: 67
diff changeset
311 ;; Map RTX code to its standard insn name
kono
parents: 67
diff changeset
312 (define_code_attr code_stdname
kono
parents: 67
diff changeset
313 [(ashift "ashl")
kono
parents: 67
diff changeset
314 (ashiftrt "ashr")
kono
parents: 67
diff changeset
315 (lshiftrt "lshr")
kono
parents: 67
diff changeset
316 (ior "ior")
kono
parents: 67
diff changeset
317 (xor "xor")
kono
parents: 67
diff changeset
318 (rotate "rotl")
kono
parents: 67
diff changeset
319 (ss_plus "ssadd") (ss_minus "sssub") (ss_neg "ssneg") (ss_abs "ssabs")
kono
parents: 67
diff changeset
320 (us_plus "usadd") (us_minus "ussub") (us_neg "usneg")
kono
parents: 67
diff changeset
321 ])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
322
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
323 ;;========================================================================
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 ;; The following is used by nonlocal_goto and setjmp.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
325 ;; The receiver pattern will create no instructions since internally
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
326 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
327 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328 ;; The 'null' receiver also avoids problems with optimisation
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
329 ;; not recognising incoming jmp and removing code that resets frame_pointer.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 ;; The code derived from builtins.c.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332 (define_expand "nonlocal_goto_receiver"
111
kono
parents: 67
diff changeset
333 [(set (reg:HI REG_Y)
kono
parents: 67
diff changeset
334 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
kono
parents: 67
diff changeset
335 ""
kono
parents: 67
diff changeset
336 {
kono
parents: 67
diff changeset
337 rtx offset = gen_int_mode (targetm.starting_frame_offset (), Pmode);
kono
parents: 67
diff changeset
338 emit_move_insn (virtual_stack_vars_rtx,
kono
parents: 67
diff changeset
339 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, offset));
kono
parents: 67
diff changeset
340 /* ; This might change the hard frame pointer in ways that aren't
kono
parents: 67
diff changeset
341 ; apparent to early optimization passes, so force a clobber. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
342 emit_clobber (hard_frame_pointer_rtx);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343 DONE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
344 })
111
kono
parents: 67
diff changeset
345
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
346
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
347 ;; Defining nonlocal_goto_receiver means we must also define this.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 ;; even though its function is identical to that in builtins.c
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
349
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
350 (define_expand "nonlocal_goto"
111
kono
parents: 67
diff changeset
351 [(use (match_operand 0 "general_operand"))
kono
parents: 67
diff changeset
352 (use (match_operand 1 "general_operand"))
kono
parents: 67
diff changeset
353 (use (match_operand 2 "general_operand"))
kono
parents: 67
diff changeset
354 (use (match_operand 3 "general_operand"))]
kono
parents: 67
diff changeset
355 ""
kono
parents: 67
diff changeset
356 {
kono
parents: 67
diff changeset
357 rtx r_label = copy_to_reg (operands[1]);
kono
parents: 67
diff changeset
358 rtx r_fp = operands[3];
kono
parents: 67
diff changeset
359 rtx r_sp = operands[2];
kono
parents: 67
diff changeset
360
kono
parents: 67
diff changeset
361 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
kono
parents: 67
diff changeset
362
kono
parents: 67
diff changeset
363 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
kono
parents: 67
diff changeset
364
kono
parents: 67
diff changeset
365 emit_move_insn (hard_frame_pointer_rtx, r_fp);
kono
parents: 67
diff changeset
366 emit_stack_restore (SAVE_NONLOCAL, r_sp);
kono
parents: 67
diff changeset
367
kono
parents: 67
diff changeset
368 emit_use (hard_frame_pointer_rtx);
kono
parents: 67
diff changeset
369 emit_use (stack_pointer_rtx);
kono
parents: 67
diff changeset
370
kono
parents: 67
diff changeset
371 emit_indirect_jump (r_label);
kono
parents: 67
diff changeset
372
kono
parents: 67
diff changeset
373 DONE;
kono
parents: 67
diff changeset
374 })
kono
parents: 67
diff changeset
375
kono
parents: 67
diff changeset
376 ;; "pushqi1"
kono
parents: 67
diff changeset
377 ;; "pushqq1" "pushuqq1"
kono
parents: 67
diff changeset
378 (define_insn "push<mode>1"
kono
parents: 67
diff changeset
379 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP)))
kono
parents: 67
diff changeset
380 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))]
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
381 ""
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
382 "@
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
383 push %0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
384 push __zero_reg__"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
385 [(set_attr "length" "1,1")])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386
111
kono
parents: 67
diff changeset
387 (define_insn "pushhi1_insn"
kono
parents: 67
diff changeset
388 [(set (mem:HI (post_dec:HI (reg:HI REG_SP)))
kono
parents: 67
diff changeset
389 (match_operand:HI 0 "register_operand" "r"))]
kono
parents: 67
diff changeset
390 ""
kono
parents: 67
diff changeset
391 "push %B0\;push %A0"
kono
parents: 67
diff changeset
392 [(set_attr "length" "2")])
kono
parents: 67
diff changeset
393
kono
parents: 67
diff changeset
394 ;; All modes for a multi-byte push. We must include complex modes here too,
kono
parents: 67
diff changeset
395 ;; lest emit_single_push_insn "helpfully" create the auto-inc itself.
kono
parents: 67
diff changeset
396 (define_mode_iterator MPUSH
kono
parents: 67
diff changeset
397 [CQI
kono
parents: 67
diff changeset
398 HI CHI HA UHA HQ UHQ
kono
parents: 67
diff changeset
399 SI CSI SA USA SQ USQ
kono
parents: 67
diff changeset
400 DI CDI DA UDA DQ UDQ
kono
parents: 67
diff changeset
401 TA UTA
kono
parents: 67
diff changeset
402 SF SC
kono
parents: 67
diff changeset
403 PSI])
kono
parents: 67
diff changeset
404
kono
parents: 67
diff changeset
405 (define_expand "push<mode>1"
kono
parents: 67
diff changeset
406 [(match_operand:MPUSH 0 "" "")]
kono
parents: 67
diff changeset
407 ""
kono
parents: 67
diff changeset
408 {
kono
parents: 67
diff changeset
409 if (MEM_P (operands[0])
kono
parents: 67
diff changeset
410 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[0])))
kono
parents: 67
diff changeset
411 {
kono
parents: 67
diff changeset
412 // Avoid (subreg (mem)) for non-generic address spaces. Because
kono
parents: 67
diff changeset
413 // of the poor addressing capabilities of these spaces it's better to
kono
parents: 67
diff changeset
414 // load them in one chunk. And it avoids PR61443.
kono
parents: 67
diff changeset
415
kono
parents: 67
diff changeset
416 operands[0] = copy_to_mode_reg (<MODE>mode, operands[0]);
kono
parents: 67
diff changeset
417 }
kono
parents: 67
diff changeset
418 else if (REG_P (operands[0])
kono
parents: 67
diff changeset
419 && IN_RANGE (REGNO (operands[0]), FIRST_VIRTUAL_REGISTER,
kono
parents: 67
diff changeset
420 LAST_VIRTUAL_REGISTER))
kono
parents: 67
diff changeset
421 {
kono
parents: 67
diff changeset
422 // Byte-wise pushing of virtual regs might result in something like
kono
parents: 67
diff changeset
423 //
kono
parents: 67
diff changeset
424 // (set (mem:QI (post_dec:HI (reg:HI 32 SP)))
kono
parents: 67
diff changeset
425 // (subreg:QI (plus:HI (reg:HI 28)
kono
parents: 67
diff changeset
426 // (const_int 17)) 0))
kono
parents: 67
diff changeset
427 //
kono
parents: 67
diff changeset
428 // after elimination. This cannot be handled by reload, cf. PR64452.
kono
parents: 67
diff changeset
429 // Reload virtuals in one chunk. That way it's possible to reload
kono
parents: 67
diff changeset
430 // above situation and finally
kono
parents: 67
diff changeset
431 //
kono
parents: 67
diff changeset
432 // (set (reg:HI **)
kono
parents: 67
diff changeset
433 // (const_int 17))
kono
parents: 67
diff changeset
434 // (set (reg:HI **)
kono
parents: 67
diff changeset
435 // (plus:HI (reg:HI **)
kono
parents: 67
diff changeset
436 // (reg:HI 28)))
kono
parents: 67
diff changeset
437 // (set (mem:HI (post_dec:HI (reg:HI 32 SP))
kono
parents: 67
diff changeset
438 // (reg:HI **)))
kono
parents: 67
diff changeset
439
kono
parents: 67
diff changeset
440 emit_insn (gen_pushhi1_insn (operands[0]));
kono
parents: 67
diff changeset
441 DONE;
kono
parents: 67
diff changeset
442 }
kono
parents: 67
diff changeset
443
kono
parents: 67
diff changeset
444 for (int i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
kono
parents: 67
diff changeset
445 {
kono
parents: 67
diff changeset
446 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
kono
parents: 67
diff changeset
447 if (part != const0_rtx)
kono
parents: 67
diff changeset
448 part = force_reg (QImode, part);
kono
parents: 67
diff changeset
449 emit_insn (gen_pushqi1 (part));
kono
parents: 67
diff changeset
450 }
kono
parents: 67
diff changeset
451 DONE;
kono
parents: 67
diff changeset
452 })
kono
parents: 67
diff changeset
453
kono
parents: 67
diff changeset
454 ;; Notice a special-case when adding N to SP where N results in a
kono
parents: 67
diff changeset
455 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
kono
parents: 67
diff changeset
456 (define_split
kono
parents: 67
diff changeset
457 [(set (reg:HI REG_SP)
kono
parents: 67
diff changeset
458 (match_operand:HI 0 "register_operand" ""))]
kono
parents: 67
diff changeset
459 "reload_completed
kono
parents: 67
diff changeset
460 && frame_pointer_needed
kono
parents: 67
diff changeset
461 && !cfun->calls_alloca
kono
parents: 67
diff changeset
462 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
kono
parents: 67
diff changeset
463 [(set (reg:HI REG_SP)
kono
parents: 67
diff changeset
464 (reg:HI REG_Y))])
kono
parents: 67
diff changeset
465
kono
parents: 67
diff changeset
466 ;;========================================================================
kono
parents: 67
diff changeset
467 ;; Move stuff around
kono
parents: 67
diff changeset
468
kono
parents: 67
diff changeset
469 ;; "loadqi_libgcc"
kono
parents: 67
diff changeset
470 ;; "loadhi_libgcc"
kono
parents: 67
diff changeset
471 ;; "loadpsi_libgcc"
kono
parents: 67
diff changeset
472 ;; "loadsi_libgcc"
kono
parents: 67
diff changeset
473 ;; "loadsf_libgcc"
kono
parents: 67
diff changeset
474 (define_expand "load<mode>_libgcc"
kono
parents: 67
diff changeset
475 [(set (match_dup 3)
kono
parents: 67
diff changeset
476 (match_dup 2))
kono
parents: 67
diff changeset
477 (set (reg:MOVMODE 22)
kono
parents: 67
diff changeset
478 (match_operand:MOVMODE 1 "memory_operand" ""))
kono
parents: 67
diff changeset
479 (set (match_operand:MOVMODE 0 "register_operand" "")
kono
parents: 67
diff changeset
480 (reg:MOVMODE 22))]
kono
parents: 67
diff changeset
481 "avr_load_libgcc_p (operands[1])"
kono
parents: 67
diff changeset
482 {
kono
parents: 67
diff changeset
483 operands[3] = gen_rtx_REG (HImode, REG_Z);
kono
parents: 67
diff changeset
484 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
kono
parents: 67
diff changeset
485 operands[1] = replace_equiv_address (operands[1], operands[3]);
kono
parents: 67
diff changeset
486 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
kono
parents: 67
diff changeset
487 })
kono
parents: 67
diff changeset
488
kono
parents: 67
diff changeset
489 ;; "load_qi_libgcc"
kono
parents: 67
diff changeset
490 ;; "load_hi_libgcc"
kono
parents: 67
diff changeset
491 ;; "load_psi_libgcc"
kono
parents: 67
diff changeset
492 ;; "load_si_libgcc"
kono
parents: 67
diff changeset
493 ;; "load_sf_libgcc"
kono
parents: 67
diff changeset
494 (define_insn "load_<mode>_libgcc"
kono
parents: 67
diff changeset
495 [(set (reg:MOVMODE 22)
kono
parents: 67
diff changeset
496 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
kono
parents: 67
diff changeset
497 "avr_load_libgcc_p (operands[0])
kono
parents: 67
diff changeset
498 && REG_P (XEXP (operands[0], 0))
kono
parents: 67
diff changeset
499 && REG_Z == REGNO (XEXP (operands[0], 0))"
kono
parents: 67
diff changeset
500 {
kono
parents: 67
diff changeset
501 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
kono
parents: 67
diff changeset
502 return "%~call __load_%0";
kono
parents: 67
diff changeset
503 }
kono
parents: 67
diff changeset
504 [(set_attr "length" "1,2")
kono
parents: 67
diff changeset
505 (set_attr "isa" "rjmp,jmp")
kono
parents: 67
diff changeset
506 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
507
kono
parents: 67
diff changeset
508
kono
parents: 67
diff changeset
509 ;; "xload8qi_A"
kono
parents: 67
diff changeset
510 ;; "xload8qq_A" "xload8uqq_A"
kono
parents: 67
diff changeset
511 (define_insn_and_split "xload8<mode>_A"
kono
parents: 67
diff changeset
512 [(set (match_operand:ALL1 0 "register_operand" "=r")
kono
parents: 67
diff changeset
513 (match_operand:ALL1 1 "memory_operand" "m"))
kono
parents: 67
diff changeset
514 (clobber (reg:HI REG_Z))]
kono
parents: 67
diff changeset
515 "can_create_pseudo_p()
kono
parents: 67
diff changeset
516 && !avr_xload_libgcc_p (<MODE>mode)
kono
parents: 67
diff changeset
517 && avr_mem_memx_p (operands[1])
kono
parents: 67
diff changeset
518 && REG_P (XEXP (operands[1], 0))"
kono
parents: 67
diff changeset
519 { gcc_unreachable(); }
kono
parents: 67
diff changeset
520 "&& 1"
kono
parents: 67
diff changeset
521 [(clobber (const_int 0))]
kono
parents: 67
diff changeset
522 {
kono
parents: 67
diff changeset
523 /* ; Split away the high part of the address. GCC's register allocator
kono
parents: 67
diff changeset
524 ; in not able to allocate segment registers and reload the resulting
kono
parents: 67
diff changeset
525 ; expressions. Notice that no address register can hold a PSImode. */
kono
parents: 67
diff changeset
526
kono
parents: 67
diff changeset
527 rtx_insn *insn;
kono
parents: 67
diff changeset
528 rtx addr = XEXP (operands[1], 0);
kono
parents: 67
diff changeset
529 rtx hi8 = gen_reg_rtx (QImode);
kono
parents: 67
diff changeset
530 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
kono
parents: 67
diff changeset
531
kono
parents: 67
diff changeset
532 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
kono
parents: 67
diff changeset
533 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
kono
parents: 67
diff changeset
534
kono
parents: 67
diff changeset
535 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8));
kono
parents: 67
diff changeset
536 set_mem_addr_space (SET_SRC (single_set (insn)),
kono
parents: 67
diff changeset
537 MEM_ADDR_SPACE (operands[1]));
kono
parents: 67
diff changeset
538 DONE;
kono
parents: 67
diff changeset
539 })
kono
parents: 67
diff changeset
540
kono
parents: 67
diff changeset
541 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A"
kono
parents: 67
diff changeset
542 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A"
kono
parents: 67
diff changeset
543 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A"
kono
parents: 67
diff changeset
544 ;; "xloadpsi_A"
kono
parents: 67
diff changeset
545 ;; "xloadsf_A"
kono
parents: 67
diff changeset
546 (define_insn_and_split "xload<mode>_A"
kono
parents: 67
diff changeset
547 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
kono
parents: 67
diff changeset
548 (match_operand:MOVMODE 1 "memory_operand" "m"))
kono
parents: 67
diff changeset
549 (clobber (reg:MOVMODE 22))
kono
parents: 67
diff changeset
550 (clobber (reg:QI 21))
kono
parents: 67
diff changeset
551 (clobber (reg:HI REG_Z))]
kono
parents: 67
diff changeset
552 "can_create_pseudo_p()
kono
parents: 67
diff changeset
553 && avr_mem_memx_p (operands[1])
kono
parents: 67
diff changeset
554 && REG_P (XEXP (operands[1], 0))"
kono
parents: 67
diff changeset
555 { gcc_unreachable(); }
kono
parents: 67
diff changeset
556 "&& 1"
kono
parents: 67
diff changeset
557 [(clobber (const_int 0))]
kono
parents: 67
diff changeset
558 {
kono
parents: 67
diff changeset
559 rtx addr = XEXP (operands[1], 0);
kono
parents: 67
diff changeset
560 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
kono
parents: 67
diff changeset
561 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
kono
parents: 67
diff changeset
562 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
kono
parents: 67
diff changeset
563 rtx_insn *insn;
kono
parents: 67
diff changeset
564
kono
parents: 67
diff changeset
565 /* Split the address to R21:Z */
kono
parents: 67
diff changeset
566 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
kono
parents: 67
diff changeset
567 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
kono
parents: 67
diff changeset
568
kono
parents: 67
diff changeset
569 /* Load with code from libgcc */
kono
parents: 67
diff changeset
570 insn = emit_insn (gen_xload_<mode>_libgcc ());
kono
parents: 67
diff changeset
571 set_mem_addr_space (SET_SRC (single_set (insn)), as);
kono
parents: 67
diff changeset
572
kono
parents: 67
diff changeset
573 /* Move to destination */
kono
parents: 67
diff changeset
574 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
kono
parents: 67
diff changeset
575
kono
parents: 67
diff changeset
576 DONE;
kono
parents: 67
diff changeset
577 })
kono
parents: 67
diff changeset
578
kono
parents: 67
diff changeset
579 ;; Move value from address space memx to a register
kono
parents: 67
diff changeset
580 ;; These insns must be prior to respective generic move insn.
kono
parents: 67
diff changeset
581
kono
parents: 67
diff changeset
582 ;; "xloadqi_8"
kono
parents: 67
diff changeset
583 ;; "xloadqq_8" "xloaduqq_8"
kono
parents: 67
diff changeset
584 (define_insn "xload<mode>_8"
kono
parents: 67
diff changeset
585 [(set (match_operand:ALL1 0 "register_operand" "=&r,r")
kono
parents: 67
diff changeset
586 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
kono
parents: 67
diff changeset
587 (reg:HI REG_Z))))]
kono
parents: 67
diff changeset
588 "!avr_xload_libgcc_p (<MODE>mode)"
kono
parents: 67
diff changeset
589 {
kono
parents: 67
diff changeset
590 return avr_out_xload (insn, operands, NULL);
kono
parents: 67
diff changeset
591 }
kono
parents: 67
diff changeset
592 [(set_attr "length" "4,4")
kono
parents: 67
diff changeset
593 (set_attr "adjust_len" "*,xload")
kono
parents: 67
diff changeset
594 (set_attr "isa" "lpmx,lpm")
kono
parents: 67
diff changeset
595 (set_attr "cc" "none")])
kono
parents: 67
diff changeset
596
kono
parents: 67
diff changeset
597 ;; R21:Z : 24-bit source address
kono
parents: 67
diff changeset
598 ;; R22 : 1-4 byte output
kono
parents: 67
diff changeset
599
kono
parents: 67
diff changeset
600 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc"
kono
parents: 67
diff changeset
601 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc"
kono
parents: 67
diff changeset
602 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc"
kono
parents: 67
diff changeset
603 ;; "xload_sf_libgcc"
kono
parents: 67
diff changeset
604 ;; "xload_psi_libgcc"
kono
parents: 67
diff changeset
605 (define_insn "xload_<mode>_libgcc"
kono
parents: 67
diff changeset
606 [(set (reg:MOVMODE 22)
kono
parents: 67
diff changeset
607 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
kono
parents: 67
diff changeset
608 (reg:HI REG_Z))))
kono
parents: 67
diff changeset
609 (clobber (reg:QI 21))
kono
parents: 67
diff changeset
610 (clobber (reg:HI REG_Z))]
kono
parents: 67
diff changeset
611 "avr_xload_libgcc_p (<MODE>mode)"
kono
parents: 67
diff changeset
612 {
kono
parents: 67
diff changeset
613 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
kono
parents: 67
diff changeset
614
kono
parents: 67
diff changeset
615 output_asm_insn ("%~call __xload_%0", &x_bytes);
kono
parents: 67
diff changeset
616 return "";
kono
parents: 67
diff changeset
617 }
kono
parents: 67
diff changeset
618 [(set_attr "type" "xcall")
kono
parents: 67
diff changeset
619 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
620
kono
parents: 67
diff changeset
621
kono
parents: 67
diff changeset
622 ;; General move expanders
kono
parents: 67
diff changeset
623
kono
parents: 67
diff changeset
624 ;; "movqi" "movqq" "movuqq"
kono
parents: 67
diff changeset
625 ;; "movhi" "movhq" "movuhq" "movha" "movuha"
kono
parents: 67
diff changeset
626 ;; "movsi" "movsq" "movusq" "movsa" "movusa"
kono
parents: 67
diff changeset
627 ;; "movsf"
kono
parents: 67
diff changeset
628 ;; "movpsi"
kono
parents: 67
diff changeset
629 (define_expand "mov<mode>"
kono
parents: 67
diff changeset
630 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
kono
parents: 67
diff changeset
631 (match_operand:MOVMODE 1 "general_operand" ""))]
kono
parents: 67
diff changeset
632 ""
kono
parents: 67
diff changeset
633 {
kono
parents: 67
diff changeset
634 rtx dest = operands[0];
kono
parents: 67
diff changeset
635 rtx src = avr_eval_addr_attrib (operands[1]);
kono
parents: 67
diff changeset
636
kono
parents: 67
diff changeset
637 if (avr_mem_flash_p (dest))
kono
parents: 67
diff changeset
638 DONE;
kono
parents: 67
diff changeset
639
kono
parents: 67
diff changeset
640 if (QImode == <MODE>mode
kono
parents: 67
diff changeset
641 && SUBREG_P (src)
kono
parents: 67
diff changeset
642 && CONSTANT_ADDRESS_P (SUBREG_REG (src))
kono
parents: 67
diff changeset
643 && can_create_pseudo_p())
kono
parents: 67
diff changeset
644 {
kono
parents: 67
diff changeset
645 // store_bitfield may want to store a SYMBOL_REF or CONST in a
kono
parents: 67
diff changeset
646 // structure that's represented as PSImode. As the upper 16 bits
kono
parents: 67
diff changeset
647 // of PSImode cannot be expressed as an HImode subreg, the rhs is
kono
parents: 67
diff changeset
648 // decomposed into QImode (word_mode) subregs of SYMBOL_REF,
kono
parents: 67
diff changeset
649 // CONST or LABEL_REF; cf. PR71103.
kono
parents: 67
diff changeset
650
kono
parents: 67
diff changeset
651 rtx const_addr = SUBREG_REG (src);
kono
parents: 67
diff changeset
652 operands[1] = src = copy_rtx (src);
kono
parents: 67
diff changeset
653 SUBREG_REG (src) = copy_to_mode_reg (GET_MODE (const_addr), const_addr);
kono
parents: 67
diff changeset
654 }
kono
parents: 67
diff changeset
655
kono
parents: 67
diff changeset
656 /* One of the operands has to be in a register. */
kono
parents: 67
diff changeset
657 if (!register_operand (dest, <MODE>mode)
kono
parents: 67
diff changeset
658 && !reg_or_0_operand (src, <MODE>mode))
kono
parents: 67
diff changeset
659 {
kono
parents: 67
diff changeset
660 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
kono
parents: 67
diff changeset
661 }
kono
parents: 67
diff changeset
662
kono
parents: 67
diff changeset
663 if (avr_mem_memx_p (src))
kono
parents: 67
diff changeset
664 {
kono
parents: 67
diff changeset
665 rtx addr = XEXP (src, 0);
kono
parents: 67
diff changeset
666
kono
parents: 67
diff changeset
667 if (!REG_P (addr))
kono
parents: 67
diff changeset
668 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
kono
parents: 67
diff changeset
669
kono
parents: 67
diff changeset
670 if (!avr_xload_libgcc_p (<MODE>mode))
kono
parents: 67
diff changeset
671 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
kono
parents: 67
diff changeset
672 ; insn-emit does not depend on the mode, it's all about operands. */
kono
parents: 67
diff changeset
673 emit_insn (gen_xload8qi_A (dest, src));
kono
parents: 67
diff changeset
674 else
kono
parents: 67
diff changeset
675 emit_insn (gen_xload<mode>_A (dest, src));
kono
parents: 67
diff changeset
676
kono
parents: 67
diff changeset
677 DONE;
kono
parents: 67
diff changeset
678 }
kono
parents: 67
diff changeset
679
kono
parents: 67
diff changeset
680 if (avr_load_libgcc_p (src))
kono
parents: 67
diff changeset
681 {
kono
parents: 67
diff changeset
682 /* For the small devices, do loads per libgcc call. */
kono
parents: 67
diff changeset
683 emit_insn (gen_load<mode>_libgcc (dest, src));
kono
parents: 67
diff changeset
684 DONE;
kono
parents: 67
diff changeset
685 }
kono
parents: 67
diff changeset
686 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
687
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
688 ;;========================================================================
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
689 ;; move byte
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
690 ;; The last alternative (any immediate constant to any register) is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
691 ;; very expensive. It should be optimized by peephole2 if a scratch
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
692 ;; register is available, but then that register could just as well be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
693 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
694 ;; are call-saved registers, and most of LD_REGS are call-used registers,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
695 ;; so this may still be a win for registers live across function calls.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
696
111
kono
parents: 67
diff changeset
697 ;; "movqi_insn"
kono
parents: 67
diff changeset
698 ;; "movqq_insn" "movuqq_insn"
kono
parents: 67
diff changeset
699 (define_insn "mov<mode>_insn"
kono
parents: 67
diff changeset
700 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
kono
parents: 67
diff changeset
701 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
kono
parents: 67
diff changeset
702 "register_operand (operands[0], <MODE>mode)
kono
parents: 67
diff changeset
703 || reg_or_0_operand (operands[1], <MODE>mode)"
kono
parents: 67
diff changeset
704 {
kono
parents: 67
diff changeset
705 return output_movqi (insn, operands, NULL);
kono
parents: 67
diff changeset
706 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
707 [(set_attr "length" "1,1,5,5,1,1,4")
111
kono
parents: 67
diff changeset
708 (set_attr "adjust_len" "mov8")
kono
parents: 67
diff changeset
709 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
710
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
711 ;; This is used in peephole2 to optimize loading immediate constants
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
712 ;; if a scratch register from LD_REGS happens to be available.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
713
111
kono
parents: 67
diff changeset
714 ;; "*reload_inqi"
kono
parents: 67
diff changeset
715 ;; "*reload_inqq" "*reload_inuqq"
kono
parents: 67
diff changeset
716 (define_insn "*reload_in<mode>"
kono
parents: 67
diff changeset
717 [(set (match_operand:ALL1 0 "register_operand" "=l")
kono
parents: 67
diff changeset
718 (match_operand:ALL1 1 "const_operand" "i"))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
719 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
720 "reload_completed"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
721 "ldi %2,lo8(%1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
722 mov %0,%2"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
723 [(set_attr "length" "2")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
724 (set_attr "cc" "none")])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
725
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
726 (define_peephole2
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
727 [(match_scratch:QI 2 "d")
111
kono
parents: 67
diff changeset
728 (set (match_operand:ALL1 0 "l_register_operand" "")
kono
parents: 67
diff changeset
729 (match_operand:ALL1 1 "const_operand" ""))]
kono
parents: 67
diff changeset
730 ; No need for a clobber reg for 0x0, 0x01 or 0xff
kono
parents: 67
diff changeset
731 "!satisfies_constraint_Y00 (operands[1])
kono
parents: 67
diff changeset
732 && !satisfies_constraint_Y01 (operands[1])
kono
parents: 67
diff changeset
733 && !satisfies_constraint_Ym1 (operands[1])"
kono
parents: 67
diff changeset
734 [(parallel [(set (match_dup 0)
kono
parents: 67
diff changeset
735 (match_dup 1))
kono
parents: 67
diff changeset
736 (clobber (match_dup 2))])])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 ;;============================================================================
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
739 ;; move word (16 bit)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
740
111
kono
parents: 67
diff changeset
741 ;; Move register $1 to the Stack Pointer register SP.
kono
parents: 67
diff changeset
742 ;; This insn is emit during function prologue/epilogue generation.
kono
parents: 67
diff changeset
743 ;; $2 = 0: We know that IRQs are off
kono
parents: 67
diff changeset
744 ;; $2 = 1: We know that IRQs are on
kono
parents: 67
diff changeset
745 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
kono
parents: 67
diff changeset
746 ;; $2 = -1: We don't know anything about IRQ on/off
kono
parents: 67
diff changeset
747 ;; Always write SP via unspec, see PR50063
kono
parents: 67
diff changeset
748
kono
parents: 67
diff changeset
749 (define_insn "movhi_sp_r"
kono
parents: 67
diff changeset
750 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
kono
parents: 67
diff changeset
751 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
kono
parents: 67
diff changeset
752 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
kono
parents: 67
diff changeset
753 UNSPECV_WRITE_SP))]
kono
parents: 67
diff changeset
754 ""
kono
parents: 67
diff changeset
755 "@
kono
parents: 67
diff changeset
756 out %B0,%B1\;out %A0,%A1
kono
parents: 67
diff changeset
757 cli\;out %B0,%B1\;sei\;out %A0,%A1
kono
parents: 67
diff changeset
758 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
kono
parents: 67
diff changeset
759 out %A0,%A1
kono
parents: 67
diff changeset
760 out %A0,%A1\;out %B0,%B1"
kono
parents: 67
diff changeset
761 [(set_attr "length" "2,4,5,1,2")
kono
parents: 67
diff changeset
762 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
763 (set_attr "cc" "none")])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
764
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
765 (define_peephole2
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
766 [(match_scratch:QI 2 "d")
111
kono
parents: 67
diff changeset
767 (set (match_operand:ALL2 0 "l_register_operand" "")
kono
parents: 67
diff changeset
768 (match_operand:ALL2 1 "const_or_immediate_operand" ""))]
kono
parents: 67
diff changeset
769 "operands[1] != CONST0_RTX (<MODE>mode)"
kono
parents: 67
diff changeset
770 [(parallel [(set (match_dup 0)
kono
parents: 67
diff changeset
771 (match_dup 1))
kono
parents: 67
diff changeset
772 (clobber (match_dup 2))])])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
773
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
774 ;; '*' because it is not used in rtl generation, only in above peephole
111
kono
parents: 67
diff changeset
775 ;; "*reload_inhi"
kono
parents: 67
diff changeset
776 ;; "*reload_inhq" "*reload_inuhq"
kono
parents: 67
diff changeset
777 ;; "*reload_inha" "*reload_inuha"
kono
parents: 67
diff changeset
778 (define_insn "*reload_in<mode>"
kono
parents: 67
diff changeset
779 [(set (match_operand:ALL2 0 "l_register_operand" "=l")
kono
parents: 67
diff changeset
780 (match_operand:ALL2 1 "immediate_operand" "i"))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
781 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
782 "reload_completed"
111
kono
parents: 67
diff changeset
783 {
kono
parents: 67
diff changeset
784 return output_reload_inhi (operands, operands[2], NULL);
kono
parents: 67
diff changeset
785 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
786 [(set_attr "length" "4")
111
kono
parents: 67
diff changeset
787 (set_attr "adjust_len" "reload_in16")
kono
parents: 67
diff changeset
788 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
789
kono
parents: 67
diff changeset
790 ;; "*movhi"
kono
parents: 67
diff changeset
791 ;; "*movhq" "*movuhq"
kono
parents: 67
diff changeset
792 ;; "*movha" "*movuha"
kono
parents: 67
diff changeset
793 (define_insn "*mov<mode>"
kono
parents: 67
diff changeset
794 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
kono
parents: 67
diff changeset
795 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
kono
parents: 67
diff changeset
796 "register_operand (operands[0], <MODE>mode)
kono
parents: 67
diff changeset
797 || reg_or_0_operand (operands[1], <MODE>mode)"
kono
parents: 67
diff changeset
798 {
kono
parents: 67
diff changeset
799 return output_movhi (insn, operands, NULL);
kono
parents: 67
diff changeset
800 }
kono
parents: 67
diff changeset
801 [(set_attr "length" "2,2,6,7,2,6,5,2")
kono
parents: 67
diff changeset
802 (set_attr "adjust_len" "mov16")
kono
parents: 67
diff changeset
803 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
804
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
805 (define_peephole2 ; movw
111
kono
parents: 67
diff changeset
806 [(set (match_operand:ALL1 0 "even_register_operand" "")
kono
parents: 67
diff changeset
807 (match_operand:ALL1 1 "even_register_operand" ""))
kono
parents: 67
diff changeset
808 (set (match_operand:ALL1 2 "odd_register_operand" "")
kono
parents: 67
diff changeset
809 (match_operand:ALL1 3 "odd_register_operand" ""))]
kono
parents: 67
diff changeset
810 "AVR_HAVE_MOVW
kono
parents: 67
diff changeset
811 && REGNO (operands[0]) == REGNO (operands[2]) - 1
kono
parents: 67
diff changeset
812 && REGNO (operands[1]) == REGNO (operands[3]) - 1"
kono
parents: 67
diff changeset
813 [(set (match_dup 4)
kono
parents: 67
diff changeset
814 (match_dup 5))]
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
815 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
816 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
817 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
818 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
819
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
820 (define_peephole2 ; movw_r
111
kono
parents: 67
diff changeset
821 [(set (match_operand:ALL1 0 "odd_register_operand" "")
kono
parents: 67
diff changeset
822 (match_operand:ALL1 1 "odd_register_operand" ""))
kono
parents: 67
diff changeset
823 (set (match_operand:ALL1 2 "even_register_operand" "")
kono
parents: 67
diff changeset
824 (match_operand:ALL1 3 "even_register_operand" ""))]
kono
parents: 67
diff changeset
825 "AVR_HAVE_MOVW
kono
parents: 67
diff changeset
826 && REGNO (operands[2]) == REGNO (operands[0]) - 1
kono
parents: 67
diff changeset
827 && REGNO (operands[3]) == REGNO (operands[1]) - 1"
kono
parents: 67
diff changeset
828 [(set (match_dup 4)
kono
parents: 67
diff changeset
829 (match_dup 5))]
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
830 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
831 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
832 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
833 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
834
111
kono
parents: 67
diff changeset
835 ;; For LPM loads from AS1 we split
kono
parents: 67
diff changeset
836 ;; R = *Z
kono
parents: 67
diff changeset
837 ;; to
kono
parents: 67
diff changeset
838 ;; R = *Z++
kono
parents: 67
diff changeset
839 ;; Z = Z - sizeof (R)
kono
parents: 67
diff changeset
840 ;;
kono
parents: 67
diff changeset
841 ;; so that the second instruction can be optimized out.
kono
parents: 67
diff changeset
842
kono
parents: 67
diff changeset
843 (define_split ; "split-lpmx"
kono
parents: 67
diff changeset
844 [(set (match_operand:HISI 0 "register_operand" "")
kono
parents: 67
diff changeset
845 (match_operand:HISI 1 "memory_operand" ""))]
kono
parents: 67
diff changeset
846 "reload_completed
kono
parents: 67
diff changeset
847 && AVR_HAVE_LPMX"
kono
parents: 67
diff changeset
848 [(set (match_dup 0)
kono
parents: 67
diff changeset
849 (match_dup 2))
kono
parents: 67
diff changeset
850 (set (match_dup 3)
kono
parents: 67
diff changeset
851 (plus:HI (match_dup 3)
kono
parents: 67
diff changeset
852 (match_dup 4)))]
kono
parents: 67
diff changeset
853 {
kono
parents: 67
diff changeset
854 rtx addr = XEXP (operands[1], 0);
kono
parents: 67
diff changeset
855
kono
parents: 67
diff changeset
856 if (!avr_mem_flash_p (operands[1])
kono
parents: 67
diff changeset
857 || !REG_P (addr)
kono
parents: 67
diff changeset
858 || reg_overlap_mentioned_p (addr, operands[0]))
kono
parents: 67
diff changeset
859 {
kono
parents: 67
diff changeset
860 FAIL;
kono
parents: 67
diff changeset
861 }
kono
parents: 67
diff changeset
862
kono
parents: 67
diff changeset
863 operands[2] = replace_equiv_address (operands[1],
kono
parents: 67
diff changeset
864 gen_rtx_POST_INC (Pmode, addr));
kono
parents: 67
diff changeset
865 operands[3] = addr;
kono
parents: 67
diff changeset
866 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
kono
parents: 67
diff changeset
867 })
kono
parents: 67
diff changeset
868
kono
parents: 67
diff changeset
869 ;;==========================================================================
kono
parents: 67
diff changeset
870 ;; xpointer move (24 bit)
kono
parents: 67
diff changeset
871
kono
parents: 67
diff changeset
872 (define_peephole2 ; *reload_inpsi
kono
parents: 67
diff changeset
873 [(match_scratch:QI 2 "d")
kono
parents: 67
diff changeset
874 (set (match_operand:PSI 0 "l_register_operand" "")
kono
parents: 67
diff changeset
875 (match_operand:PSI 1 "immediate_operand" ""))
kono
parents: 67
diff changeset
876 (match_dup 2)]
kono
parents: 67
diff changeset
877 "operands[1] != const0_rtx
kono
parents: 67
diff changeset
878 && operands[1] != constm1_rtx"
kono
parents: 67
diff changeset
879 [(parallel [(set (match_dup 0)
kono
parents: 67
diff changeset
880 (match_dup 1))
kono
parents: 67
diff changeset
881 (clobber (match_dup 2))])])
kono
parents: 67
diff changeset
882
kono
parents: 67
diff changeset
883 ;; '*' because it is not used in rtl generation.
kono
parents: 67
diff changeset
884 (define_insn "*reload_inpsi"
kono
parents: 67
diff changeset
885 [(set (match_operand:PSI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
886 (match_operand:PSI 1 "immediate_operand" "i"))
kono
parents: 67
diff changeset
887 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
kono
parents: 67
diff changeset
888 "reload_completed"
kono
parents: 67
diff changeset
889 {
kono
parents: 67
diff changeset
890 return avr_out_reload_inpsi (operands, operands[2], NULL);
kono
parents: 67
diff changeset
891 }
kono
parents: 67
diff changeset
892 [(set_attr "length" "6")
kono
parents: 67
diff changeset
893 (set_attr "adjust_len" "reload_in24")
kono
parents: 67
diff changeset
894 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
895
kono
parents: 67
diff changeset
896 (define_insn "*movpsi"
kono
parents: 67
diff changeset
897 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
kono
parents: 67
diff changeset
898 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
kono
parents: 67
diff changeset
899 "register_operand (operands[0], PSImode)
kono
parents: 67
diff changeset
900 || register_operand (operands[1], PSImode)
kono
parents: 67
diff changeset
901 || const0_rtx == operands[1]"
kono
parents: 67
diff changeset
902 {
kono
parents: 67
diff changeset
903 return avr_out_movpsi (insn, operands, NULL);
kono
parents: 67
diff changeset
904 }
kono
parents: 67
diff changeset
905 [(set_attr "length" "3,3,8,9,4,10")
kono
parents: 67
diff changeset
906 (set_attr "adjust_len" "mov24")
kono
parents: 67
diff changeset
907 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
kono
parents: 67
diff changeset
908
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
909 ;;==========================================================================
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
910 ;; move double word (32 bit)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
911
111
kono
parents: 67
diff changeset
912 (define_peephole2 ; *reload_insi
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
913 [(match_scratch:QI 2 "d")
111
kono
parents: 67
diff changeset
914 (set (match_operand:ALL4 0 "l_register_operand" "")
kono
parents: 67
diff changeset
915 (match_operand:ALL4 1 "immediate_operand" ""))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
916 (match_dup 2)]
111
kono
parents: 67
diff changeset
917 "operands[1] != CONST0_RTX (<MODE>mode)"
kono
parents: 67
diff changeset
918 [(parallel [(set (match_dup 0)
kono
parents: 67
diff changeset
919 (match_dup 1))
kono
parents: 67
diff changeset
920 (clobber (match_dup 2))])])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
921
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
922 ;; '*' because it is not used in rtl generation.
111
kono
parents: 67
diff changeset
923 ;; "*reload_insi"
kono
parents: 67
diff changeset
924 ;; "*reload_insq" "*reload_inusq"
kono
parents: 67
diff changeset
925 ;; "*reload_insa" "*reload_inusa"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
926 (define_insn "*reload_insi"
111
kono
parents: 67
diff changeset
927 [(set (match_operand:ALL4 0 "register_operand" "=r")
kono
parents: 67
diff changeset
928 (match_operand:ALL4 1 "immediate_operand" "n Ynn"))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
929 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
930 "reload_completed"
111
kono
parents: 67
diff changeset
931 {
kono
parents: 67
diff changeset
932 return output_reload_insisf (operands, operands[2], NULL);
kono
parents: 67
diff changeset
933 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
934 [(set_attr "length" "8")
111
kono
parents: 67
diff changeset
935 (set_attr "adjust_len" "reload_in32")
kono
parents: 67
diff changeset
936 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
937
kono
parents: 67
diff changeset
938
kono
parents: 67
diff changeset
939 ;; "*movsi"
kono
parents: 67
diff changeset
940 ;; "*movsq" "*movusq"
kono
parents: 67
diff changeset
941 ;; "*movsa" "*movusa"
kono
parents: 67
diff changeset
942 (define_insn "*mov<mode>"
kono
parents: 67
diff changeset
943 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
kono
parents: 67
diff changeset
944 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
kono
parents: 67
diff changeset
945 "register_operand (operands[0], <MODE>mode)
kono
parents: 67
diff changeset
946 || reg_or_0_operand (operands[1], <MODE>mode)"
kono
parents: 67
diff changeset
947 {
kono
parents: 67
diff changeset
948 return output_movsisf (insn, operands, NULL);
kono
parents: 67
diff changeset
949 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
950 [(set_attr "length" "4,4,8,9,4,10")
111
kono
parents: 67
diff changeset
951 (set_attr "adjust_len" "mov32")
kono
parents: 67
diff changeset
952 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
953
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
954 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
955 ;; move floating point numbers (32 bit)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
956
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
957 (define_insn "*movsf"
111
kono
parents: 67
diff changeset
958 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
kono
parents: 67
diff changeset
959 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
960 "register_operand (operands[0], SFmode)
111
kono
parents: 67
diff changeset
961 || reg_or_0_operand (operands[1], SFmode)"
kono
parents: 67
diff changeset
962 {
kono
parents: 67
diff changeset
963 return output_movsisf (insn, operands, NULL);
kono
parents: 67
diff changeset
964 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
965 [(set_attr "length" "4,4,8,9,4,10")
111
kono
parents: 67
diff changeset
966 (set_attr "adjust_len" "mov32")
kono
parents: 67
diff changeset
967 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
kono
parents: 67
diff changeset
968
kono
parents: 67
diff changeset
969 (define_peephole2 ; *reload_insf
kono
parents: 67
diff changeset
970 [(match_scratch:QI 2 "d")
kono
parents: 67
diff changeset
971 (set (match_operand:SF 0 "l_register_operand" "")
kono
parents: 67
diff changeset
972 (match_operand:SF 1 "const_double_operand" ""))
kono
parents: 67
diff changeset
973 (match_dup 2)]
kono
parents: 67
diff changeset
974 "operands[1] != CONST0_RTX (SFmode)"
kono
parents: 67
diff changeset
975 [(parallel [(set (match_dup 0)
kono
parents: 67
diff changeset
976 (match_dup 1))
kono
parents: 67
diff changeset
977 (clobber (match_dup 2))])])
kono
parents: 67
diff changeset
978
kono
parents: 67
diff changeset
979 ;; '*' because it is not used in rtl generation.
kono
parents: 67
diff changeset
980 (define_insn "*reload_insf"
kono
parents: 67
diff changeset
981 [(set (match_operand:SF 0 "register_operand" "=r")
kono
parents: 67
diff changeset
982 (match_operand:SF 1 "const_double_operand" "F"))
kono
parents: 67
diff changeset
983 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
kono
parents: 67
diff changeset
984 "reload_completed"
kono
parents: 67
diff changeset
985 {
kono
parents: 67
diff changeset
986 return output_reload_insisf (operands, operands[2], NULL);
kono
parents: 67
diff changeset
987 }
kono
parents: 67
diff changeset
988 [(set_attr "length" "8")
kono
parents: 67
diff changeset
989 (set_attr "adjust_len" "reload_in32")
kono
parents: 67
diff changeset
990 (set_attr "cc" "clobber")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
991
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
992 ;;=========================================================================
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
993 ;; move string (like memcpy)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
994
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
995 (define_expand "movmemhi"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
996 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
111
kono
parents: 67
diff changeset
997 (match_operand:BLK 1 "memory_operand" ""))
kono
parents: 67
diff changeset
998 (use (match_operand:HI 2 "const_int_operand" ""))
kono
parents: 67
diff changeset
999 (use (match_operand:HI 3 "const_int_operand" ""))])]
kono
parents: 67
diff changeset
1000 ""
kono
parents: 67
diff changeset
1001 {
kono
parents: 67
diff changeset
1002 if (avr_emit_movmemhi (operands))
kono
parents: 67
diff changeset
1003 DONE;
kono
parents: 67
diff changeset
1004
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1005 FAIL;
111
kono
parents: 67
diff changeset
1006 })
kono
parents: 67
diff changeset
1007
kono
parents: 67
diff changeset
1008 (define_mode_attr MOVMEM_r_d [(QI "r")
kono
parents: 67
diff changeset
1009 (HI "wd")])
kono
parents: 67
diff changeset
1010
kono
parents: 67
diff changeset
1011 ;; $0 : Address Space
kono
parents: 67
diff changeset
1012 ;; $1, $2 : Loop register
kono
parents: 67
diff changeset
1013 ;; R30 : source address
kono
parents: 67
diff changeset
1014 ;; R26 : destination address
kono
parents: 67
diff changeset
1015
kono
parents: 67
diff changeset
1016 ;; "movmem_qi"
kono
parents: 67
diff changeset
1017 ;; "movmem_hi"
kono
parents: 67
diff changeset
1018 (define_insn "movmem_<mode>"
kono
parents: 67
diff changeset
1019 [(set (mem:BLK (reg:HI REG_X))
kono
parents: 67
diff changeset
1020 (mem:BLK (reg:HI REG_Z)))
kono
parents: 67
diff changeset
1021 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
kono
parents: 67
diff changeset
1022 UNSPEC_MOVMEM)
kono
parents: 67
diff changeset
1023 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
kono
parents: 67
diff changeset
1024 (clobber (reg:HI REG_X))
kono
parents: 67
diff changeset
1025 (clobber (reg:HI REG_Z))
kono
parents: 67
diff changeset
1026 (clobber (reg:QI LPM_REGNO))
kono
parents: 67
diff changeset
1027 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
kono
parents: 67
diff changeset
1028 ""
kono
parents: 67
diff changeset
1029 {
kono
parents: 67
diff changeset
1030 return avr_out_movmem (insn, operands, NULL);
kono
parents: 67
diff changeset
1031 }
kono
parents: 67
diff changeset
1032 [(set_attr "adjust_len" "movmem")
kono
parents: 67
diff changeset
1033 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
1034
kono
parents: 67
diff changeset
1035
kono
parents: 67
diff changeset
1036 ;; $0 : Address Space
kono
parents: 67
diff changeset
1037 ;; $1 : RAMPZ RAM address
kono
parents: 67
diff changeset
1038 ;; R24 : #bytes and loop register
kono
parents: 67
diff changeset
1039 ;; R23:Z : 24-bit source address
kono
parents: 67
diff changeset
1040 ;; R26 : 16-bit destination address
kono
parents: 67
diff changeset
1041
kono
parents: 67
diff changeset
1042 ;; "movmemx_qi"
kono
parents: 67
diff changeset
1043 ;; "movmemx_hi"
kono
parents: 67
diff changeset
1044 (define_insn "movmemx_<mode>"
kono
parents: 67
diff changeset
1045 [(set (mem:BLK (reg:HI REG_X))
kono
parents: 67
diff changeset
1046 (mem:BLK (lo_sum:PSI (reg:QI 23)
kono
parents: 67
diff changeset
1047 (reg:HI REG_Z))))
kono
parents: 67
diff changeset
1048 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
kono
parents: 67
diff changeset
1049 UNSPEC_MOVMEM)
kono
parents: 67
diff changeset
1050 (use (reg:QIHI 24))
kono
parents: 67
diff changeset
1051 (clobber (reg:HI REG_X))
kono
parents: 67
diff changeset
1052 (clobber (reg:HI REG_Z))
kono
parents: 67
diff changeset
1053 (clobber (reg:QI LPM_REGNO))
kono
parents: 67
diff changeset
1054 (clobber (reg:HI 24))
kono
parents: 67
diff changeset
1055 (clobber (reg:QI 23))
kono
parents: 67
diff changeset
1056 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
kono
parents: 67
diff changeset
1057 ""
kono
parents: 67
diff changeset
1058 "%~call __movmemx_<mode>"
kono
parents: 67
diff changeset
1059 [(set_attr "type" "xcall")
kono
parents: 67
diff changeset
1060 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
1061
kono
parents: 67
diff changeset
1062
kono
parents: 67
diff changeset
1063 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1064 ;; memset (%0, %2, %1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1065
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1066 (define_expand "setmemhi"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1067 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
111
kono
parents: 67
diff changeset
1068 (match_operand 2 "const_int_operand" ""))
kono
parents: 67
diff changeset
1069 (use (match_operand:HI 1 "const_int_operand" ""))
kono
parents: 67
diff changeset
1070 (use (match_operand:HI 3 "const_int_operand" ""))
kono
parents: 67
diff changeset
1071 (clobber (match_scratch:HI 5 ""))
kono
parents: 67
diff changeset
1072 (clobber (match_dup 4))])]
kono
parents: 67
diff changeset
1073 ""
kono
parents: 67
diff changeset
1074 {
kono
parents: 67
diff changeset
1075 rtx addr0;
kono
parents: 67
diff changeset
1076 machine_mode mode;
kono
parents: 67
diff changeset
1077
kono
parents: 67
diff changeset
1078 /* If value to set is not zero, use the library routine. */
kono
parents: 67
diff changeset
1079 if (operands[2] != const0_rtx)
kono
parents: 67
diff changeset
1080 FAIL;
kono
parents: 67
diff changeset
1081
kono
parents: 67
diff changeset
1082 if (!CONST_INT_P (operands[1]))
kono
parents: 67
diff changeset
1083 FAIL;
kono
parents: 67
diff changeset
1084
kono
parents: 67
diff changeset
1085 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
kono
parents: 67
diff changeset
1086 operands[4] = gen_rtx_SCRATCH (mode);
kono
parents: 67
diff changeset
1087 operands[1] = copy_to_mode_reg (mode,
kono
parents: 67
diff changeset
1088 gen_int_mode (INTVAL (operands[1]), mode));
kono
parents: 67
diff changeset
1089 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
kono
parents: 67
diff changeset
1090 operands[0] = gen_rtx_MEM (BLKmode, addr0);
kono
parents: 67
diff changeset
1091 })
kono
parents: 67
diff changeset
1092
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1093
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1094 (define_insn "*clrmemqi"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1095 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
111
kono
parents: 67
diff changeset
1096 (const_int 0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1097 (use (match_operand:QI 1 "register_operand" "r"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1098 (use (match_operand:QI 2 "const_int_operand" "n"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1099 (clobber (match_scratch:HI 3 "=0"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1100 (clobber (match_scratch:QI 4 "=&1"))]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1101 ""
111
kono
parents: 67
diff changeset
1102 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1103 [(set_attr "length" "3")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1104 (set_attr "cc" "clobber")])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1105
111
kono
parents: 67
diff changeset
1106
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1107 (define_insn "*clrmemhi"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1108 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
111
kono
parents: 67
diff changeset
1109 (const_int 0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1110 (use (match_operand:HI 1 "register_operand" "!w,d"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1111 (use (match_operand:HI 2 "const_int_operand" "n,n"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1112 (clobber (match_scratch:HI 3 "=0,0"))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1113 (clobber (match_scratch:HI 4 "=&1,&1"))]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1114 ""
111
kono
parents: 67
diff changeset
1115 "@
kono
parents: 67
diff changeset
1116 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
kono
parents: 67
diff changeset
1117 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1118 [(set_attr "length" "3,4")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1119 (set_attr "cc" "clobber,clobber")])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1120
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1121 (define_expand "strlenhi"
111
kono
parents: 67
diff changeset
1122 [(set (match_dup 4)
kono
parents: 67
diff changeset
1123 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
kono
parents: 67
diff changeset
1124 (match_operand:QI 2 "const_int_operand" "")
kono
parents: 67
diff changeset
1125 (match_operand:HI 3 "immediate_operand" "")]
kono
parents: 67
diff changeset
1126 UNSPEC_STRLEN))
kono
parents: 67
diff changeset
1127 (set (match_dup 4)
kono
parents: 67
diff changeset
1128 (plus:HI (match_dup 4)
kono
parents: 67
diff changeset
1129 (const_int -1)))
kono
parents: 67
diff changeset
1130 (parallel [(set (match_operand:HI 0 "register_operand" "")
kono
parents: 67
diff changeset
1131 (minus:HI (match_dup 4)
kono
parents: 67
diff changeset
1132 (match_dup 5)))
kono
parents: 67
diff changeset
1133 (clobber (scratch:QI))])]
kono
parents: 67
diff changeset
1134 ""
kono
parents: 67
diff changeset
1135 {
kono
parents: 67
diff changeset
1136 rtx addr;
kono
parents: 67
diff changeset
1137 if (operands[2] != const0_rtx)
kono
parents: 67
diff changeset
1138 FAIL;
kono
parents: 67
diff changeset
1139 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
kono
parents: 67
diff changeset
1140 operands[1] = gen_rtx_MEM (BLKmode, addr);
kono
parents: 67
diff changeset
1141 operands[5] = addr;
kono
parents: 67
diff changeset
1142 operands[4] = gen_reg_rtx (HImode);
kono
parents: 67
diff changeset
1143 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1144
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1145 (define_insn "*strlenhi"
111
kono
parents: 67
diff changeset
1146 [(set (match_operand:HI 0 "register_operand" "=e")
kono
parents: 67
diff changeset
1147 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
kono
parents: 67
diff changeset
1148 (const_int 0)
kono
parents: 67
diff changeset
1149 (match_operand:HI 2 "immediate_operand" "i")]
kono
parents: 67
diff changeset
1150 UNSPEC_STRLEN))]
kono
parents: 67
diff changeset
1151 ""
kono
parents: 67
diff changeset
1152 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1153 [(set_attr "length" "3")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1154 (set_attr "cc" "clobber")])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1155
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1156 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1157 ; add bytes
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1158
111
kono
parents: 67
diff changeset
1159 ;; "addqi3"
kono
parents: 67
diff changeset
1160 ;; "addqq3" "adduqq3"
kono
parents: 67
diff changeset
1161 (define_insn "add<mode>3"
kono
parents: 67
diff changeset
1162 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
kono
parents: 67
diff changeset
1163 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
kono
parents: 67
diff changeset
1164 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1165 ""
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1166 "@
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1167 add %0,%2
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1168 subi %0,lo8(-(%2))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1169 inc %0
111
kono
parents: 67
diff changeset
1170 dec %0
kono
parents: 67
diff changeset
1171 inc %0\;inc %0
kono
parents: 67
diff changeset
1172 dec %0\;dec %0"
kono
parents: 67
diff changeset
1173 [(set_attr "length" "1,1,1,1,2,2")
kono
parents: 67
diff changeset
1174 (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")])
kono
parents: 67
diff changeset
1175
kono
parents: 67
diff changeset
1176 ;; "addhi3"
kono
parents: 67
diff changeset
1177 ;; "addhq3" "adduhq3"
kono
parents: 67
diff changeset
1178 ;; "addha3" "adduha3"
kono
parents: 67
diff changeset
1179 (define_expand "add<mode>3"
kono
parents: 67
diff changeset
1180 [(set (match_operand:ALL2 0 "register_operand" "")
kono
parents: 67
diff changeset
1181 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "")
kono
parents: 67
diff changeset
1182 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))]
kono
parents: 67
diff changeset
1183 ""
kono
parents: 67
diff changeset
1184 {
kono
parents: 67
diff changeset
1185 if (CONST_INT_P (operands[2]))
kono
parents: 67
diff changeset
1186 {
kono
parents: 67
diff changeset
1187 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
kono
parents: 67
diff changeset
1188
kono
parents: 67
diff changeset
1189 if (can_create_pseudo_p()
kono
parents: 67
diff changeset
1190 && !stack_register_operand (operands[0], HImode)
kono
parents: 67
diff changeset
1191 && !stack_register_operand (operands[1], HImode)
kono
parents: 67
diff changeset
1192 && !d_register_operand (operands[0], HImode)
kono
parents: 67
diff changeset
1193 && !d_register_operand (operands[1], HImode))
kono
parents: 67
diff changeset
1194 {
kono
parents: 67
diff changeset
1195 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
kono
parents: 67
diff changeset
1196 DONE;
kono
parents: 67
diff changeset
1197 }
kono
parents: 67
diff changeset
1198 }
kono
parents: 67
diff changeset
1199
kono
parents: 67
diff changeset
1200 if (CONST_FIXED_P (operands[2]))
kono
parents: 67
diff changeset
1201 {
kono
parents: 67
diff changeset
1202 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
kono
parents: 67
diff changeset
1203 DONE;
kono
parents: 67
diff changeset
1204 }
kono
parents: 67
diff changeset
1205 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1206
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1207
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1208 (define_insn "*addhi3_zero_extend"
111
kono
parents: 67
diff changeset
1209 [(set (match_operand:HI 0 "register_operand" "=r,*?r")
kono
parents: 67
diff changeset
1210 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r ,0"))
kono
parents: 67
diff changeset
1211 (match_operand:HI 2 "register_operand" "0 ,r")))]
kono
parents: 67
diff changeset
1212 ""
kono
parents: 67
diff changeset
1213 "@
kono
parents: 67
diff changeset
1214 add %A0,%1\;adc %B0,__zero_reg__
kono
parents: 67
diff changeset
1215 add %A0,%A2\;mov %B0,%B2\;adc %B0,__zero_reg__"
kono
parents: 67
diff changeset
1216 [(set_attr "length" "2,3")
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1217 (set_attr "cc" "set_n")])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1218
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1219 (define_insn "*addhi3_zero_extend1"
111
kono
parents: 67
diff changeset
1220 [(set (match_operand:HI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1221 (plus:HI (match_operand:HI 1 "register_operand" "0")
kono
parents: 67
diff changeset
1222 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
kono
parents: 67
diff changeset
1223 ""
kono
parents: 67
diff changeset
1224 "add %A0,%2\;adc %B0,__zero_reg__"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1225 [(set_attr "length" "2")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1226 (set_attr "cc" "set_n")])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1227
111
kono
parents: 67
diff changeset
1228 (define_insn "*addhi3.sign_extend1"
kono
parents: 67
diff changeset
1229 [(set (match_operand:HI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1230 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
kono
parents: 67
diff changeset
1231 (match_operand:HI 2 "register_operand" "0")))]
kono
parents: 67
diff changeset
1232 ""
kono
parents: 67
diff changeset
1233 {
kono
parents: 67
diff changeset
1234 return reg_overlap_mentioned_p (operands[0], operands[1])
kono
parents: 67
diff changeset
1235 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
kono
parents: 67
diff changeset
1236 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
kono
parents: 67
diff changeset
1237 }
kono
parents: 67
diff changeset
1238 [(set_attr "length" "5")
kono
parents: 67
diff changeset
1239 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
1240
kono
parents: 67
diff changeset
1241 (define_insn "*addhi3_zero_extend.const"
kono
parents: 67
diff changeset
1242 [(set (match_operand:HI 0 "register_operand" "=d")
kono
parents: 67
diff changeset
1243 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
kono
parents: 67
diff changeset
1244 (match_operand:HI 2 "const_m255_to_m1_operand" "Cn8")))]
kono
parents: 67
diff changeset
1245 ""
kono
parents: 67
diff changeset
1246 "subi %A0,%n2\;sbc %B0,%B0"
kono
parents: 67
diff changeset
1247 [(set_attr "length" "2")
kono
parents: 67
diff changeset
1248 (set_attr "cc" "set_czn")])
kono
parents: 67
diff changeset
1249
kono
parents: 67
diff changeset
1250 (define_insn "*usum_widenqihi3"
kono
parents: 67
diff changeset
1251 [(set (match_operand:HI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1252 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
kono
parents: 67
diff changeset
1253 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
kono
parents: 67
diff changeset
1254 ""
kono
parents: 67
diff changeset
1255 "add %A0,%2\;clr %B0\;rol %B0"
kono
parents: 67
diff changeset
1256 [(set_attr "length" "3")
kono
parents: 67
diff changeset
1257 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
1258
kono
parents: 67
diff changeset
1259 (define_insn "*udiff_widenqihi3"
kono
parents: 67
diff changeset
1260 [(set (match_operand:HI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1261 (minus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
kono
parents: 67
diff changeset
1262 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
kono
parents: 67
diff changeset
1263 ""
kono
parents: 67
diff changeset
1264 "sub %A0,%2\;sbc %B0,%B0"
kono
parents: 67
diff changeset
1265 [(set_attr "length" "2")
kono
parents: 67
diff changeset
1266 (set_attr "cc" "set_czn")])
kono
parents: 67
diff changeset
1267
kono
parents: 67
diff changeset
1268 (define_insn "*addhi3_sp"
kono
parents: 67
diff changeset
1269 [(set (match_operand:HI 1 "stack_register_operand" "=q")
kono
parents: 67
diff changeset
1270 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
kono
parents: 67
diff changeset
1271 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
kono
parents: 67
diff changeset
1272 ""
kono
parents: 67
diff changeset
1273 {
kono
parents: 67
diff changeset
1274 return avr_out_addto_sp (operands, NULL);
kono
parents: 67
diff changeset
1275 }
kono
parents: 67
diff changeset
1276 [(set_attr "length" "6")
kono
parents: 67
diff changeset
1277 (set_attr "adjust_len" "addto_sp")])
kono
parents: 67
diff changeset
1278
kono
parents: 67
diff changeset
1279 ;; "*addhi3"
kono
parents: 67
diff changeset
1280 ;; "*addhq3" "*adduhq3"
kono
parents: 67
diff changeset
1281 ;; "*addha3" "*adduha3"
kono
parents: 67
diff changeset
1282 (define_insn "*add<mode>3"
kono
parents: 67
diff changeset
1283 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d")
kono
parents: 67
diff changeset
1284 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
kono
parents: 67
diff changeset
1285 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
kono
parents: 67
diff changeset
1286 ""
kono
parents: 67
diff changeset
1287 {
kono
parents: 67
diff changeset
1288 return avr_out_plus (insn, operands);
kono
parents: 67
diff changeset
1289 }
kono
parents: 67
diff changeset
1290 [(set_attr "length" "2")
kono
parents: 67
diff changeset
1291 (set_attr "adjust_len" "plus")
kono
parents: 67
diff changeset
1292 (set_attr "cc" "plus")])
kono
parents: 67
diff changeset
1293
kono
parents: 67
diff changeset
1294 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
kono
parents: 67
diff changeset
1295 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
kono
parents: 67
diff changeset
1296 ;; itself because that insn is special to reload.
kono
parents: 67
diff changeset
1297
kono
parents: 67
diff changeset
1298 (define_peephole2 ; addhi3_clobber
kono
parents: 67
diff changeset
1299 [(set (match_operand:ALL2 0 "d_register_operand" "")
kono
parents: 67
diff changeset
1300 (match_operand:ALL2 1 "const_operand" ""))
kono
parents: 67
diff changeset
1301 (set (match_operand:ALL2 2 "l_register_operand" "")
kono
parents: 67
diff changeset
1302 (plus:ALL2 (match_dup 2)
kono
parents: 67
diff changeset
1303 (match_dup 0)))]
kono
parents: 67
diff changeset
1304 "peep2_reg_dead_p (2, operands[0])"
kono
parents: 67
diff changeset
1305 [(parallel [(set (match_dup 2)
kono
parents: 67
diff changeset
1306 (plus:ALL2 (match_dup 2)
kono
parents: 67
diff changeset
1307 (match_dup 1)))
kono
parents: 67
diff changeset
1308 (clobber (match_dup 3))])]
kono
parents: 67
diff changeset
1309 {
kono
parents: 67
diff changeset
1310 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
kono
parents: 67
diff changeset
1311 })
kono
parents: 67
diff changeset
1312
kono
parents: 67
diff changeset
1313 ;; Same, but with reload to NO_LD_REGS
kono
parents: 67
diff changeset
1314 ;; Combine *reload_inhi with *addhi3
kono
parents: 67
diff changeset
1315
kono
parents: 67
diff changeset
1316 (define_peephole2 ; addhi3_clobber
kono
parents: 67
diff changeset
1317 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
kono
parents: 67
diff changeset
1318 (match_operand:ALL2 1 "const_operand" ""))
kono
parents: 67
diff changeset
1319 (clobber (match_operand:QI 2 "d_register_operand" ""))])
kono
parents: 67
diff changeset
1320 (set (match_operand:ALL2 3 "l_register_operand" "")
kono
parents: 67
diff changeset
1321 (plus:ALL2 (match_dup 3)
kono
parents: 67
diff changeset
1322 (match_dup 0)))]
kono
parents: 67
diff changeset
1323 "peep2_reg_dead_p (2, operands[0])"
kono
parents: 67
diff changeset
1324 [(parallel [(set (match_dup 3)
kono
parents: 67
diff changeset
1325 (plus:ALL2 (match_dup 3)
kono
parents: 67
diff changeset
1326 (match_dup 1)))
kono
parents: 67
diff changeset
1327 (clobber (match_dup 2))])])
kono
parents: 67
diff changeset
1328
kono
parents: 67
diff changeset
1329 ;; "addhi3_clobber"
kono
parents: 67
diff changeset
1330 ;; "addhq3_clobber" "adduhq3_clobber"
kono
parents: 67
diff changeset
1331 ;; "addha3_clobber" "adduha3_clobber"
kono
parents: 67
diff changeset
1332 (define_insn "add<mode>3_clobber"
kono
parents: 67
diff changeset
1333 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
kono
parents: 67
diff changeset
1334 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
kono
parents: 67
diff changeset
1335 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
kono
parents: 67
diff changeset
1336 (clobber (match_scratch:QI 3 "=X ,X ,&d"))]
kono
parents: 67
diff changeset
1337 ""
kono
parents: 67
diff changeset
1338 {
kono
parents: 67
diff changeset
1339 return avr_out_plus (insn, operands);
kono
parents: 67
diff changeset
1340 }
kono
parents: 67
diff changeset
1341 [(set_attr "length" "4")
kono
parents: 67
diff changeset
1342 (set_attr "adjust_len" "plus")
kono
parents: 67
diff changeset
1343 (set_attr "cc" "plus")])
kono
parents: 67
diff changeset
1344
kono
parents: 67
diff changeset
1345
kono
parents: 67
diff changeset
1346 ;; "addsi3"
kono
parents: 67
diff changeset
1347 ;; "addsq3" "addusq3"
kono
parents: 67
diff changeset
1348 ;; "addsa3" "addusa3"
kono
parents: 67
diff changeset
1349 (define_insn "add<mode>3"
kono
parents: 67
diff changeset
1350 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
kono
parents: 67
diff changeset
1351 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
kono
parents: 67
diff changeset
1352 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
kono
parents: 67
diff changeset
1353 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
kono
parents: 67
diff changeset
1354 ""
kono
parents: 67
diff changeset
1355 {
kono
parents: 67
diff changeset
1356 return avr_out_plus (insn, operands);
kono
parents: 67
diff changeset
1357 }
kono
parents: 67
diff changeset
1358 [(set_attr "length" "4")
kono
parents: 67
diff changeset
1359 (set_attr "adjust_len" "plus")
kono
parents: 67
diff changeset
1360 (set_attr "cc" "plus")])
kono
parents: 67
diff changeset
1361
kono
parents: 67
diff changeset
1362 (define_insn "*addpsi3_zero_extend.qi"
kono
parents: 67
diff changeset
1363 [(set (match_operand:PSI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1364 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
kono
parents: 67
diff changeset
1365 (match_operand:PSI 2 "register_operand" "0")))]
kono
parents: 67
diff changeset
1366 ""
kono
parents: 67
diff changeset
1367 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
kono
parents: 67
diff changeset
1368 [(set_attr "length" "3")
kono
parents: 67
diff changeset
1369 (set_attr "cc" "set_n")])
kono
parents: 67
diff changeset
1370
kono
parents: 67
diff changeset
1371 (define_insn "*addpsi3_zero_extend.hi"
kono
parents: 67
diff changeset
1372 [(set (match_operand:PSI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1373 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
kono
parents: 67
diff changeset
1374 (match_operand:PSI 2 "register_operand" "0")))]
kono
parents: 67
diff changeset
1375 ""
kono
parents: 67
diff changeset
1376 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
kono
parents: 67
diff changeset
1377 [(set_attr "length" "3")
kono
parents: 67
diff changeset
1378 (set_attr "cc" "set_n")])
kono
parents: 67
diff changeset
1379
kono
parents: 67
diff changeset
1380 (define_insn "*addpsi3_sign_extend.hi"
kono
parents: 67
diff changeset
1381 [(set (match_operand:PSI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1382 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
kono
parents: 67
diff changeset
1383 (match_operand:PSI 2 "register_operand" "0")))]
kono
parents: 67
diff changeset
1384 ""
kono
parents: 67
diff changeset
1385 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
kono
parents: 67
diff changeset
1386 [(set_attr "length" "5")
kono
parents: 67
diff changeset
1387 (set_attr "cc" "set_n")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1388
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1389 (define_insn "*addsi3_zero_extend"
111
kono
parents: 67
diff changeset
1390 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1391 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
kono
parents: 67
diff changeset
1392 (match_operand:SI 2 "register_operand" "0")))]
kono
parents: 67
diff changeset
1393 ""
kono
parents: 67
diff changeset
1394 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
kono
parents: 67
diff changeset
1395 [(set_attr "length" "4")
kono
parents: 67
diff changeset
1396 (set_attr "cc" "set_n")])
kono
parents: 67
diff changeset
1397
kono
parents: 67
diff changeset
1398 (define_insn "*addsi3_zero_extend.hi"
kono
parents: 67
diff changeset
1399 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1400 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
kono
parents: 67
diff changeset
1401 (match_operand:SI 2 "register_operand" "0")))]
kono
parents: 67
diff changeset
1402 ""
kono
parents: 67
diff changeset
1403 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1404 [(set_attr "length" "4")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1405 (set_attr "cc" "set_n")])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1406
111
kono
parents: 67
diff changeset
1407 (define_insn "addpsi3"
kono
parents: 67
diff changeset
1408 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r")
kono
parents: 67
diff changeset
1409 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
kono
parents: 67
diff changeset
1410 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
kono
parents: 67
diff changeset
1411 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
kono
parents: 67
diff changeset
1412 ""
kono
parents: 67
diff changeset
1413 {
kono
parents: 67
diff changeset
1414 return avr_out_plus (insn, operands);
kono
parents: 67
diff changeset
1415 }
kono
parents: 67
diff changeset
1416 [(set_attr "length" "3")
kono
parents: 67
diff changeset
1417 (set_attr "adjust_len" "plus")
kono
parents: 67
diff changeset
1418 (set_attr "cc" "plus")])
kono
parents: 67
diff changeset
1419
kono
parents: 67
diff changeset
1420 (define_insn "subpsi3"
kono
parents: 67
diff changeset
1421 [(set (match_operand:PSI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1422 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
kono
parents: 67
diff changeset
1423 (match_operand:PSI 2 "register_operand" "r")))]
kono
parents: 67
diff changeset
1424 ""
kono
parents: 67
diff changeset
1425 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
kono
parents: 67
diff changeset
1426 [(set_attr "length" "3")
kono
parents: 67
diff changeset
1427 (set_attr "cc" "set_czn")])
kono
parents: 67
diff changeset
1428
kono
parents: 67
diff changeset
1429 (define_insn "*subpsi3_zero_extend.qi"
kono
parents: 67
diff changeset
1430 [(set (match_operand:PSI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1431 (minus:PSI (match_operand:SI 1 "register_operand" "0")
kono
parents: 67
diff changeset
1432 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
kono
parents: 67
diff changeset
1433 ""
kono
parents: 67
diff changeset
1434 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
kono
parents: 67
diff changeset
1435 [(set_attr "length" "3")
kono
parents: 67
diff changeset
1436 (set_attr "cc" "set_czn")])
kono
parents: 67
diff changeset
1437
kono
parents: 67
diff changeset
1438 (define_insn "*subpsi3_zero_extend.hi"
kono
parents: 67
diff changeset
1439 [(set (match_operand:PSI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1440 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
kono
parents: 67
diff changeset
1441 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
kono
parents: 67
diff changeset
1442 ""
kono
parents: 67
diff changeset
1443 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
kono
parents: 67
diff changeset
1444 [(set_attr "length" "3")
kono
parents: 67
diff changeset
1445 (set_attr "cc" "set_czn")])
kono
parents: 67
diff changeset
1446
kono
parents: 67
diff changeset
1447 (define_insn "*subpsi3_sign_extend.hi"
kono
parents: 67
diff changeset
1448 [(set (match_operand:PSI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1449 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
kono
parents: 67
diff changeset
1450 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
kono
parents: 67
diff changeset
1451 ""
kono
parents: 67
diff changeset
1452 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
kono
parents: 67
diff changeset
1453 [(set_attr "length" "5")
kono
parents: 67
diff changeset
1454 (set_attr "cc" "set_czn")])
kono
parents: 67
diff changeset
1455
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1456 ;-----------------------------------------------------------------------------
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1457 ; sub bytes
111
kono
parents: 67
diff changeset
1458
kono
parents: 67
diff changeset
1459 ;; "subqi3"
kono
parents: 67
diff changeset
1460 ;; "subqq3" "subuqq3"
kono
parents: 67
diff changeset
1461 (define_insn "sub<mode>3"
kono
parents: 67
diff changeset
1462 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r")
kono
parents: 67
diff changeset
1463 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
kono
parents: 67
diff changeset
1464 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1465 ""
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1466 "@
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1467 sub %0,%2
111
kono
parents: 67
diff changeset
1468 subi %0,lo8(%2)
kono
parents: 67
diff changeset
1469 dec %0
kono
parents: 67
diff changeset
1470 inc %0
kono
parents: 67
diff changeset
1471 dec %0\;dec %0
kono
parents: 67
diff changeset
1472 inc %0\;inc %0"
kono
parents: 67
diff changeset
1473 [(set_attr "length" "1,1,1,1,2,2")
kono
parents: 67
diff changeset
1474 (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")])
kono
parents: 67
diff changeset
1475
kono
parents: 67
diff changeset
1476 ;; "subhi3"
kono
parents: 67
diff changeset
1477 ;; "subhq3" "subuhq3"
kono
parents: 67
diff changeset
1478 ;; "subha3" "subuha3"
kono
parents: 67
diff changeset
1479 (define_insn "sub<mode>3"
kono
parents: 67
diff changeset
1480 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r")
kono
parents: 67
diff changeset
1481 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
kono
parents: 67
diff changeset
1482 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
kono
parents: 67
diff changeset
1483 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
kono
parents: 67
diff changeset
1484 ""
kono
parents: 67
diff changeset
1485 {
kono
parents: 67
diff changeset
1486 return avr_out_plus (insn, operands);
kono
parents: 67
diff changeset
1487 }
kono
parents: 67
diff changeset
1488 [(set_attr "adjust_len" "plus")
kono
parents: 67
diff changeset
1489 (set_attr "cc" "plus")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1490
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1491 (define_insn "*subhi3_zero_extend1"
111
kono
parents: 67
diff changeset
1492 [(set (match_operand:HI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1493 (minus:HI (match_operand:HI 1 "register_operand" "0")
kono
parents: 67
diff changeset
1494 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
kono
parents: 67
diff changeset
1495 ""
kono
parents: 67
diff changeset
1496 "sub %A0,%2\;sbc %B0,__zero_reg__"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1497 [(set_attr "length" "2")
111
kono
parents: 67
diff changeset
1498 (set_attr "cc" "set_czn")])
kono
parents: 67
diff changeset
1499
kono
parents: 67
diff changeset
1500 (define_insn "*subhi3.sign_extend2"
kono
parents: 67
diff changeset
1501 [(set (match_operand:HI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1502 (minus:HI (match_operand:HI 1 "register_operand" "0")
kono
parents: 67
diff changeset
1503 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
kono
parents: 67
diff changeset
1504 ""
kono
parents: 67
diff changeset
1505 {
kono
parents: 67
diff changeset
1506 return reg_overlap_mentioned_p (operands[0], operands[2])
kono
parents: 67
diff changeset
1507 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
kono
parents: 67
diff changeset
1508 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
kono
parents: 67
diff changeset
1509 }
kono
parents: 67
diff changeset
1510 [(set_attr "length" "5")
kono
parents: 67
diff changeset
1511 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
1512
kono
parents: 67
diff changeset
1513 ;; "subsi3"
kono
parents: 67
diff changeset
1514 ;; "subsq3" "subusq3"
kono
parents: 67
diff changeset
1515 ;; "subsa3" "subusa3"
kono
parents: 67
diff changeset
1516 (define_insn "sub<mode>3"
kono
parents: 67
diff changeset
1517 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
kono
parents: 67
diff changeset
1518 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
kono
parents: 67
diff changeset
1519 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
kono
parents: 67
diff changeset
1520 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
kono
parents: 67
diff changeset
1521 ""
kono
parents: 67
diff changeset
1522 {
kono
parents: 67
diff changeset
1523 return avr_out_plus (insn, operands);
kono
parents: 67
diff changeset
1524 }
kono
parents: 67
diff changeset
1525 [(set_attr "adjust_len" "plus")
kono
parents: 67
diff changeset
1526 (set_attr "cc" "plus")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1527
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1528 (define_insn "*subsi3_zero_extend"
111
kono
parents: 67
diff changeset
1529 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1530 (minus:SI (match_operand:SI 1 "register_operand" "0")
kono
parents: 67
diff changeset
1531 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
kono
parents: 67
diff changeset
1532 ""
kono
parents: 67
diff changeset
1533 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1534 [(set_attr "length" "4")
111
kono
parents: 67
diff changeset
1535 (set_attr "cc" "set_czn")])
kono
parents: 67
diff changeset
1536
kono
parents: 67
diff changeset
1537 (define_insn "*subsi3_zero_extend.hi"
kono
parents: 67
diff changeset
1538 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1539 (minus:SI (match_operand:SI 1 "register_operand" "0")
kono
parents: 67
diff changeset
1540 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
kono
parents: 67
diff changeset
1541 ""
kono
parents: 67
diff changeset
1542 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
kono
parents: 67
diff changeset
1543 [(set_attr "length" "4")
kono
parents: 67
diff changeset
1544 (set_attr "cc" "set_czn")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1545
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1546 ;******************************************************************************
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1547 ; mul
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1548
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1549 (define_expand "mulqi3"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1550 [(set (match_operand:QI 0 "register_operand" "")
111
kono
parents: 67
diff changeset
1551 (mult:QI (match_operand:QI 1 "register_operand" "")
kono
parents: 67
diff changeset
1552 (match_operand:QI 2 "register_operand" "")))]
kono
parents: 67
diff changeset
1553 ""
kono
parents: 67
diff changeset
1554 {
kono
parents: 67
diff changeset
1555 if (!AVR_HAVE_MUL)
kono
parents: 67
diff changeset
1556 {
kono
parents: 67
diff changeset
1557 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
kono
parents: 67
diff changeset
1558 DONE;
kono
parents: 67
diff changeset
1559 }
kono
parents: 67
diff changeset
1560 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1561
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1562 (define_insn "*mulqi3_enh"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1563 [(set (match_operand:QI 0 "register_operand" "=r")
111
kono
parents: 67
diff changeset
1564 (mult:QI (match_operand:QI 1 "register_operand" "r")
kono
parents: 67
diff changeset
1565 (match_operand:QI 2 "register_operand" "r")))]
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1566 "AVR_HAVE_MUL"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1567 "mul %1,%2
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1568 mov %0,r0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1569 clr r1"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1570 [(set_attr "length" "3")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1571 (set_attr "cc" "clobber")])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1572
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1573 (define_expand "mulqi3_call"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1574 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1575 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1576 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
111
kono
parents: 67
diff changeset
1577 (clobber (reg:QI 22))])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1578 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1579 ""
111
kono
parents: 67
diff changeset
1580 {
kono
parents: 67
diff changeset
1581 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
kono
parents: 67
diff changeset
1582 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1583
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1584 (define_insn "*mulqi3_call"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1585 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1586 (clobber (reg:QI 22))]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1587 "!AVR_HAVE_MUL"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1588 "%~call __mulqi3"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1589 [(set_attr "type" "xcall")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1590 (set_attr "cc" "clobber")])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1591
111
kono
parents: 67
diff changeset
1592 ;; "umulqi3_highpart"
kono
parents: 67
diff changeset
1593 ;; "smulqi3_highpart"
kono
parents: 67
diff changeset
1594 (define_insn "<extend_su>mulqi3_highpart"
kono
parents: 67
diff changeset
1595 [(set (match_operand:QI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1596 (truncate:QI
kono
parents: 67
diff changeset
1597 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
kono
parents: 67
diff changeset
1598 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
kono
parents: 67
diff changeset
1599 (const_int 8))))]
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1600 "AVR_HAVE_MUL"
111
kono
parents: 67
diff changeset
1601 "mul<extend_s> %1,%2
kono
parents: 67
diff changeset
1602 mov %0,r1
kono
parents: 67
diff changeset
1603 clr __zero_reg__"
kono
parents: 67
diff changeset
1604 [(set_attr "length" "3")
kono
parents: 67
diff changeset
1605 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
1606
kono
parents: 67
diff changeset
1607
kono
parents: 67
diff changeset
1608 ;; Used when expanding div or mod inline for some special values
kono
parents: 67
diff changeset
1609 (define_insn "*subqi3.ashiftrt7"
kono
parents: 67
diff changeset
1610 [(set (match_operand:QI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1611 (minus:QI (match_operand:QI 1 "register_operand" "0")
kono
parents: 67
diff changeset
1612 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
kono
parents: 67
diff changeset
1613 (const_int 7))))]
kono
parents: 67
diff changeset
1614 ""
kono
parents: 67
diff changeset
1615 "sbrc %2,7\;inc %0"
kono
parents: 67
diff changeset
1616 [(set_attr "length" "2")
kono
parents: 67
diff changeset
1617 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
1618
kono
parents: 67
diff changeset
1619 (define_insn "*addqi3.lt0"
kono
parents: 67
diff changeset
1620 [(set (match_operand:QI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1621 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
kono
parents: 67
diff changeset
1622 (const_int 0))
kono
parents: 67
diff changeset
1623 (match_operand:QI 2 "register_operand" "0")))]
kono
parents: 67
diff changeset
1624 ""
kono
parents: 67
diff changeset
1625 "sbrc %1,7\;inc %0"
kono
parents: 67
diff changeset
1626 [(set_attr "length" "2")
kono
parents: 67
diff changeset
1627 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
1628
kono
parents: 67
diff changeset
1629 (define_insn "*addhi3.lt0"
kono
parents: 67
diff changeset
1630 [(set (match_operand:HI 0 "register_operand" "=w,r")
kono
parents: 67
diff changeset
1631 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
kono
parents: 67
diff changeset
1632 (const_int 0))
kono
parents: 67
diff changeset
1633 (match_operand:HI 2 "register_operand" "0,0")))
kono
parents: 67
diff changeset
1634 (clobber (match_scratch:QI 3 "=X,&1"))]
kono
parents: 67
diff changeset
1635 ""
kono
parents: 67
diff changeset
1636 "@
kono
parents: 67
diff changeset
1637 sbrc %1,7\;adiw %0,1
kono
parents: 67
diff changeset
1638 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
kono
parents: 67
diff changeset
1639 [(set_attr "length" "2,3")
kono
parents: 67
diff changeset
1640 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
1641
kono
parents: 67
diff changeset
1642 (define_insn "*addpsi3.lt0"
kono
parents: 67
diff changeset
1643 [(set (match_operand:PSI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1644 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
kono
parents: 67
diff changeset
1645 (const_int 23))
kono
parents: 67
diff changeset
1646 (match_operand:PSI 2 "register_operand" "0")))]
kono
parents: 67
diff changeset
1647 ""
kono
parents: 67
diff changeset
1648 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
kono
parents: 67
diff changeset
1649 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
kono
parents: 67
diff changeset
1650 [(set_attr "length" "5")
kono
parents: 67
diff changeset
1651 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
1652
kono
parents: 67
diff changeset
1653 (define_insn "*addsi3.lt0"
kono
parents: 67
diff changeset
1654 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1655 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
kono
parents: 67
diff changeset
1656 (const_int 31))
kono
parents: 67
diff changeset
1657 (match_operand:SI 2 "register_operand" "0")))]
kono
parents: 67
diff changeset
1658 ""
kono
parents: 67
diff changeset
1659 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
kono
parents: 67
diff changeset
1660 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
kono
parents: 67
diff changeset
1661 [(set_attr "length" "6")
kono
parents: 67
diff changeset
1662 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
1663
kono
parents: 67
diff changeset
1664 (define_insn "*umulqihi3.call"
kono
parents: 67
diff changeset
1665 [(set (reg:HI 24)
kono
parents: 67
diff changeset
1666 (mult:HI (zero_extend:HI (reg:QI 22))
kono
parents: 67
diff changeset
1667 (zero_extend:HI (reg:QI 24))))
kono
parents: 67
diff changeset
1668 (clobber (reg:QI 21))
kono
parents: 67
diff changeset
1669 (clobber (reg:HI 22))]
kono
parents: 67
diff changeset
1670 "!AVR_HAVE_MUL"
kono
parents: 67
diff changeset
1671 "%~call __umulqihi3"
kono
parents: 67
diff changeset
1672 [(set_attr "type" "xcall")
kono
parents: 67
diff changeset
1673 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
1674
kono
parents: 67
diff changeset
1675 ;; "umulqihi3"
kono
parents: 67
diff changeset
1676 ;; "mulqihi3"
kono
parents: 67
diff changeset
1677 (define_insn "<extend_u>mulqihi3"
kono
parents: 67
diff changeset
1678 [(set (match_operand:HI 0 "register_operand" "=r")
kono
parents: 67
diff changeset
1679 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
kono
parents: 67
diff changeset
1680 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
kono
parents: 67
diff changeset
1681 "AVR_HAVE_MUL"
kono
parents: 67
diff changeset
1682 "mul<extend_s> %1,%2
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1683 movw %0,r0
111
kono
parents: 67
diff changeset
1684 clr __zero_reg__"
kono
parents: 67
diff changeset
1685 [(set_attr "length" "3")
kono
parents: 67
diff changeset
1686 (set_attr "cc" "clobber")])
kono
parents: 67
diff changeset
1687
kono
parents: 67
diff changeset
1688 (define_insn "usmulqihi3"
kono
parents: