| 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 |
|
|