X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fmain.c;h=c091aa2d2e0d818dacca58ae28037a5e6edd1a3a;hb=acde2aabe3a1ebe76bf020ca62ef61c824f94b19;hp=5547e34edfb66044e8e6880448c1cdce98d00eca;hpb=33a22bd9eb00ed7326b06ef484e37537cabae64d;p=fw%2Fsdcc diff --git a/src/pic16/main.c b/src/pic16/main.c index 5547e34e..c091aa2d 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -233,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"... */ } } @@ -266,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"... */ } @@ -300,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"... */ } @@ -516,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; } @@ -555,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; } @@ -674,10 +674,10 @@ static void _pic16_linkEdit(void) shash_add(&linkValues, "incdirs", joinStrSet( appendStrSet(tSet, "-I\"", "\""))); shash_add(&linkValues, "lflags", joinStrSet(linkOptionsSet)); - shash_add(&linkValues, "outfile", dstFileName); + shash_add(&linkValues, "outfile", fullDstFileName ? fullDstFileName : dstFileName); if(fullSrcFileName) { - sprintf(temp, "%s.o", dstFileName); + sprintf(temp, "%s.o", fullDstFileName ? fullDstFileName : dstFileName); // addSetHead(&relFilesSet, Safe_strdup(temp)); shash_add(&linkValues, "user_ofile", temp); } @@ -914,25 +914,114 @@ _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)); + int symL, symR, symRes, sizeL = 0, sizeR = 0, sizeRes = 0; + + /* 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; + + /* 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 [-128..256) + * and the other is an unsigned byte, use native MUL + */ + if (ic->op == '*') + { + /* use native mult for `*: x --> {u8_t, s8_t}' */ + if (sizeRes == 1) { return TRUE; } -#if 1 - /* multiplication is fixed */ - /* support mul for char/int/long */ - if((ic->op == '*') - && (IS_SYMOP(IC_LEFT(ic))) - && (getSize(OP_SYMBOL(IC_LEFT(ic))->type ) < 2)) - return TRUE; -#endif + /* 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 [-128..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 >= -128 && l < 256) + { + sizeL = 1; + } else { + //printf( "%s: left value %ld outside [-128..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 >= -128 && l < 256) + { + sizeR = 1; + } else { + //printf( "%s: right value %ld outside [-128..256)\n", __FUNCTION__, l ); + } + } + + /* use native mult iff left and right are (unsigned) 8-bit operands */ + if (sizeL == 1 && sizeR == 1) { return TRUE; } + } + + if (ic->op == '/' || ic->op == '%') + { + /* We must catch /: {u8_t,s8_t} x {u8_t,s8_t} --> {u8_t,s8_t}, + * because SDCC will call 'divuchar' even for u8_t / s8_t. + * Example: 128 / -2 becomes 128 / 254 = 0 != -64... */ + if (sizeL == 1 && sizeR == 1) return TRUE; + + /* What about literals? */ + 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 >= -128 && l < 256) + { + sizeL = 1; + } else { + //printf( "%s: left value %ld outside [-128..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 >= -128 && l < 256) + { + sizeR = 1; + } else { + //printf( "%s: right value %ld outside [-128..256)\n", __FUNCTION__, l ); + } + } + if (sizeL == 1 && sizeR == 1) { return TRUE; } + } -#if 0 - /* support div for char/int/long */ - if((ic->op == '/') - && (IS_SYMOP(IC_LEFT(ic))) - && (getSize(OP_SYMBOL(IC_LEFT(ic))->type ) < 0)) - return TRUE; -#endif - return FALSE; } @@ -1072,6 +1161,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