2 pic16 specific general functions.
4 Note that mlh prepended _pic16_ on the static functions. Makes
5 it easier to set a breakpoint using the debugger.
16 static char _defaultRules[] =
21 /* list of key words used by pic16 */
22 static char *_pic16_keywords[] =
49 void pic16_pCodeInitRegisters(void);
51 void pic16_assignRegisters (eBBlock ** ebbs, int count);
53 static int regParmFlg = 0; /* determine if we can register a parameter */
58 asm_addTree (&asm_asxxxx_mapping);
59 pic16_pCodeInitRegisters();
64 _pic16_reset_regparm ()
70 _pic16_regparm (sym_link * l)
72 /* for this processor it is simple
73 can pass only the first parameter in a register */
82 _process_pragma(const char *sz)
84 static const char *WHITE = " \t";
85 char *ptr = strtok((char *)sz, WHITE);
87 if (startsWith (ptr, "memmap"))
94 start = strtok((char *)NULL, WHITE);
95 end = strtok((char *)NULL, WHITE);
96 type = strtok((char *)NULL, WHITE);
97 alias = strtok((char *)NULL, WHITE);
99 if (start != (char *)NULL
100 && end != (char *)NULL
101 && type != (char *)NULL) {
102 value *startVal = constVal(start);
103 value *endVal = constVal(end);
107 if (alias == (char *)NULL) {
108 aliasVal = constVal(0);
110 aliasVal = constVal(alias);
113 r.start_address = (int)floatFromVal(startVal);
114 r.end_address = (int)floatFromVal(endVal);
115 r.alias = (int)floatFromVal(aliasVal);
116 r.bank = (r.start_address >> 7) & 0xf;
118 if (strcmp(type, "RAM") == 0) {
119 pic16_addMemRange(&r, 0);
120 } else if (strcmp(type, "SFR") == 0) {
121 pic16_addMemRange(&r, 1);
128 } else if (startsWith (ptr, "maxram")) {
129 char *maxRAM = strtok((char *)NULL, WHITE);
131 if (maxRAM != (char *)NULL) {
135 maxRAMVal = constVal(maxRAM);
136 maxRAMaddress = (int)floatFromVal(maxRAMVal);
137 pic16_setMaxRAM(maxRAMaddress);
146 _pic16_parseOptions (int *pargc, char **argv, int *i)
148 /* TODO: allow port-specific command line options to specify
149 * segment names here.
155 _pic16_finaliseOptions (void)
158 port->mem.default_local_map = data;
159 port->mem.default_globl_map = data;
161 /* Hack-o-matic: if we are using the flat24 model,
162 * adjust pointer sizes.
164 if (options.model == MODEL_FLAT24)
167 fprintf (stderr, "*** WARNING: you should use the '-mds390' option "
168 "for DS80C390 support. This code generator is "
169 "badly out of date and probably broken.\n");
171 port->s.fptr_size = 3;
172 port->s.gptr_size = 4;
173 port->stack.isr_overhead++; /* Will save dpx on ISR entry. */
175 port->stack.call_overhead++; /* This acounts for the extra byte
176 * of return addres on the stack.
177 * but is ugly. There must be a
181 fReturn = fReturn390;
185 if (options.model == MODEL_LARGE)
187 port->mem.default_local_map = xdata;
188 port->mem.default_globl_map = xdata;
192 port->mem.default_local_map = data;
193 port->mem.default_globl_map = data;
196 if (options.stack10bit)
198 if (options.model != MODEL_FLAT24)
201 "*** warning: 10 bit stack mode is only supported in flat24 model.\n");
202 fprintf (stderr, "\t10 bit stack mode disabled.\n");
203 options.stack10bit = 0;
207 /* Fixup the memory map for the stack; it is now in
208 * far space and requires a FPOINTER to access it.
211 istack->ptrType = FPOINTER;
218 _pic16_setDefaultOptions (void)
223 _pic16_getRegName (struct regs *reg)
230 extern char *pic16_processor_base_name(void);
233 _pic16_genAssemblerPreamble (FILE * of)
235 char * name = pic16_processor_base_name();
240 fprintf(stderr,"WARNING: No Pic has been selected, defaulting to %s\n",name);
243 fprintf (of, "\tlist\tp=%s\n",&name[1]);
244 fprintf (of, "\tinclude \"%s.inc\"\n",name);
247 fprintf (of, "\t__config _CONFIG1H,0x%x\n",pic16_getConfigWord(0x300001));
248 fprintf (of, "\t__config _CONFIG2L,0x%x\n",pic16_getConfigWord(0x300002));
249 fprintf (of, "\t__config _CONFIG2H,0x%x\n",pic16_getConfigWord(0x300003));
250 fprintf (of, "\t__config _CONFIG3H,0x%x\n",pic16_getConfigWord(0x300005));
251 fprintf (of, "\t__config _CONFIG4L,0x%x\n",pic16_getConfigWord(0x300006));
252 fprintf (of, "\t__config _CONFIG5L,0x%x\n",pic16_getConfigWord(0x300008));
253 fprintf (of, "\t__config _CONFIG5H,0x%x\n",pic16_getConfigWord(0x300009));
254 fprintf (of, "\t__config _CONFIG6L,0x%x\n",pic16_getConfigWord(0x30000a));
255 fprintf (of, "\t__config _CONFIG6H,0x%x\n",pic16_getConfigWord(0x30000b));
256 fprintf (of, "\t__config _CONFIG7L,0x%x\n",pic16_getConfigWord(0x30000c));
257 fprintf (of, "\t__config _CONFIG7H,0x%x\n",pic16_getConfigWord(0x30000d));
260 fprintf (of, "\tradix dec\n");
263 /* Generate interrupt vector table. */
265 _pic16_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
272 if (options.model != MODEL_FLAT24)
274 /* Let the default code handle it. */
279 /* PIC18F family has only two interrupts, the high and the low
280 * priority interrupts, which reside in 0x0008 and 0x0018 respectively */
282 fprintf(of, "; RESET vector\n");
283 fprintf(of, "\tgoto\t__sdcc_gsinit_startup\n");
284 fprintf(of, "\tres 2\n");
287 fprintf(of, "; High priority interrupt vector 0x0008\n");
290 fprintf(of, "\tgoto\t%s\n", interrupts[1]->rname);
291 fprintf(of, "\tres\t6\n");
293 fprintf(of, "\tretfie\n");
294 fprintf(of, "\tres\t14\n");
297 fprintf(of, "; Low priority interrupt vector 0x0018\n");
299 fprintf(of, "\tgoto\t%s\n", interrupts[2]->rname);
301 fprintf(of, "\tretfie\n");
304 /* now for the other interrupts */
305 for (i = 0; i < maxInterrupts; i++)
307 fprintf(of, "; %s priority interrupt vector 0x%s\n", (i==0)?"high":"low", (i==0)?"0008":"0018");
310 fprintf (of, "\tgoto\t%s\n\tres\t4\n", interrupts[i]->rname);
314 fprintf (of, "\tretfie\n\tres\t7\n");
323 _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
325 // sym_link *test = NULL;
328 fprintf(stderr,"checking for native mult\n");
337 if ( IS_LITERAL (left))
339 fprintf(stderr,"left is lit\n");
341 val = OP_VALUE (IC_LEFT (ic));
343 else if ( IS_LITERAL (right))
345 fprintf(stderr,"right is lit\n");
347 val = OP_VALUE (IC_RIGHT (ic));
351 fprintf(stderr,"oops, neither is lit so no\n");
355 if ( getSize (test) <= 2)
357 fprintf(stderr,"yep\n");
360 fprintf(stderr,"nope\n");
366 /** $1 is always the basename.
367 $2 is always the output file.
369 $l is the list of extra options that should be there somewhere...
370 MUST be terminated with a NULL.
372 static const char *_linkCmd[] =
374 "gplink", "\"$1.o\"", "-o $1", "$l", NULL
377 /* Sigh. This really is not good. For now, I recommend:
378 * sdcc -S -mpic16 file.c
379 * the -S option does not compile or link
381 static const char *_asmCmd[] =
383 "gpasm", "-c -I/usr/local/share/gputils/header", "\"$1.asm\"", NULL
392 "MCU PIC16", /* Target name */
393 "p18f442", /* Processor */
396 TRUE, /* Emit glue around main */
397 MODEL_SMALL | MODEL_LARGE | MODEL_FLAT24,
405 //"-plosgffc", /* Options with debug */
406 //"-plosgff", /* Options without debug */
409 NULL /* no do_assemble function */
421 /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
422 1, 2, 2, 4, 2, 2, 2, 1, 4, 4
423 /* TSD - I changed the size of gptr from 3 to 1. However, it should be
424 2 so that we can accomodate the PIC's with 4 register banks (like the
429 "XSEG (XDATA)", // xstack
430 "STACK (DATA)", // istack
431 "CSEG (CODE)", // code
432 "DSEG (DATA)", // data
433 "ISEG (DATA)", // idata
434 "XSEG (XDATA)", // xdata
436 "RSEG (DATA)", // reg
437 "GSINIT (CODE)", // static
438 "OSEG (OVR,DATA)", // overlay
439 "GSFINAL (CODE)", // post static
440 "HOME (CODE)", // home
443 NULL, // default location for auto vars
444 NULL, // default location for global vars
445 1 // code is read only
451 /* pic16 has an 8 bit mul */
459 _pic16_finaliseOptions,
460 _pic16_setDefaultOptions,
461 pic16_assignRegisters,
464 _pic16_genAssemblerPreamble,
465 NULL, /* no genAssemblerEnd */
467 NULL, // _pic16_genXINIT
468 _pic16_reset_regparm,
470 _process_pragma, /* process a pragma */
476 1, /* transform <= to ! > */
477 1, /* transform >= to ! < */
478 1, /* transform != to !(a == b) */
480 FALSE, /* No array initializer support. */
481 0, /* no CSE cost estimation yet */
482 NULL, /* no builtin functions */
483 GPOINTER, /* treat unqualified pointers as "generic" pointers */
484 1, /* reset labelKey to 1 */
485 1, /* globals & local static allowed */