blob: ca54ff94b379954d303287e0cd2b2f5babf836b1 [file] [log] [blame]
PulkoMandy17fc7592022-07-28 18:27:54 +02001/* MEGA65 / 45GS02 backend for vbcc
2 (c) Volker Barthelmann 2020
3 (c) Paul Gardner-Stephen 2020
4
5*/
6
7/* built-time configurable options: */
8#define NUM_GPRS 32
9#define NUM_PAIRS (NUM_GPRS/2)
10#define NUM_BIG 4
11#define NUM_BIGP (NUM_BIG/2)
12#define FIXED_SP 1
13
14#include "dt.h"
15
16#undef CHAR
17#undef SHORT
18#undef INT
19#undef LONG
20#undef LLONG
21#undef FLOAT
22#undef DOUBLE
23#undef LDOUBLE
24#undef VOID
25#undef POINTER
26#undef ARRAY
27#undef STRUCT
28#undef UNION
29#undef ENUM
30#undef FUNKT
31#undef BOOL
32#undef MAXINT
33#undef MAX_TYPE
34
35#define CHAR 1
36#define SHORT 2
37#define INT 3
38#define LONG 4
39#define LLONG 5
40#define FLOAT 6
41#define DOUBLE 7
42#define LDOUBLE 8
43#define VOID 9
44#define POINTER 10
45#define FPOINTER 11
46#define HPOINTER 12
47#define ARRAY 13
48#define STRUCT 14
49#define UNION 15
50#define ENUM 16
51#define FUNKT 17
52#define BOOL 18
53
54#define MAXINT 19
55
56#define MAX_TYPE MAXINT
57
58
59#define POINTER_TYPE(x) pointer_type(x)
60#define POINTER_VARADR(x) pointer_varadr(x)
61extern int pointer_type();
62extern int pointer_varadr();
63#define ISPOINTER(x) ((x&NQ)>=POINTER&&(x&NQ)<=HPOINTER)
64#define ISSCALAR(x) ((x&NQ)>=CHAR&&(x&NQ)<=HPOINTER)
65#define ISINT(x) ((x&NQ)>=CHAR&&(x&NQ)<=LLONG)
66#define PTRDIFF_T(x) ((x)==HPOINTER?LONG:INT)
67
68typedef zllong zmax;
69typedef zullong zumax;
70
71union atyps{
72 zchar vchar;
73 zuchar vuchar;
74 zshort vshort;
75 zushort vushort;
76 zint vint;
77 zuint vuint;
78 zlong vlong;
79 zulong vulong;
80 zllong vllong;
81 zullong vullong;
82 zmax vmax;
83 zumax vumax;
84 zfloat vfloat;
85 zdouble vdouble;
86 zldouble vldouble;
87};
88
89
90/* internally used by the backend */
91#define FIRST_GPR 10
92#define LAST_GPR (FIRST_GPR+NUM_GPRS-1)
93#define FIRST_PAIR (LAST_GPR+1)
94#define LAST_PAIR (FIRST_PAIR+NUM_PAIRS-1)
95#define FIRST_BIG (LAST_PAIR+1)
96#define LAST_BIG (FIRST_BIG+NUM_BIG-1)
97#define FIRST_BIGP (LAST_BIG+1)
98#define LAST_BIGP (FIRST_BIGP+NUM_BIGP-1)
99
100/* This struct can be used to implement machine-specific */
101/* addressing-modes. */
102/* Currently possible are (const,gpr) and (gpr,gpr) */
103struct AddressingMode{
104 int flags;
105 int base;
106 int idx;
107 long offset;
108 void *v;
109};
110
111/* The number of registers of the target machine. */
112#define MAXR LAST_BIGP
113
114/* Number of commandline-options the code-generator accepts. */
115#define MAXGF 20
116
117/* If this is set to zero vbcc will not generate ICs where the */
118/* target operand is the same as the 2nd source operand. */
119/* This can sometimes simplify the code-generator, but usually */
120/* the code is better if the code-generator allows it. */
121#define USEQ2ASZ 1
122
123/* This specifies the smallest integer type that can be added to a */
124/* pointer. */
125#define MINADDI2P CHAR
126
127/* If the bytes of an integer are ordered most significant byte */
128/* byte first and then decreasing set BIGENDIAN to 1. */
129#define BIGENDIAN 0
130
131/* If the bytes of an integer are ordered lest significant byte */
132/* byte first and then increasing set LITTLEENDIAN to 1. */
133#define LITTLEENDIAN 1
134
135/* Note that BIGENDIAN and LITTLEENDIAN are mutually exclusive. */
136
137/* If switch-statements should be generated as a sequence of */
138/* SUB,TST,BEQ ICs rather than COMPARE,BEQ ICs set this to 1. */
139/* This can yield better code on some machines. */
140#define SWITCHSUBS 0
141
142/* In optimizing compilation certain library memcpy/strcpy-calls */
143/* with length known at compile-time will be inlined using an */
144/* ASSIGN-IC if the size is less or equal to INLINEMEMCPY. */
145/* The type used for the ASSIGN-IC will be UNSIGNED|CHAR. */
146#define INLINEMEMCPY 1024
147
148/* Parameters are sometimes passed in registers without __reg. */
149#define HAVE_REGPARMS 1
150
151/* Parameters on the stack should be pushed in order rather than */
152/* in reverse order. */
153#define ORDERED_PUSH FIXED_SP
154
155/* Structure for reg_parm(). */
156struct reg_handle{
157 int regs;
158 int bregs;
159};
160
161/* We have some target-specific variable attributes. */
162#define HAVE_TARGET_ATTRIBUTES
163
164/* We have target-specific pragmas */
165#define HAVE_TARGET_PRAGMAS
166
167/* We keep track of all registers modified by a function. */
168#define HAVE_REGS_MODIFIED 1
169
170/* We have a implement our own cost-functions to adapt
171 register-allocation */
172#define HAVE_TARGET_RALLOC 1
173#define cost_move_reg(x,y) 3
174// MEGA65 CPU has one wait-state on reads when CPU is at full speed
175#define cost_load_reg(x,y) 5
176#define cost_save_reg(x,y) 4
177#define cost_pushpop_reg(x) 6
178
179/* size of buffer for asm-output, this can be used to do
180 peephole-optimizations of the generated assembly-output */
181#define EMIT_BUF_LEN 1024 /* should be enough */
182/* number of asm-output lines buffered */
183#define EMIT_BUF_DEPTH 8
184
185/* We have no asm_peephole to optimize assembly-output */
186#define HAVE_TARGET_PEEPHOLE 1
187
188/* we do not have a mark_eff_ics function, this is used to prevent
189 optimizations on code which can already be implemented by efficient
190 assembly */
191#undef HAVE_TARGET_EFF_IC
192
193/* we have additional types */
194#define HAVE_EXT_TYPES
195#define HAVE_TGT_PRINTVAL
196
197/* we do not need extra elements in the IC */
198#undef HAVE_EXT_IC
199
200/* we do not use unsigned int as size_t (but unsigned long, the default) */
201#define HAVE_INT_SIZET 1
202
203/* we do not need register-pairs */
204#define HAVE_REGPAIRS 1
205
206
207/* do not create CONVERT ICs from integers smaller than int to floats */
208#define MIN_INT_TO_FLOAT_TYPE INT
209
210/* do not create CONVERT ICs from floats to ints smaller than int */
211#define MIN_FLOAT_TO_INT_TYPE INT
212
213/* do not create CONVERT_ICs from floats to unsigned integers */
214#define AVOID_FLOAT_TO_UNSIGNED 0
215
216/* do not create CONVERT_ICs from unsigned integers to floats */
217#define AVOID_UNSIGNED_TO_FLOAT 0
218
219/* convert multiplications/division by powers of two to shifts */
220#define HAVE_POF2OPT 1
221
222/* We use builtin libcalls for some operations */
223#define HAVE_LIBCALLS 1
224
225/* Use char for return of comparison libcalls */
226#define LIBCALL_CMPTYPE CHAR
227
228/* We prefer BNE rather than BGT. */
229#define HAVE_WANTBNE 1
230
231#define BESTCOPYT CHAR
232
233#define HAVE_AOS4 1
234
235#define CHARCONV(x) cbmconv(x)
236unsigned char cbmconv(unsigned char);
237
238#define ALLOCVLA_REG FIRST_PAIR
239#define ALLOCVLA_INLINEASM "\tlda\tsp\n"\
240 "\tsec\n"\
241 "\tsbc\tr0\n"\
242 "\tsta\tsp\n"\
243 "\tlda\tsp+1\n"\
244 "\tsbc\tr1\n"\
245 "\tsta\tsp+1\n"\
246 "\tlda\tsp\n"\
247 "\tclc\n"\
248 "\tldx\tsp+1\n"\
249 "\tadc\t#___fo\n"\
250 "\tbcc\t*+3\n"\
251 "\tinx\n"
252
253#define FREEVLA_REG FIRST_PAIR
254#define FREEVLA_INLINEASM "\tlda\tr0\n"\
255 "\tsta\tsp\n"\
256 "\tlda\tr1\n"\
257 "\tsta\tsp+1\n"
258
259#define OLDSPVLA_INLINEASM "\tlda\tsp+1\n"\
260 "\ttax\n"\
261 "\tlda\tsp"
262
263#define FPVLA_REG (LAST_PAIR-2)
264
265#define HAVE_TARGET_VARHOOK_POST 1
266
267#define HAVE_DECIDE_REVERSE 1
268
269#define HAVE_TARGET_EFF_IC 1