1 /*****************************************************************************/
5 /* 6502 code generator */
9 /* (C) 1998 Ullrich von Bassewitz */
11 /* D-70597 Stuttgart */
12 /* EMail: uz@musoftware.de */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
41 /*****************************************************************************/
43 /*****************************************************************************/
47 /* Code generator flags.
48 * Note: The type flags are designed so that a smaller type may override a
49 * larger one by or'ing it into the existing one.
51 #define CF_NONE 0x0000 /* No special flags */
53 #define CF_TYPE 0x000F /* Mask for operand type */
54 #define CF_CHAR 0x0003 /* Operation on characters */
55 #define CF_INT 0x0001 /* Operation on ints */
56 #define CF_PTR CF_INT /* Alias for readability */
57 #define CF_LONG 0x0000 /* Operation on longs */
59 #define CF_UNSIGNED 0x0010 /* Value is unsigned */
60 #define CF_CONST 0x0020 /* Constant value available */
61 #define CF_CONSTADDR 0x0040 /* Constant address value available */
62 #define CF_TEST 0x0080 /* Test value */
63 #define CF_FIXARGC 0x0100 /* Function has fixed arg count */
64 #define CF_FORCECHAR 0x0200 /* Handle chars as chars, not ints */
65 #define CF_SHORT 0x0400 /* Use short addressing */
66 #define CF_REG 0x0800 /* Value is in primary register */
68 /* Type of static address */
69 #define CF_ADDRMASK 0xF000 /* Type of address */
70 #define CF_STATIC 0x0000 /* Static local */
71 #define CF_EXTERNAL 0x1000 /* Static external */
72 #define CF_ABSOLUTE 0x2000 /* Numeric absolute address */
73 #define CF_LOCAL 0x4000 /* Auto variable */
74 #define CF_REGVAR 0x8000 /* Register variable */
78 /* Compiler relative stackpointer */
83 /*****************************************************************************/
84 /* Pre- and postamble */
85 /*****************************************************************************/
89 void g_preamble (void);
90 /* Generate the assembler code preamble */
92 void g_postamble (void);
93 /* Generate assembler code postamble */
97 /*****************************************************************************/
99 /*****************************************************************************/
103 void g_usecode (void);
104 /* Switch to the code segment */
106 void g_userodata (void);
107 /* Switch to the read only data segment */
109 void g_usedata (void);
110 /* Switch to the data segment */
112 void g_usebss (void);
113 /* Switch to the bss segment */
115 void g_codename (const char* Name);
116 /* Set the name of the CODE segment */
118 void g_rodataname (const char* Name);
119 /* Set the name of the RODATA segment */
121 void g_dataname (const char* Name);
122 /* Set the name of the DATA segment */
124 void g_bssname (const char* Name);
125 /* Set the name of the BSS segment */
129 /*****************************************************************************/
130 /* Functions handling local labels */
131 /*****************************************************************************/
135 void g_defloclabel (unsigned label);
136 /* Define a local label */
140 /*****************************************************************************/
141 /* Functions handling global labels */
142 /*****************************************************************************/
146 void g_defgloblabel (const char* Name);
147 /* Define a global label with the given name */
149 void g_defexport (const char* Name, int ZP);
150 /* Export the given label */
152 void g_defimport (const char* Name, int ZP);
153 /* Import the given label */
157 /*****************************************************************************/
159 /*****************************************************************************/
163 int pop (unsigned flags);
164 /* Pop an argument of the given size */
166 int push (unsigned flags);
167 /* Push an argument of the given size */
169 unsigned sizeofarg (unsigned flags);
170 /* Return the size of a function argument type that is encoded in flags */
174 /*****************************************************************************/
175 /* type conversion and similiar stuff */
176 /*****************************************************************************/
180 void g_toslong (unsigned flags);
181 /* Make sure, the value on TOS is a long. Convert if necessary */
183 void g_tosint (unsigned flags);
184 /* Make sure, the value on TOS is an int. Convert if necessary */
186 void g_reglong (unsigned flags);
187 /* Make sure, the value in the primary register a long. Convert if necessary */
189 unsigned g_typeadjust (unsigned lhs, unsigned rhs);
190 /* Adjust the integer operands before doing a binary operation. lhs is a flags
191 * value, that corresponds to the value on TOS, rhs corresponds to the value
192 * in (e)ax. The return value is the the flags value for the resulting type.
195 unsigned g_typecast (unsigned lhs, unsigned rhs);
196 /* Cast the value in the primary register to the operand size that is flagged
197 * by the lhs value. Return the result value.
200 void g_scale (unsigned flags, long val);
201 /* Scale the value in the primary register by the given value. If val is positive,
202 * scale up, is val is negative, scale down. This function is used to scale
203 * the operands or results of pointer arithmetic by the size of the type, the
209 /*****************************************************************************/
210 /* Function entry and exit */
211 /*****************************************************************************/
215 void g_enter (unsigned flags, unsigned argsize);
216 /* Function prologue */
218 void g_leave (int flags, int val);
219 /* Function epilogue */
223 /*****************************************************************************/
224 /* Register variables */
225 /*****************************************************************************/
229 void g_save_regvars (int RegOffs, unsigned Bytes);
230 /* Save register variables */
232 void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes);
233 /* Restore register variables */
237 /*****************************************************************************/
238 /* Fetching memory cells */
239 /*****************************************************************************/
243 void g_getimmed (unsigned Flags, unsigned long Val, unsigned Offs);
244 /* Load a constant into the primary register */
246 void g_getstatic (unsigned Flags, unsigned long Label, unsigned Offs);
247 /* Fetch an static memory cell into the primary register */
249 void g_getlocal (unsigned Flags, int Offs);
250 /* Fetch specified local object (local var). */
252 void g_getind (unsigned Flags, unsigned Offs);
253 /* Fetch the specified object type indirect through the primary register
254 * into the primary register
257 void g_leasp (int Offs);
258 /* Fetch the address of the specified symbol into the primary register */
260 void g_leavariadic (int Offs);
261 /* Fetch the address of a parameter in a variadic function into the primary
267 /*****************************************************************************/
268 /* Store into memory */
269 /*****************************************************************************/
273 void g_putstatic (unsigned flags, unsigned long label, unsigned offs);
274 /* Store the primary register into the specified static memory cell */
276 void g_putlocal (unsigned flags, int offs);
277 /* Put data into local object. */
279 void g_putind (unsigned flags, unsigned offs);
280 /* Store the specified object type in the primary register at the address
281 * on the top of the stack
286 /*****************************************************************************/
287 /* Adds and subs of variables fix a fixed address */
288 /*****************************************************************************/
292 void g_addlocal (unsigned flags, int offs);
293 /* Add a local variable to ax */
295 void g_addstatic (unsigned flags, unsigned long label, unsigned offs);
296 /* Add a static variable to ax */
300 /*****************************************************************************/
301 /* Compares of ax with a variable with fixed address */
302 /*****************************************************************************/
306 void g_cmplocal (unsigned flags, int offs);
307 /* Compare a local variable to ax */
309 void g_cmpstatic (unsigned flags, unsigned label, unsigned offs);
310 /* Compare a static variable to ax */
314 /*****************************************************************************/
315 /* Special op= functions */
316 /*****************************************************************************/
320 void g_addeqstatic (unsigned flags, unsigned long label, unsigned offs,
322 /* Emit += for a static variable */
324 void g_addeqlocal (unsigned flags, int offs, unsigned long val);
325 /* Emit += for a local variable */
327 void g_addeqind (unsigned flags, unsigned offs, unsigned long val);
328 /* Emit += for the location with address in ax */
330 void g_subeqstatic (unsigned flags, unsigned long label, unsigned offs,
332 /* Emit -= for a static variable */
334 void g_subeqlocal (unsigned flags, int offs, unsigned long val);
335 /* Emit -= for a local variable */
337 void g_subeqind (unsigned flags, unsigned offs, unsigned long val);
338 /* Emit -= for the location with address in ax */
342 /*****************************************************************************/
343 /* Add a variable address to the value in ax */
344 /*****************************************************************************/
348 void g_addaddr_local (unsigned flags, int offs);
349 /* Add the address of a local variable to ax */
351 void g_addaddr_static (unsigned flags, unsigned long label, unsigned offs);
352 /* Add the address of a static variable to ax */
356 /*****************************************************************************/
358 /*****************************************************************************/
362 void g_save (unsigned flags);
363 void g_restore (unsigned flags);
365 void g_cmp (unsigned flags, unsigned long val);
366 /* Immidiate compare. The primary register will not be changed, Z flag
370 void g_test (unsigned flags);
371 void g_push (unsigned flags, unsigned long val);
372 void g_swap (unsigned flags);
373 void g_call (unsigned flags, char *lbl, unsigned argsize);
374 void g_callind (unsigned flags, unsigned argsize);
375 void g_jump (unsigned label);
376 void g_switch (unsigned flags);
378 void g_case (unsigned flags, unsigned label, unsigned long val);
379 /* Create table code for one case selector */
381 void g_truejump (unsigned flags, unsigned label);
382 /* Jump to label if zero flag clear */
384 void g_falsejump (unsigned flags, unsigned label);
385 /* Jump to label if zero flag set */
387 void g_space (int space);
388 /* Create or drop space on the stack */
390 void g_cstackcheck (void);
391 /* Check for a C stack overflow */
393 void g_stackcheck (void);
394 /* Check for a stack overflow */
396 void g_add (unsigned flags, unsigned long val);
397 void g_sub (unsigned flags, unsigned long val);
398 void g_rsub (unsigned flags, unsigned long val);
399 void g_mul (unsigned flags, unsigned long val);
400 void g_div (unsigned flags, unsigned long val);
401 void g_mod (unsigned flags, unsigned long val);
402 void g_or (unsigned flags, unsigned long val);
403 void g_xor (unsigned flags, unsigned long val);
404 void g_and (unsigned flags, unsigned long val);
405 void g_asr (unsigned flags, unsigned long val);
406 void g_asl (unsigned flags, unsigned long val);
407 void g_neg (unsigned flags);
408 void g_bneg (unsigned flags);
409 void g_com (unsigned flags);
410 void g_inc (unsigned flags, unsigned long n);
411 void g_dec (unsigned flags, unsigned long n);
412 void g_eq (unsigned flags, unsigned long val);
413 void g_ne (unsigned flags, unsigned long val);
414 void g_lt (unsigned flags, unsigned long val);
415 void g_le (unsigned flags, unsigned long val);
416 void g_gt (unsigned flags, unsigned long val);
417 void g_ge (unsigned flags, unsigned long val);
419 void g_res (unsigned n);
420 /* Reserve static storage, n bytes */
422 void g_defdata (unsigned flags, unsigned long val, unsigned offs);
423 /* Define data with the size given in flags */
425 void g_defbytes (const void* bytes, unsigned count);
426 /* Output a row of bytes as a constant */
428 void g_zerobytes (unsigned n);
429 /* Output n bytes of data initialized with zero */
433 /*****************************************************************************/
434 /* Inlined known functions */
435 /*****************************************************************************/
439 void g_strlen (unsigned flags, unsigned long val, unsigned offs);
440 /* Inline the strlen() function */
444 /* End of codegen.h */