X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fmain.c;h=e67b89c124bd4af241fec0a0924a399e0fe5aff4;hb=d0b75a25e014ff9924b4961e7927de9f591f5d0d;hp=e57c29993f7c91070c553a93fe65524b77a1f83d;hpb=4db4740164fed3cb25145cfdaadb986fc0690507;p=fw%2Fsdcc diff --git a/src/pic16/main.c b/src/pic16/main.c index e57c2999..e67b89c1 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -53,6 +53,7 @@ static char *_pic16_keywords[] = "pdata", "reentrant", "sfr", + "sfr16", "using", "_data", "_code", @@ -62,6 +63,10 @@ static char *_pic16_keywords[] = "_naked", "shadowregs", "wparam", + "prodlp", + "prodhp", + "fsr0lp", + "fixed16x16", // "bit", // "idata", @@ -75,6 +80,8 @@ static char *_pic16_keywords[] = pic16_sectioninfo_t pic16_sectioninfo; +int xinst=0; + extern char *pic16_processor_base_name(void); @@ -94,7 +101,6 @@ extern set *libFilesSet; /* for an unknowned reason. - EEP */ void pic16_emitDebuggerSymbol (char *); -extern regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop); extern void pic16_emitConfigRegs(FILE *of); extern void pic16_emitIDRegs(FILE *of); @@ -115,7 +121,7 @@ _pic16_reset_regparm (void) } static int -_pic16_regparm (sym_link * l) +_pic16_regparm (sym_link * l, bool reentrant) { /* force all parameters via SEND/RECEIVE */ if(0 /*pic16_options.ip_stack*/) { @@ -205,14 +211,10 @@ _process_pragma(const char *sz) stackLen = 64; fprintf(stderr, "%s:%d: warning: setting stack to default size %d (0x%04x)\n", filename, lineno-1, stackLen, stackLen); - -// fprintf(stderr, "%s:%d setting stack to default size %d\n", __FILE__, __LINE__, stackLen); } -// fprintf(stderr, "Initializing stack pointer at 0x%x len 0x%x\n", stackPos, stackLen); - /* check sanity of stack */ - if ((stackPos >> 8) != ((stackPos+stackLen) >> 8)) { + if ((stackPos >> 8) != ((stackPos+stackLen-1) >> 8)) { fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] crosses memory bank boundaries (not fully tested)\n", filename,lineno-1, stackPos, stackPos+stackLen-1); } @@ -231,7 +233,7 @@ _process_pragma(const char *sz) if (stackPos+stackLen > pic16->RAMsize) { fprintf (stderr, "%s:%u: error: stack [0x%03X,0x%03X] is placed outside available memory [0x000,0x%03X]!\n", filename, lineno-1, stackPos, stackPos+stackLen-1, pic16->RAMsize-1); - exit(-1); + exit(EXIT_FAILURE); return 1; /* considered an error, but this reports "invalid pragma stack"... */ } } @@ -264,7 +266,7 @@ _process_pragma(const char *sz) if (!symname || !location) { fprintf (stderr, "%s:%d: #pragma code [symbol] [location] -- symbol or location missing\n", filename, lineno-1); - exit (-1); + exit (EXIT_FAILURE); return 1; /* considered an error, but this reports "invalid pragma code"... */ } @@ -298,7 +300,7 @@ _process_pragma(const char *sz) if (!symname || !sectname) { fprintf (stderr, "%s:%d: #pragma udata [section-name] [symbol] -- section-name or symbol missing!\n", filename, lineno-1); - exit (-1); + exit (EXIT_FAILURE); return 1; /* considered an error, but this reports "invalid pragma code"... */ } @@ -476,6 +478,10 @@ OPTION pic16_optionsTable[]= { { 0, OPTIMIZE_GOTO, NULL, "try to use (conditional) BRA instead of GOTO"}, { 0, OPTIMIZE_CMP, NULL, "try to optimize some compares"}, { 0, OPTIMIZE_DF, NULL, "thoroughly analyze data flow (memory and time intensive!)"}, + { 0, "--num-func-alloc-regs", &pic16_options.CATregs, "dump number of temporary registers allocated for each function"}, +#if XINST + { 'y', "--extended", &xinst, "enable Extended Instruction Set/Literal Offset Addressing mode"}, +#endif { 0, NULL, NULL, NULL} }; @@ -510,7 +516,7 @@ _pic16_parseOptions (int *pargc, char **argv, int *i) else if(!STRCASECMP(stkmodel, "large"))pic16_options.stack_model = 1; else { fprintf(stderr, "Unknown stack model: %s", stkmodel); - exit(-1); + exit(EXIT_FAILURE); } return TRUE; } @@ -549,7 +555,7 @@ _pic16_parseOptions (int *pargc, char **argv, int *i) else if(!STRCASECMP(tmp, "crlf"))pic16_nl = 1; else { fprintf(stderr, "invalid termination character id\n"); - exit(-1); + exit(EXIT_FAILURE); } return TRUE; } @@ -638,13 +644,18 @@ extern set *linkOptionsSet; char *msprintf(hTab *pvals, const char *pformat, ...); int my_system(const char *cmd); +/* forward declarations */ +extern const char *pic16_linkCmd[]; +extern const char *pic16_asmCmd[]; +extern set *asmOptionsSet; + /* custom function to link objects */ static void _pic16_linkEdit(void) { hTab *linkValues=NULL; - char lfrm[256]; + char lfrm[1024]; char *lcmd; - char temp[128]; + char temp[1024]; set *tSet=NULL; int ret; @@ -653,10 +664,9 @@ static void _pic16_linkEdit(void) * {linker} {incdirs} {lflags} -o {outfile} {spec_ofiles} {ofiles} {libs} * */ - - sprintf(lfrm, "{linker} {incdirs} {lflags} -o {outfile} {user_ofile} {spec_ofiles} {ofiles} {libs}"); - - shash_add(&linkValues, "linker", "gplink"); + sprintf(lfrm, "{linker} {incdirs} {lflags} -o {outfile} {user_ofile} {ofiles} {spec_ofiles} {libs}"); + + shash_add(&linkValues, "linker", pic16_linkCmd[0]); mergeSets(&tSet, libDirsSet); mergeSets(&tSet, libPathsSet); @@ -706,11 +716,6 @@ static void _pic16_linkEdit(void) } -/* forward declarations */ -extern const char *pic16_linkCmd[]; -extern const char *pic16_asmCmd[]; -extern set *asmOptionsSet; - static void _pic16_finaliseOptions (void) { @@ -825,6 +830,7 @@ _pic16_setDefaultOptions (void) pic16_options.ip_stack = 1; /* set to 1 to enable ipop/ipush for stack */ pic16_options.gstack = 0; pic16_options.debgen = 0; + pic16_options.CATregs = 0; } static const char * @@ -908,21 +914,80 @@ _pic16_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts) * False to convert it to function call */ static bool _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right) { -// fprintf(stderr,"checking for native mult for %c (size: %d)\n", ic->op, getSize(OP_SYMBOL(IC_RESULT(ic))->type)); + //fprintf(stderr,"checking for native mult for %c (size: %d)\n", ic->op, getSize(OP_SYMBOL(IC_RESULT(ic))->type)); + + /* Checks to enable native multiplication. + * PICs do not offer native division at all... + * + * Ideas: + * ( i) if result is just one byte, use native MUL + * (regardless of the operands) + * ( ii) if left and right are unsigned 8-bit operands, + * use native MUL + * (iii) if left or right is a literal in the range of [0..255) + * and the other is an unsigned byte, use native MUL + */ + if (ic->op == '*') + { + int symL, symR, symRes, sizeL = 0, sizeR = 0, sizeRes = 0; -#if 1 - /* multiplication is fixed */ - /* support mul for char/int/long */ - if((ic->op == '*') - && (getSize(OP_SYMBOL(IC_LEFT(ic))->type ) < 2))return TRUE; -#endif + /* left/right are symbols? */ + symL = IS_SYMOP(IC_LEFT(ic)); + symR = IS_SYMOP(IC_RIGHT(ic)); + symRes = IS_SYMOP(IC_RESULT(ic)); + + /* --> then determine their sizes */ + sizeL = symL ? getSize(OP_SYM_TYPE(IC_LEFT(ic))) : 4; + sizeR = symR ? getSize(OP_SYM_TYPE(IC_RIGHT(ic))) : 4; + sizeRes = symRes ? getSize(OP_SYM_TYPE(IC_RESULT(ic))) : 4; + + /* use native mult for `*: x --> {u8_t, s8_t}' */ + if (sizeRes == 1) { return TRUE; } + + /* use native mult for `u8_t x u8_t --> { u16_t, s16_t }' */ + if (sizeL == 1 && symL && SPEC_USIGN(OP_SYM_TYPE(IC_LEFT(ic)))) { + sizeL = 1; + } else { + //printf( "%s: left too large (%u) / signed (%u)\n", __FUNCTION__, sizeL, symL && !SPEC_USIGN(OP_SYM_TYPE(IC_LEFT(ic)))); + sizeL = 4; + } + if (sizeR == 1 && symR && SPEC_USIGN(OP_SYM_TYPE(IC_RIGHT(ic)))) { + sizeR = 1; + } else { + //printf( "%s: right too large (%u) / signed (%u)\n", __FUNCTION__, sizeR, symR && !SPEC_USIGN(OP_SYM_TYPE(IC_RIGHT(ic)))); + sizeR = 4; + } + + /* also allow literals [0..256) for left/right operands */ + if (IS_VALOP(IC_LEFT(ic))) + { + long l = (long)floatFromVal( OP_VALUE( IC_LEFT(ic) ) ); + sizeL = 4; + //printf( "%s: val(left) = %ld\n", __FUNCTION__, l ); + if (l >= 0 && l < 256) + { + sizeL = 1; + } else { + //printf( "%s: left value %ld outside [0..256)\n", __FUNCTION__, l ); + } + } + if (IS_VALOP( IC_RIGHT(ic) )) + { + long l = (long)floatFromVal( OP_VALUE( IC_RIGHT(ic) ) ); + sizeR = 4; + //printf( "%s: val(right) = %ld\n", __FUNCTION__, l ); + if (l >= 0 && l < 256) + { + sizeR = 1; + } else { + //printf( "%s: right value %ld outside [0..256)\n", __FUNCTION__, l ); + } + } + + /* use native mult iff left and right are (unsigned) 8-bit operands */ + if (sizeL == 1 && sizeR == 1) { return TRUE; } + } -#if 0 - /* support div for char/int/long */ - if((getSize(OP_SYMBOL(IC_LEFT(ic))->type ) < 0) - && (ic->op == '/'))return TRUE; -#endif - return FALSE; } @@ -1062,6 +1127,15 @@ PORT pic16_port = 4, /* float */ 4 /* max */ }, + + /* generic pointer tags */ + { + 0x00, /* far */ + 0x80, /* near */ + 0x00, /* xstack */ + 0x00 /* code */ + }, + { "XSEG (XDATA)", // xstack "STACK (DATA)", // istack