PIC port - Scott Dattalo scott@dattalo.com (2000)
PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
- Vangelis Rokas vrokas@otenet.gr (2003,2004,2005)
+ Bug Fixes - Raphael Neider rneider@web.de (2004,2005)
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
static asmop *newAsmop (short type);
static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op);
extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
-static void mov2f(asmop *dst, asmop *src, int offset);
static void mov2fp(pCodeOp *dst, asmop *src, int offset);
static pCodeOp *pic16_popRegFromIdx(int rIdx);
pCodeOpReg *pcor;
pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
- pcor->pcop.type = pc->pcop.type;
+ memcpy (pcor, pc, sizeof (pCodeOpReg));
+ pcor->r->wasUsed = 1;
+
+ //pcor->pcop.type = pc->pcop.type;
if(pc->pcop.name) {
if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
} else
pcor->pcop.name = NULL;
- pcor->r = pc->r;
- pcor->rIdx = pc->rIdx;
- pcor->r->wasUsed=1;
- pcor->instance = pc->instance;
+ //pcor->r = pc->r;
+ //pcor->rIdx = pc->rIdx;
+ //pcor->r->wasUsed=1;
+ //pcor->instance = pc->instance;
// DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
}
-static void mov2f(asmop *dst, asmop *src, int offset)
+void pic16_mov2f(asmop *dst, asmop *src, int offset)
{
if(is_LitAOp(src)) {
pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
size = AOP_SIZE(op);
while(size--) {
- mov2f(AOP(result), AOP(op), offset);
+ pic16_mov2f(AOP(result), AOP(op), offset);
offset++;
}
* wrapper segment at vector address. The user should take care for
* this instead. -- VR */
- if(!IFFUNC_ISNAKED(ftype) && (FUNC_INTNO(sym->type) =! INTNO_UNSPEC)) {
+ if(!IFFUNC_ISNAKED(ftype) && (FUNC_INTNO(sym->type) != INTNO_UNSPEC)) {
asym = newSymbol(asymname, 0);
apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
pic16_addpBlock( apb );
pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------"));
pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
- pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
+ //pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
+ //pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_newpCodeOpLabel (sym->rname, 0)));
+ pic16_addpCode2pBlock(apb, pic16_newpCodeAsmDir ("GOTO", "%s", sym->rname)); /* this suppresses a warning in LinkFlow */
/* mark the end of this tiny function */
pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
left = right;
right = dummy;
- performedLt ^= 1; // instead of "left < right" we check for "right >= left+1"
+ performedLt ^= 1; // instead of "left < right" we check for "right >= left+1, i.e. "right < left+1"
} else if (isAOP_LIT(right)) {
lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
} // if
pctemp = pic16_popGetTempReg(1);
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
- pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_MOVWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
static void genInline (iCode *ic)
{
char *buffer, *bp, *bp1;
- char *cbuf;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
}
bp = bp1 = buffer;
- cbuf = Safe_strdup( buffer );
-
+#if 0
+ /* This is an experimental code for #pragma inline
+ and is temporarily disabled for 2.5.0 release */
if(asmInlineMap)
{
symbol *sym;
char *s;
+ char *cbuf;
int cblen;
cbuf = Safe_strdup(buffer);
bp = bp1 = buffer;
}
+#endif /* 0 */
/* emit each line as a code */
while (*bp) {
} else {
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offr));
pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
}
} else {
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offr));
}
default:
#endif
{
/* we don't know if left is a literal or a register, take care -- VR */
- mov2f(AOP(result), AOP(left), offset);
+ pic16_mov2f(AOP(result), AOP(left), offset);
}
offset++;
}
#if 1
/* this is already done, why change it? */
if (!pic16_sameRegs(AOP(left),AOP(result))) {
- mov2f(AOP(result), AOP(left), 0);
+ pic16_mov2f(AOP(result), AOP(left), 0);
}
#endif
} else {
/* we don't know if left is a literal or a register, take care -- VR */
- mov2f(AOP(result), AOP(left), offset);
+ pic16_mov2f(AOP(result), AOP(left), offset);
}
offset++;
}
tlbl = newiTempLabel(NULL);
if (!pic16_sameRegs(AOP(left),AOP(result))) {
- mov2f(AOP(result), AOP(left), 0);
+ pic16_mov2f(AOP(result), AOP(left), 0);
// pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
// pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
if(sign) {
pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),MSB16));
}
}
if(shCount == 0){
assert (res_size <= lsize);
while (res_size--) {
- mov2f (AOP(result), AOP(left), res_size);
+ pic16_mov2f (AOP(result), AOP(left), res_size);
} // for
}
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
if(sign) {
pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),LSB));
}
} else {
// (e.g. char c = 0x100 << -3 will become c = 0x00 >> 3 == 0x00 instad of 0x20)
// This is fine, as it only occurs for left shifting with negative count which is not standardized!
for (offset=0; offset < min(AOP_SIZE(left), AOP_SIZE(result)); offset++) {
- mov2f (AOP(result),AOP(left), offset);
+ pic16_mov2f (AOP(result),AOP(left), offset);
} // for
// if result is longer than left, fill with zeros (or sign)
pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
}
- // warnings will be emitted below
+ // warnings will be emitted below (if desired)
//pic16_emitpcomment ("; =?= genPackBits, GPOINTER...");
//werror(W_POSSBUG2, __FILE__, __LINE__);
break;
// this should work in all cases (as soon as gptrget/gptrput work on EEPROM and PROGRAM MEMORY)
//pic16_emitpcomment ("; =?= genPackBits, GPOINTER access");
- werror(W_POSSBUG2, __FILE__, __LINE__);
+ //werror(W_POSSBUG2, __FILE__, __LINE__);
break;
default:
operand *result, iCode *ic)
{
int size;
- sym_link *retype = getSpec(operandType(right));
+ sym_link *retype = getSpec(operandType(result));
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
move it to the correct pointer register */
type = operandType(result);
etype = getSpec(type);
+
/* if left is of type of pointer then it is simple */
if (IS_PTR(type) && !IS_FUNC(type->next)) {
p_type = DCL_TYPE(type);
if (AOP_TYPE(right) == AOP_REG) {
DEBUGpic16_emitcode("; ", "%s:%d assign from register\n", __FUNCTION__, __LINE__);
while (size--) {
-
pic16_emitpcode (POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset++));
} // while
goto release;
}
+ /* when do we have to read the program memory?
+ * - if right itself is a symbol in code space
+ * (we don't care what it points to if it's a pointer)
+ * - AND right is not a function (we would want its address)
+ */
if(AOP_TYPE(right) != AOP_LIT
- && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))
+ && IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(right)))
&& !IS_FUNC(OP_SYM_TYPE(right))
- ) {
+ && !IS_ITEMP(right))
+ {
DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__);
fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
pic16_popCopyReg(&pic16_pc_tblptru)));
}
- size = min(getSize(OP_SYM_ETYPE(right)), AOP_SIZE(result));
+ /* must fetch 3 bytes for pointers (was OP_SYM_ETYPE before) */
+ size = min(getSize(OP_SYM_TYPE(right)), AOP_SIZE(result));
while(size--) {
pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat),
offset++;
}
- size = getSize(OP_SYM_ETYPE(right));
+ /* FIXME: for pointers we need to extend differently (according
+ * to pointer type DATA/CODE/EEPROM/... :*/
+ size = getSize(OP_SYM_TYPE(right));
if(AOP_SIZE(result) > size) {
size = AOP_SIZE(result) - size;
while(size--) {
while (size--) {
if(offset < AOP_SIZE(right)) {
DEBUGpic16_emitcode("; ***","%s %d - pointer cast3 ptype = 0x%x",__FUNCTION__,__LINE__, p_type);
- mov2f(AOP(result), AOP(right), offset);
+ pic16_mov2f(AOP(result), AOP(right), offset);
/*
if ((AOP_TYPE(right) == AOP_PCODE) &&
AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
while (size--) {
if(!_G.resDirect)
- mov2f(AOP(result), AOP(right), offset);
+ pic16_mov2f(AOP(result), AOP(right), offset);
offset++;
}
/* Save one instruction of casting char to int */
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
} else {
pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));