2 hc08 specific general functions.
4 Note that mlh prepended _hc08_ on the static functions. Makes
5 it easier to set a breakpoint using the debugger.
11 #include "../SDCCutil.h"
13 void copyFile(FILE *dest, FILE *src);
14 extern char * iComments2;
16 static char _defaultRules[] =
21 /* list of key words used by msc51 */
22 static char *_hc08_keywords[] =
52 void hc08_assignRegisters (eBBlock ** ebbs, int count);
54 static int regParmFlg = 0; /* determine if we can register a parameter */
59 asm_addTree (&asm_asxxxx_mapping);
63 _hc08_reset_regparm ()
69 _hc08_regparm (sym_link * l)
71 int size = getSize(l);
73 /* If they fit completely, the first two bytes of parameters can go */
74 /* into A and X, otherwise, they go on the stack. Examples: */
75 /* foo(char p1) A <- p1 */
76 /* foo(char p1, char p2) A <- p1, X <- p2 */
77 /* foo(char p1, char p2, char p3) A <- p1, X <- p2, stack <- p3 */
78 /* foo(int p1) XA <- p1 */
79 /* foo(long p1) stack <- p1 */
80 /* foo(char p1, int p2) A <- p1, stack <- p2 */
81 /* foo(int p1, char p2) XA <- p1, stack <- p2 */
86 if ((regParmFlg+size)>2)
93 return 1+regParmFlg-size;
97 _hc08_parseOptions (int *pargc, char **argv, int *i)
103 _hc08_finaliseOptions (void)
105 if (options.noXinitOpt) {
109 if (options.model == MODEL_LARGE) {
110 port->mem.default_local_map = xdata;
111 port->mem.default_globl_map = xdata;
115 port->mem.default_local_map = data;
116 port->mem.default_globl_map = data;
122 _hc08_setDefaultOptions (void)
124 options.code_loc = 0x8000;
125 options.data_loc = 0x80;
126 options.xdata_loc = 0x100;
127 options.stack_loc = 0x7fff;
128 options.out_fmt = 1; /* use motorola S19 output */
130 options.ommitFramePtr = 1; /* no frame pointer (we use SP */
131 /* offsets instead) */
136 _hc08_getRegName (struct regs *reg)
144 _hc08_genAssemblerPreamble (FILE * of)
147 symbol *mainExists=newSymbol("main", 0);
150 fprintf (of, "\t.area %s\n",port->mem.code_name);
151 fprintf (of, "\t.area %s\n",port->mem.static_name);
152 fprintf (of, "\t.area %s\n",port->mem.post_static_name);
153 fprintf (of, "\t.area %s\n",port->mem.xinit_name);
154 fprintf (of, "\t.area %s\n",port->mem.data_name);
155 fprintf (of, "\t.area %s\n",port->mem.overlay_name);
156 fprintf (of, "\t.area %s\n",port->mem.bit_name);
157 fprintf (of, "\t.area %s\n",port->mem.xdata_name);
158 fprintf (of, "\t.area %s\n",port->mem.xidata_name);
160 if ((mainExists=findSymWithLevel(SymbolTab, mainExists)))
162 // generate interrupt vector table
163 fprintf (of, "\t.area\tCODEIVT (ABS)\n");
164 fprintf (of, "\t.org\t0x%4x\n", (0xfffe - (maxInterrupts * 2)));
166 for (i=maxInterrupts;i>0;i--)
169 fprintf (of, "\t.dw\t%s\n", interrupts[i]->rname);
171 fprintf (of, "\t.dw\t0\n");
173 fprintf (of, "\t.dw\t%s", "__sdcc_gs_init_startup\n\n");
175 fprintf (of, "\t.area GSINIT\n");
176 fprintf (of, "__sdcc_gs_init_startup:\n");
177 if (options.stack_loc)
179 fprintf (of, "\tldhx\t#0x%4x\n", options.stack_loc+1);
180 fprintf (of, "\ttxs\n");
183 fprintf (of, "\trsp\n");
184 fprintf (of, "\tjsr\t__sdcc_external_startup\n");
185 fprintf (of, "\tbeq\t__sdcc_init_data\n");
186 fprintf (of, "\tjmp\t__sdcc_program_startup\n");
187 fprintf (of, "__sdcc_init_data:\n");
189 fprintf (of, "; _hc08_genXINIT() start\n");
190 fprintf (of, " ldhx #0\n");
191 fprintf (of, "00001$:\n");
192 fprintf (of, " cphx #l_XINIT\n");
193 fprintf (of, " beq 00002$\n");
194 fprintf (of, " lda s_XINIT,x\n");
195 fprintf (of, " sta s_XISEG,x\n");
196 fprintf (of, " aix #1\n");
197 fprintf (of, " bra 00001$\n");
198 fprintf (of, "00002$:\n");
199 fprintf (of, "; _hc08_genXINIT() end\n");
201 fprintf (of, "\t.area GSFINAL\n");
202 fprintf (of, "\tjmp\t__sdcc_program_startup\n\n");
204 fprintf (of, "\t.area CSEG\n");
205 fprintf (of, "__sdcc_program_startup:\n");
206 fprintf (of, "\tjsr\t_main\n");
207 fprintf (of, "\tbra\t.\n");
213 _hc08_genExtraAreas (FILE * asmFile, bool mainExists)
215 fprintf (asmFile, "%s", iComments2);
216 fprintf (asmFile, "; external ram data\n");
217 fprintf (asmFile, "%s", iComments2);
218 copyFile (asmFile, xdata->oFile);
222 /* Generate interrupt vector table. */
224 _hc08_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
228 fprintf (of, "\t.area\tCODEIVT (ABS)\n");
229 fprintf (of, "\t.org\t0x%4x\n",
230 (0xfffe - (maxInterrupts * 2)));
232 for (i=maxInterrupts;i>0;i--)
235 fprintf (of, "\t.dw\t%s\n", interrupts[i]->rname);
237 fprintf (of, "\t.dw\t0\n");
239 fprintf (of, "\t.dw\t%s", "__sdcc_gs_init_startup\n");
244 /* Generate code to copy XINIT to XISEG */
245 static void _hc08_genXINIT (FILE * of) {
246 fprintf (of, "; _hc08_genXINIT() start\n");
247 fprintf (of, "; _hc08_genXINIT() end\n");
251 /* Do CSE estimation */
252 static bool cseCostEstimation (iCode *ic, iCode *pdic)
254 operand *result = IC_RESULT(ic);
255 sym_link *result_type = operandType(result);
257 return 0; /* disable CSE */
259 /* if it is a pointer then return ok for now */
260 if (IC_RESULT(ic) && IS_PTR(result_type)) return 1;
262 if (ic->op == ADDRESS_OF)
265 /* if bitwise | add & subtract then no since hc08 is pretty good at it
266 so we will cse only if they are local (i.e. both ic & pdic belong to
267 the same basic block */
268 if (IS_BITWISE_OP(ic) || ic->op == '+' || ic->op == '-') {
269 /* then if they are the same Basic block then ok */
270 if (ic->eBBlockNum == pdic->eBBlockNum) return 1;
274 /* for others it is cheaper to do the cse */
279 /* Indicate which extended bit operations this port supports */
281 hasExtBitOp (int op, int size)
286 || (op == SWAP && size <= 2)
293 /* Indicate the expense of an access to an output storage class */
295 oclsExpense (struct memmap *oclass)
297 /* The hc08's addressing modes allow access to all storage classes */
298 /* inexpensively (<=0) */
300 if (IN_DIRSPACE (oclass)) /* direct addressing mode is fastest */
302 if (IN_FARSPACE (oclass)) /* extended addressing mode is almost at fast */
304 if (oclass == istack) /* stack is the slowest, but still faster than */
305 return 0; /* trying to copy to a temp location elsewhere */
307 return 0; /* anything we missed */
312 /** $1 is always the basename.
313 $2 is always the output file.
315 $l is the list of extra options that should be there somewhere...
316 MUST be terminated with a NULL.
318 static const char *_linkCmd[] =
320 "link-hc08", "-nf", "\"$1\"", NULL
323 /* $3 is replaced by assembler.debug_opts resp. port->assembler.plain_opts */
324 static const char *_asmCmd[] =
326 "as-hc08", "$l", "$3", "\"$1.asm\"", NULL
334 "HC08", /* Target name */
335 NULL, /* Processor name */
338 FALSE, /* Emit glue around main */
339 MODEL_SMALL | MODEL_LARGE,
345 "-plosgffc", /* Options with debug */
346 "-plosgff", /* Options without debug */
349 NULL /* no do_assemble function */
361 /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
362 1, 2, 2, 4, 2, 2, 2, 1, 4, 4
377 "XISEG", // initialized xdata
378 "XINIT", // a code copy of xiseg
383 { _hc08_genExtraAreas,
388 /* hc08 has an 8 bit mul */
396 _hc08_finaliseOptions,
397 _hc08_setDefaultOptions,
398 hc08_assignRegisters,
401 _hc08_genAssemblerPreamble,
402 NULL, /* no genAssemblerEnd */
407 NULL, /* process_pragma */
408 NULL, /* getMangledFunctionName */
409 NULL, /* hasNativeMulFor */
410 hasExtBitOp, /* hasExtBitOp */
411 oclsExpense, /* oclsExpense */
412 TRUE, /* use_dw_for_init */
413 FALSE, /* little endian */
416 1, /* transform <= to ! > */
417 1, /* transform >= to ! < */
418 1, /* transform != to !(a == b) */
420 FALSE, /* No array initializer support. */
422 NULL, /* no builtin functions */
423 GPOINTER, /* treat unqualified pointers as "generic" pointers */
424 1, /* reset labelKey to 1 */
425 1, /* globals & local static allowed */