"pdata",
"reentrant",
"sfr",
+ "sfr16",
"using",
"_data",
"_code",
"_naked",
"shadowregs",
"wparam",
+ "prodlp",
+ "prodhp",
+ "fsr0lp",
"fixed16x16",
// "bit",
pic16_sectioninfo_t pic16_sectioninfo;
+int xinst=0;
+
extern char *pic16_processor_base_name(void);
/* 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);
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);
}
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"... */
}
}
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"... */
}
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"... */
}
{ 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}
};
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;
}
else if(!STRCASECMP(tmp, "crlf"))pic16_nl = 1;
else {
fprintf(stderr, "invalid termination character id\n");
- exit(-1);
+ exit(EXIT_FAILURE);
}
return TRUE;
}
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;
* {linker} {incdirs} {lflags} -o {outfile} {spec_ofiles} {ofiles} {libs}
*
*/
-
- sprintf(lfrm, "{linker} {incdirs} {lflags} -o {outfile} {user_ofile} {ofiles} {spec_ofiles} {libs}");
+ sprintf(lfrm, "{linker} {incdirs} {lflags} -w -r -o {outfile} {user_ofile} {ofiles} {spec_ofiles} {libs}");
shash_add(&linkValues, "linker", pic16_linkCmd[0]);
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);
}
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 *
}
fprintf (of, "\tlist\tp=%s\n",&name[1]);
+ if (pic16_mplab_comp) {
+ // provide ACCESS macro used during SFR accesses
+ fprintf (of, "\tinclude <p%s.inc>\n", &name[1]);
+ }
if(!pic16_options.omit_configw) {
pic16_emitConfigRegs(of);
* 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 == '*')
- && (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((getSize(OP_SYMBOL(IC_LEFT(ic))->type ) < 0)
- && (ic->op == '/'))return TRUE;
-#endif
-
return FALSE;
}
*/
const char *pic16_linkCmd[] =
{
- "gplink", "$l", "-o \"$2\"", "\"$1\"","$3", NULL
+ "gplink", "$l", "-w", "-r", "-o \"$2\"", "\"$1\"","$3", NULL
};
4, /* float */
4 /* max */
},
+
+ /* generic pointer tags */
+ {
+ 0x00, /* far */
+ 0x80, /* near */
+ 0x00, /* xstack */
+ 0x00 /* code */
+ },
+
{
"XSEG (XDATA)", // xstack
"STACK (DATA)", // istack