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