xref: /netbsd-src/external/gpl3/gcc.old/dist/libgcc/config/avr/libf7/asm-defs.h (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
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