+2003-07-14 Bernhard Held <bernhard@bernhardheld.de>
+
+ pic16 progress by Vangelis:
+ * src/SDCCglobl.h:
+ * src/SDCCmain.c:
+ * src/pic/Makefile:
+ * src/pic:
+ * pic/Makefile:
+ * pic16/device.c:
+ * pic16/device.h:
+ * pic16/gen.c:
+ * pic16/gen.h:
+ * pic16/genarith.c:
+ * pic16/glue.c:
+ * pic16/main.c:
+ * pic16/pcode.c:
+ * pic16/pcode.h:
+ * pic16/pcodepeep.c:
+ * pic16/peeph.def:
+
2003-07-13 Jesus Calvino-Fraga <jesusc@ece.ubc.ca>
* src/SDCCmain.c, src/SDCCglobl.h: added option --no-std-crt0
Scott D. for Vangelis Rokas (vrokas@otenet.gr). I (scott) don't
know all the details, but essentially this set of changes enable
the pic16 port to generate movff instructions and generate assembler
- directives,
- * src/SDCCmain.c:
- * src/pic16/gen.c:
+ directives,
+ * src/SDCCmain.c:
+ * src/pic16/gen.c:
* src/pic16/glue.c:
* src/pic16/pcode.c:
* src/pic16/device.c:
int noCcodeInAsm; /* hide c-code from asm */
int iCodeInAsm; /* show i-code in asm */
int printSearchDirs; /* display the directories in the compiler's search path */
+ int gen_banksel; /* enable the generation of the banksel assembler directive in pic16 port */
int vc_err_style; /* errors and warnings are compatible with Micro$oft visual studio */
int use_stdout; /* send errors to stdout instead of stderr */
int no_std_crt0; /*For the z80/gbz80 do not link default crt0.o*/
#if !OPT_DISABLE_Z80 || !OPT_DISABLE_GBZ80
{ 0, "--no-std-crt0", &options.no_std_crt0, "For the z80/gbz80 do not link default crt0.o"},
#endif
- /* End of options */
-#if 0 /* 10jun03 !OPT_DISABLE_PIC16 */
- { 0, "--no-movff", &options.no_movff, "disable generating MOVFF opcode in PIC16 port"},
+#if !OPT_DISABLE_PIC16
{ 0, "--gen-banksel", &options.gen_banksel, "enable the generation of banksel assembler directives in PIC16 port"},
#endif
+ /* End of options */
{ 0, NULL }
};
# Make all in this directory
+PORT = pic
+
include ../port.mk
static PIC_device *pic=NULL;
AssignedMemory *pic16_finalMapping=NULL;
+int pic16_finalMappingSize=0;
#define DEFAULT_CONFIG_BYTE 0xff
fputc('\n',of);
- //pic16_finalMapping[start].reg->isEmitted = 1;
+//#warning why is the following line commented out?! (VR)
+// pic16_finalMapping[start].reg->isEmitted = 1;
}
}
*/
extern AssignedMemory *pic16_finalMapping;
+
+/*
+ * pic16_finalMappingSize - Size of register assignments that pic16_finalMapping can hold
+ */
+
+extern int pic16_finalMappingSize;
+
+
#define PROCESSOR_NAMES 4
/* Processor unique attributes */
typedef struct PIC_device {
bool r0iu = FALSE , r1iu = FALSE;
bool r0ou = FALSE , r1ou = FALSE;
-
//fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
+
/* the logic: if r0 & r1 used in the instruction
then we are in trouble otherwise */
if (!op)
return ;
- // DEBUGpic16_emitcode(";","%d",__LINE__);
+ DEBUGpic16_emitcode(";","%d",__LINE__);
/* if this a literal */
if (IS_OP_LITERAL(op)) {
op->aop = aop = newAsmop(AOP_LIT);
if(PCOR(pcop)->r == NULL) {
//fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
+
//fprintf(stderr, "allocating new register -> %s\n", str);
+
DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
} else {
DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
/* if this is an interrupt service routine then
save acc, b, dpl, dph */
if (IFFUNC_ISISR(sym->type)) {
- pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
- pic16_emitpcodeNULLop(POC_NOP);
- pic16_emitpcodeNULLop(POC_NOP);
- pic16_emitpcodeNULLop(POC_NOP);
+
+#if 0
+ pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
+
+ /* what is the reason of having these 3 NOPS? VR - 030701 */
+ pic16_emitpcodeNULLop(POC_NOP);
+ pic16_emitpcodeNULLop(POC_NOP);
+ pic16_emitpcodeNULLop(POC_NOP);
+#endif
+
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
_G.debugLine = 0;
}
- pic16_emitcode ("reti","");
+// pic16_emitcode ("reti","");
pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
+
+#if 0
pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
+#endif
pic16_emitpcodeNULLop(POC_RETFIE);
} else {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(!options_no_movff) {
-
+#if 1
/* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
normally should work, but mind that thw W register live range
is not checked, so if the code generator assumes that the W
Vangelis Rokas 030603 (vrokas@otenet.gr) */
- pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
- } else {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
+#else
/* This is the old code, which is assumed(?!) that works fine(!?) */
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
- }
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+#endif
}
offset++;
}
#endif
+// dumpiCode(lic);
+
for (ic = lic ; ic ; ic = ic->next ) {
// fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
#define MOVA(x) if (strcmp(x,"a") && strcmp(x,"acc")) pic16_emitcode(";XXX mov","a,%s %s,%d",x,__FILE__,__LINE__);
#define CLRC pic16_emitcode(";XXX clr","c %s,%d",__FILE__,__LINE__);
+
#define BIT_NUMBER(x) (x & 7)
#define BIT_REGISTER(x) (x>>3)
const char *pic16_pCodeOpType( pCodeOp *pcop);
+void dumpiCode(iCode *lic);
#endif
DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
/* if the literal value of the right hand side
is greater than 1 then it is faster to add */
- if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
+ if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 1) // this was > 2 why? VR
return FALSE ;
/* if increment 16 bits in register */
}
DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
- /* if left is in accumulator - probably a bit operation*/
+ /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
if( strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
}
/*-----------------------------------------------------------------*/
-/* pic16_genPlus - generates code for addition */
+/* pic16_genPlus - generates code for addition */
/*-----------------------------------------------------------------*/
void pic16_genPlus (iCode *ic)
{
int size, offset = 0;
-
+ operand *result, *left, *right;
+
/* special cases :- */
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+#if 1
+ result = IC_RESULT(ic);
+ left = IC_LEFT(ic);
+ right = IC_RIGHT(ic);
+ pic16_aopOp (left,ic,FALSE);
+ pic16_aopOp (right,ic,FALSE);
+ pic16_aopOp (result,ic,TRUE);
+ DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
+
+#else
pic16_aopOp (IC_LEFT(ic),ic,FALSE);
pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
pic16_aopOp (IC_RESULT(ic),ic,TRUE);
-
DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
+#endif
+
/* if literal, literal on the right or
if left requires ACC or right is already
return;
}
- fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
- fprintf (vFile, ";__interrupt_vect:\n");
+/*
+ * update started by Vangelis Rokas on 19-Jun-2003
+ * all fprintf() calls are prefixed with ';' so they seem
+ * as comments to the assembler. I (VR) removed them */
+
+// fprintf (vFile, "\t.area\t%s\n", CODE_NAME);
+ fprintf(vFile, "\tcode\t0x0000\n");
+ fprintf (vFile, "__interrupt_vect:\n");
if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
pic16emitOverlay(ovrFile);
- pic16_AnalyzepCode('*');
+ pic16_AnalyzepCode('*');
//#ifdef PCODE_DEBUG
//pic16_printCallTree(stderr);
pic16_InlinepCode();
- pic16_AnalyzepCode('*');
+ pic16_AnalyzepCode('*');
pic16_pcode_test();
copyFile (asmFile, bit->oFile);
- fprintf (asmFile, "\tORG 0\n");
+/* the following is commented out. the CODE directive will be
+ used instead before code */
+
+// fprintf (asmFile, "\tORG 0\n");
/* copy the interrupt vector table */
if (mainf && IFFUNC_HASBODY(mainf->type)) {
fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
-
+
if (mainf && IFFUNC_HASBODY(mainf->type)) {
fprintf (asmFile,"__sdcc_gsinit_startup:\n");
+
+#if 0
+ /* 8051 legacy (?!) - VR 20-Jun-2003 */
/* if external stack is specified then the
higher order byte of the xdatalocation is
going into P2 and the lower order going into
fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
(unsigned int)options.xdata_loc & 0xff);
}
+#endif
}
* by the ugly shucking and jiving about 20 lines ago.
*/
fprintf(asmFile, ";\t.area %s\n", port->mem.post_static_name);
- fprintf (asmFile,";\tljmp\t__sdcc_program_startup\n");
+ fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
}
/* copy over code */
//copyFile (stderr, code->oFile);
+ fprintf(asmFile, "; I code from now on!\n");
pic16_copypCode(asmFile, 'I');
+
+ fprintf(asmFile, "; dbName from now on!\n");
pic16_copypCode(asmFile, statsg->dbName);
+
+ fprintf(asmFile, "; X code from now on!\n");
pic16_copypCode(asmFile, 'X');
+ fprintf(asmFile, "; M code from now on!\n");
pic16_copypCode(asmFile, 'M');
pic16_copypCode(asmFile, code->dbName);
pic16_copypCode(asmFile, 'P');
{
asm_addTree (&asm_asxxxx_mapping);
pic16_pCodeInitRegisters();
+ maxInterrupts = 2;
}
static void
{
int i;
+#if 0
if (options.model != MODEL_FLAT24)
{
/* Let the default code handle it. */
return FALSE;
}
+#endif
+
+ /* PIC18F family has only two interrupts, the high and the low
+ * priority interrupts, which reside in 0x0008 and 0x0018 respectively */
+
+ fprintf(of, "; RESET vector\n");
+ fprintf(of, "\tgoto\t__sdcc_gsinit_startup\n");
+ fprintf(of, "\tres 2\n");
- fprintf (of, "\t;ajmp\t__sdcc_gsinit_startup\n");
+ fprintf(of, "; High priority interrupt vector 0x0008\n");
+
+ if(interrupts[1]) {
+ fprintf(of, "\tgoto\t%s\n", interrupts[1]->rname);
+ fprintf(of, "\tres\t6\n");
+ } else {
+ fprintf(of, "\tretfie\n");
+ fprintf(of, "\tres\t14\n");
+ }
+
+ fprintf(of, "; Low priority interrupt vector 0x0018\n");
+ if(interrupts[2]) {
+ fprintf(of, "\tgoto\t%s\n", interrupts[2]->rname);
+ } else {
+ fprintf(of, "\tretfie\n");
+ }
+#if 0
/* now for the other interrupts */
for (i = 0; i < maxInterrupts; i++)
{
+ fprintf(of, "; %s priority interrupt vector 0x%s\n", (i==0)?"high":"low", (i==0)?"0008":"0018");
if (interrupts[i])
{
- fprintf (of, "\t;ljmp\t%s\n\t.ds\t4\n", interrupts[i]->rname);
+ fprintf (of, "\tgoto\t%s\n\tres\t4\n", interrupts[i]->rname);
}
else
{
- fprintf (of, "\t;reti\n\t.ds\t7\n");
+ fprintf (of, "\tretfie\n\tres\t7\n");
}
}
+#endif
return TRUE;
}
TARGET_ID_PIC16,
"pic16",
"MCU PIC16", /* Target name */
- "p18f452", /* Processor */
+ "p18f442", /* Processor */
{
pic16glue,
TRUE, /* Emit glue around main */
*/
},
{
- "XSEG (XDATA)",
- "STACK (DATA)",
- "CSEG (CODE)",
- "DSEG (DATA)",
- "ISEG (DATA)",
- "XSEG (XDATA)",
- "BSEG (BIT)",
- "RSEG (DATA)",
- "GSINIT (CODE)",
- "OSEG (OVR,DATA)",
- "GSFINAL (CODE)",
- "HOME (CODE)",
- NULL, // xidata
- NULL, // xinit
- NULL,
- NULL,
- 1 // code is read only
+ "XSEG (XDATA)", // xstack
+ "STACK (DATA)", // istack
+ "CSEG (CODE)", // code
+ "DSEG (DATA)", // data
+ "ISEG (DATA)", // idata
+ "XSEG (XDATA)", // xdata
+ "BSEG (BIT)", // bit
+ "RSEG (DATA)", // reg
+ "GSINIT (CODE)", // static
+ "OSEG (OVR,DATA)", // overlay
+ "GSFINAL (CODE)", // post static
+ "HOME (CODE)", // home
+ NULL, // xidata
+ NULL, // xinit
+ NULL, // default location for auto vars
+ NULL, // default location for global vars
+ 1 // code is read only
},
{ NULL, NULL },
{
static hTab *pic16MnemonicsHash = NULL;
static hTab *pic16pCodePeepCommandsHash = NULL;
-int options_gen_banksel = 1;
-
static pFile *the_pFile = NULL;
static pBlock *pb_dead_pcodes = NULL;
};
-#if 1
+#if 0
// mdubuc - Remove TRIS
pCodeInstruction pic16_pciTRIS = {
pic16Mnemonics[POC_SUBFWB_D1] = &pic16_pciSUBFWB_D1;
pic16Mnemonics[POC_SWAPF] = &pic16_pciSWAPF;
pic16Mnemonics[POC_SWAPFW] = &pic16_pciSWAPFW;
- pic16Mnemonics[POC_TRIS] = &pic16_pciTRIS;
+// pic16Mnemonics[POC_TRIS] = &pic16_pciTRIS;
pic16Mnemonics[POC_TSTFSZ] = &pic16_pciTSTFSZ;
pic16Mnemonics[POC_XORLW] = &pic16_pciXORLW;
pic16Mnemonics[POC_XORWF] = &pic16_pciXORWF;
}
-
/*-----------------------------------------------------------------*/
/* pic16_get_op2 - variant to support two memory operand commands */
/*-----------------------------------------------------------------*/
if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) {
-#if 1
if(PCI(pc)->is2MemOp) {
-// fprintf(stderr, "HELP !\n");
-#if 1
SAFE_snprintf(&s,&size, "%s,%s",
pic16_get_op(PCOP(PCI(pc)->pcop), NULL, 0),
pic16_get_op2(PCOP(PCI(pc)->pcop), NULL, 0));
break;
-#endif
}
-#endif
if(PCI(pc)->isBitInst) {
if(PCI(pc)->pcop->type == PO_GPR_BIT) {
if(!pc)
return;
-
/*
* if bsr == -1 then do not insert a MOVLB instruction, but rather
* insert a BANKSEL assembler directive for the symbol used by
* bank at linking time
*/
- if(!options_gen_banksel || bsr != -1) {
- new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(bsr));
+ if(!options.gen_banksel || bsr != -1) {
+// new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(bsr));
+ return;
} else {
/* emit the BANKSEL [symbol] */
// if (cur_bank != reg_bank) {
cur_bank = reg_bank;
- insertBankSwitch(0, pc, (options_gen_banksel)?-1:cur_bank); //cur_bank);
+ insertBankSwitch(0, pc, (options.gen_banksel)?-1:cur_bank); //cur_bank);
// }
}else {
// for(pb = the_pFile->pbHead; pb; pb = pb->next)
pic16_pCodeRegOptimizeRegUsage(level);
- OptimizepCode('*');
+
+ if(!options.nopeep)
+ OptimizepCode('*');
/*
}
}
- changes = OptimizepCode(dbName);
+ if(!options.nopeep)
+ changes = OptimizepCode(dbName);
+ else changes = 0;
} while(changes && (i++ < MAX_PASSES));
POC_SUBFWB_D1,
POC_SWAPF,
POC_SWAPFW,
- POC_TRIS , // To be removed
+// POC_TRIS , // To be removed
POC_TSTFSZ,
POC_XORLW,
POC_XORWF,
return (i+1);
}
- //dump1Token(*pat); DFPRINTF((stderr,"\n"));
+// dump1Token(*pat); fputc('\n', stderr); DFPRINTF((stderr,"\n"));
if(pct->tt != *pat)
return 0;
for( ; ln; ln = ln->next) {
//DFPRINTF((stderr,"%s\n",ln->line));
+// fprintf(stderr, "peep rule : %s\n", ln->line);
tokenizeLineNode(ln->line);
int i;
fprintf(stderr,"ERROR assembling line:\n%s\n",ln->line);
fprintf(stderr,"Tokens:\n");
- for(i=0; i<5; i++)
+ for(i=0; i<8; i++)
dump1Token(tokArr[i].tt);
fputc('\n',stderr);
exit (1);
peepRuleBlock2pCodeBlock(pr->match, ¤tRule->target);
//DFPRINTF((stderr,"finished target, here it is in pcode form:\n"));
- //pic16_printpBlock(stderr, currentRule->target.pb);
+// pic16_printpBlock(stderr, currentRule->target.pb);
//DFPRINTF((stderr,"target with labels merged:\n"));
//pic16_pBlockMergeLabels(curBlock);
if(!pcops || !pcopd)
return 0;
-/*
+
+#if 1
fprintf(stderr," Comparing operands %s",
pic16_get_op( pcops,NULL,0));
fprintf(stderr," to %s\n",
pic16_get_op( pcopd,NULL,0));
-*/
+#endif
if(pcops->type != pcopd->type) {
//fprintf(stderr," - fail - diff types\n");
if(!pcin && pct) {
DFPRINTF((stderr," partial match... no more code\n"));
- fprintf(stderr," partial match... no more code\n");
+// fprintf(stderr," partial match... no more code\n");
matched = 0;
}
if(!pct) {
// From: Vangelis Rokas (vrokas@otenet.gr)
//replace {
-// movf %1,W
+// movf %1,w
// movwf %2
//} by {
// ; peep 12 - Use movff to move source to dest
// movff %1, %2
//}
+
+//replace restart {
+// banksel %1
+// banksel %2
+//} by {
+// ; peep 13 - remove redudant banksel directive
+// banksel %2
+//}
+
+//replace restart {
+// movff %1,%2
+// movf %1,w
+//} by {
+// ; peep 14a - movff/movf is 6 bytes long, movfw/movwf is 4
+// movf %1,w
+// movwf %2
+//}
+
+//replace restart {
+// movff %1,%2
+// movff %1,%3
+//} by {
+// ; peep 14b - movff/movff is 8 bytes long movf/mowf/movwf is 6
+// movf %1,w
+// movwf %2
+// movwf %3
+//}
+
+replace {
+ movff %1,%2
+} by {
+ ; peep xxx - test peep to see if peep rules can handle movff
+ movf %1,w
+ movwf %2
+}