119 |
#endif |
#endif |
120 |
|
|
121 |
/* |
/* |
122 |
Smart version of movw (use register numbers as arguments): |
Smart version of movw: |
123 |
- uses "movw" if possible (supported by MCU, and both registers even) |
- uses "movw" if possible (supported by MCU, and both registers even) |
124 |
- handles overlapping register pairs correctly |
- handles overlapping register pairs correctly |
125 |
- no instruction generated if source and destination are the same |
- no instruction generated if source and destination are the same |
126 |
(may expand to 0, 1 or 2 instructions). |
(may expand to 0, 1 or 2 instructions). |
127 |
*/ |
*/ |
128 |
|
|
129 |
.macro X_movw dest src |
.macro X_movw dst src |
130 |
.if ((\src) - (\dest)) /* different registers */ |
.L_movw_dst = -1 |
131 |
.if (((\src) | (\dest)) & 0x01) |
.L_movw_src = -1 |
132 |
.if (((\src)-(\dest)) & 0x80) /* src < dest */ |
.L_movw_n = 0 |
133 |
mov (\dest)+1, (\src)+1 |
.irp reg, r0, r1, r2, r3, r4, r5, r6, r7, \ |
134 |
mov (\dest), (\src) |
r8, r9, r10, r11, r12, r13, r14, r15, \ |
135 |
.else /* src > dest */ |
r16, r17, r18, r19, r20, r21, r22, r23, \ |
136 |
mov (\dest), (\src) |
r24, r25, r26, r27, r28, r29, r30, r31 |
137 |
mov (\dest)+1, (\src)+1 |
.ifc \reg,\dst |
138 |
.endif |
.L_movw_dst = .L_movw_n |
139 |
.else /* both even -> overlap not possible */ |
.endif |
140 |
#if __AVR_ENHANCED__ |
.ifc \reg,\src |
141 |
movw (\dest), (\src) |
.L_movw_src = .L_movw_n |
|
#else |
|
|
mov (\dest), (\src) |
|
|
mov (\dest)+1, (\src)+1 |
|
|
#endif |
|
142 |
.endif |
.endif |
143 |
|
.L_movw_n = .L_movw_n + 1 |
144 |
|
.endr |
145 |
|
.if .L_movw_dst < 0 |
146 |
|
.L_movw_n = 0 |
147 |
|
.rept 32 |
148 |
|
.if \dst == .L_movw_n |
149 |
|
.L_movw_dst = .L_movw_n |
150 |
|
.endif |
151 |
|
.L_movw_n = .L_movw_n + 1 |
152 |
|
.endr |
153 |
|
.endif |
154 |
|
.if .L_movw_src < 0 |
155 |
|
.L_movw_n = 0 |
156 |
|
.rept 32 |
157 |
|
.if \src == .L_movw_n |
158 |
|
.L_movw_src = .L_movw_n |
159 |
|
.endif |
160 |
|
.L_movw_n = .L_movw_n + 1 |
161 |
|
.endr |
162 |
|
.endif |
163 |
|
.if (.L_movw_dst < 0) || (.L_movw_src < 0) |
164 |
|
.err ; Invalid arg. |
165 |
|
.endif |
166 |
|
|
167 |
|
.if ((.L_movw_src) - (.L_movw_dst)) /* different registers */ |
168 |
|
.if (((.L_movw_src) | (.L_movw_dst)) & 0x01) |
169 |
|
.if (((.L_movw_src)-(.L_movw_dst)) & 0x80) /* src < dest */ |
170 |
|
mov (.L_movw_dst)+1, (.L_movw_src)+1 |
171 |
|
mov (.L_movw_dst), (.L_movw_src) |
172 |
|
.else /* src > dest */ |
173 |
|
mov (.L_movw_dst), (.L_movw_src) |
174 |
|
mov (.L_movw_dst)+1, (.L_movw_src)+1 |
175 |
|
.endif |
176 |
|
.else /* both even -> overlap not possible */ |
177 |
|
#if defined(__AVR_ENHANCED__) && __AVR_ENHANCED__ |
178 |
|
movw \dst, \src |
179 |
|
#else |
180 |
|
mov (.L_movw_dst), (.L_movw_src) |
181 |
|
mov (.L_movw_dst)+1, (.L_movw_src)+1 |
182 |
|
#endif |
183 |
|
.endif |
184 |
.endif |
.endif |
185 |
.endm |
.endm |
186 |
|
|