1*0bfacb9bSmrg /* Definitions of target machine for TI PRU.
2*0bfacb9bSmrg    Copyright (C) 2014-2020 Free Software Foundation, Inc.
3*0bfacb9bSmrg    Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
4*0bfacb9bSmrg 
5*0bfacb9bSmrg    This file is part of GCC.
6*0bfacb9bSmrg 
7*0bfacb9bSmrg    GCC is free software; you can redistribute it and/or modify it
8*0bfacb9bSmrg    under the terms of the GNU General Public License as published
9*0bfacb9bSmrg    by the Free Software Foundation; either version 3, or (at your
10*0bfacb9bSmrg    option) any later version.
11*0bfacb9bSmrg 
12*0bfacb9bSmrg    GCC is distributed in the hope that it will be useful, but WITHOUT
13*0bfacb9bSmrg    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14*0bfacb9bSmrg    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15*0bfacb9bSmrg    License for more details.
16*0bfacb9bSmrg 
17*0bfacb9bSmrg    You should have received a copy of the GNU General Public License
18*0bfacb9bSmrg    along with GCC; see the file COPYING3.  If not see
19*0bfacb9bSmrg    <http://www.gnu.org/licenses/>.  */
20*0bfacb9bSmrg 
21*0bfacb9bSmrg #ifndef GCC_PRU_H
22*0bfacb9bSmrg #define GCC_PRU_H
23*0bfacb9bSmrg 
24*0bfacb9bSmrg #include "config/pru/pru-opts.h"
25*0bfacb9bSmrg 
26*0bfacb9bSmrg /* Define built-in preprocessor macros.  */
27*0bfacb9bSmrg #define TARGET_CPU_CPP_BUILTINS()		    \
28*0bfacb9bSmrg   do						    \
29*0bfacb9bSmrg     {						    \
30*0bfacb9bSmrg       builtin_define_std ("__PRU__");		    \
31*0bfacb9bSmrg       builtin_define_std ("__pru__");		    \
32*0bfacb9bSmrg       builtin_define_std ("__PRU_V3__");	    \
33*0bfacb9bSmrg       builtin_define_std ("__LITTLE_ENDIAN__");	    \
34*0bfacb9bSmrg       builtin_define_std ("__little_endian__");	    \
35*0bfacb9bSmrg       /* Trampolines are disabled for now.  */	    \
36*0bfacb9bSmrg       builtin_define_std ("NO_TRAMPOLINES");	    \
37*0bfacb9bSmrg     }						    \
38*0bfacb9bSmrg   while (0)
39*0bfacb9bSmrg 
40*0bfacb9bSmrg /* TI ABI implementation is not feature-complete enough (e.g. function
41*0bfacb9bSmrg    pointers are not supported), so we cannot list it as a multilib variant.
42*0bfacb9bSmrg    To prevent misuse from users, do not link any of the standard libraries.  */
43*0bfacb9bSmrg #define DRIVER_SELF_SPECS			      \
44*0bfacb9bSmrg   "%{mabi=ti:-nodefaultlibs} "			      \
45*0bfacb9bSmrg   "%{mmcu=*:-specs=device-specs/%*%s %<mmcu=*} "
46*0bfacb9bSmrg 
47*0bfacb9bSmrg #undef CPP_SPEC
48*0bfacb9bSmrg #define CPP_SPEC					\
49*0bfacb9bSmrg   "%(cpp_device) "					\
50*0bfacb9bSmrg   "%{mabi=ti:-D__PRU_EABI_TI__; :-D__PRU_EABI_GNU__}"
51*0bfacb9bSmrg 
52*0bfacb9bSmrg /* Do not relax when in TI ABI mode since TI tools do not always
53*0bfacb9bSmrg    put PRU_S10_PCREL.  */
54*0bfacb9bSmrg #undef  LINK_SPEC
55*0bfacb9bSmrg #define LINK_SPEC					    \
56*0bfacb9bSmrg   "%(link_device) "					    \
57*0bfacb9bSmrg   "%{mabi=ti:--no-relax;:%{mno-relax:--no-relax;:--relax}} "   \
58*0bfacb9bSmrg   "%{shared:%eshared is not supported} "
59*0bfacb9bSmrg 
60*0bfacb9bSmrg /* CRT0 is carefully maintained to be compatible with both GNU and TI ABIs.  */
61*0bfacb9bSmrg #undef  STARTFILE_SPEC
62*0bfacb9bSmrg #define STARTFILE_SPEC							\
63*0bfacb9bSmrg   "%{!pg:%{minrt:crt0-minrt.o%s}%{!minrt:crt0.o%s}} %{!mabi=ti:-lgcc} "
64*0bfacb9bSmrg 
65*0bfacb9bSmrg #undef  ENDFILE_SPEC
66*0bfacb9bSmrg #define ENDFILE_SPEC "%{!mabi=ti:-lgloss} "
67*0bfacb9bSmrg 
68*0bfacb9bSmrg /* TI ABI mandates that ELF symbols do not start with any prefix.  */
69*0bfacb9bSmrg #undef USER_LABEL_PREFIX
70*0bfacb9bSmrg #define USER_LABEL_PREFIX ""
71*0bfacb9bSmrg 
72*0bfacb9bSmrg #undef LOCAL_LABEL_PREFIX
73*0bfacb9bSmrg #define LOCAL_LABEL_PREFIX ".L"
74*0bfacb9bSmrg 
75*0bfacb9bSmrg /* Storage layout.  */
76*0bfacb9bSmrg 
77*0bfacb9bSmrg #define DEFAULT_SIGNED_CHAR 0
78*0bfacb9bSmrg #define BITS_BIG_ENDIAN 0
79*0bfacb9bSmrg #define BYTES_BIG_ENDIAN 0
80*0bfacb9bSmrg #define WORDS_BIG_ENDIAN 0
81*0bfacb9bSmrg 
82*0bfacb9bSmrg /* PRU is represented in GCC as an 8-bit CPU with fast 16-bit and 32-bit
83*0bfacb9bSmrg    arithmetic.  */
84*0bfacb9bSmrg #define BITS_PER_WORD 8
85*0bfacb9bSmrg 
86*0bfacb9bSmrg #ifdef IN_LIBGCC2
87*0bfacb9bSmrg /* This is to get correct SI and DI modes in libgcc2.c (32 and 64 bits).  */
88*0bfacb9bSmrg #define UNITS_PER_WORD 4
89*0bfacb9bSmrg #else
90*0bfacb9bSmrg /* Width of a word, in units (bytes).  */
91*0bfacb9bSmrg #define UNITS_PER_WORD 1
92*0bfacb9bSmrg #endif
93*0bfacb9bSmrg 
94*0bfacb9bSmrg #define POINTER_SIZE 32
95*0bfacb9bSmrg #define BIGGEST_ALIGNMENT 8
96*0bfacb9bSmrg #define STRICT_ALIGNMENT 0
97*0bfacb9bSmrg #define FUNCTION_BOUNDARY 8	/* Func pointers are word-addressed.  */
98*0bfacb9bSmrg #define PARM_BOUNDARY 8
99*0bfacb9bSmrg #define STACK_BOUNDARY 8
100*0bfacb9bSmrg #define MAX_FIXED_MODE_SIZE 64
101*0bfacb9bSmrg 
102*0bfacb9bSmrg #define POINTERS_EXTEND_UNSIGNED 1
103*0bfacb9bSmrg 
104*0bfacb9bSmrg /* Layout of source language data types.  */
105*0bfacb9bSmrg 
106*0bfacb9bSmrg #define INT_TYPE_SIZE 32
107*0bfacb9bSmrg #define SHORT_TYPE_SIZE 16
108*0bfacb9bSmrg #define LONG_TYPE_SIZE 32
109*0bfacb9bSmrg #define LONG_LONG_TYPE_SIZE 64
110*0bfacb9bSmrg #define FLOAT_TYPE_SIZE 32
111*0bfacb9bSmrg #define DOUBLE_TYPE_SIZE 64
112*0bfacb9bSmrg #define LONG_DOUBLE_TYPE_SIZE DOUBLE_TYPE_SIZE
113*0bfacb9bSmrg 
114*0bfacb9bSmrg #undef SIZE_TYPE
115*0bfacb9bSmrg #define SIZE_TYPE "unsigned int"
116*0bfacb9bSmrg 
117*0bfacb9bSmrg #undef PTRDIFF_TYPE
118*0bfacb9bSmrg #define PTRDIFF_TYPE "int"
119*0bfacb9bSmrg 
120*0bfacb9bSmrg 
121*0bfacb9bSmrg /* Basic characteristics of PRU registers:
122*0bfacb9bSmrg 
123*0bfacb9bSmrg    Regno  Name
124*0bfacb9bSmrg    0      r0		  Caller Saved.  Also used as a static chain register.
125*0bfacb9bSmrg    1      r1		  Caller Saved.  Also used as a temporary by function.
126*0bfacb9bSmrg 			  profiler and function prologue/epilogue.
127*0bfacb9bSmrg    2      r2       sp	  Stack Pointer.
128*0bfacb9bSmrg    3*     r3.w0    ra	  Return Address (16-bit).
129*0bfacb9bSmrg    4      r4       fp	  Frame Pointer, also called Argument Pointer in ABI.
130*0bfacb9bSmrg    5-13   r5-r13	  Callee Saved Registers.
131*0bfacb9bSmrg    14-29  r14-r29	  Register Arguments.  Caller Saved Registers.
132*0bfacb9bSmrg    14-15  r14-r15	  Return Location.
133*0bfacb9bSmrg    30     r30		  Special I/O register.  Not used by compiler.
134*0bfacb9bSmrg    31     r31		  Special I/O register.  Not used by compiler.
135*0bfacb9bSmrg 
136*0bfacb9bSmrg    32     loop_cntr	  Internal register used as a counter by LOOP insns.
137*0bfacb9bSmrg 
138*0bfacb9bSmrg    33     pc		  Not an actual register.
139*0bfacb9bSmrg 
140*0bfacb9bSmrg    34     fake_fp	  Fake Frame Pointer (always eliminated).
141*0bfacb9bSmrg    35     fake_ap	  Fake Argument Pointer (always eliminated).
142*0bfacb9bSmrg    36			  First Pseudo Register.
143*0bfacb9bSmrg 
144*0bfacb9bSmrg    The definitions for some hard register numbers are located in pru.md.
145*0bfacb9bSmrg    Note that GCC's internal register numbering differs from the conventional
146*0bfacb9bSmrg    register naming in PRU ISA.  PRU ISA defines word-based register numbers
147*0bfacb9bSmrg    and sub-register suffixes (e.g. RA is r3.w0).  GCC uses linear numbering
148*0bfacb9bSmrg    of 8 bit sub-registers (e.g. RA starts at r12).  When outputting assembly,
149*0bfacb9bSmrg    GCC will take into account the RTL operand size (e.g. r12:HI) in order to
150*0bfacb9bSmrg    translate to the conventional PRU ISA format expected by GAS (r3.w0).
151*0bfacb9bSmrg */
152*0bfacb9bSmrg 
153*0bfacb9bSmrg #define FIXED_REGISTERS				\
154*0bfacb9bSmrg   {						\
155*0bfacb9bSmrg /*   0 */  0,0,0,0, 0,0,0,0, 1,1,1,1, 1,1,1,1,	\
156*0bfacb9bSmrg /*   4 */  0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,	\
157*0bfacb9bSmrg /*   8 */  0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,	\
158*0bfacb9bSmrg /*  12 */  0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,	\
159*0bfacb9bSmrg /*  16 */  0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,	\
160*0bfacb9bSmrg /*  20 */  0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,	\
161*0bfacb9bSmrg /*  24 */  0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,	\
162*0bfacb9bSmrg /*  28 */  0,0,0,0, 0,0,0,0, 1,1,1,1, 1,1,1,1,	\
163*0bfacb9bSmrg /*  32 */  1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1	\
164*0bfacb9bSmrg   }
165*0bfacb9bSmrg 
166*0bfacb9bSmrg /* Call used == caller saved + fixed regs + args + ret vals.  */
167*0bfacb9bSmrg #define CALL_USED_REGISTERS			\
168*0bfacb9bSmrg   {						\
169*0bfacb9bSmrg /*   0 */  1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,	\
170*0bfacb9bSmrg /*   4 */  0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,	\
171*0bfacb9bSmrg /*   8 */  0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,	\
172*0bfacb9bSmrg /*  12 */  0,0,0,0, 0,0,0,0, 1,1,1,1, 1,1,1,1,	\
173*0bfacb9bSmrg /*  16 */  1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,	\
174*0bfacb9bSmrg /*  20 */  1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,	\
175*0bfacb9bSmrg /*  24 */  1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,	\
176*0bfacb9bSmrg /*  28 */  1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,	\
177*0bfacb9bSmrg /*  32 */  1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1	\
178*0bfacb9bSmrg   }
179*0bfacb9bSmrg 
180*0bfacb9bSmrg #define PRU_SEQ_R(X)  (X) * 4 + 0, (X) * 4 + 1, (X) * 4 + 2, (X) * 4 + 3
181*0bfacb9bSmrg #define REG_ALLOC_ORDER							    \
182*0bfacb9bSmrg   {									    \
183*0bfacb9bSmrg     /* Call-clobbered, yet not used for parameters.  */			    \
184*0bfacb9bSmrg     PRU_SEQ_R (0),  PRU_SEQ_R ( 1),					    \
185*0bfacb9bSmrg 									    \
186*0bfacb9bSmrg     PRU_SEQ_R (14), PRU_SEQ_R (15), PRU_SEQ_R (16), PRU_SEQ_R (17),	    \
187*0bfacb9bSmrg     PRU_SEQ_R (18), PRU_SEQ_R (19), PRU_SEQ_R (20), PRU_SEQ_R (21),	    \
188*0bfacb9bSmrg     PRU_SEQ_R (22), PRU_SEQ_R (23), PRU_SEQ_R (24), PRU_SEQ_R (25),	    \
189*0bfacb9bSmrg     PRU_SEQ_R (26), PRU_SEQ_R (27), PRU_SEQ_R (28), PRU_SEQ_R (29),	    \
190*0bfacb9bSmrg 									    \
191*0bfacb9bSmrg     PRU_SEQ_R ( 5), PRU_SEQ_R ( 6), PRU_SEQ_R ( 7), PRU_SEQ_R ( 8),	    \
192*0bfacb9bSmrg     PRU_SEQ_R ( 9), PRU_SEQ_R (10), PRU_SEQ_R (11), PRU_SEQ_R (12),	    \
193*0bfacb9bSmrg     PRU_SEQ_R (13),							    \
194*0bfacb9bSmrg 									    \
195*0bfacb9bSmrg     PRU_SEQ_R ( 4),							    \
196*0bfacb9bSmrg     PRU_SEQ_R ( 2), PRU_SEQ_R ( 3),					    \
197*0bfacb9bSmrg 									    \
198*0bfacb9bSmrg     /* I/O and virtual registers.  */					    \
199*0bfacb9bSmrg     PRU_SEQ_R (30), PRU_SEQ_R (31), PRU_SEQ_R (32), PRU_SEQ_R (33),	    \
200*0bfacb9bSmrg     PRU_SEQ_R (34), PRU_SEQ_R (35)					    \
201*0bfacb9bSmrg   }
202*0bfacb9bSmrg 
203*0bfacb9bSmrg /* Register Classes.  */
204*0bfacb9bSmrg 
205*0bfacb9bSmrg enum reg_class
206*0bfacb9bSmrg {
207*0bfacb9bSmrg   NO_REGS,
208*0bfacb9bSmrg   SIB_REGS,
209*0bfacb9bSmrg   LOOPCNTR_REGS,
210*0bfacb9bSmrg   MULDST_REGS,
211*0bfacb9bSmrg   MULSRC0_REGS,
212*0bfacb9bSmrg   MULSRC1_REGS,
213*0bfacb9bSmrg   GP_REGS,
214*0bfacb9bSmrg   ALL_REGS,
215*0bfacb9bSmrg   LIM_REG_CLASSES
216*0bfacb9bSmrg };
217*0bfacb9bSmrg 
218*0bfacb9bSmrg #define N_REG_CLASSES (int) LIM_REG_CLASSES
219*0bfacb9bSmrg 
220*0bfacb9bSmrg #define REG_CLASS_NAMES   \
221*0bfacb9bSmrg   {  "NO_REGS",		  \
222*0bfacb9bSmrg      "SIB_REGS",	  \
223*0bfacb9bSmrg      "LOOPCNTR_REGS",	  \
224*0bfacb9bSmrg      "MULDST_REGS",	  \
225*0bfacb9bSmrg      "MULSRC0_REGS",	  \
226*0bfacb9bSmrg      "MULSRC1_REGS",	  \
227*0bfacb9bSmrg      "GP_REGS",		  \
228*0bfacb9bSmrg      "ALL_REGS" }
229*0bfacb9bSmrg 
230*0bfacb9bSmrg #define GENERAL_REGS ALL_REGS
231*0bfacb9bSmrg 
232*0bfacb9bSmrg #define REG_CLASS_CONTENTS					\
233*0bfacb9bSmrg   {								\
234*0bfacb9bSmrg     /* NO_REGS	      */ { 0, 0, 0, 0, 0},			\
235*0bfacb9bSmrg     /* SIB_REGS	      */ { 0xf, 0xff000000, ~0, 0xffffff, 0},	\
236*0bfacb9bSmrg     /* LOOPCNTR_REGS  */ { 0, 0, 0, 0, 0xf},			\
237*0bfacb9bSmrg     /* MULDST_REGS    */ { 0, 0, 0, 0x00000f00, 0},		\
238*0bfacb9bSmrg     /* MULSRC0_REGS   */ { 0, 0, 0, 0x000f0000, 0},		\
239*0bfacb9bSmrg     /* MULSRC1_REGS   */ { 0, 0, 0, 0x00f00000, 0},		\
240*0bfacb9bSmrg     /* GP_REGS	      */ { ~0, ~0, ~0, ~0, 0},			\
241*0bfacb9bSmrg     /* ALL_REGS	      */ { ~0,~0, ~0, ~0, ~0}			\
242*0bfacb9bSmrg   }
243*0bfacb9bSmrg 
244*0bfacb9bSmrg 
245*0bfacb9bSmrg #define GP_REG_P(REGNO) ((unsigned)(REGNO) <= LAST_GP_REGNUM)
246*0bfacb9bSmrg #define REGNO_REG_CLASS(REGNO)						    \
247*0bfacb9bSmrg 	((REGNO) == MULDST_REGNUM ? MULDST_REGS				    \
248*0bfacb9bSmrg 	 : (REGNO) == MULSRC0_REGNUM ? MULSRC0_REGS			    \
249*0bfacb9bSmrg 	 : (REGNO) == MULSRC1_REGNUM ? MULSRC1_REGS			    \
250*0bfacb9bSmrg 	 : (REGNO) >= FIRST_ARG_REGNUM					    \
251*0bfacb9bSmrg 	    && (REGNO) <= LAST_ARG_REGNUM ? SIB_REGS			    \
252*0bfacb9bSmrg 	 : (REGNO) == STATIC_CHAIN_REGNUM ? SIB_REGS			    \
253*0bfacb9bSmrg 	 : (REGNO) == LOOPCNTR_REGNUM ? LOOPCNTR_REGS			    \
254*0bfacb9bSmrg 	 : (REGNO) <= LAST_NONIO_GP_REGNUM ? GP_REGS			    \
255*0bfacb9bSmrg 	 : ALL_REGS)
256*0bfacb9bSmrg 
257*0bfacb9bSmrg #define CLASS_MAX_NREGS(CLASS, MODE) \
258*0bfacb9bSmrg   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
259*0bfacb9bSmrg 
260*0bfacb9bSmrg /* Arbitrarily set to a non-argument register.  Not defined by TI ABI.  */
261*0bfacb9bSmrg #define STATIC_CHAIN_REGNUM      0	/* r0 */
262*0bfacb9bSmrg 
263*0bfacb9bSmrg /* Tests for various kinds of constants used in the PRU port.  */
264*0bfacb9bSmrg #define SHIFT_INT(X) (IN_RANGE ((X), 0, 31))
265*0bfacb9bSmrg 
266*0bfacb9bSmrg #define UHWORD_INT(X) (IN_RANGE ((X), 0, 0xffff))
267*0bfacb9bSmrg #define SHWORD_INT(X) (IN_RANGE ((X), -32768, 32767))
268*0bfacb9bSmrg #define UBYTE_INT(X) (IN_RANGE ((X), 0, 0xff))
269*0bfacb9bSmrg #define SBYTE_INT(X) (IN_RANGE ((X), -128, 127))
270*0bfacb9bSmrg 
271*0bfacb9bSmrg /* Say that the epilogue uses the return address register.  Note that
272*0bfacb9bSmrg    in the case of sibcalls, the values "used by the epilogue" are
273*0bfacb9bSmrg    considered live at the start of the called function.  */
274*0bfacb9bSmrg #define EPILOGUE_USES(REGNO) (epilogue_completed		\
275*0bfacb9bSmrg 			      && (((REGNO) == RA_REGNUM)		\
276*0bfacb9bSmrg 				  || (REGNO) == (RA_REGNUM + 1)))
277*0bfacb9bSmrg 
278*0bfacb9bSmrg /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
279*0bfacb9bSmrg    the stack pointer does not matter.  The value is tested only in
280*0bfacb9bSmrg    functions that have frame pointers.
281*0bfacb9bSmrg    No definition is equivalent to always zero.  */
282*0bfacb9bSmrg 
283*0bfacb9bSmrg #define EXIT_IGNORE_STACK 1
284*0bfacb9bSmrg 
285*0bfacb9bSmrg /* Trampolines are not supported, but put a define to keep the build.  */
286*0bfacb9bSmrg #define TRAMPOLINE_SIZE 4
287*0bfacb9bSmrg 
288*0bfacb9bSmrg /* Stack layout.  */
289*0bfacb9bSmrg #define STACK_GROWS_DOWNWARD  1
290*0bfacb9bSmrg #undef FRAME_GROWS_DOWNWARD
291*0bfacb9bSmrg #define FIRST_PARM_OFFSET(FUNDECL) 0
292*0bfacb9bSmrg 
293*0bfacb9bSmrg /* Before the prologue, RA lives in r3.w2.  */
294*0bfacb9bSmrg #define INCOMING_RETURN_ADDR_RTX	gen_rtx_REG (HImode, RA_REGNUM)
295*0bfacb9bSmrg 
296*0bfacb9bSmrg #define RETURN_ADDR_RTX(C,F) pru_get_return_address (C)
297*0bfacb9bSmrg 
298*0bfacb9bSmrg #define DWARF_FRAME_RETURN_COLUMN RA_REGNUM
299*0bfacb9bSmrg 
300*0bfacb9bSmrg /* The CFA includes the pretend args.  */
301*0bfacb9bSmrg #define ARG_POINTER_CFA_OFFSET(FNDECL) \
302*0bfacb9bSmrg   (gcc_assert ((FNDECL) == current_function_decl), \
303*0bfacb9bSmrg    FIRST_PARM_OFFSET (FNDECL) + crtl->args.pretend_args_size)
304*0bfacb9bSmrg 
305*0bfacb9bSmrg /* Frame/arg pointer elimination settings.  */
306*0bfacb9bSmrg #define ELIMINABLE_REGS							\
307*0bfacb9bSmrg {{ ARG_POINTER_REGNUM,   STACK_POINTER_REGNUM},				\
308*0bfacb9bSmrg  { ARG_POINTER_REGNUM,   HARD_FRAME_POINTER_REGNUM},			\
309*0bfacb9bSmrg  { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},				\
310*0bfacb9bSmrg  { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
311*0bfacb9bSmrg 
312*0bfacb9bSmrg #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
313*0bfacb9bSmrg   (OFFSET) = pru_initial_elimination_offset ((FROM), (TO))
314*0bfacb9bSmrg 
315*0bfacb9bSmrg #define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \
316*0bfacb9bSmrg   pru_hard_regno_rename_ok (OLD_REG, NEW_REG)
317*0bfacb9bSmrg 
318*0bfacb9bSmrg /* Calling convention definitions.  */
319*0bfacb9bSmrg #if !defined(IN_LIBGCC2)
320*0bfacb9bSmrg 
321*0bfacb9bSmrg #define NUM_ARG_REGS (LAST_ARG_REGNUM - FIRST_ARG_REGNUM + 1)
322*0bfacb9bSmrg 
323*0bfacb9bSmrg typedef struct pru_args
324*0bfacb9bSmrg {
325*0bfacb9bSmrg   bool regs_used[NUM_ARG_REGS];
326*0bfacb9bSmrg } CUMULATIVE_ARGS;
327*0bfacb9bSmrg 
328*0bfacb9bSmrg #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS)  \
329*0bfacb9bSmrg   do {									  \
330*0bfacb9bSmrg       memset ((CUM).regs_used, 0, sizeof ((CUM).regs_used));		  \
331*0bfacb9bSmrg   } while (0)
332*0bfacb9bSmrg 
333*0bfacb9bSmrg #define FUNCTION_ARG_REGNO_P(REGNO) \
334*0bfacb9bSmrg   ((REGNO) >= FIRST_ARG_REGNUM && (REGNO) <= LAST_ARG_REGNUM)
335*0bfacb9bSmrg 
336*0bfacb9bSmrg /* Passing function arguments on stack.  */
337*0bfacb9bSmrg #define PUSH_ARGS 0
338*0bfacb9bSmrg #define ACCUMULATE_OUTGOING_ARGS 1
339*0bfacb9bSmrg 
340*0bfacb9bSmrg /* We define TARGET_RETURN_IN_MEMORY, so set to zero.  */
341*0bfacb9bSmrg #define DEFAULT_PCC_STRUCT_RETURN 0
342*0bfacb9bSmrg 
343*0bfacb9bSmrg /* Profiling.  */
344*0bfacb9bSmrg #define PROFILE_BEFORE_PROLOGUE
345*0bfacb9bSmrg #define NO_PROFILE_COUNTERS 1
346*0bfacb9bSmrg #define FUNCTION_PROFILER(FILE, LABELNO) \
347*0bfacb9bSmrg   pru_function_profiler ((FILE), (LABELNO))
348*0bfacb9bSmrg 
349*0bfacb9bSmrg #endif	/* IN_LIBGCC2 */
350*0bfacb9bSmrg 
351*0bfacb9bSmrg /* Addressing modes.  */
352*0bfacb9bSmrg 
353*0bfacb9bSmrg #define CONSTANT_ADDRESS_P(X) \
354*0bfacb9bSmrg   (CONSTANT_P (X) && memory_address_p (SImode, X))
355*0bfacb9bSmrg 
356*0bfacb9bSmrg #define MAX_REGS_PER_ADDRESS 2
357*0bfacb9bSmrg #define BASE_REG_CLASS ALL_REGS
358*0bfacb9bSmrg #define INDEX_REG_CLASS ALL_REGS
359*0bfacb9bSmrg 
360*0bfacb9bSmrg #define REGNO_OK_FOR_BASE_P(REGNO) pru_regno_ok_for_base_p ((REGNO), true)
361*0bfacb9bSmrg #define REGNO_OK_FOR_INDEX_P(REGNO) pru_regno_ok_for_index_p ((REGNO), true)
362*0bfacb9bSmrg 
363*0bfacb9bSmrg /* Limited by the insns in pru-ldst-multiple.md.  */
364*0bfacb9bSmrg #define MOVE_MAX 8
365*0bfacb9bSmrg #define SLOW_BYTE_ACCESS 1
366*0bfacb9bSmrg 
367*0bfacb9bSmrg /* It is as good to call a constant function address as to call an address
368*0bfacb9bSmrg    kept in a register.  */
369*0bfacb9bSmrg #define NO_FUNCTION_CSE 1
370*0bfacb9bSmrg 
371*0bfacb9bSmrg /* Define output assembler language.  */
372*0bfacb9bSmrg 
373*0bfacb9bSmrg #define ASM_APP_ON "#APP\n"
374*0bfacb9bSmrg #define ASM_APP_OFF "#NO_APP\n"
375*0bfacb9bSmrg 
376*0bfacb9bSmrg #define ASM_COMMENT_START "# "
377*0bfacb9bSmrg 
378*0bfacb9bSmrg #define GLOBAL_ASM_OP "\t.global\t"
379*0bfacb9bSmrg 
380*0bfacb9bSmrg #define PRU_NAME_R(X)  X".b0", X".b1", X".b2", X".b3"
381*0bfacb9bSmrg #define REGISTER_NAMES		  \
382*0bfacb9bSmrg   {				  \
383*0bfacb9bSmrg     PRU_NAME_R ("r0"),		  \
384*0bfacb9bSmrg     PRU_NAME_R ("r1"),		  \
385*0bfacb9bSmrg     PRU_NAME_R ("r2"),		  \
386*0bfacb9bSmrg     PRU_NAME_R ("r3"),		  \
387*0bfacb9bSmrg     PRU_NAME_R ("r4"),		  \
388*0bfacb9bSmrg     PRU_NAME_R ("r5"),		  \
389*0bfacb9bSmrg     PRU_NAME_R ("r6"),		  \
390*0bfacb9bSmrg     PRU_NAME_R ("r7"),		  \
391*0bfacb9bSmrg     PRU_NAME_R ("r8"),		  \
392*0bfacb9bSmrg     PRU_NAME_R ("r9"),		  \
393*0bfacb9bSmrg     PRU_NAME_R ("r10"),		  \
394*0bfacb9bSmrg     PRU_NAME_R ("r11"),		  \
395*0bfacb9bSmrg     PRU_NAME_R ("r12"),		  \
396*0bfacb9bSmrg     PRU_NAME_R ("r13"),		  \
397*0bfacb9bSmrg     PRU_NAME_R ("r14"),		  \
398*0bfacb9bSmrg     PRU_NAME_R ("r15"),		  \
399*0bfacb9bSmrg     PRU_NAME_R ("r16"),		  \
400*0bfacb9bSmrg     PRU_NAME_R ("r17"),		  \
401*0bfacb9bSmrg     PRU_NAME_R ("r18"),		  \
402*0bfacb9bSmrg     PRU_NAME_R ("r19"),		  \
403*0bfacb9bSmrg     PRU_NAME_R ("r20"),		  \
404*0bfacb9bSmrg     PRU_NAME_R ("r21"),		  \
405*0bfacb9bSmrg     PRU_NAME_R ("r22"),		  \
406*0bfacb9bSmrg     PRU_NAME_R ("r23"),		  \
407*0bfacb9bSmrg     PRU_NAME_R ("r24"),		  \
408*0bfacb9bSmrg     PRU_NAME_R ("r25"),		  \
409*0bfacb9bSmrg     PRU_NAME_R ("r26"),		  \
410*0bfacb9bSmrg     PRU_NAME_R ("r27"),		  \
411*0bfacb9bSmrg     PRU_NAME_R ("r28"),		  \
412*0bfacb9bSmrg     PRU_NAME_R ("r29"),		  \
413*0bfacb9bSmrg     PRU_NAME_R ("r30"),		  \
414*0bfacb9bSmrg     PRU_NAME_R ("r31"),		  \
415*0bfacb9bSmrg     PRU_NAME_R ("loopcntr_reg"),  \
416*0bfacb9bSmrg     PRU_NAME_R ("pc"),		  \
417*0bfacb9bSmrg     PRU_NAME_R ("fake_fp"),	  \
418*0bfacb9bSmrg     PRU_NAME_R ("fake_ap"),	  \
419*0bfacb9bSmrg }
420*0bfacb9bSmrg 
421*0bfacb9bSmrg #define PRU_OVERLAP_R(X)	      \
422*0bfacb9bSmrg   { "r" #X	, X * 4	    ,  4 },   \
423*0bfacb9bSmrg   { "r" #X ".w0", X * 4 + 0 ,  2 },   \
424*0bfacb9bSmrg   { "r" #X ".w1", X * 4 + 1 ,  2 },   \
425*0bfacb9bSmrg   { "r" #X ".w2", X * 4 + 2 ,  2 }
426*0bfacb9bSmrg 
427*0bfacb9bSmrg #define OVERLAPPING_REGISTER_NAMES  \
428*0bfacb9bSmrg   {				    \
429*0bfacb9bSmrg     /* Aliases.  */		    \
430*0bfacb9bSmrg     { "sp", 2 * 4, 4 },		    \
431*0bfacb9bSmrg     { "ra", 3 * 4, 2 },		    \
432*0bfacb9bSmrg     { "fp", 4 * 4, 4 },		    \
433*0bfacb9bSmrg     PRU_OVERLAP_R (0),		    \
434*0bfacb9bSmrg     PRU_OVERLAP_R (1),		    \
435*0bfacb9bSmrg     PRU_OVERLAP_R (2),		    \
436*0bfacb9bSmrg     PRU_OVERLAP_R (3),		    \
437*0bfacb9bSmrg     PRU_OVERLAP_R (4),		    \
438*0bfacb9bSmrg     PRU_OVERLAP_R (5),		    \
439*0bfacb9bSmrg     PRU_OVERLAP_R (6),		    \
440*0bfacb9bSmrg     PRU_OVERLAP_R (7),		    \
441*0bfacb9bSmrg     PRU_OVERLAP_R (8),		    \
442*0bfacb9bSmrg     PRU_OVERLAP_R (9),		    \
443*0bfacb9bSmrg     PRU_OVERLAP_R (10),		    \
444*0bfacb9bSmrg     PRU_OVERLAP_R (11),		    \
445*0bfacb9bSmrg     PRU_OVERLAP_R (12),		    \
446*0bfacb9bSmrg     PRU_OVERLAP_R (13),		    \
447*0bfacb9bSmrg     PRU_OVERLAP_R (14),		    \
448*0bfacb9bSmrg     PRU_OVERLAP_R (15),		    \
449*0bfacb9bSmrg     PRU_OVERLAP_R (16),		    \
450*0bfacb9bSmrg     PRU_OVERLAP_R (17),		    \
451*0bfacb9bSmrg     PRU_OVERLAP_R (18),		    \
452*0bfacb9bSmrg     PRU_OVERLAP_R (19),		    \
453*0bfacb9bSmrg     PRU_OVERLAP_R (20),		    \
454*0bfacb9bSmrg     PRU_OVERLAP_R (21),		    \
455*0bfacb9bSmrg     PRU_OVERLAP_R (22),		    \
456*0bfacb9bSmrg     PRU_OVERLAP_R (23),		    \
457*0bfacb9bSmrg     PRU_OVERLAP_R (24),		    \
458*0bfacb9bSmrg     PRU_OVERLAP_R (25),		    \
459*0bfacb9bSmrg     PRU_OVERLAP_R (26),		    \
460*0bfacb9bSmrg     PRU_OVERLAP_R (27),		    \
461*0bfacb9bSmrg     PRU_OVERLAP_R (28),		    \
462*0bfacb9bSmrg     PRU_OVERLAP_R (29),		    \
463*0bfacb9bSmrg     PRU_OVERLAP_R (30),		    \
464*0bfacb9bSmrg     PRU_OVERLAP_R (31),		    \
465*0bfacb9bSmrg }
466*0bfacb9bSmrg 
467*0bfacb9bSmrg #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)				    \
468*0bfacb9bSmrg   do									    \
469*0bfacb9bSmrg     {									    \
470*0bfacb9bSmrg       fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE);    \
471*0bfacb9bSmrg       fprintf (FILE, "%%pmem(.L%u)\n", (unsigned) (VALUE));		    \
472*0bfacb9bSmrg     }									    \
473*0bfacb9bSmrg   while (0)
474*0bfacb9bSmrg 
475*0bfacb9bSmrg #define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL)		    \
476*0bfacb9bSmrg   do									    \
477*0bfacb9bSmrg     {									    \
478*0bfacb9bSmrg       fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), STREAM);  \
479*0bfacb9bSmrg       fprintf (STREAM, "%%pmem(.L%u-.L%u)\n", (unsigned) (VALUE),	    \
480*0bfacb9bSmrg 	       (unsigned) (REL));					    \
481*0bfacb9bSmrg     }									    \
482*0bfacb9bSmrg   while (0)
483*0bfacb9bSmrg 
484*0bfacb9bSmrg /* Section directives.  */
485*0bfacb9bSmrg 
486*0bfacb9bSmrg /* Output before read-only data.  */
487*0bfacb9bSmrg #define TEXT_SECTION_ASM_OP "\t.section\t.text"
488*0bfacb9bSmrg 
489*0bfacb9bSmrg /* Output before writable data.  */
490*0bfacb9bSmrg #define DATA_SECTION_ASM_OP "\t.section\t.data"
491*0bfacb9bSmrg 
492*0bfacb9bSmrg /* Output before uninitialized data.  */
493*0bfacb9bSmrg #define BSS_SECTION_ASM_OP "\t.section\t.bss"
494*0bfacb9bSmrg 
495*0bfacb9bSmrg #define CTORS_SECTION_ASM_OP "\t.section\t.init_array,\"aw\",%init_array"
496*0bfacb9bSmrg #define DTORS_SECTION_ASM_OP "\t.section\t.fini_array,\"aw\",%fini_array"
497*0bfacb9bSmrg 
498*0bfacb9bSmrg #undef INIT_SECTION_ASM_OP
499*0bfacb9bSmrg #undef FINI_SECTION_ASM_OP
500*0bfacb9bSmrg #define INIT_ARRAY_SECTION_ASM_OP CTORS_SECTION_ASM_OP
501*0bfacb9bSmrg #define FINI_ARRAY_SECTION_ASM_OP DTORS_SECTION_ASM_OP
502*0bfacb9bSmrg 
503*0bfacb9bSmrg /* Since we use .init_array/.fini_array we don't need the markers at
504*0bfacb9bSmrg    the start and end of the ctors/dtors arrays.  */
505*0bfacb9bSmrg #define CTOR_LIST_BEGIN asm (CTORS_SECTION_ASM_OP)
506*0bfacb9bSmrg #define CTOR_LIST_END		/* empty */
507*0bfacb9bSmrg #define DTOR_LIST_BEGIN asm (DTORS_SECTION_ASM_OP)
508*0bfacb9bSmrg #define DTOR_LIST_END		/* empty */
509*0bfacb9bSmrg 
510*0bfacb9bSmrg #undef TARGET_ASM_CONSTRUCTOR
511*0bfacb9bSmrg #define TARGET_ASM_CONSTRUCTOR pru_elf_asm_constructor
512*0bfacb9bSmrg 
513*0bfacb9bSmrg #undef TARGET_ASM_DESTRUCTOR
514*0bfacb9bSmrg #define TARGET_ASM_DESTRUCTOR pru_elf_asm_destructor
515*0bfacb9bSmrg 
516*0bfacb9bSmrg #define ASM_OUTPUT_ALIGN(FILE, LOG)		      \
517*0bfacb9bSmrg   do {						      \
518*0bfacb9bSmrg     fprintf ((FILE), "%s%d\n", ALIGN_ASM_OP, (LOG));  \
519*0bfacb9bSmrg   } while (0)
520*0bfacb9bSmrg 
521*0bfacb9bSmrg #undef  ASM_OUTPUT_ALIGNED_COMMON
522*0bfacb9bSmrg #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)		\
523*0bfacb9bSmrg do									\
524*0bfacb9bSmrg   {									\
525*0bfacb9bSmrg     fprintf ((FILE), "%s", COMMON_ASM_OP);				\
526*0bfacb9bSmrg     assemble_name ((FILE), (NAME));					\
527*0bfacb9bSmrg     fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n", (SIZE),	\
528*0bfacb9bSmrg 	     (ALIGN) / BITS_PER_UNIT);					\
529*0bfacb9bSmrg   }									\
530*0bfacb9bSmrg while (0)
531*0bfacb9bSmrg 
532*0bfacb9bSmrg 
533*0bfacb9bSmrg /* This says how to output assembler code to declare an
534*0bfacb9bSmrg    uninitialized internal linkage data object.  Under SVR4,
535*0bfacb9bSmrg    the linker seems to want the alignment of data objects
536*0bfacb9bSmrg    to depend on their types.  We do exactly that here.  */
537*0bfacb9bSmrg 
538*0bfacb9bSmrg #undef  ASM_OUTPUT_ALIGNED_LOCAL
539*0bfacb9bSmrg #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
540*0bfacb9bSmrg do {									\
541*0bfacb9bSmrg   switch_to_section (bss_section);					\
542*0bfacb9bSmrg   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
543*0bfacb9bSmrg   if (!flag_inhibit_size_directive)					\
544*0bfacb9bSmrg     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
545*0bfacb9bSmrg   ASM_OUTPUT_ALIGN ((FILE), exact_log2 ((ALIGN) / BITS_PER_UNIT));      \
546*0bfacb9bSmrg   ASM_OUTPUT_LABEL (FILE, NAME);					\
547*0bfacb9bSmrg   ASM_OUTPUT_SKIP ((FILE), (SIZE) ? (SIZE) : 1);			\
548*0bfacb9bSmrg } while (0)
549*0bfacb9bSmrg 
550*0bfacb9bSmrg /* Misc parameters.  */
551*0bfacb9bSmrg 
552*0bfacb9bSmrg #define TARGET_SUPPORTS_WIDE_INT 1
553*0bfacb9bSmrg 
554*0bfacb9bSmrg #define STORE_FLAG_VALUE 1
555*0bfacb9bSmrg #define Pmode SImode
556*0bfacb9bSmrg #define FUNCTION_MODE Pmode
557*0bfacb9bSmrg 
558*0bfacb9bSmrg #define CASE_VECTOR_MODE Pmode
559*0bfacb9bSmrg 
560*0bfacb9bSmrg /* Jumps are cheap on PRU.  */
561*0bfacb9bSmrg #define LOGICAL_OP_NON_SHORT_CIRCUIT		0
562*0bfacb9bSmrg 
563*0bfacb9bSmrg /* Unfortunately the LBBO instruction does not zero-extend data.  */
564*0bfacb9bSmrg #undef LOAD_EXTEND_OP
565*0bfacb9bSmrg 
566*0bfacb9bSmrg #undef WORD_REGISTER_OPERATIONS
567*0bfacb9bSmrg 
568*0bfacb9bSmrg #define HAS_LONG_UNCOND_BRANCH			1
569*0bfacb9bSmrg #define HAS_LONG_COND_BRANCH			1
570*0bfacb9bSmrg 
571*0bfacb9bSmrg #define REGISTER_TARGET_PRAGMAS() pru_register_pragmas ()
572*0bfacb9bSmrg 
573*0bfacb9bSmrg #endif /* GCC_PRU_H */
574