+2004-09-12 Vangelis Rokas <vrokas AT otenet.gr>
+
+ * src/pic16/device.h (pic16_options_t): added field use_crt,
+ crt_name, no_crt,
+ * src/pic16/genarith.c (pic16_genPlus): added an assert(0) line to
+ catch a probable future bug,
+ * src/pic16/gen.c: aopIdx function commented out,
+ * (genAssign): commented out old code which used aopIdx,
+ * src/pic16/glue.c (pic16glue): removed some legacy fragments of
+ code, added if conditionals to take into account the --use-crt
+ command line options,
+ * src/pic16/main.c (pic16_optionsTable): added new command line
+ options, --use-crt= and --no-crt,
+ * (_pic16_linkEdit): now the proper crt object is added in the
+ linker command line except than when --no-crt is specified,
+ * src/pic16/pcode.c,
+ * src/pic16/pcode.h: added some structures and functions for a new
+ optimization scheme to compansete for instruction overhead between
+ same iCodes, this scheme is currently under development and is not
+ working in any way,
+ * src/pic16/gen.c (genAnd): added patch provided by Aaron Collwell
+ to && operator,
+ * device/lib/pic16/startup/crt0i.c,
+ * device/lib/pic16/startup/crt0iz.c: added global char variable
+ __uflags to force the generation of an idata section
+
+
2004-09-12 Bernhard Held <bernhard AT bernhardheld.de>
* doc/Makefile,
extern TABLAT;
extern POSTINC0;
+/* global variable for forcing gplink to add _cinit section */
+char __uflags = 0;
+
/* external reference to the user's main routine */
extern void main (void);
extern POSTINC0;
extern POSTDEC0;
+/* global variable for forcing gplink to add _cinit section */
+char __uflags = 0;
+
/* external reference to the user's main routine */
extern void main (void);
int ivt_loc;
int nodefaultlibs;
int dumpcalltree;
+ int use_crt;
+ char *crt_name;
+ int no_crt;
} pic16_options_t;
#define STACK_MODEL_SMALL (pic16_options.stack_model == 0)
static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op);
extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
static void mov2w (asmop *aop, int offset);
-static int aopIdx (asmop *aop, int offset);
+//static int aopIdx (asmop *aop, int offset);
int pic16_labelOffset=0;
extern int pic16_debug_verbose;
return aop;
}
+#if 0
static int aopIdx (asmop *aop, int offset)
{
if(!aop)
return aop->aopu.aop_reg[offset]->rIdx;
}
+#endif
+
/*-----------------------------------------------------------------*/
/* regsInCommon - two operands have some registers in common */
/*-----------------------------------------------------------------*/
} else {
symbol *tlbl = newiTempLabel(NULL);
int sizel = AOP_SIZE(left);
+
+ /* here to add patch from Aaron */
if(size)
- pic16_emitcode("setb","c");
- while(sizel--){
- if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
+ emitSETC; //pic16_emitcode("setb","c");
+
+
+ while(sizel--) {
+ if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
+
+
+ /* patch provided by Aaron Colwell */
+ if((posbit = isLiteralBit(bytelit)) != 0) {
+ pic16_emitpcode(((rIfx.condition) ? POC_BTFSS : POC_BTFSC ),
+ pic16_newpCodeOpBit(pic16_aopGet(AOP(left),
+ offset,FALSE,
+ FALSE),
+ (posbit-1),0, PO_GPR_REGISTER));
+
+ pic16_emitpcode(POC_BRA, pic16_popGetLabel(tlbl->key));
+ } else {
+ if (bytelit == 0xff) {
+ /* Aaron had a MOVF instruction here, changed to MOVFW cause
+ * a peephole could optimize it out -- VR */
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
+ } else {
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
+ pic16_emitpcode(POC_ANDLW, pic16_popGetLit(bytelit));
+ }
+
+ pic16_emitpcode(((rIfx.condition) ? POC_BZ : POC_BNZ),
+ pic16_popGetLabel(tlbl->key));
+ }
+
+#if 0
+ /* old code, left here for reference -- VR 09/2004 */
MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
// byte == 2^n ?
if((posbit = isLiteralBit(bytelit)) != 0)
pic16_emitcode("anl","a,%s",
pic16_aopGet(AOP(right),offset,FALSE,TRUE));
pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
- }
+ }
+#endif
}
offset++;
}
// bit = left & literal
- if(size){
- pic16_emitcode("clr","c");
- pic16_emitcode("","%05d_DS_:",tlbl->key+100);
+ if(size) {
+ emitCLRC;
+ pic16_emitpLabel(tlbl->key);
}
// if(left & literal)
- else{
- if(ifx)
- jmpTrueOrFalse(ifx, tlbl);
- goto release ;
+ else {
+ if(ifx) {
+ pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
+ pic16_emitpLabel(tlbl->key);
+ ifx->generated = 1;
+ }
+ goto release;
}
}
+
pic16_outBitC(result);
goto release ;
}
+#if 0
/* VR - What is this?! */
if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(aopIdx(AOP(result),0) == 4) {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- assert(0);
+
+ /* this is a workaround to save value of right into wreg too,
+ * value of wreg is going to be used later */
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
goto release;
// assert(0);
DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
}
+#endif
know_W=-1;
while (size--) {
}
+ assert( 0 );
// TODO: anything from here to before "release:" is probably obsolete and should be removed
// when the regression tests are stable
addSetHead(&tmpfileSet,ovrFile);
pic16_pCodeInitRegisters();
- if (mainf && IFFUNC_HASBODY(mainf->type)) {
+
+ if (pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
pic16_addpBlock(pb);
fprintf (asmFile, "; global & static initialisations\n");
fprintf (asmFile, "%s", iComments2);
-#if 0
- /* copy over code */
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "\tcode\n");
- fprintf (asmFile, "%s", iComments2);
-#endif
-
if(pic16_debug_verbose)
fprintf(asmFile, "; A code from now on!\n");
pic16_copypCode(asmFile, 'A');
- if(mainf && IFFUNC_HASBODY(mainf->type)) {
- fprintf(asmFile, "\tcode\n");
- fprintf(asmFile,"__sdcc_gsinit_startup:\n");
-
-#if 0
- /* FIXME 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 */
-
- if (options.useXstack) {
- fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
- (((unsigned int)options.xdata_loc) >> 8) & 0xff);
- fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
- (unsigned int)options.xdata_loc & 0xff);
+ if(pic16_options.no_crt) {
+ if(mainf && IFFUNC_HASBODY(mainf->type)) {
+ fprintf(asmFile, "\tcode\n");
+ fprintf(asmFile,"__sdcc_gsinit_startup:\n");
}
-#endif
}
// copyFile (stderr, code->oFile);
pic16_copypCode(asmFile, statsg->dbName);
- if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
- fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
+ if(pic16_options.no_crt) {
+ if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
+ fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
+ }
}
#define MPLAB_COMPAT "--mplab-comp"
#define NL_OPT "--nl="
+#define USE_CRT "--use-crt="
char *alt_asm=NULL;
char *alt_link=NULL;
{ 0, MPLAB_COMPAT, &pic16_mplab_comp, "enable compatibility mode for MPLAB utilities (MPASM/MPLINK)"},
{ 0, "--fstack", &pic16_fstack, "enable stack optimizations"},
{ 0, NL_OPT, NULL, "new line, \"lf\" or \"crlf\""},
+ { 0, USE_CRT, NULL, "use <crt-o> run-time initialization module"},
+ { 0, "--no-crt", &pic16_options.no_crt, "do not link any default run-time initialization module"},
{ 0, NULL, NULL, NULL}
};
}
return TRUE;
}
+
+ if(ISOPT(USE_CRT)) {
+ char *tmp;
+
+ tmp = Safe_strdup( getStringArg(USE_CRT, argv, i, *pargc) );
+ pic16_options.use_crt = 1; pic16_options.no_crt = 0;
+ pic16_options.crt_name = tmp;
+ }
return FALSE;
}
addSetHead(&relFilesSet, temp);
}
-// shash_add(&linkValues, "spec_ofiles", "crt0i.o");
+ if(pic16_options.use_crt && !pic16_options.no_crt)
+ shash_add(&linkValues, "spec_ofiles", pic16_options.crt_name); //"crt0i.o");
shash_add(&linkValues, "ofiles", joinStrSet(relFilesSet));
shash_add(&linkValues, "libs", joinStrSet(libFilesSet));
pic16_options.ivt_loc = 0x000000;
pic16_options.nodefaultlibs = 0;
pic16_options.dumpcalltree = 0;
+ pic16_options.use_crt = 1;
+ pic16_options.crt_name = "crt0i"; /* the default crt to link */
+ pic16_options.no_crt = 0;
}
static const char *
return ( (pCode *)pcl );
}
+#if 0
+pCode *pic16_newpCodeInfo(INFO_TYPE type, pCodeOp *pcop)
+{
+
+}
+#endif
+
/*-----------------------------------------------------------------*/
/* newpBlock - create and return a pointer to a new pBlock */
return pB;
}
+
+
/*-----------------------------------------------------------------*/
/* pic16_newpCodeOpLabel - Create a new label given the key */
/* Note, a negative key means that the label is part of wild card */
return pcop;
}
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+pCodeOp *pic16_newpCodeOpOpt(OPT_TYPE type, char *key)
+{
+ pCodeOpOpt *pcop;
+
+ pcop = Safe_calloc(1, sizeof(pCodeOpOpt));
+
+ pcop->type = type;
+ pcop->key = Safe_strdup( key );
+
+ return (PCOP(pcop));
+}
+
+
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
case PC_BAD:
SAFE_snprintf(&s,&size,";A bad pCode is being used\n");
+ break;
+
+ case PC_INFO:
+ SAFE_snprintf(&s,&size,"; PC INFO pcode\n");
+ break;
}
return str;
* in the pCode peep hole optimizer */
PC_CSOURCE, /* C-Source Line */
PC_ASMDIR, /* Assembler directive */
- PC_BAD /* Mark the pCode object as being bad */
+ PC_BAD, /* Mark the pCode object as being bad */
+ PC_INFO /* pCode informatio node, used primarily in optimizing */
} PC_TYPE;
+
+/***********************************************************************
+ * INFO_TYPE - information node types
+ ***********************************************************************/
+
+typedef enum
+{
+ INF_OPTIMIZATION, /* structure contains optimization information */
+} INFO_TYPE;
+
+
+
+/***********************************************************************
+ * OPT_TYPE - optimization node types
+ ***********************************************************************/
+
+typedef enum
+{
+ OPT_BEGIN, /* mark beginning of optimization block */
+ OPT_END, /* mark ending of optimization block */
+} OPT_TYPE;
+
+
+
/************************************************/
/*************** Structures ********************/
/************************************************/
} pCodeOpWild;
+typedef struct pCodeOpOpt
+{
+ pCodeOp pcop;
+
+ OPT_TYPE type; /* optimization node type */
+
+ char *key; /* key by which a block is identified */
+} pCodeOpOpt;
+
+
+
/*************************************************
pCode
} pCodeWild;
+
+/*************************************************
+ pInfo
+
+ Here are stored generic informaton
+*************************************************/
+typedef struct pInfo
+{
+ pCode pc;
+
+ INFO_TYPE type; /* info node type */
+
+ pCodeOp *oper1; /* info node arguments */
+} pInfo;
+
+
/*************************************************
pBlock
#define PCOR(x) ((pCodeOpReg *)(x))
#define PCOR2(x) ((pCodeOpReg2 *)(x))
#define PCORB(x) ((pCodeOpRegBit *)(x))
+#define PCOO(x) ((pCodeOpOpt *)(x))
#define PCOW(x) ((pCodeOpWild *)(x))
#define PCOW2(x) (PCOW(PCOW(x)->pcop2))
#define PBR(x) ((pBranch *)(x))