00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <avr/io.h>
00040
00041
00042
00043 #ifndef __USER_LABEL_PREFIX__
00044 #define __USER_LABEL_PREFIX__ _
00045 #endif
00046
00047 #ifndef __REGISTER_PREFIX__
00048 #define __REGISTER_PREFIX__
00049 #endif
00050
00051
00052 #define _L $
00053
00054 #define CONCAT1(a, b) CONCAT2(a, b)
00055 #define CONCAT2(a, b) a ## b
00056
00057 #define _U(x) CONCAT1(__USER_LABEL_PREFIX__, x)
00058
00059 #define _R(x) CONCAT1(__REGISTER_PREFIX__, x)
00060
00061
00062
00063
00064 #define r0 _R(r0)
00065 #define r1 _R(r1)
00066 #define r2 _R(r2)
00067 #define r3 _R(r3)
00068 #define r4 _R(r4)
00069 #define r5 _R(r5)
00070 #define r6 _R(r6)
00071 #define r7 _R(r7)
00072 #define r8 _R(r8)
00073 #define r9 _R(r9)
00074 #define r10 _R(r10)
00075 #define r11 _R(r11)
00076 #define r12 _R(r12)
00077 #define r13 _R(r13)
00078 #define r14 _R(r14)
00079 #define r15 _R(r15)
00080 #define r16 _R(r16)
00081 #define r17 _R(r17)
00082 #define r18 _R(r18)
00083 #define r19 _R(r19)
00084 #define r20 _R(r20)
00085 #define r21 _R(r21)
00086 #define r22 _R(r22)
00087 #define r23 _R(r23)
00088 #define r24 _R(r24)
00089 #define r25 _R(r25)
00090 #define r26 _R(r26)
00091 #define r27 _R(r27)
00092 #define r28 _R(r28)
00093 #define r29 _R(r29)
00094 #define r30 _R(r30)
00095 #define r31 _R(r31)
00096
00097 #ifndef __tmp_reg__
00098 #define __tmp_reg__ r0
00099 #endif
00100
00101 #ifndef __zero_reg__
00102 #define __zero_reg__ r1
00103 #endif
00104
00105 #if __AVR_MEGA__
00106 #define XJMP jmp
00107 #define XCALL call
00108 #else
00109 #define XJMP rjmp
00110 #define XCALL rcall
00111 #endif
00112
00113
00114 #define PROLOGUE_SAVES(offset) XJMP (__prologue_saves__ + 2 * (offset))
00115 #define EPILOGUE_RESTORES(offset) XJMP (__epilogue_restores__ + 2 * (offset))
00116
00117 #if FLASHEND > 0x10000
00118 #define BIG_CODE 1
00119 #else
00120 #define BIG_CODE 0
00121 #endif
00122
00123 #ifndef __AVR_HAVE_MOVW__
00124 # if defined(__AVR_ENHANCED__) && __AVR_ENHANCED__
00125 # define __AVR_HAVE_MOVW__ 1
00126 # endif
00127 #endif
00128
00129 #ifndef __AVR_HAVE_LPMX__
00130 # if defined(__AVR_ENHANCED__) && __AVR_ENHANCED__
00131 # define __AVR_HAVE_LPMX__ 1
00132 # endif
00133 #endif
00134
00135 #ifndef __AVR_HAVE_MUL__
00136 # if defined(__AVR_ENHANCED__) && __AVR_ENHANCED__
00137 # define __AVR_HAVE_MUL__ 1
00138 # endif
00139 #endif
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 .macro X_movw dst src
00150 .L_movw_dst = -1
00151 .L_movw_src = -1
00152 .L_movw_n = 0
00153 .irp reg, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, \
00154 r10,r11,r12,r13,r14,r15,r16,r17,r18,r19, \
00155 r20,r21,r22,r23,r24,r25,r26,r27,r28,r29, \
00156 r30,r31
00157 .ifc \reg,\dst
00158 .L_movw_dst = .L_movw_n
00159 .endif
00160 .ifc \reg,\src
00161 .L_movw_src = .L_movw_n
00162 .endif
00163 .L_movw_n = .L_movw_n + 1
00164 .endr
00165 .L_movw_n = 0
00166 .irp reg, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, \
00167 R10,R11,R12,R13,R14,R15,R16,R17,R18,R19, \
00168 R20,R21,R22,R23,R24,R25,R26,R27,R28,R29, \
00169 R30,R31
00170 .ifc \reg,\dst
00171 .L_movw_dst = .L_movw_n
00172 .endif
00173 .ifc \reg,\src
00174 .L_movw_src = .L_movw_n
00175 .endif
00176 .L_movw_n = .L_movw_n + 1
00177 .endr
00178 .if .L_movw_dst < 0
00179 .L_movw_n = 0
00180 .rept 32
00181 .if \dst == .L_movw_n
00182 .L_movw_dst = .L_movw_n
00183 .endif
00184 .L_movw_n = .L_movw_n + 1
00185 .endr
00186 .endif
00187 .if .L_movw_src < 0
00188 .L_movw_n = 0
00189 .rept 32
00190 .if \src == .L_movw_n
00191 .L_movw_src = .L_movw_n
00192 .endif
00193 .L_movw_n = .L_movw_n + 1
00194 .endr
00195 .endif
00196 .if (.L_movw_dst < 0) || (.L_movw_src < 0)
00197 .err ; Invalid 'X_movw' arg.
00198 .endif
00199
00200 .if ((.L_movw_src) - (.L_movw_dst))
00201 .if (((.L_movw_src) | (.L_movw_dst)) & 0x01)
00202 .if (((.L_movw_src)-(.L_movw_dst)) & 0x80)
00203 mov (.L_movw_dst)+1, (.L_movw_src)+1
00204 mov (.L_movw_dst), (.L_movw_src)
00205 .else
00206 mov (.L_movw_dst), (.L_movw_src)
00207 mov (.L_movw_dst)+1, (.L_movw_src)+1
00208 .endif
00209 .else
00210 #if defined(__AVR_HAVE_MOVW__) && __AVR_HAVE_MOVW__
00211 movw \dst, \src
00212 #else
00213 mov (.L_movw_dst), (.L_movw_src)
00214 mov (.L_movw_dst)+1, (.L_movw_src)+1
00215 #endif
00216 .endif
00217 .endif
00218 .endm
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 .macro X_lpm dst=r0, src=Z
00240
00241
00242 .L_lpm_dst = -1
00243
00244 .L_lpm_n = 0
00245 .irp reg, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, \
00246 r10,r11,r12,r13,r14,r15,r16,r17,r18,r19, \
00247 r20,r21,r22,r23,r24,r25,r26,r27,r28,r29, \
00248 r30,r31
00249 .ifc \reg,\dst
00250 .L_lpm_dst = .L_lpm_n
00251 .endif
00252 .L_lpm_n = .L_lpm_n + 1
00253 .endr
00254
00255 .L_lpm_n = 0
00256 .irp reg, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, \
00257 R10,R11,R12,R13,R14,R15,R16,R17,R18,R19, \
00258 R20,R21,R22,R23,R24,R25,R26,R27,R28,R29, \
00259 R30,R31
00260 .ifc \reg,\dst
00261 .L_lpm_dst = .L_lpm_n
00262 .endif
00263 .L_lpm_n = .L_lpm_n + 1
00264 .endr
00265
00266 .if .L_lpm_dst < 0
00267 .L_lpm_n = 0
00268 .rept 32
00269 .if \dst == .L_lpm_n
00270 .L_lpm_dst = .L_lpm_n
00271 .endif
00272 .L_lpm_n = .L_lpm_n + 1
00273 .endr
00274 .endif
00275
00276 .if (.L_lpm_dst < 0)
00277 .err ; Invalid dst arg of 'X_lpm' macro.
00278 .endif
00279
00280
00281 .L_lpm_src = -1
00282 .L_lpm_n = 0
00283 .irp reg, z,Z,z+,Z+
00284 .ifc \reg,\src
00285 .L_lpm_src = .L_lpm_n
00286 .endif
00287 .L_lpm_n = .L_lpm_n + 1
00288 .endr
00289
00290 .if (.L_lpm_src < 0)
00291 .err ; Invalid src arg of 'X_lpm' macro.
00292 .endif
00293
00294
00295 .if .L_lpm_src < 2
00296 .if .L_lpm_dst == 0
00297 lpm
00298 .else
00299 #if defined(__AVR_HAVE_LPMX__) && __AVR_HAVE_LPMX__
00300 lpm .L_lpm_dst, Z
00301 #else
00302 lpm
00303 mov .L_lpm_dst, r0
00304 #endif
00305 .endif
00306 .else
00307 .if (.L_lpm_dst >= 30)
00308 .err ; Registers 30 and 31 are inhibited as 'X_lpm *,Z+' dst.
00309 .endif
00310 #if defined(__AVR_HAVE_LPMX__) && __AVR_HAVE_LPMX__
00311 lpm .L_lpm_dst, Z+
00312 #else
00313 lpm
00314 .if .L_lpm_dst
00315 mov .L_lpm_dst, r0
00316 .endif
00317 adiw r30, 1
00318 #endif
00319 .endif
00320 .endm
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 .macro LPM_R0_ZPLUS_INIT hhi
00336 #if __AVR_ENHANCED__
00337 #if BIG_CODE
00338 out AVR_RAMPZ_ADDR, \hhi
00339 #endif
00340 #endif
00341 .endm
00342
00343 .macro LPM_R0_ZPLUS_NEXT hhi
00344 #if __AVR_ENHANCED__
00345 #if BIG_CODE
00346
00347 elpm r0, Z+
00348 #else
00349
00350 lpm r0, Z+
00351 #endif
00352 #else
00353 #if BIG_CODE
00354
00355 out AVR_RAMPZ_ADDR, \hhi
00356 elpm
00357 adiw r30,1
00358 adc \hhi, __zero_reg__
00359 #else
00360
00361 lpm
00362 adiw r30,1
00363 #endif
00364 #endif
00365 .endm