+2004-03-02 Vangelis Rokas <vrokas AT otenet.gr>
+
+ * src/pic16/device.c (checkAddSym): NEW, adds a symbol to set while
+ checking if symbol is already in set,
+ * src/pic16/device.h: prototype for checkAddSym,
+ * src/pic16/gen.c: (_G): added entry interruptvector,
+ * (assignResultValue): removed some commented out lines,
+ * (genFunction): check for ISR via sym->type, absolute section for
+ interrupt code is created via a new pBlock, the goto instruction is
+ placed now correctly at the interrupt vector position, changed all
+ references from ivec to _G.interruptvector,
+ * WREG,STATUS,BSR are not saved in stack upon an entry to interrupt
+ is the interrupt is a high priority one, same for return from ISR,
+ * src/pic16/glue.c: changed all calls of addSetHead for publics and
+ externs to calls of checkAddSym,
+ * src/pic16/pcode.c (pic16_pBlockConvert2*): emit warning when
+ pic16_pcode_verbose flag is set,
+ * src/pic16/pcode.h: extern to pic16_pcode_verbose,
+ * src/pic16/pcoderegs.c: message about how many registers are saved
+ will only be emitted if pic16_pcode_verbose flag is set,
+
2004-03-02 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
* src/ds390/ralloc.h,
* (print_idataType, print_idata): NEW to create idata sections
* src/pic16/device.h: idataSymSet new variable
* src/pic16/gen.c (genFunction): fixed some bugs in string
- comparing, improved the aboslute section creation for ISRs,
+ comparing, improved the absolute section creation for ISRs,
added FSR0L/FSR0H in registers that are saved in an ISR,
* (genInline): fixed the processing of inline snippets,
now they undergo no process by the peephole optimizer
short debugLine;
short nRegsSaved;
set *sendSet;
+ int interruptvector;
} _G;
/* Resolved ifx structure. This structure stores information
if(size>1) {
/* 16-bits, result in PRODL:WREG */
pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
-// pic16_emitpcode(POC_MOVFF,
-// pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(oper), 1)));
}
if(size>2) {
/* 24-bits, result in PRODH:PRODL:WREG */
pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
-
-// pic16_emitpcode(POC_MOVFF,
-// pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(oper), 2)));
}
if(size>3) {
/* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
-
-// pic16_emitpcode(POC_MOVFF,
-// pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr0l), pic16_popGet(AOP(oper), 3)));
}
} else {
/* >32-bits, result on stack, and FSR0 points to beginning.
{
symbol *sym;
sym_link *ftype;
-
+
DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
labelOffset += (max_key+4);
ftype = operandType(IC_LEFT(ic));
sym = OP_SYMBOL(IC_LEFT(ic));
- if(/*!IFFUNC_ISNAKED(ftype) &&*/ IFFUNC_ISISR(ftype)) {
+ if(IFFUNC_ISISR(sym->type /*ftype*/)) {
/* create an absolute section at the interrupt vector:
- * that is 0x0008 for interrupt 1, 0x0018 interrupt 2 */
- int ivec;
+ * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
symbol *asym;
char asymname[128];
-
+ pBlock *apb;
+
{
int i, found=-1;
sym = OP_SYMBOL( IC_LEFT(ic));
for(i=0;i<=2;i++) {
-// fprintf(stderr, "comparing name int %d\t%s with %s\n",
-// i, interrupts[i]->name, sym->name);
if(interrupts[i]->name
&& !STRCASECMP(interrupts[i]->name, sym->name)) {
found = i;
if(found == -1) {
fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
__FILE__, __LINE__, sym->name);
- exit(-1);
+ assert( 0 );
}
- ivec = found;
+ _G.interruptvector = found;
}
- sprintf(asymname, "ivec_%d_%s", ivec, sym->name);
+
+ sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
asym = newSymbol(asymname, 0);
- pic16_emitcode(";","-----------------------------------------");
- pic16_emitcode(";"," interrupt vector %d for function %s", ivec, sym->name);
- pic16_emitcode(";","-----------------------------------------");
- pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(moduleName, asym->name));
- pic16_pBlockConvert2Absolute(pb);
+ apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
+ pic16_addpBlock( apb );
+
+ pic16_addpCode2pBlock(apb,
+ pic16_newpCodeCharP(";-----------------------------------------"));
- pic16_emitpcode(POC_GOTO, pic16_popGetWithString( sym->rname ));
+
+ pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
+
+ pic16_addpCode2pBlock(apb,
+ pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
/* mark the end of this tiny function */
- pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
+ pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
{
absSym *abSym;
abSym = Safe_calloc(1, sizeof(absSym));
abSym->name = Safe_strdup( asymname );
- switch( ivec ) {
+ switch( _G.interruptvector ) {
case 0: abSym->address = 0x000000; break;
case 1: abSym->address = 0x000008; break;
case 2: abSym->address = 0x000018; break;
pic16_emitcode("","%s:",sym->rname);
pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
+
{
absSym *ab;
pic16_pBlockConvert2Absolute(pb);
break;
}
-
+
}
if (IFFUNC_ISISR(sym->type)) {
int i;
/* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
- pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
- pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
- pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
+ if(!(_G.interruptvector == 1)) {
+
+ /* do not save WREG,STATUS,BSR for high priority interrupts
+ * because they are stored in the hardware shadow registers already */
+
+ pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
+ pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
+ pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
+ }
+
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
- pic16_pBlockConvert2ISR(pb);
+// pic16_pBlockConvert2ISR(pb);
/* if any registers used */
if (sym->regsUsed) {
DEBUGpic16_emitcode("; **", "Saving used registers in stack");
for ( i = 0 ; i < sym->regsUsed->size ; i++) {
if (bitVectBitValue(sym->regsUsed,i)) {
+
// fprintf(stderr, "%s:%d function %s uses register %s\n",
// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
// pic16_regWithIdx(i)->name);
pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
+
// pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
// &pic16_pc_postdec1, 0));
+
_G.nRegsSaved++;
}
}
pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
+
+ if(!(_G.interruptvector == 1)) {
+ /* do not restore interrupt vector for WREG,STATUS,BSR
+ * for high priority interrupt, see genFunction */
+
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
+ }
+ _G.interruptvector = 0; /* sanity check */
+
+// pic16_pBlockConvert2ISR(pb);
+
/* if debug then send end of function */
/* if (options.debug && currFunc) */
pic16_aopOp(right,ic,FALSE);
size = AOP_SIZE(right);
- fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
-#if 1
+// fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
+
+#if 0
if ( AOP_TYPE(result) == AOP_PCODE) {
fprintf(stderr,"genDataPointerSet %s, %d\n",
AOP(result)->aopu.pcop->name,
/* if extern then add to externs */
if (IS_EXTERN (sym->etype)) {
// if(sym->used) // fixme
- addSetHead(&externs, sym);
+ checkAddSym(&externs, sym);
+// addSetHead(&externs, sym);
continue;
}
!IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
// regs *reg;
- addSetHead (&publics, sym);
+ checkAddSym(&publics, sym);
+// addSetHead(&publics, sym);
// reg = pic16_allocRegByName(sym->name, sym->size); //( operandFromSymbol( sym ));
// checkAddReg(&pic16_rel_udata, reg);
if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
if(SPEC_OCLS(sym->etype) == code) {
// fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
- addSetHead(&publics, sym);
+ checkAddSym(&publics, sym);
+// addSetHead(&publics, sym);
}
continue;
}
/* if it is "extern" then do nothing */
if (IS_EXTERN (sym->etype)) {
- addSetHead(&externs, sym);
+ checkAddSym(&externs, sym);
+// addSetHead(&externs, sym);
continue;
}
/* if it is not static add it to the public
table */
- if (!IS_STATIC (sym->etype))
- addSetHead (&publics, sym);
+ if (!IS_STATIC (sym->etype)) {
+ checkAddSym(&publics, sym);
+// addSetHead (&publics, sym);
+ }
#if 0
/* print extra debug info if required */
/* if global variable & not static or extern
and addPublics allowed then add it to the public set */
if ((sym->_isparm && !IS_REGPARM (sym->etype))
- && !IS_STATIC (sym->etype))
- addSetHead (&publics, sym);
+ && !IS_STATIC (sym->etype)) {
+ checkAddSym(&publics, sym);
+// addSetHead (&publics, sym);
+ }
/* if extern then do nothing or is a function
then do nothing */