2 pic14 specific general functions.
4 Note that mlh prepended _pic14_ on the static functions. Makes
5 it easier to set a breakpoint using the debugger.
12 #include "SDCCmacro.h"
18 static char _defaultRules[] =
24 /* list of key words used by pic14 */
25 static char *_pic14_keywords[] =
52 pic14_options_t pic14_options;
54 extern int debug_verbose; /* from pcode.c */
55 static OPTION _pic14_poptions[] = {
56 { 0 , "--debug-xtra", &debug_verbose, "show more debug info in assembly output" },
57 { 0 , "--no-pcode-opt", &pic14_options.disable_df, "disable (slightly faulty) optimization on pCode" },
58 { 0 , NULL, NULL, NULL }
61 void pCodeInitRegisters(void);
63 void pic14_assignRegisters (ebbIndex *);
65 /* Also defined in gen.h, but the #include is commented out */
66 /* for an unknowned reason. - EEP */
67 void pic14_emitDebuggerSymbol (char *);
69 static int regParmFlg = 0; /* determine if we can register a parameter */
74 asm_addTree (&asm_asxxxx_mapping);
76 memset (&pic14_options, 0, sizeof (pic14_options));
80 _pic14_reset_regparm (void)
86 _pic14_regparm (sym_link * l, bool reentrant)
88 /* for this processor it is simple
89 can pass only the first parameter in a register */
98 _process_pragma(const char *sz)
100 static const char *WHITE = " \t";
101 char *ptr = strtok((char *)sz, WHITE);
103 if (startsWith (ptr, "memmap"))
110 start = strtok((char *)NULL, WHITE);
111 end = strtok((char *)NULL, WHITE);
112 type = strtok((char *)NULL, WHITE);
113 alias = strtok((char *)NULL, WHITE);
115 if (start != (char *)NULL
116 && end != (char *)NULL
117 && type != (char *)NULL) {
118 value *startVal = constVal(start);
119 value *endVal = constVal(end);
123 if (alias == (char *)NULL) {
124 aliasVal = constVal(0);
126 aliasVal = constVal(alias);
129 r.start_address = (int)floatFromVal(startVal);
130 r.end_address = (int)floatFromVal(endVal);
131 r.alias = (int)floatFromVal(aliasVal);
132 r.bank = (r.start_address >> 7) & 3;
134 if (strcmp(type, "RAM") == 0) {
136 } else if (strcmp(type, "SFR") == 0) {
144 } else if (startsWith (ptr, "maxram")) {
145 char *maxRAM = strtok((char *)NULL, WHITE);
147 if (maxRAM != (char *)NULL) {
151 maxRAMVal = constVal(maxRAM);
152 maxRAMaddress = (int)floatFromVal(maxRAMVal);
153 setMaxRAM(maxRAMaddress);
161 extern char *udata_section_name;
164 _pic14_parseOptions (int *pargc, char **argv, int *i)
168 /* TODO: allow port-specific command line options to specify
169 * segment names here.
172 /* This is a temporary hack, to solve problems with some processors
173 * that do not have udata section. It will be changed when a more
174 * robust solution is figured out -- VR 27-11-2003 FIXME
176 strcpy(buf, "--udata-section-name");
177 if(!strncmp(buf, argv[ *i ], strlen(buf))) {
178 if(strlen(argv[ *i ]) <= strlen(buf)+1) {
179 fprintf(stderr, "WARNING: no `%s' entered\n", buf+2);
182 udata_section_name = strdup( strchr(argv[*i], '=') + 1 );
191 _pic14_finaliseOptions (void)
194 port->mem.default_local_map = data;
195 port->mem.default_globl_map = data;
197 /* Hack-o-matic: if we are using the flat24 model,
198 * adjust pointer sizes.
200 if (options.model == MODEL_FLAT24)
203 fprintf (stderr, "*** WARNING: you should use the '-mds390' option "
204 "for DS80C390 support. This code generator is "
205 "badly out of date and probably broken.\n");
207 port->s.fptr_size = 3;
208 port->s.gptr_size = 4;
209 port->stack.isr_overhead++; /* Will save dpx on ISR entry. */
211 port->stack.call_overhead++; /* This acounts for the extra byte
212 * of return addres on the stack.
213 * but is ugly. There must be a
217 fReturn = fReturn390;
221 if (options.model == MODEL_LARGE)
223 port->mem.default_local_map = xdata;
224 port->mem.default_globl_map = xdata;
228 port->mem.default_local_map = data;
229 port->mem.default_globl_map = data;
232 if (options.stack10bit)
234 if (options.model != MODEL_FLAT24)
237 "*** warning: 10 bit stack mode is only supported in flat24 model.\n");
238 fprintf (stderr, "\t10 bit stack mode disabled.\n");
239 options.stack10bit = 0;
243 /* Fixup the memory map for the stack; it is now in
244 * far space and requires a FPOINTER to access it.
247 istack->ptrType = FPOINTER;
254 _pic14_setDefaultOptions (void)
259 _pic14_getRegName (struct regs *reg)
266 extern char *processor_base_name(void);
269 _pic14_genAssemblerPreamble (FILE * of)
271 char * name = processor_base_name();
276 fprintf(stderr,"WARNING: No Pic has been selected, defaulting to %s\n",name);
279 fprintf (of, "\tlist\tp=%s\n",&name[1]);
280 fprintf (of, "\tradix dec\n");
281 fprintf (of, "\tinclude \"%s.inc\"\n",name);
284 /* Generate interrupt vector table. */
286 _pic14_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
290 if (options.model != MODEL_FLAT24)
292 /* Let the default code handle it. */
296 fprintf (of, "\t;ajmp\t__sdcc_gsinit_startup\n");
298 /* now for the other interrupts */
299 for (i = 0; i < maxInterrupts; i++)
303 fprintf (of, "\t;ljmp\t%s\n\t.ds\t4\n", interrupts[i]->rname);
307 fprintf (of, "\t;reti\n\t.ds\t7\n");
315 _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
318 sym_link *test = NULL;
322 //fprintf(stderr,"checking for native mult\n");
329 /* multiply chars in-place */
330 if (getSize(left) == 1 && getSize(right) == 1)
333 /* use library functions for more complex maths */
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 /* Indicate which extended bit operations this port supports */
368 hasExtBitOp (int op, int size)
372 /* || op == GETHBIT */ /* GETHBIT doesn't look complete for PIC */
379 /* Indicate the expense of an access to an output storage class */
381 oclsExpense (struct memmap *oclass)
383 /* The IN_FARSPACE test is compatible with historical behaviour, */
384 /* but I don't think it is applicable to PIC. If so, please feel */
385 /* free to remove this test -- EEP */
386 if (IN_FARSPACE(oclass))
392 /** $1 is always the basename.
393 $2 is always the output file.
395 $l is the list of extra options that should be there somewhere...
396 MUST be terminated with a NULL.
398 static const char *_linkCmd[] =
400 "gplink", "$l", "-o \"$2\"", "\"$1\"", "$3", NULL
403 static const char *_asmCmd[] =
405 "gpasm", "$l", "-c", "\"$1.asm\"", NULL
409 extern set *libFilesSet;
410 extern set *libDirsSet;
411 extern set *libPathsSet;
412 extern set *includeDirsSet;
413 extern set *userIncDirsSet;
414 extern set *dataDirsSetSet;
415 extern set *relFilesSet;
416 extern set *linkOptionsSet;
418 static void _pic14_do_link (void)
420 hTab *linkValues=NULL;
428 * link command format:
429 * {linker} {incdirs} {lflags} -o {outfile} {spec_ofiles} {ofiles} {libs}
433 sprintf(lfrm, "{linker} {incdirs} {sysincdirs} {lflags} -o {outfile} {user_ofile} {spec_ofiles} {ofiles} {libs}");
435 shash_add(&linkValues, "linker", "gplink");
437 /* LIBRARY SEARCH DIRS */
438 mergeSets(&tSet, libPathsSet);
439 mergeSets(&tSet, libDirsSet);
440 shash_add(&linkValues, "incdirs", joinStrSet(appendStrSet(tSet, "-I\"", "\"")));
442 SNPRINTF (&temp[0], 128, "%cpic\"", DIR_SEPARATOR_CHAR);
443 joinStrSet(appendStrSet(libDirsSet, "-I\"", &temp[0]));
444 shash_add(&linkValues, "sysincdirs", joinStrSet(appendStrSet(libDirsSet, "-I\"", &temp[0])));
446 shash_add(&linkValues, "lflags", joinStrSet(linkOptionsSet));
448 shash_add(&linkValues, "outfile", dstFileName);
450 if(fullSrcFileName) {
451 sprintf(temp, "%s.o", dstFileName);
452 shash_add(&linkValues, "user_ofile", temp);
455 shash_add(&linkValues, "ofiles", joinStrSet(relFilesSet));
458 addSet(&libFilesSet, "libsdcc.lib");
459 shash_add(&linkValues, "libs", joinStrSet(libFilesSet));
461 lcmd = msprintf(linkValues, lfrm);
463 ret = my_system( lcmd );
476 "MCU pic", /* Target name */
480 TRUE, /* Emit glue around main */
481 MODEL_SMALL | MODEL_LARGE | MODEL_FLAT24,
489 //"-plosgffc", /* Options with debug */
490 //"-plosgff", /* Options without debug */
493 NULL /* no do_assemble function */
498 _pic14_do_link, /* own do link function */
506 /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
507 1, 2, 2, 4, 2, 2, 3, 1, 4, 4
508 /* TSD - I changed the size of gptr from 3 to 1. However, it should be
509 2 so that we can accomodate the PIC's with 4 register banks (like the
529 "CONST (CODE)", // const_name - const data (code or not)
532 1 // code is read only
538 /* pic14 has an 8 bit mul */
543 pic14_emitDebuggerSymbol
546 255/3, /* maxCount */
547 3, /* sizeofElement */
548 /* The rest of these costs are bogus. They approximate */
549 /* the behavior of src/SDCCicode.c 1.207 and earlier. */
550 {4,4,4}, /* sizeofMatchJump[] */
551 {0,0,0}, /* sizeofRangeCompare[] */
552 0, /* sizeofSubtract */
553 3, /* sizeofDispatch */
560 _pic14_finaliseOptions,
561 _pic14_setDefaultOptions,
562 pic14_assignRegisters,
565 _pic14_genAssemblerPreamble,
566 NULL, /* no genAssemblerEnd */
568 NULL, // _pic14_genXINIT
569 NULL, /* genInitStartup */
570 _pic14_reset_regparm,
572 _process_pragma, /* process a pragma */
575 hasExtBitOp, /* hasExtBitOp */
576 oclsExpense, /* oclsExpense */
578 // TRUE, /* little endian */
579 FALSE, /* little endian - PIC code enumlates big endian */
582 1, /* transform <= to ! > */
583 1, /* transform >= to ! < */
584 1, /* transform != to !(a == b) */
586 FALSE, /* No array initializer support. */
587 0, /* no CSE cost estimation yet */
588 NULL, /* no builtin functions */
589 GPOINTER, /* treat unqualified pointers as "generic" pointers */
590 1, /* reset labelKey to 1 */
591 1, /* globals & local static allowed */