extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
void genMult8X8_8 (operand *, operand *,operand *);
+pCode *AssembleLine(char *line);
+extern void printpBlock(FILE *of, pBlock *pb);
static int labelOffset=0;
extern int debug_verbose;
while (*bp) {
if (*bp == '\n') {
*bp++ = '\0';
- pic14_emitcode(bp1,"");
- addpCode2pBlock(pb,newpCodeInlineP(bp1));
+
+ if(*bp1)
+ addpCode2pBlock(pb,AssembleLine(bp1));
bp1 = bp;
} else {
if (*bp == ':') {
bp++;
}
}
- if (bp1 != bp) {
- pic14_emitcode(bp1,"");
- addpCode2pBlock(pb,newpCodeInlineP(bp1));
- }
- /* pic14_emitcode("",buffer); */
+ if ((bp1 != bp) && *bp1)
+ addpCode2pBlock(pb,AssembleLine(bp1));
+
+ Safe_free(buffer);
+
_G.inLine -= (!options.asmpeep);
}
/*-----------------------------------------------------------------*/
void addpCode2pBlock(pBlock *pb, pCode *pc)
{
+
+ if(!pc)
+ return;
+
if(!pb->pcHead) {
/* If this is the first pcode to be added to a block that
* was initialized with a NULL pcode, then go ahead and
* make this pcode the head and tail */
pb->pcHead = pb->pcTail = pc;
} else {
+ // if(pb->pcTail)
pb->pcTail->next = pc;
+
pc->prev = pb->pcTail;
- //pc->next = NULL;
pc->pb = pb;
+
pb->pcTail = pc;
}
}
/* Now loop through the pBlock and merge the labels with the opcodes */
- for(pc = pb->pcHead; pc; pc = pc->next) {
+ pc = pb->pcHead;
+ // for(pc = pb->pcHead; pc; pc = pc->next) {
+
+ while(pc) {
+ pCode *pcn = pc->next;
if(pc->type == PC_LABEL) {
//fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
if((pcnext = findNextInstruction(pc) )) {
- pCode *pcn = pc->next;
-
// Unlink the pCode label from it's pCode chain
unlinkpCode(pc);
pbr->pc = pc;
pbr->next = NULL;
-
PCI(pcnext)->label = pBranchAppend(PCI(pcnext)->label,pbr);
-
- pc = pcn;
} else {
fprintf(stderr, "WARNING: couldn't associate label %s with an instruction\n",PCL(pc)->label);
/* merge the source line symbolic info into the next instruction */
if((pcnext = findNextInstruction(pc) )) {
- pCode *pcn = pc->next;
-
// Unlink the pCode label from it's pCode chain
unlinkpCode(pc);
PCI(pcnext)->cline = PCCS(pc);
//fprintf(stderr, "merging CSRC\n");
//genericPrint(stderr,pcnext);
- pc = pcn;
}
}
-
+ pc = pcn;
}
pBlockRemoveUnusedLabels(pb);
pCodeInstruction *pci=NULL;
pCodeOp *pcosubtype;
+ if(!pcwb) {
+ fprintf(stderr,"ERROR %s:%d - can't assemble line\n",__FILE__,__LINE__);
+ return NULL;
+ }
+
dest = cvt_extract_destination(&p[3]);
DFPRINTF((stderr,"altpat_mnem2a %s var %d destination %s(%d)\n",
/* pcode. */
/*-----------------------------------------------------------------*/
-void parseTokens(pCodeWildBlock *pcwb)
+int parseTokens(pCodeWildBlock *pcwb, pCode **pcret)
{
unsigned i;
pCode *pc;
+ int error = 0;
if(!tokIdx)
- return;
+ return error;
for(i=0; i<=tokIdx; i++)
dump1Token(tokArr[i].tt);
//if(curBlock && pc)
//addpCode2pBlock(curBlock, pc);
- addpCode2pBlock(pcwb->pb, pc);
+ if(pc) {
+ if (pcret) {
+ *pcret = pc;
+ return 0; // Only accept one line for now.
+ } else
+ addpCode2pBlock(pcwb->pb, pc);
+ } else
+ error++;
}
j += c;
}
}
-
+ return error;
}
/*-----------------------------------------------------------------*/
//DFPRINTF((stderr,"%s\n",ln->line));
tokenizeLineNode(ln->line);
- parseTokens(pcwb);
+
+ if(parseTokens(pcwb,NULL)) {
+ fprintf(stderr,"ERROR assembling line:\n%s\n",ln->line);
+ exit (1);
+ }
+ }
+}
+/*-----------------------------------------------------------------*/
+/* */
+/*-----------------------------------------------------------------*/
+pCode *AssembleLine(char *line)
+{
+ pCode *pc=NULL;
+
+ if(!line || !*line) {
+ fprintf(stderr,"WARNING returning NULL in AssembleLine\n");
+ return NULL;
}
+
+ tokenizeLineNode(line);
+
+ if(parseTokens(NULL,&pc))
+ fprintf(stderr, "WARNING: unable to assemble line:\n%s\n",line);
+
+ return pc;
+
}
/*-----------------------------------------------------------------*/
{
/* First, get rid of registers that are used only one time */
-
RemoveRegsFromSet(dynInternalRegs);
RemoveRegsFromSet(dynAllocRegs);
RemoveRegsFromSet(dynStackRegs);
*
*
*-----------------------------------------------------------------*/
-void pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int can_free)
+int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int can_free)
{
pCode *pct1, *pct2;
regs *reg1, *reg2;
+ int t = total_registers_saved;
+
if(pc2->seq < pc1->seq) {
pct1 = pc2;
pc2 = pc1;
if(PCI(pct2)->op == POC_MOVWF) {
reg2 = getRegFromInstruction(pct2);
- if(reg2 && !regUsedinRange(pc1,pc2,reg2)) {
+ if(reg2 && !regUsedinRange(pc1,pc2,reg2) && (reg2->type != REG_SFR)) {
pct2->seq = pc1->seq;
unlinkpCode(pct2);
pCodeInsertAfter(pc1,pct2);
Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
total_registers_saved++; // debugging stats.
- return;
+ return 1;
}
/*
fprintf(stderr, " couldn't optimize\n");
}
+ return (total_registers_saved != t);
}
/*-----------------------------------------------------------------*
* void pCodeRegOptimeRegUsage(pBlock *pb)
*-----------------------------------------------------------------*/
-void OptimizeRegUsage(set *fregs)
+void OptimizeRegUsage(set *fregs, int optimize_multi_uses)
{
regs *reg;
int used;
+ pCode *pc1=NULL, *pc2=NULL;
while(fregs) {
* instructions are examined. If possible, they're optimized out.
*/
- pCode *pc1, *pc2;
/*
fprintf (stderr, "OptimizeRegUsage: %s addr=0x%03x rIdx=0x%03x type=%d used=%d\n",
reg->name,
reg->wasUsed = 0;
total_registers_saved++; // debugging stats.
- } else if(used > 2) {
+ } else if( (used > 2) && optimize_multi_uses) {
+
+ set *rset1=NULL;
+ set *rset2=NULL;
+ int searching=1;
+
+ pCodeFlow *pcfl1=NULL, *pcfl2=NULL;
/* examine the number of times this register is used */
+
+ rset1 = reg->reglives.usedpCodes;
+ while(rset1 && searching) {
+
+ pc1 = rset1->item;
+ rset2 = rset1->next;
+
+ if(pc1 && isPCI(pc1) && ( (pcfl1 = PCI(pc1)->pcflow) != NULL) ) {
+
+ while(rset2 && searching) {
+
+ pc2 = rset2->item;
+ if(pc2 && isPCI(pc2) && ( (pcfl2 = PCI(pc2)->pcflow) != NULL) ) {
+ if(pcfl2 == pcfl1) {
+/*
+ fprintf(stderr, " two instruction in same flow\n");
+ pc1->print(stderr, pc1);
+ pc2->print(stderr, pc2);
+*/
+ //if(pCodeOptime2pCodes(pc1, pc2, pcfl_used, reg, 1))
+ // searching = 0;
+ }
+ }
+
+ rset2 = rset2->next;
+
+ }
+ }
+ rset1 = rset1->next;
+ }
}
}
void pCodeRegOptimizeRegUsage(void)
{
- int passes = 4;
+ int passes;
int saved = 0;
int t = total_registers_saved;
+ int optimize_multi = 0;
do {
- saved = total_registers_saved;
+ passes = 4;
+
+ //fprintf(stderr, " multi opti %d\n",optimize_multi);
+
+ do {
+ saved = total_registers_saved;
- /* Identify registers used in one flow sequence */
- OptimizeRegUsage(dynAllocRegs);
- OptimizeRegUsage(dynStackRegs);
- OptimizeRegUsage(dynDirectRegs);
+ /* Identify registers used in one flow sequence */
+ OptimizeRegUsage(dynAllocRegs,optimize_multi);
+ OptimizeRegUsage(dynStackRegs,0);
+ OptimizeRegUsage(dynDirectRegs,0);
- if(total_registers_saved != saved)
- fprintf(stderr, " *** Saved %d registers, total saved %d ***\n", total_registers_saved-saved,total_registers_saved);
+ if(total_registers_saved != saved)
+ fprintf(stderr, " *** Saved %d registers, total saved %d ***\n", total_registers_saved-saved,total_registers_saved);
+
+ } while( passes-- && (total_registers_saved != saved));
- } while( passes-- && (total_registers_saved != saved));
+ optimize_multi++;
+ } while (optimize_multi < 2);
if(total_registers_saved == t)
fprintf(stderr, "No registers saved on this pass\n");