1 /* Copyright (C) 2019-2020 Free Software Foundation, Inc. 2 3 This file is part of LIBF7, which is part of GCC. 4 5 GCC is free software; you can redistribute it and/or modify it under 6 the terms of the GNU General Public License as published by the Free 7 Software Foundation; either version 3, or (at your option) any later 8 version. 9 10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 11 WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 for more details. 14 15 Under Section 7 of GPL version 3, you are granted additional 16 permissions described in the GCC Runtime Library Exception, version 17 3.1, as published by the Free Software Foundation. 18 19 You should have received a copy of the GNU General Public License and 20 a copy of the GCC Runtime Library Exception along with this program; 21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 22 <http://www.gnu.org/licenses/>. */ 23 24 #ifndef ASM_DEFS_H 25 #define ASM_DEFS_H 26 27 #ifdef __AVR__ 28 #ifdef __ASSEMBLER__ 29 /*****************************************************************/ 30 /* Stuff for Assembler-only */ 31 /*****************************************************************/ 32 33 #if defined (__AVR_TINY__) 34 #define __tmp_reg__ 16 35 #define __zero_reg__ 17 36 #else 37 #define __tmp_reg__ 0 38 #define __zero_reg__ 1 39 #endif /* AVR_TINY */ 40 41 #define __SREG__ 0x3f 42 #define __SP_L__ 0x3d 43 #if defined (__AVR_HAVE_SPH__) 44 #define __SP_H__ 0x3e 45 #endif 46 47 #if !defined ASM_DEFS_HAVE_DEFUN 48 .macro DEFUN name 49 .global \name 50 .func \name 51 \name: 52 .endm 53 54 .macro ENDF name 55 .size \name, .-\name 56 .endfunc 57 .endm 58 59 .macro LABEL name 60 .global \name 61 \name: 62 .endm 63 #endif /* HAVE_DEFUN */ 64 65 66 #if defined (__AVR_HAVE_JMP_CALL__) 67 #define XCALL call 68 #define XJMP jmp 69 #else 70 #define XCALL rcall 71 #define XJMP rjmp 72 #endif 73 74 #if defined (__AVR_HAVE_EIJMP_EICALL__) 75 #define XICALL eicall 76 #define XIJMP eijmp 77 #define PC_SIZE 3 78 #else 79 #define XICALL icall 80 #define XIJMP ijmp 81 #define PC_SIZE 2 82 #endif 83 84 .macro skipnext 85 cpse r16, r16 86 .endm 87 88 /* 89 Factor out support of MOVW. Usage is like 90 91 wmov 30, 24 92 93 to move R25:R24 to R31:R30, i.e. plain register numbers 94 are required and no register prefix 'R'. 95 */ 96 97 #if defined (__AVR_HAVE_MOVW__) 98 #define wmov movw 99 #else 100 .macro wmov dst src 101 ..dst = \dst 102 ..src = \src 103 ..regno = 0 104 .irp reg, \ 105 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, \ 106 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ 107 r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, \ 108 r30, r31 109 .ifc \reg,\dst 110 ..dst = ..regno 111 .endif 112 .ifc \reg,\src 113 ..src = ..regno 114 .endif 115 ..regno = ..regno + 1 116 .endr 117 118 ..regno = 0 119 120 .irp reg, \ 121 R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, \ 122 R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, \ 123 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, \ 124 R30, R31 125 .ifc \reg,\dst 126 ..dst = ..regno 127 .endif 128 .ifc \reg,\src 129 ..src = ..regno 130 .endif 131 ..regno = ..regno + 1 132 .endr 133 134 ..regno = 0 135 136 .irp reg, \ 137 X, x, XL, xl, Xl, xL, x, x \ 138 Y, y, YL, yl, Yl, yL, y, y, \ 139 Z, z, ZL, zl, Zl, zL, z, z 140 .ifc \reg,\dst 141 ..dst = (..regno / 8) + 26 142 .endif 143 .ifc \reg,\src 144 ..src = (..regno / 8) + 26 145 .endif 146 ..regno = ..regno + 1 147 .endr 148 149 mov ..dst+0, ..src+0 150 mov ..dst+1, ..src+1 151 .endm 152 #endif /* MOVW */ 153 154 155 #if !defined (__AVR_TINY__) 156 /* 157 Convenience macro for easy use of __prologue_saves__ from libgcc. 158 Push the N_PUSHED callee-saved registers Y, R17, R16, R15, ... 159 with 0 <= N_PUSHED <= 18. The frame pointer (Y) is set up according 160 to a frame size of N_FRAME. Clobbers TMP_REG. 161 For the code of __prologue_saves__ from libgcc see 162 http://gcc.gnu.org/viewcvs/gcc/trunk/libgcc/config/avr/lib1funcs.S?revision=267494&view=markup#l2159 163 */ 164 165 .macro do_prologue_saves n_pushed n_frame=0 166 ldi r26, lo8(\n_frame) 167 ldi r27, hi8(\n_frame) 168 ldi r30, lo8(gs(.L_prologue_saves.\@)) 169 ldi r31, hi8(gs(.L_prologue_saves.\@)) 170 XJMP __prologue_saves__ + ((18 - (\n_pushed)) * 2) 171 .L_prologue_saves.\@: 172 .endm 173 174 /* 175 Convenience macro for easy use of __epilogue_restores__ from libgcc. 176 Undo the effect of __prologue_saves__. Clobbers TMP_REG. 177 For the code of __epilogue_restores__ from libgcc see 178 http://gcc.gnu.org/viewcvs/gcc/trunk/libgcc/config/avr/lib1funcs.S?revision=267494&view=markup#l2216 179 */ 180 181 .macro do_epilogue_restores n_pushed n_frame=0 182 in r28, __SP_L__ 183 #ifdef __AVR_HAVE_SPH__ 184 in r29, __SP_H__ 185 .if \n_frame > 63 186 subi r28, lo8(-\n_frame) 187 sbci r29, hi8(-\n_frame) 188 .elseif \n_frame > 0 189 adiw r28, \n_frame 190 .endif 191 #else 192 clr r29 193 .if \n_frame > 0 194 subi r28, lo8(-\n_frame) 195 .endif 196 #endif /* HAVE SPH */ 197 ldi r30, \n_pushed 198 XJMP __epilogue_restores__ + ((18 - (\n_pushed)) * 2) 199 .endm 200 201 #endif /* AVR_TINY */ 202 203 #else /* Assembler */ 204 /*****************************************************************/ 205 /* Space for C/C++ only Stuff */ 206 /*****************************************************************/ 207 #endif /* Assembler */ 208 209 /*****************************************************************/ 210 /* Space for Generic Stuff (Assembler, C, C++) */ 211 /*****************************************************************/ 212 213 #ifdef __AVR_PM_BASE_ADDRESS__ 214 /* 215 Devices with a linear address space: Flash memory is seen in the 216 RAM address space at an offset of __AVR_PM_BASE_ADDRESS__ and can 217 be accessed by LD*. This is the case for devices like ATtiny40 218 (avrtiny) or ATtiny1616 and ATmega4808 (avrxmega3). The default 219 linker script locates .rodata in the .text output section and 220 at the required offset. 221 */ 222 #define RODATA_SECTION .rodata.asm 223 #define USE_LD 1 224 #define USE_LPM 0 225 #else /* PM_BASE_ADDRESS */ 226 /* 227 No linear address space. As .rodata is located in RAM, we have to 228 use .progmem.data (located in flash) and LPM to read the data. 229 This will also work for devices from avrxmega3. 230 */ 231 #define RODATA_SECTION .progmem.data.asm 232 #define USE_LD 0 233 #define USE_LPM 1 234 #endif /* PM_BASE_ADDRESS */ 235 236 #endif /* target AVR */ 237 #endif /* ASM_DEFS_H */ 238