static int labelOffset=0;
extern int pic16_debug_verbose;
static int optimized_for_speed = 0;
+/*
+ hack hack
+
+*/
+int options_no_movff = 1;
/* max_key keeps track of the largest label number used in
a function. This is then used to adjust the label offset
lineCurr->isDebug = _G.debugLine;
pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
-
va_end(ap);
+
+// fprintf(stderr, "%s\n", lb);
}
pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
else
DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
+
+// fprintf(stderr, "%s\n", pcop->name);
}
void pic16_emitpcodeNULLop(PIC_OPCODE poc)
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 */
DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
/* if already has one */
- if (sym->aop)
+ if (sym->aop) {
+ DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
return sym->aop;
+ }
/* assign depending on the storage class */
/* if it is on the stack or indirectly addressable */
/* if the underlying symbol has a aop */
if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
- DEBUGpic16_emitcode(";","%d",__LINE__);
+ DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
op->aop = OP_SYMBOL(op)->aop;
return;
}
/* if this is a true symbol */
if (IS_TRUE_SYMOP(op)) {
- //DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
+ DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
op->aop = aopForSym(ic,OP_SYMBOL(op),result);
return ;
}
sym = OP_SYMBOL(op);
-
+ DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
/* if the type is a conditional */
if (sym->regType == REG_CND) {
aop = op->aop = sym->aop = newAsmop(AOP_CRY);
pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
pcop->type = PO_DIR;
- DEBUGpic16_emitcode(";","%d",__LINE__);
+ DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str);
+// fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
if(!str)
str = "BAD_STRING";
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);
return pcop;
}
+
+/*---------------------------------------------------------------------------------*/
+/* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
+/* VR 030601 */
+/*---------------------------------------------------------------------------------*/
+pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
+{
+ pCodeOpReg2 *pcop2;
+ pCodeOp *temp;
+
+ pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
+ temp = pic16_popGet(aop_dst, offset);
+ pcop2->pcop2 = temp;
+
+ return PCOP(pcop2);
+}
+
+
/*-----------------------------------------------------------------*/
/* pic16_popGet - asm operator to pcode operator conversion */
/*-----------------------------------------------------------------*/
case AOP_DIR:
return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
+
#if 0
pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
pcop->type = PO_DIR;
pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
*/
if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
- DEBUGpic16_emitcode("; ", "same registers");
pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
} else {
- DEBUGpic16_emitcode(";", "not sames registers!");
pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
}
switch(lit & 0xff) {
case 0x00:
/* and'ing with 0 has clears the result */
- pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+// pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
break;
case 0xff:
int p = my_powof2( (~lit) & 0xff );
if(p>=0) {
/* only one bit is set in the literal, so use a bcf instruction */
- pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
+// pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
} else {
size = AOP_SIZE(IC_RESULT(ic));
offset = 0;
+
while (size--) {
pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
offset++;
}
+
pic16_freeAsmop(left,NULL,ic,FALSE);
pic16_freeAsmop(result,NULL,ic,TRUE);
right = IC_RIGHT(ic) ;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
+
/* if they are the same */
if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
return ;
/* if the result is a bit */
if (AOP_TYPE(result) == AOP_CRY) {
-
/* if the right size is a literal then
we know what the value is */
if (AOP_TYPE(right) == AOP_LIT) {
if(AOP_TYPE(right) == AOP_LIT)
lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+/* VR - What is this?! */
if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(aopIdx(AOP(result),0) == 4) {
}
} else {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+
+ if(!options_no_movff) {
+
+ /* 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
+ is already loaded after such a pair, wrong code will be generated.
+
+ Checking the live range is the next step.
+ This is experimental code yet and has not been fully tested yet.
+ USE WITH CARE. Revert to old code by setting 0 to the condition above.
+ Vangelis Rokas 030603 (vrokas@otenet.gr) */
+
+
+ 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));
+ }
}
offset++;
}
/*-----------------------------------------------------------------*/
-/* genJumpTab - genrates code for jump table */
+/* genJumpTab - generates code for jump table */
/*-----------------------------------------------------------------*/
static void genJumpTab (iCode *ic)
{
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-------------------------------------------------------------------------*/
-
#include <stdio.h>
#include "common.h" // Include everything in the SDCC src directory
static hTab *pic16MnemonicsHash = NULL;
static hTab *pic16pCodePeepCommandsHash = NULL;
-
+int options_gen_banksel = 1;
static pFile *the_pFile = NULL;
static pBlock *pb_dead_pcodes = NULL;
extern void pic16_BuildFlowTree(pBlock *pb);
extern void pic16_pCodeRegOptimizeRegUsage(int level);
extern int pic16_picIsInitialized(void);
-#if !OPT_DISABLE_PIC
+#if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16
// From pic/pcode.c:
extern void SAFE_snprintf(char **str, size_t *size, const char *format, ...);
extern int mnem2key(char const *mnem);
-#endif // OPT_DISABLE_PIC
+#endif // OPT_DISABLE_PIC || !OPT_DISABLE_PIC16
/****************************************************************/
/* Forward declarations */
static void pCodePrintFunction(FILE *of, pCode *pc);
static void pCodeOpPrint(FILE *of, pCodeOp *pcop);
static char *pic16_get_op_from_instruction( pCodeInstruction *pcc);
-char *pic16_get_op( pCodeOp *pcop,char *buff,size_t buf_size);
+char *pic16_get_op(pCodeOp *pcop,char *buff,size_t buf_size);
int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd);
int pic16_pCodePeepMatchRule(pCode *pc);
static void pBlockStats(FILE *of, pBlock *pb);
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_Z) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_W | PCC_Z) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
(PCC_REGISTER | PCC_Z) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
(PCC_W | PCC_Z) // outCond
1, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_LITERAL), // inCond
(PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
1, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_LITERAL), // inCond
(PCC_W | PCC_Z | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_Z | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_W | PCC_Z) // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_REL_ADDR | PCC_C), // inCond
PCC_NONE // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_BSF,
(PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
PCC_REGISTER // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_REL_ADDR | PCC_N), // inCond
PCC_NONE // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_REL_ADDR | PCC_C), // inCond
PCC_NONE // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_REL_ADDR | PCC_N), // inCond
PCC_NONE // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_REL_ADDR | PCC_OV), // inCond
PCC_NONE // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_REL_ADDR | PCC_Z), // inCond
PCC_NONE // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_REL_ADDR | PCC_OV), // inCond
PCC_NONE // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REL_ADDR, // inCond
PCC_NONE // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_BCF,
(PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
(PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_BTFSS,
(PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
PCC_EXAMINE_PCOP // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_BTFSC,
(PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
PCC_EXAMINE_PCOP // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
(PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_Z, // inCond
PCC_NONE // outCond
0, // literal operand
0, // RAM access bit
1, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_NONE, // inCond
PCC_NONE // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_W // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_NONE, // inCond
PCC_NONE // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
PCC_NONE // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
PCC_NONE // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
PCC_NONE // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_W, // inCond
(PCC_W | PCC_C) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_W // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_W // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_W // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REL_ADDR, // inCond
PCC_NONE // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
(PCC_REGISTER | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_W // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_W // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_Z | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_W | PCC_Z | PCC_N) // outCond
1, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_LITERAL), // inCond
(PCC_W | PCC_Z | PCC_N) // outCond
1, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_REGISTER | PCC_LITERAL), // mdubuc - Should we use a special syntax for
// f (identifies FSRx)?
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
(PCC_Z | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
(PCC_W | PCC_Z) // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 1, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER2 // outCond
1, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_NONE | PCC_LITERAL), // inCond
PCC_REGISTER // outCond - BSR
1, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_NONE | PCC_LITERAL), // inCond
PCC_W // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_W // outCond
1, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_LITERAL), // inCond
PCC_REGISTER // outCond - PROD
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
PCC_REGISTER // outCond - PROD
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
(PCC_REGISTER | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_NONE, // inCond
PCC_NONE // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_NONE, // inCond
PCC_NONE // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_NONE, // inCond
PCC_NONE // outCond
0, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REL_ADDR, // inCond
PCC_NONE // outCond
0, // literal operand
0, // RAM access bit
1, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_NONE, // inCond
PCC_NONE // outCond (not true... affects the GIE bit too)
1, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_LITERAL, // inCond
PCC_W // outCond
0, // literal operand
0, // RAM access bit
1, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_NONE, // inCond
PCC_NONE // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_C | PCC_Z | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
(PCC_W | PCC_C | PCC_Z | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
(PCC_REGISTER | PCC_Z | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
(PCC_W | PCC_Z | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_C | PCC_Z | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
(PCC_W | PCC_C | PCC_Z | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
(PCC_REGISTER | PCC_Z | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
(PCC_W | PCC_Z | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
1, // literal operand
0, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_LITERAL), // inCond
(PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
(PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_Z) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_W | PCC_Z | PCC_OV | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
(PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
(PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
(PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
(PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_REGISTER), // inCond
(PCC_REGISTER) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_REGISTER), // inCond
(PCC_W) // outCond
};
+
+#if 1
// mdubuc - Remove TRIS
pCodeInstruction pic16_pciTRIS = {
0,0, // dest, bit instruction
0,0, // branch, skip
0, // literal operand
+ 0, // second memory operand
POC_NOP,
PCC_NONE, // inCond
PCC_REGISTER // outCond
};
+#endif
pCodeInstruction pic16_pciTSTFSZ = { // mdubuc - New
{PC_OPCODE, NULL, NULL, 0, NULL,
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
PCC_REGISTER, // inCond
PCC_NONE // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_Z | PCC_N) // outCond
0, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_W | PCC_Z | PCC_N) // outCond
1, // literal operand
1, // RAM access bit
0, // fast call/return mode select bit
+ 0, // second memory operand
POC_NOP,
(PCC_W | PCC_LITERAL), // inCond
(PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_N) // outCond
}
/*-----------------------------------------------------------------*/
-/* pic16_newpCodeCSource - create a new pCode Source Symbol */
+/* pic16_newpCodeCSource - create a new pCode Source Symbol */
/*-----------------------------------------------------------------*/
pCode *pic16_newpCodeCSource(int ln, char *f, char *l)
return ( (pCode *)pccs);
}
+
+
+/*******************************************************************/
+/* pic16_newpCodeAsmDir - create a new pCode Assembler Directive */
+/* added by VR 6-Jun-2003 */
+/*******************************************************************/
+
+pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...)
+{
+ pCodeAsmDir *pcad;
+ va_list ap;
+ char buffer[256]; // how long can a directive be?!
+ char *lbp=buffer;
+
+
+ pcad = Safe_calloc(1, sizeof(pCodeAsmDir));
+ pcad->pc.type = PC_ASMDIR;
+ pcad->pc.prev = pcad->pc.next = NULL;
+ pcad->pc.pb = NULL;
+
+ pcad->pc.destruct = genericDestruct;
+ pcad->pc.print = genericPrint;
+
+ if(asdir && *asdir) {
+ pcad->directive = Safe_strdup( asdir );
+ }
+
+ va_start(ap, argfmt);
+
+ if(argfmt && *argfmt)
+ vsprintf(buffer, argfmt, ap);
+
+ va_end(ap);
+
+ while(isspace(*lbp))lbp++;
+
+ if(lbp && *lbp)
+ pcad->arg = Safe_strdup( lbp );
+
+ return ((pCode *)pcad);
+}
+
/*-----------------------------------------------------------------*/
/* pCodeLabelDestruct - free memory used by a label. */
/*-----------------------------------------------------------------*/
regs *reg = pic16_getRegFromInstruction(pc);
if(reg)
deleteSetItem (&(reg->reglives.usedpCodes),pc);
+
+ if(PCI(pc)->is2MemOp) {
+ reg = pic16_getRegFromInstruction2(pc);
+ if(reg)
+ deleteSetItem(&(reg->reglives.usedpCodes), pc);
+ }
}
/* Instead of deleting the memory used by this pCode, mark
}
+
+
#if 0
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
s = buffer;
//size = sizeof(buffer);
if( PCOR(pcop)->instance) {
- SAFE_snprintf(&s,&size,"(%s + %d)",
- pcop->name,
- PCOR(pcop)->instance );
+ SAFE_snprintf(&s,&size,"(%s + %d)",
+ pcop->name,
+ PCOR(pcop)->instance );
+ }
//fprintf(stderr,"PO_DIR %s\n",buffer);
- } else
+ else
SAFE_snprintf(&s,&size,"%s",pcop->name);
return buffer;
}
+
+/*-----------------------------------------------------------------*/
+/* pic16_get_op2 - variant to support two memory operand commands */
+/*-----------------------------------------------------------------*/
+char *pic16_get_op2(pCodeOp *pcop,char *buffer, size_t size)
+{
+ regs *r;
+ static char b[50];
+ char *s;
+ int use_buffer = 1; // copy the string to the passed buffer pointer
+
+ if(!buffer) {
+ buffer = b;
+ size = sizeof(b);
+ use_buffer = 0; // Don't bother copying the string to the buffer.
+ }
+
+#if 0
+ fprintf(stderr, "%s:%d second operand %s is %d\tPO_DIR(%d) PO_GPR_TEMP(%d) PO_IMMEDIATE(%d) PO_INDF0(%d) PO_FSR0(%d)\n",
+ __FUNCTION__, __LINE__, PCOR(PCOR2(pcop)->pcop2)->r->name, PCOR2(pcop)->pcop2->type,
+ PO_DIR, PO_GPR_TEMP, PO_IMMEDIATE, PO_INDF0, PO_FSR0);
+#endif
+
+ if(pcop) {
+ switch(PCOR2(pcop)->pcop2->type) {
+ case PO_INDF0:
+ case PO_FSR0:
+ if(use_buffer) {
+ SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name);
+ return buffer;
+ }
+ return PCOR(PCOR2(pcop)->pcop2)->r->name;
+ break;
+ case PO_GPR_TEMP:
+ r = pic16_regWithIdx(PCOR(PCOR2(pcop)->pcop2)->r->rIdx);
+
+ if(use_buffer) {
+ SAFE_snprintf(&buffer,&size,"%s",r->name);
+ return buffer;
+ }
+
+ return r->name;
+
+
+ case PO_IMMEDIATE:
+ break;
+#if 0
+ s = buffer;
+
+ if(PCOI(pcop)->_const) {
+
+ if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
+ SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)",
+ pcop->name,
+ PCOI(pcop)->index,
+ 8 * PCOI(pcop)->offset );
+ } else
+ SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index);
+ } else {
+
+ if( PCOI(pcop)->index) { // && PCOI(pcc->pcop)->offset<4) {
+ SAFE_snprintf(&s,&size,"(%s + %d)",
+ pcop->name,
+ PCOI(pcop)->index );
+ } else {
+ if(PCOI(pcop)->offset)
+ SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset);
+ else
+ SAFE_snprintf(&s,&size,"%s",pcop->name);
+ }
+ }
+
+ return buffer;
+#endif
+
+ case PO_DIR:
+ s = buffer;
+ //size = sizeof(buffer);
+ if( PCOR(PCOR2(pcop)->pcop2)->instance) {
+ SAFE_snprintf(&s,&size,"(%s + %d)",
+ PCOR(PCOR2(pcop)->pcop2)->r->name,
+ PCOR(PCOR2(pcop)->pcop2)->instance );
+ }
+ //fprintf(stderr,"PO_DIR %s\n",buffer);
+ else
+ SAFE_snprintf(&s,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name);
+ return buffer;
+
+ default:
+#if 0
+ if (PCOR2(pcop)->r1->name) {
+ if(use_buffer) {
+ SAFE_snprintf(&buffer,&size,"%s",PCOR2(pcop)->r1->name);
+ return buffer;
+ }
+ return PCOR2(pcop)->r1->name;
+ }
+#endif
+ }
+ }
+
+ return "NO operand";
+
+}
+
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static char *pic16_get_op_from_instruction( pCodeInstruction *pcc)
switch(pc->type) {
case PC_OPCODE:
-
SAFE_snprintf(&s,&size, "\t%s\t", PCI(pc)->mnemonic);
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( (((pCodeOpRegBit *)(PCI(pc)->pcop))->inBitSpace) )
case PC_CSOURCE:
SAFE_snprintf(&s,&size,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
break;
+ case PC_ASMDIR:
+ SAFE_snprintf(&s,&size,"\t%s\t%s\n", PCAD(pc)->directive, PCAD(pc)->arg?PCAD(pc)->arg:"");
+ break;
case PC_BAD:
SAFE_snprintf(&s,&size,";A bad pCode is being used\n");
/* Debug */
if(pic16_debug_verbose) {
- fprintf(of, "\t;key=%03x",pc->seq);
+ fprintf(of, "\t;key=%03x %d",pc->seq, __LINE__);
if(PCI(pc)->pcflow)
fprintf(of,",flow seq=%03x",PCI(pc)->pcflow->pc.seq);
}
}
+ fprintf(of, "\n");
+ break;
+
#if 0
{
pBranch *dpb = pc->to; // debug
}
}
#endif
- fprintf(of,"\n");
- break;
+// fprintf(of,"\n"); // these are moved prior to #if 0
+// break;
case PC_WILD:
fprintf(of,";\tWild opcode: id=%d\n",PCW(pc)->id);
case PC_CSOURCE:
fprintf(of,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
break;
+ case PC_ASMDIR:
+ fprintf(of, "\t%s\t%s\n", PCAD(pc)->directive, PCAD(pc)->arg?PCAD(pc)->arg:"");
+ break;
+
case PC_LABEL:
default:
fprintf(of,"unknown pCode type %d\n",pc->type);
}
+/*-------------------------------------------------------------------------------*/
+/* pic16_getRegFromInstruction2 - variant to support two memory operand commands */
+/*-------------------------------------------------------------------------------*/
+regs * pic16_getRegFromInstruction2(pCode *pc)
+{
+
+ if(!pc ||
+ !isPCI(pc) ||
+ !PCI(pc)->pcop ||
+ PCI(pc)->num_ops == 0 ||
+ (PCI(pc)->num_ops == 1)) // accept only 2 operand commands
+ return NULL;
+
+
+/*
+ * operands supported in MOVFF:
+ * PO_INF0/PO_FSR0
+ * PO_GPR_TEMP
+ * PO_IMMEDIATE
+ * PO_DIR
+ *
+ */
+ switch(PCI(pc)->pcop->type) {
+ case PO_INDF0:
+ case PO_FSR0:
+ return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r;
+
+ // return typeRegWithIdx (PCOR(PCI(pc)->pcop)->rIdx, REG_SFR, 0);
+
+// case PO_BIT:
+ case PO_GPR_TEMP:
+ //fprintf(stderr, "pic16_getRegFromInstruction - bit or temp\n");
+ return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r;
+
+ case PO_IMMEDIATE:
+ break;
+#if 0
+ if(PCOI(PCI(pc)->pcop)->r)
+ return (PCOI(PCI(pc)->pcop)->r);
+
+ //fprintf(stderr, "pic16_getRegFromInstruction - immediate\n");
+ return pic16_dirregWithName(PCI(pc)->pcop->name);
+ //return NULL; // PCOR(PCI(pc)->pcop)->r;
+#endif
+
+ case PO_GPR_BIT:
+ break;
+// return PCOR2(PCI(pc)->pcop)->r;
+
+ case PO_DIR:
+ //fprintf(stderr, "pic16_getRegFromInstruction - dir\n");
+ return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r;
+
+ case PO_LITERAL:
+ break;
+ //fprintf(stderr, "pic16_getRegFromInstruction - literal\n");
+
+ default:
+ //fprintf(stderr, "pic16_getRegFromInstruction - unknown reg type %d\n",PCI(pc)->pcop->type);
+ //genericPrint(stderr, pc);
+ break;
+ }
+
+ return NULL;
+
+}
+
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
+/* insertBankSwitch - inserts a bank switch statement in the assembly listing */
/*-----------------------------------------------------------------*/
static void insertBankSwitch(int position, pCode *pc, int bsr)
{
pCode *new_pc;
+ regs *reg;
if(!pc)
return;
- new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(bsr));
+
+/*
+ * if bsr == -1 then do not insert a MOVLB instruction, but rather
+ * insert a BANKSEL assembler directive for the symbol used by
+ * the pCode. This will allow the linker to setup the correct
+ * bank at linking time
+ */
+
+ if(!options_gen_banksel || bsr != -1) {
+ new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(bsr));
+ } else {
+ /* emit the BANKSEL [symbol] */
+
+ /* IMPORTANT: The following code does not check if a symbol is
+ * split in multiple banks. This should be corrected. - VR 6/6/2003 */
+
+ reg = pic16_getRegFromInstruction(pc);
+ if(!reg)return;
+ new_pc = pic16_newpCodeAsmDir("BANKSEL", "%s", reg->name);
+
+ position = 0; // position is always before (sanity check!)
+ }
+
+#if 0
+ fprintf(stderr, "%s:%d: inserting bank switch\tbank = %d\n", __FUNCTION__, __LINE__, bsr);
+ pc->print(stderr, pc);
+#endif
if(position) {
/* insert the bank switch after this pc instruction */
while(pic16_isPCinFlow(pc,PCODE(pcfl))) {
reg = pic16_getRegFromInstruction(pc);
-#if 0
+
+#if 1
if(reg) {
- fprintf(stderr, " %s ",reg->name);
+ fprintf(stderr, "%s:%d %s ",__FUNCTION__, __LINE__, reg->name);
fprintf(stderr, "addr = 0x%03x, bank = %d\n",reg->address,REG_BANK(reg));
}
* not a skip type instruction */
pcprev = findPrevpCode(pc->prev, PC_OPCODE);
- if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) {
+ if(!pcprev || (pcprev && !isPCI_SKIP(pcprev) /* && !isBankInstruction(pcprev)*/)) {
int reg_bank;
reg_bank = (reg) ? REG_BANK(reg) : 0;
entry and exit.
*/
- //fprintf(stderr, "FixBankFlow - Phase 1\n");
+// fprintf(stderr, "FixBankFlow - Phase 1\n");
for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
pcflow != NULL;
}
}
- //fprintf(stderr, "FixBankFlow - Phase 2\n");
+// fprintf(stderr, "FixBankFlow - Phase 2\n");
for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
pcflow != NULL;
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
-static void FixRegisterBanking(pBlock *pb)
+static void pic16_FixRegisterBanking(pBlock *pb)
{
pCode *pc=NULL;
pCode *pcprev=NULL;
return;
/* loop through all of the flow blocks with in one pblock */
- //fprintf(stderr,"Register banking\n");
+// fprintf(stderr,"%s:%d: Register banking\n", __FUNCTION__, __LINE__);
+
cur_bank = 0;
do {
/* at this point, pc should point to a PC_FLOW object */
requirements */
// do {
- if(isPCI(pc)) {
- //genericPrint(stderr, pc);
+ if(isPCI(pc) && !PCI(pc)->is2MemOp) {
+// genericPrint(stderr, pc);
reg = pic16_getRegFromInstruction(pc);
#if 0
if(reg) {
- fprintf(stderr, " %s ",reg->name);
- fprintf(stderr, "addr = 0x%03x, bank = %d, bit=%d\n",
- reg->address,REG_BANK(reg),reg->isBitField);
+ fprintf(stderr, "%s:%d: %s %d\n",__FUNCTION__, __LINE__, reg->name, reg->rIdx);
+ fprintf(stderr, "addr = 0x%03x, bank = %d, bit=%d\tmapped = %d sfr=%d fix=%d\n",
+ reg->address,REG_BANK(reg),reg->isBitField, reg->isMapped,
+ pic16_finalMapping[ reg->rIdx ].isSFR, reg->isFixed);
}
#endif
- if( ( (reg && !isACCESS_BANK(reg) && REG_BANK(reg)!=cur_bank) ||
- ((PCI(pc)->op == POC_CALL) && (cur_bank != 0) ) ) &&
- (!isPCI_LIT(pc)) ){
+ /* the !(reg->rIdx==-1) is a temporary hack. It should be changed - VR 6-Jun-2003 */
+ if( ( (reg && !(reg->rIdx==-1) && !isACCESS_BANK(reg) /*&& REG_BANK(reg)!=cur_bank*/ && !isBankInstruction(pc)) ||
+ ((PCI(pc)->op != POC_CALL) /*&& (cur_bank != 0)*/ ) ) &&
+ (!isPCI_LIT(pc)) ) {
/* Examine the instruction before this one to make sure it is
* not a skip type instruction */
pcprev = findPrevpCode(pc->prev, PC_OPCODE);
- if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) {
+ if(!pcprev || (pcprev && !isPCI_SKIP(pcprev) /*&& !isBankInstruction(pcprev)*/)) {
int reg_bank;
- reg_bank = (reg) ? REG_BANK(reg) : 0;
-
- if (cur_bank != reg_bank) {
- cur_bank = reg_bank;
- insertBankSwitch(0, pc, cur_bank);
- }
+ reg_bank = (reg) ? REG_BANK(reg) : 0;
+
+// fprintf(stderr, "%s:%d add bank = %d\n", __FUNCTION__, __LINE__, reg_bank);
+// pc->print(stderr, pc);
+
+// if (cur_bank != reg_bank) {
+ cur_bank = reg_bank;
+ insertBankSwitch(0, pc, (options_gen_banksel)?-1:cur_bank); //cur_bank);
+// }
}else {
//fprintf(stderr, "Bummer can't switch banks\n");
* and register banking is fixed.
*/
- //for(pb = the_pFile->pbHead; pb; pb = pb->next)
- //FixRegisterBanking(pb);
+#if 0
+ for(pb = the_pFile->pbHead; pb; pb = pb->next)
+ pic16_FixRegisterBanking(pb);
+#endif
/* Phase 2 - Flow Analysis
*
for(pb = the_pFile->pbHead; pb; pb = pb->next)
BanksUsedFlow(pb);
+
for(pb = the_pFile->pbHead; pb; pb = pb->next)
- FixRegisterBanking(pb);
+ pic16_FixRegisterBanking(pb);
}
regs *r1,*r2;
for(r1=setFirstItem(regset); r1; r1=setNextItem(regset)) {
+// fprintf(stderr, "marking register = %s\t", r1->name);
r2 = pic16_regWithIdx(r1->rIdx);
+// fprintf(stderr, "to register = %s\n", r2->name);
r2->isFree = 0;
r2->wasUsed = 1;
}