+2004-01-06 Vangelis Rokas <vrokas@otenet.gr>
+
+ PIC16 port related changes:
+ * device.c: removed pic16_finalMapping and pic16_finalMappingSize,
+ added variable stackPos,
+
+ * gen.c: genCall, assignResultValue: added support for
+ pushing/retrieving function parameters to/from stack,
+ genFunction,genEndFunction: setup stack frame for the
+ generated function,
+ genAddrOf: will be changed according to bug 863624
+
+ * added files genutils.c and genutils.h which contain gen*
+ debugged and optimised functions extracted from gen.c
+
+ * glue.c: added variable 'externs' which holds extern symbols,
+ pic16emitRegularMap: is modified to properly handle relocatable
+ symbols under the new scheme,
+ pic16createInterruptVect: is modified
+ pic16printPublics: is modified to emit 'global' assembler directives,
+ added pic16_printExterns to print extern symbols,
+ pic16glue: initializes stack/frame pointer in the beginning of
+ the assembly output. Temporary hack, will be corrected later,
+ because gplink yet does not support stack and SDCC does not
+ yet support a type of crt0.o object to create the final binary.
+
+ * Removed many lines that contain 8051 legacy code.
+ * The code is finally placed under a 'code' directive.
+ * Added port specific options.
+
+ * _process_pragma: simplified since now we do not need *special*
+ include file to define SFR registers. But a separate header
+ will be needed. This will be developed later.
+ * _pic16_parseOptions: added, parses port specific options:
+ --pgen-banksel, --obanksel=, --pomit-config-words, --pomit-ivt,
+ --pleave-reset-vector, --penable-stack, --pstack-model, --debug-xtra
+ --preplace-udata-with=
+
+ * _pic16_setDefaultOptions: modified to initialize section names,
+ but hack is temporarly out of order since it needs improvement.
+ * _pic16_genAssemblerPreamble: configuration words are emitted by
+ their address instead of their name. This part is incomplete and
+ supports only the 18Fxx2 devices. Other devices will emit an error
+ during assembly since they do not contain the same set of config
+ registers
+ * _pic16_genIVT: is modified,
+
+ * pcode.c: added definitions for some hardware registers that are needed
+ for stack support
+ * added flag is2LitOp and variable pci_magic in pCodeInstruction.
+ All PCI entries are updated. Now LFSR is supported.
+ * Removed pic16_pciTRIS is mentioned by mdubuc in source
+ * added pic16_newpCodeOpLit2 to support instructions with
+ two literal arguments
+ * pic16_pCode2str: corrected code that emits assembler instructions
+ with two literal operands and those that have an access bit modifier
+ * genericPrint: now PC_ASMDIR pCodes, can emit a label if it exists,
+ this fixes a bug which caused some labels to be lost, when an
+ assembler directive was added, i.e. banksel,
+ * pic16_FixRegisterBanking: improved logic that causes the insertion
+ of bank switching,
+ * InlineFunction: functions that are called once, are not any more
+ inlined. This can be a port option in the future,
+
+ * pcode.h: added pCodeOpLit2 and added variable label in pCodeAsmDir
+
+ * ralloc.c: added pic16_rel_udata and pic16_fix_udata variables which
+ hold the corresponding uninitialized symbols,
+ * pic16_allocProcessorRegister: registers have explicit marked the
+ accessBank field,
+ * pic16_allocInternalRegister: registers are explicit marked as
+ not used,
+ * pic16_writeUsedRegs: pic16_dynDirectBitRegs was missing from the
+ processing list, so bit registers were lost,
+ *
+
+ * ralloc.h: added field 'accessBank' and original symbol operand
+ in register definition,
+ * removed the field isMapped from register definition,
+
+ ** Several functions have been removed from various sources:
+ BanksUsedFlow2,BanksUsedFlow,FixBankFlow,InstructionRegBank,
+ pic16_addMemRange,pic16_isREGinBank,pic16_dump_map,pic16_dump_cblock
+ isSFR,validAddress,mapRegister,assignRegister,pic16_assignFixedRegisters
+ pic16_assignRelocatableRegisters
+
+ ** others have been introduced:
+ pic16_areRegsSame,pic16_dump_section,checkAddReg,pic16_groupRegistersInSection
+ pic16_popGetLit2,pic16_popCombine2,pushw,pushaop
+
2004-01-05 Vangelis Rokas <vrokas@otenet.gr>
* support/scripts/inc2h.pl: changed definition of BIT_AT
int noCcodeInAsm; /* hide c-code from asm */
int iCodeInAsm; /* show i-code in asm */
int printSearchDirs; /* display the directories in the compiler's search path */
- int gen_banksel; /* enable the generation of the banksel assembler directive in pic16 port */
int vc_err_style; /* errors and warnings are compatible with Micro$oft visual studio */
int use_stdout; /* send errors to stdout instead of stderr */
int no_std_crt0; /*For the z80/gbz80 do not link default crt0.o*/
{ 0, OPTION_USE_STDOUT, &options.use_stdout, "send errors to stdout instead of stderr"},
#if !OPT_DISABLE_Z80 || !OPT_DISABLE_GBZ80
{ 0, "--no-std-crt0", &options.no_std_crt0, "For the z80/gbz80 do not link default crt0.o"},
-#endif
-#if !OPT_DISABLE_PIC16
- { 0, "--gen-banksel", &options.gen_banksel, "enable the generation of banksel assembler directives in PIC16 port"},
#endif
/* End of options */
{ 0, NULL }
/** Gets the string argument to this option. If the option is '--opt'
then for input of '--optxyz' or '--opt xyz' returns xyz.
*/
-static char *
+char *
getStringArg(const char *szStart, char **argv, int *pi, int argc)
{
if (argv[*pi][strlen(szStart)])
/** Gets the integer argument to this option using the same rules as
getStringArg.
*/
-static int
+int
getIntArg(const char *szStart, char **argv, int *pi, int argc)
{
return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi, argc)));
static PIC_device *pic=NULL;
-AssignedMemory *pic16_finalMapping=NULL;
-int pic16_finalMappingSize=0;
+//AssignedMemory *pic16_finalMapping=NULL;
+//int pic16_finalMappingSize=0;
#define DEFAULT_CONFIG_BYTE 0xff
static unsigned int config7l_word = DEFAULT_CONFIG7L_WORD;
static unsigned int config7h_word = DEFAULT_CONFIG7H_WORD;
-void pic16_addMemRange(memRange *r, int type)
-{
- int i;
- int alias = r->alias;
-
- if (pic->maxRAMaddress < 0) {
- fprintf(stderr, "missing \"#pragma maxram\" setting\n");
- return;
- }
-
-// fprintf(stderr, "%s: adding memory range from 0x%x to 0x%x type= %d\n",
-// __FUNCTION__, r->start_address, r->end_address, type);
-
- do {
- for (i=r->start_address; i<= r->end_address; i++) {
- if ((i|alias) <= pic->maxRAMaddress) {
- pic16_finalMapping[i | alias].isValid = 1;
- pic16_finalMapping[i | alias].alias = r->alias;
- pic16_finalMapping[i | alias].bank = r->bank;
- if(type) {
- /* hack for now */
- pic16_finalMapping[i | alias].isSFR = 1;
- } else {
- pic16_finalMapping[i | alias].isSFR = 0;
- }
- } else {
- fprintf(stderr, "WARNING: %s:%s memory at 0x%x is beyond max ram = 0x%x\n",
- __FILE__,__FUNCTION__,(i|alias), pic->maxRAMaddress);
- }
- }
-
- /* Decrement alias */
- if (alias) {
- alias -= ((alias & (alias - 1)) ^ alias);
- } else {
- alias--;
- }
-
- } while (alias >= 0);
-}
+unsigned int stackPos = 0;
void pic16_setMaxRAM(int size)
{
- int i;
pic->maxRAMaddress = size;
+ stackPos = pic->RAMsize-1;
if (pic->maxRAMaddress < 0) {
fprintf(stderr, "invalid \"#pragma maxram 0x%x\" setting\n",
return;
}
- pic16_finalMapping = Safe_calloc(1+pic->maxRAMaddress,
- sizeof(AssignedMemory));
+// pic16_finalMapping = Safe_calloc(1+pic->maxRAMaddress,
+// sizeof(AssignedMemory));
/* Now initialize the pic16_finalMapping array */
- for(i=0; i<=pic->maxRAMaddress; i++) {
- pic16_finalMapping[i].reg = NULL;
- pic16_finalMapping[i].isValid = 0;
- }
+// for(i=0; i<=pic->maxRAMaddress; i++) {
+// pic16_finalMapping[i].reg = NULL;
+// pic16_finalMapping[i].isValid = 0;
+// }
}
/*-----------------------------------------------------------------*
*-----------------------------------------------------------------*/
-
+#if 0
int pic16_isREGinBank(regs *reg, int bank)
{
return 0;
}
-
+#endif
/*-----------------------------------------------------------------*
*-----------------------------------------------------------------*/
int pic16_REGallBanks(regs *reg)
if(!reg || !pic)
return 0;
- if (reg->address > pic->maxRAMaddress)
+ if ((int)reg->address > pic->maxRAMaddress)
return 0;
return 1;
/*
* pic16_dump_map -- debug stuff
*/
-
+#if 0
void pic16_dump_map(void)
{
int i;
}
}
+#endif
-void pic16_dump_cblock(FILE *of)
-{
- int start=-1;
- int addr=0;
- int bank_base;
-
- //pic16_dump_map(); /* display the register map */
-
- if (pic->maxRAMaddress < 0) {
- fprintf(stderr, "missing \"#pragma maxram\" setting\n");
- return;
- }
-
- do {
-
- if(pic16_finalMapping[addr].reg && !pic16_finalMapping[addr].reg->isEmitted
- && pic16_finalMapping[addr].reg->wasUsed) {
-
- if(start<0)
- start = addr;
- } else {
- if(start>=0) {
-
- /* clear the lower 7-bits of the start address of the first
- * variable declared in this bank. The upper bits for the mid
- * range pics are the bank select bits.
- */
-
- bank_base = start & 0xfff8;
-
- /* The bank number printed in the cblock comment tacitly
- * assumes that the first register in the contiguous group
- * of registers represents the bank for the whole group */
-
- if ((pic16_finalMapping[start].bank == 0 && start <= 0x7f) ||
- pic16_finalMapping[start].isSFR)
- fprintf(of," cblock 0X%04X\t; Access Bank\n",start);
- else
- fprintf(of," cblock 0X%04X\t; Bank %d\n",start,pic16_finalMapping[start].bank);
-
- for( ; start < addr; start++) {
- if((pic16_finalMapping[start].reg) && !pic16_finalMapping[start].reg->isEmitted ) {
- fprintf(of,"\t%s",pic16_finalMapping[start].reg->name);
-
- /* If this register is aliased in multiple banks, then
- * mangle the variable name with the alias address: */
- if(pic16_finalMapping[start].alias & start)
- fprintf(of,"_%x",bank_base);
-
- if(pic16_finalMapping[start].instance)
- fprintf(of,"_%d",pic16_finalMapping[start].instance);
-
-
- fputc('\n',of);
-//#warning why is the following line commented out?! (VR)
-// pic16_finalMapping[start].reg->isEmitted = 1;
- }
+void pic16_dump_section(FILE *of, char *sname, set *section, int fix)
+{
+ static int abs_section_no=0;
+ regs *r, *rprev;
+ int init_addr;
+
+ if(!fix) {
+ fprintf(of, "\n\n\tudata\n");
+ for(r = setFirstItem(section); r; r = setNextItem(section)) {
+ fprintf(of, "%s\tres\t%d\n", r->name, r->size);
+ }
+ } else {
+ r = setFirstItem(section);
+ if(!r)return;
+ init_addr = r->address;
+ fprintf(of, "\n\nstatic_%s_%02d\tudata\t0X%04X\n", moduleName, abs_section_no++, init_addr);
+
+ rprev = NULL;
+ for(; r; r = setNextItem(section)) {
+ init_addr = r->address;
+
+ if(rprev && (init_addr != (rprev->address + rprev->size))) {
+ fprintf(of, "\nstatic_%s_%02d\tudata\t0X%04X\n", moduleName, abs_section_no++, init_addr);
+ }
+
+ fprintf(of, "%s\tres\t%d\n", r->name, r->size);
+ rprev = r;
+ }
}
+}
- fprintf(of," endc\n");
-
- start = -1;
- }
-
- }
-
- addr++;
- } while(addr <= pic->maxRAMaddress);
-
-}
/*-----------------------------------------------------------------*
* void pic16_list_valid_pics(int ncols, int list_alias)
*-----------------------------------------------------------------*/
void pic16_init_pic(char *pic_type)
{
- pic = pic16_find_device(pic_type);
+ pic = pic16_find_device(pic_type);
- if(!pic) {
- if(pic_type)
- fprintf(stderr, "'%s' was not found.\n", pic_type);
- else
- fprintf(stderr, "No processor has been specified (use -pPROCESSOR_NAME)\n");
+ if(!pic) {
+ if(pic_type)
+ fprintf(stderr, "'%s' was not found.\n", pic_type);
+ else
+ fprintf(stderr, "No processor has been specified (use -pPROCESSOR_NAME)\n");
- fprintf(stderr,"Valid devices are:\n");
+ fprintf(stderr,"Valid devices are:\n");
- pic16_list_valid_pics(4,0);
- exit(1);
- }
+ pic16_list_valid_pics(4,0);
+ exit(1);
+ }
- pic->maxRAMaddress = -1;
+// printf("PIC processor found and initialized: %s\n", pic_type);
+ pic16_setMaxRAM( 0xfff );
}
/*-----------------------------------------------------------------*
return pic->name[0];
}
-static int isSFR(int address)
-{
-
- if( (address > pic->maxRAMaddress) || !pic16_finalMapping[address].isSFR)
- return 0;
-
- return 1;
-
-}
+#if 0
/*-----------------------------------------------------------------*
*-----------------------------------------------------------------*/
static int validAddress(int address, int reg_size)
{
int i;
+#if 0
if (pic->maxRAMaddress < 0) {
fprintf(stderr, "missing \"#pragma maxram\" setting\n");
return 0;
pic16_finalMapping[address+i].reg ||
pic16_finalMapping[address+i].isSFR )
return 0;
+#endif
return 1;
}
+#endif
-/*-----------------------------------------------------------------*
- *-----------------------------------------------------------------*/
-static void mapRegister(regs *reg)
-{
-
- int i;
- int alias;
-
- if(!reg || !reg->size) {
- fprintf(stderr,"WARNING: %s:%s:%d Bad register\n",__FILE__,__FUNCTION__,__LINE__);
- return;
- }
-
- if (pic->maxRAMaddress < 0) {
- fprintf(stderr, "missing \"#pragma maxram\" setting\n");
- return;
- }
-
- for(i=0; i<reg->size; i++) {
-
- alias = pic16_finalMapping[reg->address].alias;
- reg->alias = alias;
-
- do {
-
-// fprintf(stdout,"mapping %s to address 0x%02x, reg size = %d\n",reg->name, (reg->address+alias+i),reg->size);
-
- pic16_finalMapping[reg->address + alias + i].reg = reg;
- pic16_finalMapping[reg->address + alias + i].instance = i;
-
- /* Decrement alias */
- if(alias)
- alias -= ((alias & (alias - 1)) ^ alias);
- else
- alias--;
-
- } while (alias>=0);
- }
-
- // fprintf(stderr,"%s - %s addr = 0x%03x, size %d\n",__FUNCTION__,reg->name, reg->address,reg->size);
-
- reg->isMapped = 1;
-
-}
-
-/*-----------------------------------------------------------------*
- *-----------------------------------------------------------------*/
-static int assignRegister(regs *reg, int start_address)
+void checkAddReg(set **set, regs *reg)
{
- int i;
+ regs *tmp;
-// fprintf(stderr,"%s - %s start_address = 0x%03x\t(max=0x%03x)\n",__FUNCTION__,reg->name, start_address, pic->maxRAMaddress);
- if(reg->isFixed) {
- if (validAddress(reg->address,reg->size)) {
-// fprintf(stderr,"fixed %s - %s address = 0x%03x\n",__FUNCTION__,reg->name, reg->address);
- mapRegister(reg);
- return reg->address;
- }
-
- if( isSFR(reg->address)) {
-// fprintf(stderr,"sfr %s - %s address = 0x%03x\n",__FUNCTION__,reg->name, reg->address);
- mapRegister(reg);
- return reg->address;
- }
-
- //fprintf(stderr, "WARNING: Ignoring Out of Range register assignment at fixed address %d, %s\n",
- // reg->address, reg->name);
-
- } else {
-
- /* This register does not have a fixed address requirement
- * so we'll search through all availble ram address and
- * assign the first one */
-
- for (i=start_address; i<=pic->maxRAMaddress; i++) {
-
- if (validAddress(i,reg->size)) {
-// fprintf(stderr, "found valid address = 0x%04x\n", i);
- reg->address = i;
- mapRegister(reg);
- return i;
- }
- }
-
- fprintf(stderr, "WARNING: No more RAM available for %s\n",reg->name);
-
- }
-
- return -1;
+ for(tmp = setFirstItem(*set); tmp; tmp = setNextItem(*set)) {
+ if(!strcmp(tmp->name, reg->name))break;
+ }
+
+ if(!tmp)
+ addSet(set, reg);
}
/*-----------------------------------------------------------------*
+ * void pic16_groupRegistersInSection - add each register to its *
+ * corresponding section *
*-----------------------------------------------------------------*/
-void pic16_assignFixedRegisters(set *regset)
+void pic16_groupRegistersInSection(set *regset)
{
regs *reg;
- for (reg = setFirstItem(regset) ; reg ;
- reg = setNextItem(regset)) {
-
- if(reg->isFixed)
- assignRegister(reg,0);
- }
-
+ for(reg=setFirstItem(regset); reg; reg = setNextItem(regset)) {
+ if(reg->wasUsed
+ && !(reg->regop && SPEC_EXTR(OP_SYM_ETYPE(reg->regop)))) {
+ if(reg->isFixed)
+ checkAddReg(&pic16_fix_udata, reg);
+
+ if(!reg->isFixed)
+ checkAddReg(&pic16_rel_udata, reg);
+ }
+ }
}
-/*-----------------------------------------------------------------*
- *-----------------------------------------------------------------*/
-void pic16_assignRelocatableRegisters(set *regset, int used)
-{
- regs *reg;
- int address = 0;
- for (reg = setFirstItem(regset) ; reg ;
- reg = setNextItem(regset)) {
-
- //fprintf(stdout,"assigning %s isFixed=%d, wasUsed=%d\n",reg->name,reg->isFixed,reg->wasUsed);
-
- if((!reg->isFixed) && (used || reg->wasUsed))
- address = assignRegister(reg,address);
-
- }
-
-}
/*-----------------------------------------------------------------*
break;
}
- //fprintf(stderr,"setting config word to 0x%x\n",value);
+ fprintf(stderr,"setting config word to 0x%x\n",value);
}
/*-----------------------------------------------------------------*
return 0;
}
}
-
* pic16_finalMapping - Dynamically allocated array that records the register assignments
*/
-extern AssignedMemory *pic16_finalMapping;
+//extern AssignedMemory *pic16_finalMapping;
/*
* pic16_finalMappingSize - Size of register assignments that pic16_finalMapping can hold
*/
-extern int pic16_finalMappingSize;
+//extern int pic16_finalMappingSize;
#define PROCESSOR_NAMES 4
/* Given a pointer to a register, this macro returns the bank that it is in */
#define REG_ADDR(r) ((r)->isBitField ? (((r)->address)>>3) : (r)->address)
-#define REG_BANK(r) (pic16_finalMapping[REG_ADDR(r)].bank)
-#define REG_isALIASED(r) (pic16_finalMapping[REG_ADDR(r)].alias != 0)
-#define REG_isVALID(r) (pic16_finalMapping[REG_ADDR(r)].isValid)
+//#define REG_BANK(r) (pic16_finalMapping[REG_ADDR(r)].bank)
+//#define REG_isALIASED(r) (pic16_finalMapping[REG_ADDR(r)].alias != 0)
+//#define REG_isVALID(r) (pic16_finalMapping[REG_ADDR(r)].isValid)
+
+
+typedef struct {
+ int gen_banksel;
+ int opt_banksel;
+ int omit_configw;
+ int omit_ivt;
+ int leave_reset;
+ int enable_stack;
+ int stack_model;
+} pic16_options_t;
+
+#define USE_STACK (pic16_options.enable_stack)
+#define STACK_MODEL_SMALL (pic16_options.stack_model == 0)
+#define STACK_MODEL_LARGE (pic16_options.stack_model == 1)
+
+
+extern pic16_options_t pic16_options;
/****************************************/
void pic16_addMemRange(memRange *r, int type);
void pic16_setMaxRAM(int size);
+void checkAddReg(set **set, regs *reg);
+
+
#endif /* __DEVICE_H__ */
#include "ralloc.h"
#include "pcode.h"
#include "gen.h"
-
+#include "genutils.h"
+#include "device.h"
extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
// VR fprintf(stderr, "lb = <%s>\n", lbp);
- if(pic16_debug_verbose)
- pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
+// if(pic16_debug_verbose)
+// pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
va_end(ap);
}
if (!op)
return ;
- DEBUGpic16_emitcode(";","%d",__LINE__);
+// DEBUGpic16_emitcode(";","%d",__LINE__);
+
/* if this a literal */
if (IS_OP_LITERAL(op)) {
op->aop = aop = newAsmop(AOP_LIT);
return PCOP(pcor);
}
+
/*-----------------------------------------------------------------*/
-/* pic16_popGet - asm operator to pcode operator conversion */
+/* pic16_popGetLit - asm operator to pcode operator conversion */
/*-----------------------------------------------------------------*/
pCodeOp *pic16_popGetLit(unsigned int lit)
{
-
return pic16_newpCodeOpLit(lit);
}
+/*-----------------------------------------------------------------*/
+/* pic16_popGetLit2 - asm operator to pcode operator conversion */
+/*-----------------------------------------------------------------*/
+pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2)
+{
+ return pic16_newpCodeOpLit2(lit, lit2);
+}
+
/*-----------------------------------------------------------------*/
-/* pic16_popGetImmd - asm operator to pcode immediate conversion */
+/* pic16_popGetImmd - asm operator to pcode immediate conversion */
/*-----------------------------------------------------------------*/
pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
{
PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
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);
+// fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
+// __FUNCTION__, __LINE__, str, size, offset);
PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
//fprintf(stderr, "allocating new register -> %s\n", str);
return PCOP(pcop2);
}
+pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst)
+{
+ pCodeOpReg2 *pcop2;
+
+ pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
+ pcop2->pcop2 = pic16_popCopyReg(dst);
+
+ return PCOP(pcop2);
+}
/*-----------------------------------------------------------------*/
/* pic16_popGet - asm operator to pcode operator conversion */
return NULL;
case AOP_IMMD:
- DEBUGpic16_emitcode(";","%d",__LINE__);
+ DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
case AOP_DIR:
+ DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
-
-#if 0
- pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
- pcop->type = PO_DIR;
-
- /*
- if (offset)
- sprintf(s,"(%s + %d)",
- aop->aopu.aop_dir,
- offset);
- else
- sprintf(s,"%s",aop->aopu.aop_dir);
- pcop->name = Safe_calloc(1,strlen(s)+1);
- strcpy(pcop->name,s);
- */
- pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
- strcpy(pcop->name,aop->aopu.aop_dir);
- PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
- 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 (aop->aopu.aop_dir,aop->size);
- 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);
- }
- PCOR(pcop)->instance = offset;
-
- return pcop;
-#endif
case AOP_REG:
{
int rIdx = aop->aopu.aop_reg[offset]->rIdx;
+ DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
PCOR(pcop)->rIdx = rIdx;
PCOR(pcop)->r = pic16_regWithIdx(rIdx);
}
case AOP_CRY:
+ DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
+
pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
//if(PCOR(pcop)->r == NULL)
return pcop;
case AOP_LIT:
+ DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
case AOP_STR:
- DEBUGpic16_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
+ DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
+
/*
pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
}
+
+/*-----------------------------------------------------------------*/
+/* pushw - pushes wreg to stack */
+/*-----------------------------------------------------------------*/
+void pushw(void)
+{
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
+}
+
+
+/*-----------------------------------------------------------------*/
+/* pushaop - pushes aop to stack */
+/*-----------------------------------------------------------------*/
+void pushaop(asmop *aop, int offset)
+{
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1));
+}
+
+#if 0
+/*-----------------------------------------------------------------*/
+/* popaop - pops aop from stack */
+/*-----------------------------------------------------------------*/
+void popaop(asmop *aop, int offset)
+{
+ DEBUG
+}
+#endif
+
+void popaopidx(asmop *aop, int offset, int index)
+{
+ int ofs=1;
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if(STACK_MODEL_LARGE)ofs++;
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset))));
+}
+
/*-----------------------------------------------------------------*/
/* reAdjustPreg - points a register back to where it should */
/*-----------------------------------------------------------------*/
}
+#if !defined(GEN_Not)
/*-----------------------------------------------------------------*/
/* genNot - generate code for ! operation */
/*-----------------------------------------------------------------*/
-static void genNot (iCode *ic)
+static void pic16_genNot (iCode *ic)
{
symbol *tlbl;
int size;
pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
}
+#endif
+#if !defined(GEN_Cpl)
/*-----------------------------------------------------------------*/
/* genCpl - generate code for complement */
/*-----------------------------------------------------------------*/
-static void genCpl (iCode *ic)
+static void pic16_genCpl (iCode *ic)
{
int offset = 0;
int size ;
pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
}
+#endif
/*-----------------------------------------------------------------*/
/* genUminusFloat - unary minus for floating points */
{
int size = AOP_SIZE(oper);
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
+
+ if(!GpsuedoStkPtr) {
+// DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
+ /* The last byte in the assignment is in W */
+ size--;
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
+ GpsuedoStkPtr++;
+ }
- DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
+ while (size--) {
+// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
+// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
+
+#if STACK_SUPPORT
+ if(USE_STACK) {
+ popaopidx(AOP(oper), size, GpsuedoStkPtr);
+ } else {
+ pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
+ }
+#else
+ pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
+#endif /* STACK_SUPPORT */
+ GpsuedoStkPtr++;
- if(!GpsuedoStkPtr) {
- /* The last byte in the assignment is in W */
- size--;
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
- GpsuedoStkPtr++;
- }
+#if STACK_SUPPORT
+ if(!USE_STACK)
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
+#else
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
+#endif
- while (size--) {
- pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
- GpsuedoStkPtr++;
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
- }
+ }
+
}
#endif
}
+
+
/*-----------------------------------------------------------------*/
/* genCall - generates a call statement */
/*-----------------------------------------------------------------*/
static void genCall (iCode *ic)
{
sym_link *dtype;
+ int stackParms=0;
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* if caller saves & we have not saved then */
+ if (!ic->regsSaved)
+ saveRegisters(ic);
- /* if caller saves & we have not saved then */
- if (!ic->regsSaved)
- saveRegisters(ic);
+ /* if we are calling a function that is not using
+ * the same register bank then we need to save the
+ * destination registers on the stack */
+ dtype = operandType(IC_LEFT(ic));
+ if (currFunc && dtype &&
+ (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
+ IFFUNC_ISISR(currFunc->type) &&
+ !ic->bankSaved)
- /* if we are calling a function that is not using
- the same register bank then we need to save the
- destination registers on the stack */
- dtype = operandType(IC_LEFT(ic));
- if (currFunc && dtype &&
- (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
- IFFUNC_ISISR(currFunc->type) &&
- !ic->bankSaved)
+ saverbank(FUNC_REGBANK(dtype),ic,TRUE);
- saverbank(FUNC_REGBANK(dtype),ic,TRUE);
+ /* if send set is not empty the assign */
+ if (_G.sendSet) {
+ iCode *sic;
- /* if send set is not empty the assign */
- if (_G.sendSet) {
- iCode *sic;
- /* For the Pic port, there is no data stack.
- * So parameters passed to functions are stored
- * in registers. (The pCode optimizer will get
- * rid of most of these :).
- */
- int psuedoStkPtr=-1;
- int firstTimeThruLoop = 1;
+ /* For the Pic port, there is no data stack.
+ * So parameters passed to functions are stored
+ * in registers. (The pCode optimizer will get
+ * rid of most of these :). */
- _G.sendSet = reverseSet(_G.sendSet);
+ int psuedoStkPtr=-1;
+ int firstTimeThruLoop = 1;
- /* First figure how many parameters are getting passed */
- for (sic = setFirstItem(_G.sendSet) ; sic ;
- sic = setNextItem(_G.sendSet)) {
+ _G.sendSet = reverseSet(_G.sendSet);
- pic16_aopOp(IC_LEFT(sic),sic,FALSE);
- psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
- pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
- }
+ /* First figure how many parameters are getting passed */
+ for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
+ pic16_aopOp(IC_LEFT(sic),sic,FALSE);
+ psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
+ pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
+ }
- for (sic = setFirstItem(_G.sendSet) ; sic ;
- sic = setNextItem(_G.sendSet)) {
- int size, offset = 0;
+ stackParms = psuedoStkPtr;
- pic16_aopOp(IC_LEFT(sic),sic,FALSE);
- size = AOP_SIZE(IC_LEFT(sic));
+ for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
+ int size, offset = 0;
- while (size--) {
- DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
- pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
+ pic16_aopOp(IC_LEFT(sic),sic,FALSE);
+ size = AOP_SIZE(IC_LEFT(sic));
+
+ while (size--) {
+ DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
+ pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
+ DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
- if(!firstTimeThruLoop) {
- /* If this is not the first time we've been through the loop
- * then we need to save the parameter in a temporary
- * register. The last byte of the last parameter is
- * passed in W. */
- pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
+ if(!firstTimeThruLoop) {
+ /* If this is not the first time we've been through the loop
+ * then we need to save the parameter in a temporary
+ * register. The last byte of the last parameter is
+ * passed in W. */
+
+#if STACK_SUPPORT
+ if(USE_STACK) {
+ pushw();
+ --psuedoStkPtr; // sanity check
+ } else {
+ pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
+ }
+#else
+ pic16_emitpcode(POC_MOVWF, popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
+#endif /* STACK_SUPPORT */
+ }
+
+ firstTimeThruLoop=0;
+ mov2w (AOP(IC_LEFT(sic)), offset);
+ offset++;
+ }
+ pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
+ }
+ _G.sendSet = NULL;
}
- firstTimeThruLoop=0;
- //if (strcmp(l,fReturn[offset])) {
- mov2w (AOP(IC_LEFT(sic)), offset);
-/*
- if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
- ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
- pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
- else
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
-*/
- //}
- offset++;
- }
- pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
- }
- _G.sendSet = NULL;
- }
- /* make the call */
- pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
- OP_SYMBOL(IC_LEFT(ic))->rname :
- OP_SYMBOL(IC_LEFT(ic))->name));
-
- GpsuedoStkPtr=0;
- /* if we need assign a result value */
- if ((IS_ITEMP(IC_RESULT(ic)) &&
- (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
- OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
- IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
-
- _G.accInUse++;
- pic16_aopOp(IC_RESULT(ic),ic,FALSE);
- _G.accInUse--;
+ /* make the call */
+ pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
+ OP_SYMBOL(IC_LEFT(ic))->rname :
+ OP_SYMBOL(IC_LEFT(ic))->name));
+
+ GpsuedoStkPtr=0;
+ /* if we need assign a result value */
+ if ((IS_ITEMP(IC_RESULT(ic)) &&
+ (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
+ OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
+ IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
+
+ _G.accInUse++;
+ pic16_aopOp(IC_RESULT(ic),ic,FALSE);
+ _G.accInUse--;
- assignResultValue(IC_RESULT(ic));
+ assignResultValue(IC_RESULT(ic));
- DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
+ DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
- pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
- }
+ pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
+ }
- /* adjust the stack for parameters if
- required */
- if (ic->parmBytes) {
- int i;
- if (ic->parmBytes > 3) {
- pic16_emitcode("mov","a,%s",spname);
- pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
- pic16_emitcode("mov","%s,a",spname);
- } else
- for ( i = 0 ; i < ic->parmBytes ;i++)
- pic16_emitcode("dec","%s",spname);
+#if STACK_SUPPORT
+ if(USE_STACK) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
+ pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
+ if(STACK_MODEL_LARGE) {
+ emitSKPNC;
+ pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
+ }
+ }
+#endif
- }
+ /* adjust the stack for parameters if required */
+ fprintf(stderr, "%s:%d: ic->parmBytes= %d\n", __FILE__, __LINE__, ic->parmBytes);
- /* if register bank was saved then pop them */
- if (ic->bankSaved)
- unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
+ if (ic->parmBytes) {
+ int i;
- /* if we hade saved some registers then unsave them */
- if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
- unsaveRegisters (ic);
+ if (ic->parmBytes > 3) {
+ pic16_emitcode("mov","a,%s",spname);
+ pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
+ pic16_emitcode("mov","%s,a",spname);
+ } else
+ for ( i = 0 ; i < ic->parmBytes ;i++)
+ pic16_emitcode("dec","%s",spname);
+ }
+ /* if register bank was saved then pop them */
+ if (ic->bankSaved)
+ unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
+ /* if we hade saved some registers then unsave them */
+ if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
+ unsaveRegisters (ic);
}
/*-----------------------------------------------------------------*/
}
}
}
+
+#if STACK_SUPPORT
+ /* emit code to setup stack frame if user enabled,
+ * and function is not main() */
+
+ fprintf(stderr, "function name: %s\n", sym->name);
+ if(USE_STACK && strcmp(sym->name, "main")) {
+ /* setup the stack frame */
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1));
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l));
+ if(STACK_MODEL_LARGE)
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h));
+ }
+#endif
+
}
/* set the register bank to the desired value */
pic16_emitcode ("mov","_bp,%s",spname);
}
+ DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
+
/* adjust the stack for the function */
if (sym->stack) {
werror(W_STACK_OVERFLOW,sym->name);
if (i > 3 && sym->recvSize < 4) {
-
pic16_emitcode ("mov","a,sp");
pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
pic16_emitcode ("mov","sp,a");
}
if (sym->xstack) {
-
+ DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
pic16_emitcode ("mov","a,_spx");
pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
pic16_emitcode ("mov","_spx,a");
_G.debugLine = 0;
}
+#if STACK_SUPPORT
+ /* insert code to restore stack frame, if user enabled it
+ * and function is not main() */
+
+ if(USE_STACK && strcmp(sym->name, "main")) {
+ /* restore stack frame */
+ if(STACK_MODEL_LARGE)
+ pic16_emitpcode(POC_MOVFF,
+ pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2h ));
+ pic16_emitpcode(POC_MOVFF,
+ pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2l ));
+
+/*
+ * I added this because of a mistake in the stack pointers design
+ * They should be removed though
+
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc2, &pic16_pc_fsr2h));
+ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc2, &pic16_pc_fsr2l));
+*/
+ }
+#endif
+
pic16_emitcode ("return","");
pic16_emitpcodeNULLop(POC_RETURN);
pic16_emitcode("push","%s",l);
pushed++;
} else {
+ DEBUGpic16_emitcode(";", "%d", __LINE__);
l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
FALSE,FALSE);
+ DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
if (strcmp(fReturn[offset],l)) {
if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
if ( IC_TRUE(ifx) ) {
if(size) {
emitSKPZ;
+
+ DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
+
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
} else {
emitSKPNZ;
+
+ DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
+
+
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
}
} else {
emitSKPZ;
+
+ DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
+
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
}
/* hack hack! see if this the FSR. If so don't load W */
if(AOP_TYPE(right) != AOP_ACC) {
+// pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(result), pic16_popCopyReg(&pic16_pc_fsr0), 0));
pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
/*-----------------------------------------------------------------*/
/* genAddrOf - generates code for address of */
/*-----------------------------------------------------------------*/
+#if 0
static void genAddrOf (iCode *ic)
{
operand *right, *result, *left;
}
+#else /* new genAddrOf */
+
+static void genAddrOf (iCode *ic)
+{
+ operand *result, *left;
+ int size;
+ symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
+ pCodeOp *pcop0, *pcop1;
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
+ pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
+
+ sym = OP_SYMBOL( left );
+
+ size = AOP_SIZE(IC_RESULT(ic));
+
+ /* Assume that what we want the address of is in direct addressing space
+ * since there is no stack on the PIC, yet! -- VR */
+
+ pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, 0));
+ pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, 0));
+#if 0
+ pcop0 = pic16_newpCodeOp(sym->rname, PO_IMMEDIATE);
+ PCOI(pcop0)->offset = 0;
+ PCOI(pcop0)->index = 0;
+ pcop1 = pic16_newpCodeOp(sym->rname, PO_IMMEDIATE);
+ PCOI(pcop1)->offset = 1;
+ PCOI(pcop1)->index = 0;
+#endif
+
+ if (size == 2) {
+ pic16_emitpcode(POC_MOVLW, pcop0);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_MOVLW, pcop1);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
+ } else {
+ pic16_emitpcode(POC_MOVLW, pcop0);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+ }
+
+ pic16_freeAsmop(result,NULL,ic,TRUE);
+ pic16_freeAsmop(left, NULL, ic, FALSE);
+}
+
+#endif /* new genAddrOf */
+
#if 0
/*-----------------------------------------------------------------*/
/* genFarFarAssign - assignment when both are in far space */
#if 1
/* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
- normally should work, but mind that thw W register live range
+ normally should work, but mind that the 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.
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(!?) */
/*-----------------------------------------------------------------*/
static void genReceive (iCode *ic)
{
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (isOperandInFarSpace(IC_RESULT(ic)) &&
- ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
- IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
+ if (isOperandInFarSpace(IC_RESULT(ic)) &&
+ ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
+ IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
- int size = getSize(operandType(IC_RESULT(ic)));
- int offset = pic16_fReturnSizePic - size;
- while (size--) {
- pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
- fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
- offset++;
- }
- pic16_aopOp(IC_RESULT(ic),ic,FALSE);
- size = AOP_SIZE(IC_RESULT(ic));
- offset = 0;
- while (size--) {
- pic16_emitcode ("pop","acc");
- pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
- }
-
- } else {
- _G.accInUse++;
- pic16_aopOp(IC_RESULT(ic),ic,FALSE);
- _G.accInUse--;
- assignResultValue(IC_RESULT(ic));
- }
+ int size = getSize(operandType(IC_RESULT(ic)));
+ int offset = pic16_fReturnSizePic - size;
- pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+ while (size--) {
+ pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
+ fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
+ offset++;
+ }
+
+ DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
+
+ pic16_aopOp(IC_RESULT(ic),ic,FALSE);
+ size = AOP_SIZE(IC_RESULT(ic));
+ offset = 0;
+ while (size--) {
+ pic16_emitcode ("pop","acc");
+ pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
+ }
+ } else {
+ DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
+
+ _G.accInUse++;
+ pic16_aopOp(IC_RESULT(ic),ic,FALSE);
+ _G.accInUse--;
+ assignResultValue(IC_RESULT(ic));
+ }
+
+ pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
ic->level,ic->block);
_G.debugLine = 0;
}
- /*
- pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
- pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
- printCLine(ic->filename, ic->lineno));
- */
pic16_addpCode2pBlock(pb,
pic16_newpCodeCSource(ic->lineno,
ic->filename,
/* depending on the operation */
switch (ic->op) {
case '!' :
- genNot(ic);
+ pic16_genNot(ic);
break;
case '~' :
- genCpl(ic);
+ pic16_genCpl(ic);
break;
case UNARYMINUS:
break;
case SEND:
+ DEBUGpic16_emitcode(";ic ", "\t%c 0x%x\tSEND",ic->op, ic->op);
+
addSet(&_G.sendSet,ic);
break;
pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval);
pCodeOp *pic16_popGetLit(unsigned int lit);
+pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2);
pCodeOp *popGetWithString(char *str);
pCodeOp *pic16_popGet (asmop *aop, int offset);//, bool bit16, bool dname);
pCodeOp *pic16_popGetTempReg(void);
DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
/* if the literal value of the right hand side
- is greater than 1 then it is faster to add */
- if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 1) // this was > 2 why? VR
+ is greater than 2 then it is faster to add */
+ if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
return FALSE ;
/* if increment 16 bits in register */
}
-
/* if the sizes are greater than 1 then we cannot */
if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
AOP_SIZE(IC_LEFT(ic)) > 1 )
--- /dev/null
+/*-------------------------------------------------------------------------
+ genutils.c - source file for code generation for pic16
+ code generation utility functions
+
+ Created by Vangelis Rokas (vrokas@otenet.gr) [Nov-2003]
+
+ Based on :
+
+ Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
+ and - Jean-Louis VERN.jlvern@writeme.com (1999)
+ Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
+ PIC port - Scott Dattalo scott@dattalo.com (2000)
+ PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
+
+ 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
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding!
+
+ Notes:
+ 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
+ Made everything static
+-------------------------------------------------------------------------*/
+
+/**********************************************************
+ * Here is a list with completed genXXXXX functions
+ *
+ * genNot
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "SDCCglobl.h"
+#include "newalloc.h"
+
+#include "common.h"
+#include "SDCCpeeph.h"
+#include "ralloc.h"
+#include "pcode.h"
+#include "gen.h"
+
+#include "genutils.h"
+
+
+#if defined(GEN_Not)
+/*-----------------------------------------------------------------*/
+/* pic16_genNot - generate code for ! operation */
+/*-----------------------------------------------------------------*/
+void pic16_genNot (iCode *ic)
+{
+ int size;
+
+/*
+ * result[AOP_CRY,AOP_REG] = ! left[AOP_CRY, AOP_REG]
+ */
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* assign asmOps to operand & result */
+ pic16_aopOp (IC_LEFT(ic),ic,FALSE);
+ pic16_aopOp (IC_RESULT(ic),ic,TRUE);
+ DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
+
+ /* if in bit space then a special case */
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
+ if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
+ pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
+ pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
+ } else {
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
+ pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
+ pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
+ }
+ goto release;
+ }
+
+ size = AOP_SIZE(IC_LEFT(ic));
+ if(size == 1) {
+ pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
+ pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
+ goto release;
+ }
+
+release:
+ /* release the aops */
+ pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
+ pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+}
+
+#endif /* defined(GEN_Not) */
+
+
+
+#if defined(GEN_Cpl)
+/*-----------------------------------------------------------------*/
+/* pic16_genCpl - generate code for complement */
+/*-----------------------------------------------------------------*/
+void pic16_genCpl (iCode *ic)
+{
+ int offset = 0;
+ int size ;
+
+/*
+ * result[CRY,REG] = ~left[CRY,REG]
+ */
+
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* assign asmOps to operand & result */
+ pic16_aopOp (IC_LEFT(ic),ic,FALSE);
+ pic16_aopOp (IC_RESULT(ic),ic,TRUE);
+ DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
+
+ /* if both are in bit space then
+ a special case */
+ if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
+ AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
+
+ /* FIXME */
+ pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
+ pic16_emitcode("cpl","c");
+ pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
+ goto release;
+ }
+
+ size = AOP_SIZE(IC_RESULT(ic));
+ while (size--) {
+
+ if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
+ pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
+ } else {
+ pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
+ }
+ offset++;
+ }
+
+release:
+ /* release the aops */
+ pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
+ pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+}
+#endif /* defined(GEN_Cpl) */
+
--- /dev/null
+
+/*
+** $Id$
+*/
+
+#ifndef __GENUTILS_H__
+#define __GENUTILS_H__
+
+
+#include "common.h"
+
+
+/*
+ * The various GEN_xxxxx macros handle which functions
+ * should be included in the gen.c source. We are going to use
+ * our own functions here so, they must be commentted out from
+ * gen.c
+ */
+
+#define GEN_Not
+void pic16_genNot(iCode *ic);
+
+#define GEN_Cpl
+void pic16_genCpl(iCode *ic);
+
+
+/*
+ * global function definitions
+ */
+void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
+
+
+#endif /* __GENUTILS_H__ */
#include "ralloc.h"
#include "pcode.h"
#include "newalloc.h"
+#include "device.h"
+#include "main.h"
#ifdef WORDS_BIGENDIAN
static void printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb);
extern int noAlloc;
extern set *publics;
+extern set *externs;
extern unsigned maxInterrupts;
extern int maxRegBank;
extern symbol *mainf;
extern void printChar (FILE * ofile, char *s, int plen);
void pic16_pCodeInitRegisters(void);
+pCodeOp *pic16_popGetLit(unsigned int lit);
+pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2);
+pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
+pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst);
/*-----------------------------------------------------------------*/
/* aopLiteral - string from a literal value */
}
-
/*-----------------------------------------------------------------*/
/* emitRegularMap - emit code for maps with no special cases */
/*-----------------------------------------------------------------*/
symbol *sym;
int i, size, bitvars = 0;;
+// fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
+
if (addPublics)
+
fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
/* print the area name */
sym = setNextItem (map->syms))
{
- /* if extern then do nothing */
- if (IS_EXTERN (sym->etype))
+#if 0
+ fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
+ printTypeChain( sym->type, stderr );
+ printf("\n");
+#endif
+
+ /* if extern then add to externs */
+ if (IS_EXTERN (sym->etype)) {
+ addSetHead(&externs, sym);
continue;
+ }
/* if allocation required check is needed
then check if the symbol really requires
/* if global variable & not static or extern
and addPublics allowed then add it to the public set */
- if ((sym->level == 0 ||
+ if ((sym->used) && (sym->level == 0 ||
(sym->_isparm && !IS_REGPARM (sym->etype))) &&
addPublics &&
!IS_STATIC (sym->etype))
then do nothing */
if (IS_FUNC (sym->type))
continue;
+
#if 0
/* print extra debug info if required */
if (options.debug || sym->level == 0)
{
- cdbSymbol (sym, cdbFile, FALSE, FALSE);
+ cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
if (!sym->level) /* global */
if (IS_STATIC (sym->etype))
}
#endif
+ /* FIXME -- VR
+ * The equates are nice, but do not allow relocatable objects to
+ * be created in the form that I (VR) want to make SDCC to work */
+
/* if is has an absolute address then generate
an equate for this no need to allocate space */
if (SPEC_ABSA (sym->etype))
{
//if (options.debug || sym->level == 0)
- //fprintf (map->oFile,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
+// fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
+// sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
sym->rname,
SPEC_ADDR (sym->etype));
+
+#if 1
+ /* emit only if it is global */
+ if(sym->level == 0) {
+ regs *reg;
+ operand *op;
+
+// fprintf(stderr, "%s: implicit add of symbol = %s\n", __FUNCTION__, sym->name);
+ op = operandFromSymbol( sym );
+ reg = pic16_allocDirReg( op );
+ if(reg) {
+ //continue;
+
+ checkAddReg(&pic16_fix_udata, reg);
+ /* and add to globals list */
+ addSetHead(&publics, sym);
+ }
+ }
+#endif
}
else
{
//fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
}
- /* if it has a initial value then do it only if
+
+ /* FIXME -- VR Fix the following, so that syms to be placed
+ * in the idata section and let linker decide about their fate */
+
+ /* if it has an initial value then do it only if
it is a global variable */
+// if(sym->ival && sym->level == 0)
+
+
+#if 1
if (sym->ival && sym->level == 0) {
ast *ival = NULL;
-
+
+// if(SPEC_OCLS(sym->etype)==data) {
+// fprintf(stderr, "%s: sym %s placed in data\n", map->sname, sym->name);
+// }
+
+// fprintf(stderr, "'%s': sym '%s' has initial value\n", map->sname, sym->name);
+
if (IS_AGGREGATE (sym->type))
ival = initAggregates (sym, sym->ival, NULL);
else
eBBlockFromiCode (iCodeFromAst (ival));
sym->ival = NULL;
}
+#endif
}
}
for (sym = setFirstItem (map->syms); sym;
sym = setNextItem (map->syms))
{
+
+#if 1
+ fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
+ printTypeChain( sym->type, stderr );
+ printf("\n");
+#endif
+
+
/* if it is "extern" then do nothing */
if (IS_EXTERN (sym->etype))
continue;
static void
pic16createInterruptVect (FILE * vFile)
{
- unsigned i = 0;
mainf = newSymbol ("main", 0);
mainf->block = 0;
return;
}
-/*
- * update started by Vangelis Rokas on 19-Jun-2003
- * all fprintf() calls are prefixed with ';' so they seem
- * as comments to the assembler. I (VR) removed them */
-
-// fprintf (vFile, "\t.area\t%s\n", CODE_NAME);
- fprintf(vFile, "\tcode\t0x0000\n");
- fprintf (vFile, "__interrupt_vect:\n");
-
-
- if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
- {
- /* "generic" interrupt table header (if port doesn't specify one).
+ if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
+ fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
+ fprintf(vFile, ".intvecs\tcode\t0x0000\n");
+ fprintf (vFile, "__interrupt_vect:\n");
- * Look suspiciously like 8051 code to me...
- */
-
- fprintf (vFile, ";\tljmp\t__sdcc_gsinit_startup\n");
-
-
- /* now for the other interrupts */
- for (; i < maxInterrupts; i++)
- {
- if (interrupts[i])
- fprintf (vFile, ";\tljmp\t%s\n;\t.ds\t5\n", interrupts[i]->rname);
- else
- fprintf (vFile, ";\treti\n;\t.ds\t7\n");
+ /* this is an overkill since WE are the port,
+ * and we know if we have a genIVT function! */
+ if(port->genIVT) {
+ port->genIVT(vFile, interrupts, maxInterrupts);
+ }
}
- }
+
}
}
/*-----------------------------------------------------------------*/
-/* printPublics - generates .global for publics */
+/* printPublics - generates global declarations for publics */
/*-----------------------------------------------------------------*/
static void
pic16printPublics (FILE * afile)
{
symbol *sym;
- fprintf (afile, "%s", iComments2);
- fprintf (afile, "; publics variables in this module\n");
- fprintf (afile, "%s", iComments2);
+ fprintf (afile, "%s", iComments2);
+ fprintf (afile, "; publics variables in this module\n");
+ fprintf (afile, "%s", iComments2);
- for (sym = setFirstItem (publics); sym;
- sym = setNextItem (publics))
- fprintf (afile, ";\t.globl %s\n", sym->rname);
+ for (sym = setFirstItem (publics); sym; sym = setNextItem (publics))
+ fprintf(afile, "\tglobal %s\n", sym->rname);
}
+/*-----------------------------------------------------------------*/
+/* printExterns - generates extern declarations for externs */
+/*-----------------------------------------------------------------*/
+static void
+pic16_printExterns(FILE *afile)
+{
+ symbol *sym;
+ fprintf(afile, "%s", iComments2);
+ fprintf(afile, "; extern variables to this module\n");
+ fprintf(afile, "%s", iComments2);
+
+ for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
+ fprintf(afile, "\textern %s\n", sym->rname);
+}
/*-----------------------------------------------------------------*/
/* emitOverlay - will emit code for the overlay stuff */
}
}
+#if STACK_SUPPORT
+ if(USE_STACK) {
+ pBlock *pb = pic16_newpCodeChain(NULL, 'X', pic16_newpCodeCharP("; Setup stack & frame register"));
+
+ pic16_addpBlock(pb);
+ pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, pic16_popGetLit2(1, stackPos)));
+ pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, pic16_popGetLit2(2, stackPos)));
+
+ }
+#endif
+
/* At this point we've got all the code in the form of pCode structures */
/* Now it needs to be rearranged into the order it should be placed in the */
/* PENDING: this isnt the best place but it will do */
if (port->general.glue_up_main) {
/* create the interrupt vector table */
- pic16createInterruptVect (vFile);
+
+ pic16createInterruptVect (vFile);
}
addSetHead(&tmpfileSet,vFile);
pic16_AnalyzepCode('*');
- //#ifdef PCODE_DEBUG
- //pic16_printCallTree(stderr);
- //#endif
+#if 0
+ {
+ FILE *cFile;
+ sprintf(buffer, dstFileName);
+ strcat(buffer, ".calltree");
+ cFile = fopen(buffer, "w");
+ pic16_printCallTree( cFile );
+ fclose(cFile);
+ }
+#endif
pic16_InlinepCode();
-
pic16_AnalyzepCode('*');
-
pic16_pcode_test();
-
/* now put it all together into the assembler file */
/* create the assembler file name */
port->genAssemblerPreamble(asmFile);
}
+ /* print the extern variables to this module */
+ pic16_printExterns(asmFile);
+
/* print the global variables in this module */
pic16printPublics (asmFile);
-
+#if 0
/* copy the sfr segment */
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; special function registers\n");
fprintf (asmFile, "%s", iComments2);
copyFile (asmFile, sfr->oFile);
+#endif
/* Put all variables into a cblock */
fprintf (asmFile, "; Stack segment in internal ram \n");
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
- ";__start__stack:\n;\t.ds\t1\n\n");
+ ";__start__stack:\n;\t.ds\t1\n\n");
}
+#if 0
+ /* no indirect data in pic */
/* create the idata segment */
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; indirectly addressable internal ram data\n");
fprintf (asmFile, "%s", iComments2);
copyFile (asmFile, idata->oFile);
-
+#endif
+
+
+#if 0
+ /* no xdata in pic */
/* if external stack then reserve space of it */
if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
fprintf (asmFile,";\t.ds 256\n");
}
-
-
+#endif
+
+#if 0
+ /* no xdata in pic */
/* copy xtern ram data */
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; external ram data\n");
fprintf (asmFile, "%s", iComments2);
copyFile (asmFile, xdata->oFile);
-
+#endif
/* copy the bit segment */
fprintf (asmFile, "%s", iComments2);
/* the following is commented out. the CODE directive will be
used instead before code */
-
// fprintf (asmFile, "\tORG 0\n");
/* copy the interrupt vector table */
fprintf (asmFile, "; global & static initialisations\n");
fprintf (asmFile, "%s", iComments2);
+#if 0
+ /* FIXME 8051 Legacy -- VR */
/* Everywhere we generate a reference to the static_name area,
* (which is currently only here), we immediately follow it with a
* definition of the post_static_name area. This guarantees that
fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
+#endif
if (mainf && IFFUNC_HASBODY(mainf->type)) {
fprintf (asmFile,"__sdcc_gsinit_startup:\n");
#if 0
- /* 8051 legacy (?!) - VR 20-Jun-2003 */
+ /* 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
}
+ /* copy over code */
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "\tcode\n");
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
+
if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
{
/* This code is generated in the post-static area.
* This area is guaranteed to follow the static area
* by the ugly shucking and jiving about 20 lines ago.
*/
- fprintf(asmFile, ";\t.area %s\n", port->mem.post_static_name);
+// fprintf(asmFile, ";\t.area %s\n", port->mem.post_static_name);
fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
}
- /* copy over code */
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; code\n");
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
//copyFile (stderr, code->oFile);
-// fprintf(asmFile, "; I code from now on!\n");
+ fprintf(asmFile, "; I code from now on!\n");
pic16_copypCode(asmFile, 'I');
fprintf(asmFile, "; X code from now on!\n");
pic16_copypCode(asmFile, 'X');
+
fprintf(asmFile, "; M code from now on!\n");
pic16_copypCode(asmFile, 'M');
+
pic16_copypCode(asmFile, code->dbName);
+
pic16_copypCode(asmFile, 'P');
fprintf (asmFile,"\tend\n");
};
+pic16_sectioninfo_t pic16_sectioninfo;
+
+
extern char *pic16_processor_base_name(void);
void pic16_pCodeInitRegisters(void);
static int regParmFlg = 0; /* determine if we can register a parameter */
+pic16_options_t pic16_options;
+
static void
_pic16_init (void)
{
- asm_addTree (&asm_asxxxx_mapping);
- pic16_pCodeInitRegisters();
- maxInterrupts = 2;
+ asm_addTree (&asm_asxxxx_mapping);
+ pic16_pCodeInitRegisters();
+ maxInterrupts = 2;
+
+
+ /* set pic16 port options to defaults */
+ pic16_options.gen_banksel = 0;
+ pic16_options.opt_banksel = 0;
+ pic16_options.omit_configw = 0;
+ pic16_options.omit_ivt = 0;
+ pic16_options.leave_reset = 0;
+ pic16_options.enable_stack = 0;
+ pic16_options.stack_model = 0; /* 0 for 'small', 1 for 'large' */
}
static void
return 1;
}
+
static int
_process_pragma(const char *sz)
{
static const char *WHITE = " \t";
char *ptr = strtok((char *)sz, WHITE);
- if (startsWith (ptr, "memmap"))
- {
- char *start;
- char *end;
- char *type;
- char *alias;
-
- start = strtok((char *)NULL, WHITE);
- end = strtok((char *)NULL, WHITE);
- type = strtok((char *)NULL, WHITE);
- alias = strtok((char *)NULL, WHITE);
-
- if (start != (char *)NULL
- && end != (char *)NULL
- && type != (char *)NULL) {
- value *startVal = constVal(start);
- value *endVal = constVal(end);
- value *aliasVal;
- memRange r;
-
- if (alias == (char *)NULL) {
- aliasVal = constVal(0);
- } else {
- aliasVal = constVal(alias);
+ if (startsWith (ptr, "maxram")) {
+ char *maxRAM = strtok((char *)NULL, WHITE);
+
+ if (maxRAM != (char *)NULL) {
+ int maxRAMaddress;
+ value *maxRAMVal;
+
+ maxRAMVal = constVal(maxRAM);
+ maxRAMaddress = (int)floatFromVal(maxRAMVal);
+ pic16_setMaxRAM(maxRAMaddress);
+ }
}
+
+ if(startsWith(ptr, "stack")) {
+ char *stackPosS = strtok((char *)NULL, WHITE);
+ value *stackPosVal;
- r.start_address = (int)floatFromVal(startVal);
- r.end_address = (int)floatFromVal(endVal);
- r.alias = (int)floatFromVal(aliasVal);
- r.bank = (r.start_address >> 7) & 0xf;
-
- if (strcmp(type, "RAM") == 0) {
- pic16_addMemRange(&r, 0);
- } else if (strcmp(type, "SFR") == 0) {
- pic16_addMemRange(&r, 1);
- } else {
- return 1;
+// fprintf(stderr, "Initializing stack pointer to 0x%x\n", (int)floatFromVal(constVal(stackPos)));
+ stackPosVal = constVal( stackPosS );
+ stackPos = (unsigned int)floatFromVal( stackPosVal );
}
- }
- return 0;
- } else if (startsWith (ptr, "maxram")) {
- char *maxRAM = strtok((char *)NULL, WHITE);
+ return 0;
+}
+
+#define REP_UDATA "--preplace-udata-with="
+#define REP_UDATAACS "--preplace-udata-acs-with="
+#define REP_UDATAOVR "--preplace-udata-ovr-with="
+#define REP_UDATASHR "--preplace-udata-sht-with="
+
+#define NAME_CODE "--psection-code-name="
+#define NAME_IDATA "--psection-idata-name="
+#define NAME_UDATA "--psection-udata-name="
+#define NAME_UDATAACS "--psection-udata-acs-name="
+#define NAME_UDATAOVR "--psection-udata-ovr-name="
+#define NAME_UDATASHR "--psection-udata-shr-name="
- if (maxRAM != (char *)NULL) {
- int maxRAMaddress;
- value *maxRAMVal;
+#define ADDR_CODE "--psection-code-addr="
+#define ADDR_IDATA "--psection-idata-addr="
+#define ADDR_UDATA "--psection-udata-addr="
+#define ADDR_UDATAACS "--psection-udata-acs-addr="
+#define ADDR_UDATAOVR "--psection-udata-ovr-addr="
+#define ADDR_UDATASHR "--psection-udata-shr-addr="
- maxRAMVal = constVal(maxRAM);
- maxRAMaddress = (int)floatFromVal(maxRAMVal);
- pic16_setMaxRAM(maxRAMaddress);
- }
+#define STACK_MODEL "--pstack-model="
+#define OPT_BANKSEL "--obanksel="
+
+
+extern int pic16_debug_verbose;
+
+OPTION pic16_optionsTable[]= {
+ { 0, "--pgen-banksel", &pic16_options.gen_banksel, "generate BANKSEL assembler directives"},
+ { 0, OPT_BANKSEL, NULL, "set banksel optimization level (default=0 no)"},
+ { 0, "--pomit-config-words", &pic16_options.omit_configw, "omit the generation of configuration words"},
+ { 0, "--pomit-ivt", &pic16_options.omit_ivt, "omit the generation of the Interrupt Vector Table"},
+ { 0, "--pleave-reset-vector",&pic16_options.leave_reset, "when omitting IVT leave RESET vector"},
+ { 0, "--penable-stack", &pic16_options.enable_stack, "enable the use of stack"},
+ { 0, STACK_MODEL, NULL, "use stack model 'small' (default) or 'large'"},
+
+ { 0, "--debug-xtra", &pic16_debug_verbose, "show more debug info in assembly output"},
+ { 0, REP_UDATA, NULL, "Place udata variables at another section: udata_acs, udata_ovr, udata_shr"},
+
+#if 0
+ /* these may not be in any use -- VR */
+ { 0, AT_UDATAACS, NULL, "Emit udata_acs variables at another section"},
+ { 0, AT_UDATAOVR, NULL, "Emit udata_ovr variables at another section"},
+ { 0, AT_UDATASHR, NULL, "Emit udata_shr variables at another section"},
+#endif
+
+#if 0
+ /* commented out for the time being -- VR */
+ { 0, NAME_CODE, NULL, "Set code section name[,address]"},
+ { 0, NAME_IDATA, NULL, "Set idata section name[,address]"},
+ { 0, NAME_UDATA, NULL, "Set udata section name[,address]"},
+ { 0, NAME_UDATAACS, NULL, "Set udata_acs section name[,address]"},
+ { 0, NAME_UDATAOVR, NULL, "Set udata_ovr section name[,address]"},
+ { 0, NAME_UDATASHR, NULL, "Set udata_shr section name[,address]"},
- return 0;
- }
- return 1;
-}
+ { 0, ADDR_CODE, NULL, "Set code section address"},
+ { 0, ADDR_IDATA, NULL, "Set idata section address"},
+ { 0, ADDR_UDATA, NULL, "Set udata section address"},
+ { 0, ADDR_UDATAACS, NULL, "Set udata_acs section address"},
+ { 0, ADDR_UDATAOVR, NULL, "Set udata_ovr section address"},
+ { 0, ADDR_UDATASHR, NULL, "Set udata_shr section address"},
+#endif
+
+ { 0, NULL, NULL, NULL}
+ };
+
+
+#define ISOPT(str) !strncmp(argv[ *i ], str, strlen(str) )
+
+extern char *getStringArg(const char *, char **, int *, int);
+extern int getIntArg(const char *, char **, int *, int);
static bool
_pic16_parseOptions (int *pargc, char **argv, int *i)
{
+ int j=0;
+// set *tset;
+
/* TODO: allow port-specific command line options to specify
* segment names here.
*/
+ /* check for arguments that have associated an integer variable */
+ while(pic16_optionsTable[j].pparameter) {
+ if(ISOPT( pic16_optionsTable[j].longOpt )) {
+ (*pic16_optionsTable[j].pparameter)++;
+ return TRUE;
+ }
+ j++;
+ }
+
+
+ if(ISOPT(STACK_MODEL)) {
+ switch(*getStringArg(STACK_MODEL, argv, i, *pargc)) {
+ case 's': pic16_options.stack_model = 0; break;
+ case 'l': pic16_options.stack_model = 1; break;
+
+ default:
+ fprintf(stderr, "Unknown stack model");
+ exit(-1);
+ }
+ return TRUE;
+ }
+
+ if(ISOPT(OPT_BANKSEL)) {
+ pic16_options.opt_banksel = getIntArg(OPT_BANKSEL, argv, i, *pargc);
+ return TRUE;
+ }
+
+ if(ISOPT(REP_UDATA)) {
+ pic16_sectioninfo.at_udata = Safe_strdup(getStringArg(REP_UDATA, argv, i, *pargc));
+ return TRUE;
+ }
+
+/*
+ if(ISOPT(AT_UDATAACS)) {
+ pic16_sectioninfo.at_udataacs = Safe_strdup( getStringArg(AT_UDATAACS, argv, i, *pargc));
+ return TRUE;
+ }
+
+ if(ISOPT(AT_UDATAOVR)) {
+ pic16_sectioninfo.at_udataovr = Safe_strdup( getStringArg(AT_UDATAOVR, argv, i, *pargc));
+ return TRUE;
+ }
+
+ if(ISOPT(AT_UDATASHR)) {
+ pic16_sectioninfo.at_udatashr = Safe_strdup( getStringArg(AT_UDATASHR, argv, i, *pargc));
+ return TRUE;
+ }
+*/
+
+#if 0
+ if(ISOPT(ADDR_CODE)) {
+ pic16_sectioninfo.addr_code = getIntArg(ADDR_CODE, argv, i, *pargc);
+ return TRUE;
+ }
+
+ if(ISOPT(ADDR_IDATA)) {
+ pic16_sectioninfo.addr_idata = getIntArg(ADDR_IDATA, argv, i, *pargc);
+ return TRUE;
+ }
+
+ if(ISOPT(ADDR_UDATA)) {
+ pic16_sectioninfo.addr_udata = getIntArg(ADDR_UDATA, argv, i, *pargc);
+ return TRUE;
+ }
+
+ if(ISOPT(ADDR_UDATAACS)) {
+ pic16_sectioninfo.addr_udataacs = getIntArg(ADDR_UDATAACS, argv, i, *pargc);
+ return TRUE;
+ }
+
+ if(ISOPT(ADDR_UDATAOVR)) {
+ pic16_sectioninfo.addr_udataovr = getIntArg(ADDR_UDATAOVR, argv, i, *pargc);
+ return TRUE;
+ }
+
+ if(ISOPT(ADDR_UDATASHR)) {
+ pic16_sectioninfo.addr_udatashr = getIntArg(ADDR_UDATASHR, argv, i, *pargc);
+ return TRUE;
+ }
+
+ tset = newSet();
+
+ if(ISOPT(NAME_CODE)) {
+ setParseWithComma(&tset, getStringArg(NAME_CODE, argv, i, *pargc));
+ if(elementsInSet(tset) > 0)
+ pic16_sectioninfo.name_code = Safe_strdup( (char *)indexSet(tset, 0));
+ if(elementsInSet(tset) > 1)
+ pic16_sectioninfo.addr_code = atoi( (char *)indexSet(tset, 1));
+ return TRUE;
+ }
+
+ if(ISOPT(NAME_IDATA)) {
+ setParseWithComma(&tset, getStringArg(NAME_IDATA, argv, i, *pargc));
+ if(elementsInSet(tset) > 0)
+ pic16_sectioninfo.name_idata = Safe_strdup( (char *)indexSet(tset, 0));
+ if(elementsInSet(tset) > 1)
+ pic16_sectioninfo.addr_idata = atoi( (char *)indexSet(tset, 1));
+ return TRUE;
+ }
+
+ if(ISOPT(NAME_UDATA)) {
+ setParseWithComma(&tset, getStringArg(NAME_UDATA, argv, i, *pargc));
+ if(elementsInSet(tset) > 0)
+ pic16_sectioninfo.name_udata = Safe_strdup( (char *)indexSet(tset, 0));
+ if(elementsInSet(tset) > 1)
+ pic16_sectioninfo.addr_udata = atoi( (char *)indexSet(tset, 1));
+ return TRUE;
+ }
+
+ if(ISOPT(NAME_UDATAACS)) {
+ setParseWithComma(&tset, getStringArg(NAME_UDATAACS, argv, i, *pargc));
+ if(elementsInSet(tset) > 0)
+ pic16_sectioninfo.name_udataacs = Safe_strdup( (char *)indexSet(tset, 0));
+ if(elementsInSet(tset) > 1)
+ pic16_sectioninfo.addr_udataacs = atoi( (char *)indexSet(tset, 1));
+ return TRUE;
+ }
+
+ if(ISOPT(NAME_UDATAOVR)) {
+ setParseWithComma(&tset, getStringArg(NAME_UDATAOVR, argv, i, *pargc));
+ if(elementsInSet(tset) > 0)
+ pic16_sectioninfo.name_udataovr = Safe_strdup( (char *)indexSet(tset, 0));
+ if(elementsInSet(tset) > 1)
+ pic16_sectioninfo.addr_udataovr = atoi( (char *)indexSet(tset, 1));
+ return TRUE;
+ }
+
+ if(ISOPT(NAME_UDATASHR)) {
+ setParseWithComma(&tset, getStringArg(NAME_UDATASHR, argv, i, *pargc));
+ if(elementsInSet(tset) > 0)
+ pic16_sectioninfo.name_udatashr = Safe_strdup( (char *)indexSet(tset, 0));
+ if(elementsInSet(tset) > 1)
+ pic16_sectioninfo.addr_udatashr = atoi( (char *)indexSet(tset, 1));
+ return TRUE;
+ }
+
+ deleteSet( &tset );
+#endif
+
return FALSE;
}
static void
_pic16_setDefaultOptions (void)
{
+ /* initialize to defaults section locations, names and addresses */
+ pic16_sectioninfo.at_udata = "udata";
+ pic16_sectioninfo.at_udataacs = "udata_acs";
+ pic16_sectioninfo.at_udataovr = "udata_ovr";
+ pic16_sectioninfo.at_udatashr = "udata_shr";
+
+ /* initialize to nothing, so let linker decide about their names */
+ pic16_sectioninfo.name_code =
+ pic16_sectioninfo.name_idata =
+ pic16_sectioninfo.name_udata =
+ pic16_sectioninfo.name_udataacs =
+ pic16_sectioninfo.name_udataovr =
+ pic16_sectioninfo.name_udatashr = "";
+
+ /* initialize to -1, so let linker decide about their address */
+ pic16_sectioninfo.addr_code =
+ pic16_sectioninfo.addr_idata =
+ pic16_sectioninfo.addr_udata =
+ pic16_sectioninfo.addr_udataacs =
+ pic16_sectioninfo.addr_udataovr =
+ pic16_sectioninfo.addr_udatashr = -1;
}
static const char *
}
-static void
-_pic16_genAssemblerPreamble (FILE * of)
+#if 0
+static char *_pic16_mangleFunctionName(char *sz)
{
- char * name = pic16_processor_base_name();
+ fprintf(stderr, "mangled function name: %s\n", sz);
- if(!name) {
+ return sz;
+}
+#endif
- name = "p18f452";
- fprintf(stderr,"WARNING: No Pic has been selected, defaulting to %s\n",name);
- }
- fprintf (of, "\tlist\tp=%s\n",&name[1]);
- fprintf (of, "\tinclude \"%s.inc\"\n",name);
+static void
+_pic16_genAssemblerPreamble (FILE * of)
+{
+ char *name = pic16_processor_base_name();
- fprintf (of, "\t__config _CONFIG1H,0x%x\n",pic16_getConfigWord(0x300001));
- fprintf (of, "\t__config _CONFIG2L,0x%x\n",pic16_getConfigWord(0x300002));
- fprintf (of, "\t__config _CONFIG2H,0x%x\n",pic16_getConfigWord(0x300003));
- fprintf (of, "\t__config _CONFIG3H,0x%x\n",pic16_getConfigWord(0x300005));
- fprintf (of, "\t__config _CONFIG4L,0x%x\n",pic16_getConfigWord(0x300006));
- fprintf (of, "\t__config _CONFIG5L,0x%x\n",pic16_getConfigWord(0x300008));
- fprintf (of, "\t__config _CONFIG5H,0x%x\n",pic16_getConfigWord(0x300009));
- fprintf (of, "\t__config _CONFIG6L,0x%x\n",pic16_getConfigWord(0x30000a));
- fprintf (of, "\t__config _CONFIG6H,0x%x\n",pic16_getConfigWord(0x30000b));
- fprintf (of, "\t__config _CONFIG7L,0x%x\n",pic16_getConfigWord(0x30000c));
- fprintf (of, "\t__config _CONFIG7H,0x%x\n",pic16_getConfigWord(0x30000d));
+ if(!name) {
+ name = "p18f452";
+ fprintf(stderr,"WARNING: No Pic has been selected, defaulting to %s\n",name);
+ }
+ fprintf (of, "\tlist\tp=%s\n",&name[1]);
+
+ if(!pic16_options.omit_configw) {
+ fprintf (of, "\t__config 0x%x,0x%x\n", 0x300001, pic16_getConfigWord(0x300001));
+ fprintf (of, "\t__config 0x%x,0x%x\n", 0x300002, pic16_getConfigWord(0x300002));
+ fprintf (of, "\t__config 0x%x,0x%x\n", 0x300003, pic16_getConfigWord(0x300003));
+ fprintf (of, "\t__config 0x%x,0x%x\n", 0x300005, pic16_getConfigWord(0x300005));
+ fprintf (of, "\t__config 0x%x,0x%x\n", 0x300006, pic16_getConfigWord(0x300006));
+ fprintf (of, "\t__config 0x%x,0x%x\n", 0x300008, pic16_getConfigWord(0x300008));
+ fprintf (of, "\t__config 0x%x,0x%x\n", 0x300009, pic16_getConfigWord(0x300009));
+ fprintf (of, "\t__config 0x%x,0x%x\n", 0x30000a, pic16_getConfigWord(0x30000a));
+ fprintf (of, "\t__config 0x%x,0x%x\n", 0x30000b, pic16_getConfigWord(0x30000b));
+ fprintf (of, "\t__config 0x%x,0x%x\n", 0x30000c, pic16_getConfigWord(0x30000c));
+ fprintf (of, "\t__config 0x%x,0x%x\n", 0x30000d, pic16_getConfigWord(0x30000d));
+ }
+
fprintf (of, "\tradix dec\n");
}
static int
_pic16_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
{
-#if 0
- int i;
-#endif
-
-#if 0
- if (options.model != MODEL_FLAT24) {
- /* Let the default code handle it. */
- return FALSE;
- }
-#endif
-
/* PIC18F family has only two interrupts, the high and the low
* priority interrupts, which reside at 0x0008 and 0x0018 respectively - VR */
- fprintf(of, "; RESET vector\n");
- fprintf(of, "\tgoto\t__sdcc_gsinit_startup\n");
- fprintf(of, "\tres 4\n");
-
-
- fprintf(of, "; High priority interrupt vector 0x0008\n");
- if(interrupts[1]) {
- fprintf(of, "\tgoto\t%s\n", interrupts[1]->rname);
- fprintf(of, "\tres\t12\n");
- } else {
- fprintf(of, "\tretfie\n");
- fprintf(of, "\tres\t14\n");
+ if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
+ fprintf(of, "; RESET vector\n");
+ fprintf(of, "\tgoto\t__sdcc_gsinit_startup\n");
}
-
- fprintf(of, "; Low priority interrupt vector 0x0018\n");
- if(interrupts[2]) {
- fprintf(of, "\tgoto\t%s\n", interrupts[2]->rname);
- } else {
- fprintf(of, "\tretfie\n");
- }
-#if 0
- /* now for the other interrupts */
- for (i = 0; i < maxInterrupts; i++)
- {
- fprintf(of, "; %s priority interrupt vector 0x%s\n", (i==0)?"high":"low", (i==0)?"0008":"0018");
- if (interrupts[i])
- {
- fprintf (of, "\tgoto\t%s\n\tres\t4\n", interrupts[i]->rname);
- }
- else
- {
- fprintf (of, "\tretfie\n\tres\t7\n");
+
+ if(!pic16_options.omit_ivt) {
+ fprintf(of, "\tres 4\n");
+
+
+ fprintf(of, "; High priority interrupt vector 0x0008\n");
+ if(interrupts[1]) {
+ fprintf(of, "\tgoto\t%s\n", interrupts[1]->rname);
+ fprintf(of, "\tres\t12\n");
+ } else {
+ fprintf(of, "\tretfie\n");
+ fprintf(of, "\tres\t14\n");
+ }
+
+ fprintf(of, "; Low priority interrupt vector 0x0018\n");
+ if(interrupts[2]) {
+ fprintf(of, "\tgoto\t%s\n", interrupts[2]->rname);
+ } else {
+ fprintf(of, "\tretfie\n");
+ }
}
- }
-#endif
return TRUE;
}
TARGET_ID_PIC16,
"pic16",
"MCU PIC16", /* Target name */
- "p18f442", /* Processor */
+ "p18f452", /* Processor */
{
pic16glue,
TRUE, /* Emit glue around main */
MODEL_SMALL
},
{
- _asmCmd,
- NULL,
- NULL,
- NULL,
- //"-plosgffc", /* Options with debug */
- //"-plosgff", /* Options without debug */
- 0,
- ".asm",
+ _asmCmd, /* assembler command and arguments */
+ NULL, /* alternate macro based form */
+ NULL, /* arguments for debug mode */
+ NULL, /* arguments for normal mode */
+ 0, /* print externs as global */
+ ".asm", /* assembler file extension */
NULL /* no do_assemble function */
},
{
- _linkCmd,
- NULL,
- NULL,
- ".rel"
+ _linkCmd, /* linker command and arguments */
+ NULL, /* alternate macro based form */
+ NULL, /* no do_link function */
+ ".rel" /* extension for object files */
},
{
_defaultRules
},
{
- /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
- 1, 2, 2, 4, 2, 2, 2, 1, 4, 4
- /* TSD - I changed the size of gptr from 3 to 1. However, it should be
- 2 so that we can accomodate the PIC's with 4 register banks (like the
- 16f877)
- */
+ /* Sizes */
+ 1, /* char */
+ 2, /* short */
+ 2, /* int */
+ 4, /* long */
+ 2, /* ptr */
+ 2, /* fptr, this should be changed to 3 for far pointers (see Microchip) */
+ 2, /* gptr */
+ 1, /* bit */
+ 4, /* float */
+ 4 /* max */
},
{
"XSEG (XDATA)", // xstack
NULL, // xinit
NULL, // default location for auto vars
NULL, // default location for global vars
- 1 // code is read only
+ 1 // code is read only 1=yes
+ },
+ {
+ NULL, /* genExtraAreaDeclaration */
+ NULL /* genExatrAreaLinkOptions */
},
- { NULL, NULL },
{
- +1, 1, 4, 1, 1, 0
+ /* stack related information */
+ -1, /* -1 stack grows downwards, +1 upwards */
+ 1, /* extra overhead when calling between banks */
+ 4, /* extra overhead when the function is an ISR */
+ 1, /* extra overhead for a function call */
+ 1, /* re-entrant space */
+ 0 /* 'banked' call overhead, mild overlap with bank_overhead */
},
/* pic16 has an 8 bit mul */
{
"_",
_pic16_init,
_pic16_parseOptions,
- NULL,
+ pic16_optionsTable,
_pic16_finaliseOptions,
_pic16_setDefaultOptions,
pic16_assignRegisters,
_pic16_reset_regparm,
_pic16_regparm,
_process_pragma, /* process a pragma */
- NULL,
+ NULL, //_pic16_mangleFunctionName, /* mangles function name */
_hasNativeMulFor,
hasExtBitOp, /* hasExtBitOp */
oclsExpense, /* oclsExpense */
- FALSE,
+ FALSE,
TRUE, /* little endian */
0, /* leave lt */
0, /* leave gt */
void x_setDefaultOptions (void);
void x_finaliseOptions (void);
+
+typedef struct {
+ char *at_udata;
+ char *at_udataacs;
+ char *at_udataovr;
+ char *at_udatashr;
+
+ char *name_code;
+ char *name_idata;
+ char *name_udata;
+ char *name_udataacs;
+ char *name_udataovr;
+ char *name_udatashr;
+
+ unsigned int addr_code;
+ unsigned int addr_idata;
+ unsigned int addr_udata;
+ unsigned int addr_udataacs;
+ unsigned int addr_udataovr;
+ unsigned int addr_udatashr;
+} pic16_sectioninfo_t;
+
#endif
// Eventually this will go into device dependent files:
pCodeOpReg pic16_pc_status = {{PO_STATUS, "_STATUS"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_indf0 = {{PO_INDF0, "_INDF0"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_fsr0 = {{PO_FSR0, "_FSR0"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_intcon = {{PO_INTCON, ""}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_pcl = {{PO_PCL, "_PCL"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_indf0 = {{PO_INDF0, "INDF0"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_fsr0 = {{PO_FSR0, "FSR0"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_intcon = {{PO_INTCON, "_INTCON"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_pcl = {{PO_PCL, "PCL"}, -1, NULL,0,NULL};
pCodeOpReg pic16_pc_pclath = {{PO_PCLATH, "_PCLATH"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_wreg = {{PO_WREG, "_WREG"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_bsr = {{PO_BSR, "_BSR"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_wreg = {{PO_WREG, "WREG"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_bsr = {{PO_BSR, "BSR"}, -1, NULL,0,NULL};
+
+pCodeOpReg pic16_pc_fsr1l = {{PO_FSR0, "FSR1L"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_fsr1h = {{PO_FSR0, "FSR1H"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_fsr2l = {{PO_FSR0, "FSR2L"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_fsr2h = {{PO_FSR0, "FSR2H"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_postinc1 = {{PO_FSR0, "POSTINC1"}, -1, NULL, 0, NULL};
+
+pCodeOpReg pic16_pc_plusw2 = {{PO_FSR0, "PLUSW2"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_preinc2 = {{PO_FSR0, "PREINC1"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_postdec1 = {{PO_FSR0, "POSTDEV1"}, -1, NULL, 0, NULL};
pCodeOpReg pic16_pc_kzero = {{PO_GPR_REGISTER, "KZ"}, -1, NULL,0,NULL};
pCodeOpReg pic16_pc_wsave = {{PO_GPR_REGISTER, "WSAVE"}, -1, NULL,0,NULL};
/* Hardcoded flags to change the behavior of the PIC port */
static int peepOptimizing = 1; /* run the peephole optimizer if nonzero */
static int functionInlining = 1; /* inline functions if nonzero */
-int pic16_debug_verbose = 1; /* Set true to inundate .asm file */
+int pic16_debug_verbose = 0; /* Set true to inundate .asm file */
//static int GpCodeSequenceNumber = 1;
static int GpcFlowSeq = 1;
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- (PCC_REGISTER | PCC_Z) // outCond
+ (PCC_REGISTER | PCC_Z), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciADDFW = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- (PCC_W | PCC_Z) // outCond
+ (PCC_W | PCC_Z), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciADDWFC = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
- (PCC_REGISTER | PCC_Z) // outCond
+ (PCC_REGISTER | PCC_Z), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciADDFWC = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
- (PCC_W | PCC_Z) // outCond
+ (PCC_W | PCC_Z), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciADDLW = {
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_LITERAL), // inCond
- (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+ (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciANDLW = {
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_LITERAL), // inCond
- (PCC_W | PCC_Z | PCC_N) // outCond
+ (PCC_W | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciANDWF = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+ (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciANDFW = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_W | PCC_Z) // outCond
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_REL_ADDR | PCC_C), // inCond
- PCC_NONE // outCond
+ PCC_NONE, // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciBCF = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_BSF,
(PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
- PCC_REGISTER // outCond
+ PCC_REGISTER, // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciBN = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_REL_ADDR | PCC_N), // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciBNC = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_REL_ADDR | PCC_C), // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciBNN = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_REL_ADDR | PCC_N), // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciBNOV = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_REL_ADDR | PCC_OV), // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciBNZ = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_REL_ADDR | PCC_Z), // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciBOV = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_REL_ADDR | PCC_OV), // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciBRA = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REL_ADDR, // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciBSF = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_BCF,
(PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
- (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond
+ (PCC_REGISTER | PCC_EXAMINE_PCOP), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciBTFSC = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_BTFSS,
(PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
- PCC_EXAMINE_PCOP // outCond
+ PCC_EXAMINE_PCOP, // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciBTFSS = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_BTFSC,
(PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
- PCC_EXAMINE_PCOP // outCond
+ PCC_EXAMINE_PCOP, // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciBTG = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
- (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond
+ (PCC_REGISTER | PCC_EXAMINE_PCOP), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciBZ = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_Z, // inCond
- PCC_NONE // outCond
+ PCC_NONE, // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciCALL = {
0, // RAM access bit
1, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_NONE, // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciCOMF = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_REGISTER // outCond
+ PCC_REGISTER , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciCOMFW = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_W // outCond
+ PCC_W , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciCLRF = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_REGISTER // outCond
+ PCC_REGISTER , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciCLRWDT = {
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_NONE, // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciCPFSEQ = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciCPFSGT = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciCPFSLT = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciDAW = {
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_W, // inCond
- (PCC_W | PCC_C) // outCond
+ (PCC_W | PCC_C), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciDCFSNZ = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_REGISTER // outCond
+ PCC_REGISTER , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciDCFSNZW = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_W // outCond
+ PCC_W , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciDECF = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_REGISTER // outCond
+ PCC_REGISTER , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciDECFW = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_W // outCond
+ PCC_W , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciDECFSZ = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_REGISTER // outCond
+ PCC_REGISTER , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciDECFSZW = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_W // outCond
+ PCC_W , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciGOTO = {
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REL_ADDR, // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciINCF = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- (PCC_REGISTER | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond
+ (PCC_REGISTER | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciINCFW = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_W // outCond
+ PCC_W , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciINCFSZ = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_REGISTER // outCond
+ PCC_REGISTER , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciINCFSZW = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_W // outCond
+ PCC_W , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciINFSNZ = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_REGISTER // outCond
+ PCC_REGISTER , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciIORWF = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+ (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciIORFW = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- (PCC_W | PCC_Z | PCC_N) // outCond
+ (PCC_W | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciIORLW = {
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_LITERAL), // inCond
- (PCC_W | PCC_Z | PCC_N) // outCond
+ (PCC_W | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciLFSR = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 1, // second literal operand
POC_NOP,
- (PCC_REGISTER | PCC_LITERAL), // mdubuc - Should we use a special syntax for
- // f (identifies FSRx)?
- PCC_REGISTER // outCond
+ (PCC_REGISTER | PCC_LITERAL),
+ PCC_REGISTER, // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciMOVF = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- (PCC_Z | PCC_N) // outCond
+ (PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciMOVFW = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- (PCC_W | PCC_Z) // outCond
+ (PCC_W | PCC_Z), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciMOVFF = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
1, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_REGISTER2 // outCond
+ PCC_REGISTER2, // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciMOVLB = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_NONE | PCC_LITERAL), // inCond
- PCC_REGISTER // outCond - BSR
+ PCC_REGISTER, // outCond - BSR
+ PCI_MAGIC
};
pCodeInstruction pic16_pciMOVLW = {
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_NONE | PCC_LITERAL), // inCond
- PCC_W // outCond
+ PCC_W, // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciMOVWF = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_W // outCond
+ PCC_W, // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciMULLW = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_LITERAL), // inCond
- PCC_REGISTER // outCond - PROD
+ PCC_REGISTER, // outCond - PROD
+ PCI_MAGIC
};
pCodeInstruction pic16_pciMULWF = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- PCC_REGISTER // outCond - PROD
+ PCC_REGISTER, // outCond - PROD
+ PCI_MAGIC
};
pCodeInstruction pic16_pciNEGF = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- (PCC_REGISTER | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+ (PCC_REGISTER | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciNOP = {
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_NONE, // inCond
- PCC_NONE // outCond
+ PCC_NONE, // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciPOP = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_NONE, // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciPUSH = {
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_NONE, // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciRCALL = { // mdubuc - New
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REL_ADDR, // inCond
- PCC_NONE // outCond
+ PCC_NONE , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciRETFIE = {
0, // RAM access bit
1, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_NONE, // inCond
- PCC_NONE // outCond (not true... affects the GIE bit too)
+ PCC_NONE, // outCond (not true... affects the GIE bit too)
+ PCI_MAGIC
};
pCodeInstruction pic16_pciRETLW = {
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_LITERAL, // inCond
- PCC_W // outCond
+ PCC_W, // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciRETURN = {
0, // RAM access bit
1, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_NONE, // inCond
- PCC_NONE // outCond
+ PCC_NONE, // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciRLCF = { // mdubuc - New
{PC_OPCODE, NULL, NULL, 0, NULL,
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
- (PCC_REGISTER | PCC_C | PCC_Z | PCC_N) // outCond
+ (PCC_REGISTER | PCC_C | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciRLCFW = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
- (PCC_W | PCC_C | PCC_Z | PCC_N) // outCond
+ (PCC_W | PCC_C | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciRLNCF = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+ (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciRLNCFW = { // mdubuc - New
{PC_OPCODE, NULL, NULL, 0, NULL,
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- (PCC_W | PCC_Z | PCC_N) // outCond
+ (PCC_W | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciRRCF = { // mdubuc - New
{PC_OPCODE, NULL, NULL, 0, NULL,
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
- (PCC_REGISTER | PCC_C | PCC_Z | PCC_N) // outCond
+ (PCC_REGISTER | PCC_C | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciRRCFW = { // mdubuc - New
{PC_OPCODE, NULL, NULL, 0, NULL,
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
- (PCC_W | PCC_C | PCC_Z | PCC_N) // outCond
+ (PCC_W | PCC_C | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciRRNCF = { // mdubuc - New
{PC_OPCODE, NULL, NULL, 0, NULL,
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+ (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciRRNCFW = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- (PCC_W | PCC_Z | PCC_N) // outCond
+ (PCC_W | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciSETF = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_REGISTER // outCond
+ PCC_REGISTER , // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciSUBLW = {
0, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_LITERAL), // inCond
- (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond
+ (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciSUBFWB = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
- (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond
+ (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciSUBWF = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- (PCC_REGISTER | PCC_Z) // outCond
+ (PCC_REGISTER | PCC_Z), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciSUBFW = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- (PCC_W | PCC_Z | PCC_OV | PCC_N) // outCond
+ (PCC_W | PCC_Z | PCC_OV | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciSUBFWB_D1 = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
- (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+ (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciSUBFWB_D0 = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
- (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+ (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciSUBWFB_D1 = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
- (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+ (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciSUBWFB_D0 = { // mdubuc - New
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER | PCC_C), // inCond
- (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+ (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciSWAPF = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_REGISTER), // inCond
- (PCC_REGISTER) // outCond
+ (PCC_REGISTER), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciSWAPFW = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_REGISTER), // inCond
- (PCC_W) // outCond
-};
-
-
-#if 0
-// mdubuc - Remove TRIS
-
-pCodeInstruction pic16_pciTRIS = {
- {PC_OPCODE, NULL, NULL, 0, NULL,
- // genericAnalyze,
- genericDestruct,
- genericPrint},
- POC_TRIS,
- "TRIS",
- NULL, // from branch
- NULL, // to branch
- NULL, // label
- NULL, // operand
- NULL, // flow block
- NULL, // C source
- 1, // num ops
- 0,0, // dest, bit instruction
- 0,0, // branch, skip
- 0, // literal operand
- 0, // second memory operand
- POC_NOP,
- PCC_NONE, // inCond
- PCC_REGISTER // outCond
+ (PCC_W), // outCond
+ PCI_MAGIC
};
-#endif
pCodeInstruction pic16_pciTSTFSZ = { // mdubuc - New
{PC_OPCODE, NULL, NULL, 0, NULL,
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_NONE // outCond
+ PCC_NONE, // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciXORWF = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+ (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciXORFW = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- (PCC_W | PCC_Z | PCC_N) // outCond
+ (PCC_W | PCC_Z | PCC_N), // outCond
+ PCI_MAGIC
};
pCodeInstruction pic16_pciXORLW = {
1, // RAM access bit
0, // fast call/return mode select bit
0, // second memory operand
+ 0, // second literal operand
POC_NOP,
(PCC_W | PCC_LITERAL), // inCond
- (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_N) // outCond
+ (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_N), // outCond
+ PCI_MAGIC
};
{
static int initialized=0;
- if(initialized)
- return;
- initialized = 1;
-
- pic16_initStack(0xfff, 8);
- pic16_init_pic(port->processor);
-
- pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"_STATUS", PO_STATUS, 0x80);
- pic16_pc_pcl.r = pic16_allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80);
- pic16_pc_pclath.r = pic16_allocProcessorRegister(IDX_PCLATH,"_PCLATH", PO_PCLATH, 0x80);
- pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"FSR0", PO_FSR0, 0x80);
- pic16_pc_indf0.r = pic16_allocProcessorRegister(IDX_INDF0,"INDF0", PO_INDF0, 0x80);
- pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"INTCON", PO_INTCON, 0x80);
- pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"WREG", PO_WREG, 0x80);
-
- pic16_pc_status.rIdx = IDX_STATUS;
- pic16_pc_fsr0.rIdx = IDX_FSR0;
- pic16_pc_indf0.rIdx = IDX_INDF0;
- pic16_pc_intcon.rIdx = IDX_INTCON;
- pic16_pc_pcl.rIdx = IDX_PCL;
- pic16_pc_pclath.rIdx = IDX_PCLATH;
- pic16_pc_wreg.rIdx = IDX_WREG;
-
- pic16_pc_kzero.r = pic16_allocInternalRegister(IDX_KZ,"KZ",PO_GPR_REGISTER,0);
- pic16_pc_ssave.r = pic16_allocInternalRegister(IDX_SSAVE,"SSAVE", PO_GPR_REGISTER, 0x80);
- pic16_pc_wsave.r = pic16_allocInternalRegister(IDX_WSAVE,"WSAVE", PO_GPR_REGISTER, 0);
-
- pic16_pc_kzero.rIdx = IDX_KZ;
- pic16_pc_wsave.rIdx = IDX_WSAVE;
- pic16_pc_ssave.rIdx = IDX_SSAVE;
-
- /* probably should put this in a separate initialization routine */
- pb_dead_pcodes = newpBlock();
+ if(initialized)
+ return;
+
+ initialized = 1;
+
+ pic16_initStack(0xfff, 8);
+ pic16_init_pic(port->processor);
+
+ pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"_STATUS", PO_STATUS, 0x00);
+ pic16_pc_pcl.r = pic16_allocProcessorRegister(IDX_PCL,"_PCL", PO_PCL, 0x80);
+ pic16_pc_pclath.r = pic16_allocProcessorRegister(IDX_PCLATH,"_PCLATH", PO_PCLATH, 0x80);
+ pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"_FSR0", PO_FSR0, 0x80);
+ pic16_pc_indf0.r = pic16_allocProcessorRegister(IDX_INDF0,"_INDF0", PO_INDF0, 0x80);
+ pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"_INTCON", PO_INTCON, 0x80);
+ pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"_WREG", PO_WREG, 0x80);
+
+ pic16_pc_fsr1l.r = pic16_allocProcessorRegister(IDX_FSR1L, "_FSR1L", PO_FSR0, 0x80);
+ pic16_pc_fsr1h.r = pic16_allocProcessorRegister(IDX_FSR1H, "_FSR1H", PO_FSR0, 0x80);
+ pic16_pc_fsr2l.r = pic16_allocProcessorRegister(IDX_FSR2L, "_FSR2L", PO_FSR0, 0x80);
+ pic16_pc_fsr2h.r = pic16_allocProcessorRegister(IDX_FSR2H, "_FSR2H", PO_FSR0, 0x80);
+ pic16_pc_postinc1.r = pic16_allocProcessorRegister(IDX_POSTINC1, "_POSTINC1", PO_FSR0, 0x80);
+ pic16_pc_postdec1.r = pic16_allocProcessorRegister(IDX_POSTDEC1, "_POSTDEC1", PO_FSR0, 0x80);
+ pic16_pc_preinc2.r = pic16_allocProcessorRegister(IDX_PREINC2, "_PREINC2", PO_FSR0, 0x80);
+ pic16_pc_plusw2.r = pic16_allocProcessorRegister(IDX_PLUSW2, "_PLUSW2", PO_FSR0, 0x80);
+
+ pic16_pc_status.rIdx = IDX_STATUS;
+ pic16_pc_fsr0.rIdx = IDX_FSR0;
+ pic16_pc_indf0.rIdx = IDX_INDF0;
+ pic16_pc_intcon.rIdx = IDX_INTCON;
+ pic16_pc_pcl.rIdx = IDX_PCL;
+ pic16_pc_pclath.rIdx = IDX_PCLATH;
+ pic16_pc_wreg.rIdx = IDX_WREG;
+ pic16_pc_fsr1l.rIdx = IDX_FSR1L;
+ pic16_pc_fsr1h.rIdx = IDX_FSR1H;
+ pic16_pc_fsr2l.rIdx = IDX_FSR2L;
+ pic16_pc_fsr2h.rIdx = IDX_FSR2H;
+ pic16_pc_postinc1.rIdx = IDX_POSTINC1;
+ pic16_pc_postdec1.rIdx = IDX_POSTDEC1;
+ pic16_pc_preinc2.rIdx = IDX_PREINC2;
+ pic16_pc_plusw2.rIdx = IDX_PLUSW2;
+
+ pic16_pc_kzero.r = pic16_allocInternalRegister(IDX_KZ,"KZ",PO_GPR_REGISTER,0);
+ pic16_pc_ssave.r = pic16_allocInternalRegister(IDX_SSAVE,"SSAVE", PO_GPR_REGISTER, 0x80);
+ pic16_pc_wsave.r = pic16_allocInternalRegister(IDX_WSAVE,"WSAVE", PO_GPR_REGISTER, 0);
+
+ pic16_pc_kzero.rIdx = IDX_KZ;
+ pic16_pc_wsave.rIdx = IDX_WSAVE;
+ pic16_pc_ssave.rIdx = IDX_SSAVE;
+
+ /* probably should put this in a separate initialization routine */
+ pb_dead_pcodes = newpBlock();
}
pic16Mnemonics[POC_SUBFWB_D1] = &pic16_pciSUBFWB_D1;
pic16Mnemonics[POC_SWAPF] = &pic16_pciSWAPF;
pic16Mnemonics[POC_SWAPFW] = &pic16_pciSWAPFW;
-// pic16Mnemonics[POC_TRIS] = &pic16_pciTRIS;
pic16Mnemonics[POC_TSTFSZ] = &pic16_pciTSTFSZ;
pic16Mnemonics[POC_XORLW] = &pic16_pciXORLW;
pic16Mnemonics[POC_XORWF] = &pic16_pciXORWF;
{
pBlock *pb;
+
+ /* this can happen in sources without code,
+ * only variable definitions */
+ if(!the_pFile)return;
+
pb = the_pFile->pbHead;
while(pb) {
{
pBlock *pb;
- if(!of || !the_pFile)
- return;
+ if(!of || !the_pFile)
+ return;
- for(pb = the_pFile->pbHead; pb; pb = pb->next) {
- if(getpBlock_dbName(pb) == dbName) {
- pBlockStats(of,pb);
- pic16_printpBlock(of,pb);
- }
- }
+ for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+ if(getpBlock_dbName(pb) == dbName) {
+// fprintf(stderr, "%s:%d: output of pb= 0x%p\n", __FILE__, __LINE__, pb);
+ pBlockStats(of,pb);
+ pic16_printpBlock(of,pb);
+ }
+ }
}
void pic16_pcode_test(void)
char buffer[256]; // how long can a directive be?!
char *lbp=buffer;
-
- pcad = Safe_calloc(1, sizeof(pCodeAsmDir));
+ pcad = Safe_alloc(/*1, */sizeof(pCodeAsmDir));
pcad->pc.type = PC_ASMDIR;
pcad->pc.prev = pcad->pc.next = NULL;
pcad->pc.pb = NULL;
if(s)
pcl->label = Safe_strdup(s);
- //fprintf(stderr,"pic16_newpCodeLabel: key=%d, name=%s\n",key, ((s)?s:""));
return ( (pCode *)pcl);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
-pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space)
+pCodeOp *pic16_newpCodeOpLit2(int lit, int lit2)
{
+ char *s = buffer;
pCodeOp *pcop;
- pcop = Safe_calloc(1,sizeof(pCodeOpImmd) );
- pcop->type = PO_IMMEDIATE;
- if(name) {
- regs *r = pic16_dirregWithName(name);
- pcop->name = Safe_strdup(name);
- PCOI(pcop)->r = r;
- if(r) {
- //fprintf(stderr, " pic16_newpCodeOpImmd reg %s exists\n",name);
- PCOI(pcop)->rIdx = r->rIdx;
- } else {
- //fprintf(stderr, " pic16_newpCodeOpImmd reg %s doesn't exist\n",name);
- PCOI(pcop)->rIdx = -1;
- }
- //fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset);
- } else {
- pcop->name = NULL;
+
+ pcop = Safe_calloc(1,sizeof(pCodeOpLit2) );
+ pcop->type = PO_LITERAL;
+
+ pcop->name = NULL;
+ if(lit>=0 && lit2>=0) {
+ sprintf(s,"0x%02x,0x%02x",lit, lit2);
+ if(s)
+ pcop->name = Safe_strdup(s);
}
- PCOI(pcop)->index = index;
- PCOI(pcop)->offset = offset;
- PCOI(pcop)->_const = code_space;
+ ((pCodeOpLit2 *)pcop)->lit = lit;
+ ((pCodeOpLit2 *)pcop)->lit2 = lit2;
+
+ return pcop;
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space)
+{
+ pCodeOp *pcop;
+
+ pcop = Safe_calloc(1,sizeof(pCodeOpImmd) );
+ pcop->type = PO_IMMEDIATE;
+ if(name) {
+ regs *r = pic16_dirregWithName(name);
+ pcop->name = Safe_strdup(name);
+ PCOI(pcop)->r = r;
+
+ if(r) {
+// fprintf(stderr, " pic16_newpCodeOpImmd reg %s exists\n",name);
+ PCOI(pcop)->rIdx = r->rIdx;
+ } else {
+ fprintf(stderr, " pic16_newpCodeOpImmd reg %s doesn't exist\n",name);
+ PCOI(pcop)->rIdx = -1;
+ }
+// fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset);
+ } else {
+ pcop->name = NULL;
+ }
+
+ PCOI(pcop)->index = index;
+ PCOI(pcop)->offset = offset;
+ PCOI(pcop)->_const = code_space;
return pcop;
}
if(PCOR(pcop)->r)
PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
+ else {
+ fprintf(stderr, "%s:%d Could not find a free GPR register\n",
+ __FUNCTION__, __LINE__);
+ exit(-1);
+ }
}
pcop->type = PCOR(pcop)->r->pc_type;
-#if 0
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static void pBlockRegs(FILE *of, pBlock *pb)
-{
-
- regs *r;
-
- r = setFirstItem(pb->tregisters);
- while (r) {
- r = setNextItem(pb->tregisters);
- }
-}
-#endif
-
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size)
}
/*-----------------------------------------------------------------*/
+/* pic16_pCode2str - convert a pCode instruction to string */
/*-----------------------------------------------------------------*/
-static char *pCode2str(char *str, size_t size, pCode *pc)
+static char *pic16_pCode2str(char *str, size_t size, pCode *pc)
{
char *s = str;
+ regs *r;
+
+ if(PCI(pc)->pci_magic != PCI_MAGIC) {
+ fprintf(stderr, "%s:%d: pCodeInstruction initialization error in instruction %s\n",
+ __FILE__, __LINE__, PCI(pc)->mnemonic);
+ exit(-1);
+ }
switch(pc->type) {
break;
}
+ if(PCI(pc)->is2LitOp) {
+ SAFE_snprintf(&s,&size, "%s", PCOP(PCI(pc)->pcop)->name);
+ break;
+ }
+
if(PCI(pc)->isBitInst) {
if(PCI(pc)->pcop->type == PO_GPR_BIT) {
if( (((pCodeOpRegBit *)(PCI(pc)->pcop))->inBitSpace) )
}else {
SAFE_snprintf(&s,&size,"%s",pic16_get_op_from_instruction(PCI(pc)));
- if( PCI(pc)->num_ops == 3)
- SAFE_snprintf(&s,&size,",%c", ( (PCI(pc)->isModReg) ? 'F':'W'));
+ if( PCI(pc)->num_ops == 3 || ((PCI(pc)->num_ops == 2) && (PCI(pc)->isAccess))) {
+ if(PCI(pc)->num_ops == 3)
+ SAFE_snprintf(&s,&size,", %c", ( (PCI(pc)->isModReg) ? 'F':'W'));
+
+ r = pic16_getRegFromInstruction(pc);
+// fprintf(stderr, "%s:%d reg = %p\tname= %s, accessBank= %d\n",
+// __FUNCTION__, __LINE__, r, (r)?r->name:"<null>", (r)?r->accessBank:-1);
+
+ if(r && !r->accessBank)SAFE_snprintf(&s,&size,", %s", "B");
+ }
}
}
{
char str[256];
- pCode2str(str, 256, pc);
+ pic16_pCode2str(str, 256, pc);
fprintf(of,"%s",str);
/* Debug */
if(pic16_debug_verbose) {
- fprintf(of, "\t;key=%03x %d",pc->seq, __LINE__);
+ fprintf(of, "\t;key=%03x",pc->seq);
if(PCI(pc)->pcflow)
- fprintf(of,",flow seq=%03x",PCI(pc)->pcflow->pc.seq);
+ fprintf(of,", flow seq=%03x",PCI(pc)->pcflow->pc.seq);
}
}
fprintf(of, "\n");
break;
-#if 0
- {
- pBranch *dpb = pc->to; // debug
- while(dpb) {
- switch ( dpb->pc->type) {
- case PC_OPCODE:
- fprintf(of, "\t;%s", PCI(dpb->pc)->mnemonic);
- break;
- case PC_LABEL:
- fprintf(of, "\t;label %d", PCL(dpb->pc)->key);
- break;
- case PC_FUNCTION:
- fprintf(of, "\t;function %s", ( (PCF(dpb->pc)->fname) ? (PCF(dpb->pc)->fname) : "[END]"));
- break;
- case PC_FLOW:
- fprintf(of, "\t;flow");
- break;
- case PC_COMMENT:
- case PC_WILD:
- break;
- }
- dpb = dpb->next;
- }
- }
-#endif
-// fprintf(of,"\n"); // these are moved prior to #if 0
-// break;
-
case PC_WILD:
fprintf(of,";\tWild opcode: id=%d\n",PCW(pc)->id);
if(PCW(pc)->pci.label)
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:"");
+ {
+ pBranch *pbl = PCAD(pc)->label;
+ while(pbl && pbl->pc) {
+ if(pbl->pc->type == PC_LABEL)
+ pCodePrintLabel(of, pbl->pc);
+ pbl = pbl->next;
+ }
+ }
+ fprintf(of, "\t%s\t%s\n", PCAD(pc)->directive, PCAD(pc)->arg?PCAD(pc)->arg:"");
break;
case PC_LABEL:
return;
if(PCL(pc)->label)
- fprintf(of,"%s\n",PCL(pc)->label);
+ fprintf(of,"%s:\n",PCL(pc)->label);
else if (PCL(pc)->key >=0)
fprintf(of,"_%05d_DS_:\n",PCL(pc)->key);
else
case PO_BIT:
case PO_GPR_TEMP:
- //fprintf(stderr, "pic16_getRegFromInstruction - bit or temp\n");
+// fprintf(stderr, "pic16_getRegFromInstruction - bit or temp\n");
return PCOR(PCI(pc)->pcop)->r;
case PO_IMMEDIATE:
return PCOR(PCI(pc)->pcop)->r;
case PO_DIR:
- //fprintf(stderr, "pic16_getRegFromInstruction - dir\n");
+// fprintf(stderr, "pic16_getRegFromInstruction - dir\n");
return PCOR(PCI(pc)->pcop)->r;
case PO_LITERAL:
//fprintf(stderr, "pic16_getRegFromInstruction - literal\n");
return 0;
}
-/*-----------------------------------------------------------------*/
-/* BanksUsedFlow - Identify which banks are used in flow 2. */
-/*-----------------------------------------------------------------*/
-static void BanksUsedFlow2(pCode *pcflow)
-{
- pCode *pc=NULL;
-
- int bank = -1;
- bool RegUsed = 0;
-
- regs *reg;
-
- if(!isPCFL(pcflow)) {
- fprintf(stderr, "BanksUsed - pcflow is not a flow object ");
- return;
- }
-
- pc = pic16_findNextInstruction(pcflow->next);
-
- PCFL(pcflow)->lastBank = -1;
-
- while(pic16_isPCinFlow(pc,pcflow)) {
-
- int bank_selected = isBankInstruction(pc);
-
- //if(PCI(pc)->pcflow)
- //fprintf(stderr,"BanksUsedFlow2, looking at seq %d\n",PCI(pc)->pcflow->pc.seq);
-
- if(bank_selected >= 0) {
- //fprintf(stderr,"BanksUsed - mucking with bank %d\n",bank_selected);
-
- /* This instruction is modifying banking bits before accessing registers */
- if(!RegUsed)
- PCFL(pcflow)->firstBank = -1;
-
- if(PCFL(pcflow)->lastBank == -1)
- PCFL(pcflow)->lastBank = 0;
-
- bank = 1 << bank_selected;
- PCFL(pcflow)->lastBank |= bank;
-
-
- } else {
- reg = pic16_getRegFromInstruction(pc);
-
- if(reg && !pic16_isREGinBank(reg, bank)) {
- int allbanks = pic16_REGallBanks(reg);
- if(bank == -1)
- PCFL(pcflow)->firstBank = allbanks;
-
- PCFL(pcflow)->lastBank = allbanks;
-
- bank = allbanks;
- }
- RegUsed = 1;
- }
-
- pc = pic16_findNextInstruction(pc->next);
- }
-
-// fprintf(stderr,"BanksUsedFlow2 flow seq=%3d, first bank = 0x%03x, Last bank 0x%03x\n",
-// pcflow->seq,PCFL(pcflow)->firstBank,PCFL(pcflow)->lastBank);
-
-
-
-}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static void BanksUsedFlow(pBlock *pb)
-{
- pCode *pcflow;
-
-
- //pb->pcHead->print(stderr, pb->pcHead);
-
- pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
- //pcflow->print(stderr,pcflow);
-
- for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
- pcflow != NULL;
- pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
- BanksUsedFlow2(pcflow);
- }
-}
/*-----------------------------------------------------------------*/
* bank at linking time
*/
- if(!options.gen_banksel || bsr != -1) {
+ if(!pic16_options.gen_banksel || bsr != -1) {
// new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(bsr));
return;
} else {
/* emit the BANKSEL [symbol] */
+ /* FIXME */
/* IMPORTANT: The following code does not check if a symbol is
* split in multiple banks. This should be corrected. - VR 6/6/2003 */
pc->print(stderr, pc);
#endif
- if(position) {
- /* insert the bank switch after this pc instruction */
- pCode *pcnext = pic16_findNextInstruction(pc);
- pic16_pCodeInsertAfter(pc, new_pc);
- if(pcnext)
- pc = pcnext;
+ if(position) {
+ /* insert the bank switch after this pc instruction */
+ pCode *pcnext = pic16_findNextInstruction(pc);
+ pic16_pCodeInsertAfter(pc, new_pc);
+ if(pcnext)
+ pc = pcnext;
- } else
- pic16_pCodeInsertAfter(pc->prev, new_pc);
+ } else
+ pic16_pCodeInsertAfter(pc->prev, new_pc);
/* Move the label, if there is one */
- if(PCI(pc)->label) {
- PCI(new_pc)->label = PCI(pc)->label;
- PCI(pc)->label = NULL;
- }
-
- /* The new instruction has the same pcflow block */
- PCI(new_pc)->pcflow = PCI(pc)->pcflow;
-
-}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static void FixRegisterBankingInFlow(pCodeFlow *pcfl, int cur_bank)
-{
- pCode *pc=NULL;
- pCode *pcprev=NULL;
- pCode *new_pc;
-
- regs *reg;
-
- if(!pcfl)
- return;
-
- pc = pic16_findNextInstruction(pcfl->pc.next);
-
- while(pic16_isPCinFlow(pc,PCODE(pcfl))) {
-
- reg = pic16_getRegFromInstruction(pc);
-
-#if 1
- if(reg) {
- fprintf(stderr, "%s:%d %s ",__FUNCTION__, __LINE__, reg->name);
- fprintf(stderr, "addr = 0x%03x, bank = %d\n",reg->address,REG_BANK(reg));
-
- }
-#endif
-
- if( ( (reg && !isACCESS_BANK(reg) && REG_BANK(reg)!=cur_bank) ||
- ((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) /* && !isBankInstruction(pcprev)*/)) {
- int reg_bank;
-
- reg_bank = (reg) ? REG_BANK(reg) : 0;
-
-
- if (cur_bank != reg_bank) {
- //fprintf(stderr, "Cool! can switch banks\n");
- cur_bank = reg_bank;
- insertBankSwitch(0, pc, cur_bank);
+ if(PCI(pc)->label) {
+// fprintf(stderr, "%s:%d: moving label due to bank switch directive src= 0x%p dst= 0x%p\n",
+// __FILE__, __LINE__, pc, new_pc);
+ PCAD(new_pc)->label = PCI(pc)->label;
+ PCI(pc)->label = NULL;
}
- } else {
- //fprintf(stderr, "Bummer can't switch banks\n");
- ;
- }
- }
-
- pcprev = pc;
- pc = pic16_findNextInstruction(pc->next);
-
- }
-
- if(pcprev && cur_bank) {
- /* Brute force - make sure that we point to bank 0 at the
- * end of each flow block */
- new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(0));
- pic16_pCodeInsertAfter(pcprev, new_pc);
- cur_bank = 0;
- //fprintf(stderr, "Brute force switch\n");
- }
-
+// fprintf(stderr, "BankSwitch has been inserted\n");
}
+
/*-----------------------------------------------------------------*/
/*int compareBankFlow - compare the banking requirements between */
/* flow objects. */
return 1;
}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static void FixBankFlow(pBlock *pb)
-{
- pCode *pc=NULL;
- pCode *pcflow;
- pCodeFlowLink *pcfl;
-
- pCode *pcflow_max_To=NULL;
- pCode *pcflow_max_From=NULL;
- int max_ToConflicts=0;
- int max_FromConflicts=0;
-
- //fprintf(stderr,"Fix Bank flow \n");
- pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
-
-
- /*
- First loop through all of the flow objects in this pcode block
- and fix the ones that have banking conflicts between the
- entry and exit.
- */
-
-// fprintf(stderr, "FixBankFlow - Phase 1\n");
-
- for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
- pcflow != NULL;
- pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
-
- if(!isPCFL(pcflow)) {
- fprintf(stderr, "FixBankFlow - pcflow is not a flow object ");
- continue;
- }
-
- if(PCFL(pcflow)->firstBank != PCFL(pcflow)->lastBank &&
- PCFL(pcflow)->firstBank >= 0 &&
- PCFL(pcflow)->lastBank >= 0 ) {
-
- int cur_bank = (PCFL(pcflow)->firstBank < PCFL(pcflow)->lastBank) ?
- PCFL(pcflow)->firstBank : PCFL(pcflow)->lastBank;
-
- FixRegisterBankingInFlow(PCFL(pcflow),cur_bank);
- BanksUsedFlow2(pcflow);
-
- }
- }
-
-// fprintf(stderr, "FixBankFlow - Phase 2\n");
-
- for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
- pcflow != NULL;
- pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
-
- int nFlows;
- int nConflicts;
-
- if(!isPCFL(pcflow)) {
- fprintf(stderr, "FixBankFlow - pcflow is not a flow object ");
- continue;
- }
-
- PCFL(pcflow)->FromConflicts = 0;
- PCFL(pcflow)->ToConflicts = 0;
-
- nFlows = 0;
- nConflicts = 0;
-
- //fprintf(stderr, " FixBankFlow flow seq %d\n",pcflow->seq);
- pcfl = setFirstItem(PCFL(pcflow)->from);
- while (pcfl) {
-
- pc = PCODE(pcfl->pcflow);
-
- if(!isPCFL(pc)) {
- fprintf(stderr,"oops dumpflow - to is not a pcflow\n");
- pc->print(stderr,pc);
- }
-
- nConflicts += compareBankFlow(PCFL(pcflow), pcfl, 0);
- nFlows++;
-
- pcfl=setNextItem(PCFL(pcflow)->from);
- }
-
- if((nFlows >= 2) && nConflicts && (PCFL(pcflow)->firstBank>0)) {
- //fprintf(stderr, " From conflicts flow seq %d, nflows %d ,nconflicts %d\n",pcflow->seq,nFlows, nConflicts);
-
- FixRegisterBankingInFlow(PCFL(pcflow),0);
- BanksUsedFlow2(pcflow);
-
- continue; /* Don't need to check the flow from here - it's already been fixed */
- }
-
- nFlows = 0;
- nConflicts = 0;
-
- pcfl = setFirstItem(PCFL(pcflow)->to);
- while (pcfl) {
-
- pc = PCODE(pcfl->pcflow);
- if(!isPCFL(pc)) {
- fprintf(stderr,"oops dumpflow - to is not a pcflow\n");
- pc->print(stderr,pc);
- }
-
- nConflicts += compareBankFlow(PCFL(pcflow), pcfl, 1);
- nFlows++;
-
- pcfl=setNextItem(PCFL(pcflow)->to);
- }
-
- if((nFlows >= 2) && nConflicts &&(nConflicts != nFlows) && (PCFL(pcflow)->lastBank>0)) {
- //fprintf(stderr, " To conflicts flow seq %d, nflows %d ,nconflicts %d\n",pcflow->seq,nFlows, nConflicts);
-
- FixRegisterBankingInFlow(PCFL(pcflow),0);
- BanksUsedFlow2(pcflow);
- }
- }
-
- /*
- Loop through the flow objects again and find the ones with the
- maximum conflicts
- */
-
- for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
- pcflow != NULL;
- pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
-
- if(PCFL(pcflow)->ToConflicts > max_ToConflicts)
- pcflow_max_To = pcflow;
-
- if(PCFL(pcflow)->FromConflicts > max_FromConflicts)
- pcflow_max_From = pcflow;
- }
-/*
- if(pcflow_max_To)
- fprintf(stderr,"compare flow Max To conflicts: seq %d conflicts %d\n",
- PCFL(pcflow_max_To)->pc.seq,
- PCFL(pcflow_max_To)->ToConflicts);
-
- if(pcflow_max_From)
- fprintf(stderr,"compare flow Max From conflicts: seq %d conflicts %d\n",
- PCFL(pcflow_max_From)->pc.seq,
- PCFL(pcflow_max_From)->FromConflicts);
-*/
-}
#if 0
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
if(pc->type == PC_LABEL) {
- //fprintf(stderr," checking merging label %s\n",PCL(pc)->label);
- //fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
+// fprintf(stderr," checking merging label %s\n",PCL(pc)->label);
+// fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
+
if((pcnext = pic16_findNextInstruction(pc) )) {
// Unlink the pCode label from it's pCode chain
pic16_unlinkpCode(pc);
- //fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key);
+// fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key);
// And link it into the instruction's pBranch labels. (Note, since
// it's possible to have multiple labels associated with one instruction
// we must provide a means to accomodate the additional labels. Thus
// opposed to being a single member of the pCodeInstruction.)
//_ALLOC(pbr,sizeof(pBranch));
+#if 1
pbr = Safe_calloc(1,sizeof(pBranch));
pbr->pc = pc;
pbr->next = NULL;
PCI(pcnext)->label = pic16_pBranchAppend(PCI(pcnext)->label,pbr);
-
+#endif
} else {
fprintf(stderr, "WARNING: couldn't associate label %s with an instruction\n",PCL(pc)->label);
}
(pcop->type == PO_LITERAL) ||
(pcop->type == PO_STR) ))
PCOR(pcop)->r = PCOR(pc)->r; /* This is dangerous... */
- PCOR(pcop)->r->wasUsed = 1; // mark register as used
+ PCOR(pcop)->r->wasUsed = 1;
+
return pcop;
}
-
-#if 0
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-int InstructionRegBank(pCode *pc)
+/*----------------------------------------------------------------------*
+ * pic16_areRegsSame - check to see if the names of two registers match *
+ *----------------------------------------------------------------------*/
+int pic16_areRegsSame(regs *r1, regs *r2)
{
- regs *reg;
-
- if( (reg = pic16_getRegFromInstruction(pc)) == NULL)
- return -1;
-
- return REG_BANK(reg);
+ if(!strcmp(r1->name, r2->name))return 1;
+ return 0;
}
-#endif
+
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
{
pCode *pc=NULL;
pCode *pcprev=NULL;
+ regs *reg, *prevreg;
- int cur_bank;
- regs *reg;
+ if(!pb)
+ return;
- if(!pb)
- return;
+ pc = pic16_findNextpCode(pb->pcHead, PC_OPCODE);
+ if(!pc)
+ return;
- //pc = pic16_findNextpCode(pb->pcHead, PC_FLOW);
- pc = pic16_findNextpCode(pb->pcHead, PC_OPCODE);
- if(!pc)
- return;
- /* loop through all of the flow blocks with in one pblock */
+ /* loop through all of the flow blocks with in one pblock */
// fprintf(stderr,"%s:%d: Register banking\n", __FUNCTION__, __LINE__);
- cur_bank = 0;
+ prevreg = NULL;
do {
/* at this point, pc should point to a PC_FLOW object */
-
-
/* for each flow block, determine the register banking
requirements */
- // do {
if(isPCI(pc) && !PCI(pc)->is2MemOp) {
-// genericPrint(stderr, pc);
-
- reg = pic16_getRegFromInstruction(pc);
-#if 0
- if(reg) {
- 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 !defined(__BORLANDC__) && !defined(_MSC_VER)
- #warning Fix this if-conditional
-#else
- #pragma message( "warning Fix this if-conditional" )
-#endif
-*/
-
- /* the !(reg->rIdx==-1) is a temporary hack. It should be changed - VR 6-Jun-2003 */
- if( ( (reg /*&& !(reg->rIdx==-1)*/ && !isACCESS_BANK(reg) && (isBankInstruction(pc)==-1) && !(reg->alias == 0x80) )
- /*|| (PCI(pc)->op != POC_CALL)*/ )
- && (!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) /*&& !isBankInstruction(pcprev)*/)) {
- int reg_bank;
-
- reg_bank = (reg) ? REG_BANK(reg) : 0;
+ reg = pic16_getRegFromInstruction(pc);
#if 0
- fprintf(stderr, "%s:%d add bank = %d\n", __FUNCTION__, __LINE__, reg_bank);
- pc->print(stderr, pc);
+ fprintf(stderr, "reg = %p\n", reg);
+ if(reg) {
+ 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->address ].isSFR, reg->isFixed);
+ }
#endif
-// 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");
- ;
- }
- }
+ /* we can be 99% that within a pBlock, between two consequtive
+ * refernces to the same register, the extra banksel is needless */
+
+ if((reg && !isACCESS_BANK(reg) && (isBankInstruction(pc) == -1))
+ && (!isPCI_LIT(pc))
+ && (PCI(pc)->op != POC_CALL)
+
+ && ( ((pic16_options.opt_banksel>0)
+ && (!prevreg || (prevreg && !pic16_areRegsSame(reg, prevreg))))
+ || (!pic16_options.opt_banksel)
+ )
+ )
+ {
+ /* Examine the instruction before this one to make sure it is
+ * not a skip type instruction */
+ pcprev = findPrevpCode(pc->prev, PC_OPCODE);
+
+ /* FIXME: if previous is SKIP pCode, we should move the BANKSEL
+ * before SKIP, but we have to check if the SKIP uses BANKSEL, etc... */
+ if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) {
+ prevreg = reg;
+ insertBankSwitch(0, pc, (pic16_options.gen_banksel)?-1:0);
+ }
+ }
pcprev = pc;
}
pc = pc->next;
- // } while(pc && !(isPCFL(pc)));
-
-
}while (pc);
+#if 0
if(pcprev && cur_bank) {
int pos = 1; /* Assume that the bank switch instruction(s)
/* Brute force - make sure that we point to bank 0 at the
* end of each flow block */
- insertBankSwitch(pos, pcprev, 0);
+// insertBankSwitch(pos, pcprev, 0);
/*
new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(0));
pic16_pCodeInsertAfter(pcprev, new_pc);
cur_bank = 0;
//fprintf(stderr, "Brute force switch\n");
}
-
-}
-
-
-
-
-#if 0
- if(reg && REG_BANK(reg)!=cur_bank) {
- //fprintf(stderr,"need to switch banks\n");
- /* 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))) {
- int b = cur_bank ^ REG_BANK(reg);
-
- cur_bank = REG_BANK(reg);
-
- switch(b & 3) {
- case 0:
- break;
- case 1:
- insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT);
- break;
- case 2:
- insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
- insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
- break;
- case 3:
- if(cur_bank & 3) {
- insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT);
- insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
- } else
- insertBankSwitch(0, pc, -1, -1);
- break;
-
- }
#endif
-
+}
static void pBlockDestruct(pBlock *pb)
static void AnalyzeFlow(int level)
{
static int times_called=0;
-
pBlock *pb;
- if(!the_pFile)
- return;
+ if(!the_pFile) {
+
+ /* remove unused allocated registers before exiting */
+ pic16_RemoveUnusedRegisters();
+
+ return;
+ }
/* if this is not the first time this function has been called,
then clean up old flow information */
- if(times_called++) {
- for(pb = the_pFile->pbHead; pb; pb = pb->next)
- unBuildFlow(pb);
-
- pic16_RegsUnMapLiveRanges();
+ if(times_called++) {
+ for(pb = the_pFile->pbHead; pb; pb = pb->next)
+ unBuildFlow(pb);
- }
+ pic16_RegsUnMapLiveRanges();
+ }
- GpcFlowSeq = 1;
+ GpcFlowSeq = 1;
/* Phase 2 - Flow Analysis - Register Banking
*
* a call or goto or whatever).
*/
- for(pb = the_pFile->pbHead; pb; pb = pb->next)
- pic16_BuildFlow(pb);
+ for(pb = the_pFile->pbHead; pb; pb = pb->next)
+ pic16_BuildFlow(pb);
/* Phase 2 - Flow Analysis - linking flow blocks
* to determine their order of excution.
*/
- for(pb = the_pFile->pbHead; pb; pb = pb->next)
- LinkFlow(pb);
+ for(pb = the_pFile->pbHead; pb; pb = pb->next)
+ LinkFlow(pb);
/* Phase 3 - Flow Analysis - Flow Tree
*
* In this phase, the individual flow blocks are examined
- * to determine their order of excution.
+ * to determine their order of execution.
*/
- for(pb = the_pFile->pbHead; pb; pb = pb->next)
- pic16_BuildFlowTree(pb);
+ for(pb = the_pFile->pbHead; pb; pb = pb->next)
+ pic16_BuildFlowTree(pb);
/* Phase x - Flow Analysis - Used Banks
* to determine the Register Banks they use
*/
- for(pb = the_pFile->pbHead; pb; pb = pb->next)
- FixBankFlow(pb);
+#if 0
+ for(pb = the_pFile->pbHead; pb; pb = pb->next)
+ FixBankFlow(pb);
+#endif
- for(pb = the_pFile->pbHead; pb; pb = pb->next)
- pic16_pCodeRegMapLiveRanges(pb);
+ for(pb = the_pFile->pbHead; pb; pb = pb->next)
+ pic16_pCodeRegMapLiveRanges(pb);
- pic16_RemoveUnusedRegisters();
+ pic16_RemoveUnusedRegisters();
// for(pb = the_pFile->pbHead; pb; pb = pb->next)
- pic16_pCodeRegOptimizeRegUsage(level);
+ pic16_pCodeRegOptimizeRegUsage(level);
if(!options.nopeep)
OptimizepCode('*');
-/*
- for(pb = the_pFile->pbHead; pb; pb = pb->next)
- DumpFlow(pb);
-*/
+#if 0
+ for(pb = the_pFile->pbHead; pb; pb = pb->next)
+ DumpFlow(pb);
+#endif
+
/* debug stuff */
- for(pb = the_pFile->pbHead; pb; pb = pb->next) {
- pCode *pcflow;
- for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
- (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
- pcflow = pcflow->next) {
+ for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+ pCode *pcflow;
+ for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
+ (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
+ pcflow = pcflow->next) {
+
+ FillFlow(PCFL(pcflow));
+ }
+ }
- FillFlow(PCFL(pcflow));
- }
- }
+#if 0
+ for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+ pCode *pcflow;
-/*
- for(pb = the_pFile->pbHead; pb; pb = pb->next) {
- pCode *pcflow;
- for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
- (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
- pcflow = pcflow->next) {
+ for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
+ (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
+ pcflow = pcflow->next) {
- FlowStats(PCFL(pcflow));
- }
- }
-*/
+ FlowStats(PCFL(pcflow));
+ }
+ }
+#endif
}
+/* VR -- no need to analyze banking in flow, but left here :
+ * 1. because it may be used in the future for other purposes
+ * 2. because if omitted we'll miss some optimization done here
+ *
+ * Perhaps I should rename it to something else
+ */
+
/*-----------------------------------------------------------------*/
/* pic16_AnalyzeBanking - Called after the memory addresses have been */
/* assigned to the registers. */
{
pBlock *pb;
- if(!pic16_picIsInitialized()) {
- fprintf(stderr,"Temporary ERROR: at the moment you have to use\n");
- fprintf(stderr,"an include file create by inc2h.pl. See SDCC source:\n");
- fprintf(stderr,"support/scripts/inc2h.pl\n");
- fprintf(stderr,"this is a nuisance bug that will be fixed shortly\n");
+ if(!pic16_picIsInitialized()) {
+ fprintf(stderr,"Temporary ERROR: at the moment you have to use\n");
+ fprintf(stderr,"an include file create by inc2h.pl. See SDCC source:\n");
+ fprintf(stderr,"support/scripts/inc2h.pl\n");
+ fprintf(stderr,"this is a nuisance bug that will be fixed shortly\n");
- exit(1);
- }
+ /* I think it took a long long time to fix this bug! ;-) -- VR */
- /* Phase x - Flow Analysis - Used Banks
- *
- * In this phase, the individual flow blocks are examined
- * to determine the Register Banks they use
- */
+ exit(1);
+ }
- AnalyzeFlow(0);
- AnalyzeFlow(1);
- for(pb = the_pFile->pbHead; pb; pb = pb->next)
- BanksUsedFlow(pb);
+ /* Phase x - Flow Analysis - Used Banks
+ *
+ * In this phase, the individual flow blocks are examined
+ * to determine the Register Banks they use
+ */
- for(pb = the_pFile->pbHead; pb; pb = pb->next)
- pic16_FixRegisterBanking(pb);
-}
+ AnalyzeFlow(0);
+ AnalyzeFlow(1);
+// for(pb = the_pFile->pbHead; pb; pb = pb->next)
+// BanksUsedFlow(pb);
+
+ if(!the_pFile)return;
+
+ for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+// fprintf(stderr, "%s:%d: Fix register banking in pb= 0x%p\n", __FILE__, __LINE__, pb);
+ pic16_FixRegisterBanking(pb);
+ }
+
+}
/*-----------------------------------------------------------------*/
/* buildCallTree - Look at the flow and extract all of the calls. */
pBranch *pbr;
- if(pcn && isPCF(pcn) && (PCF(pcn)->ncalled == 1)) {
+ if(pcn && isPCF(pcn) && (PCF(pcn)->ncalled == 0)) { /* change 0 to 1 to enable inlining */
//fprintf(stderr,"Cool can inline:\n");
//pcn->print(stderr,pcn);
int lit;
} pCodeOpLit;
+typedef struct pCodeOpLit2
+{
+ pCodeOp pcop;
+ int lit;
+ int lit2;
+} pCodeOpLit2;
+
+
typedef struct pCodeOpImmd
{
pCodeOp pcop;
struct pBlock *pb;
pCodeOp *pcop2; // second memory operand
-/*
- int rIdx1;
- struct regs *r1;
-*/
-
} pCodeOpReg2;
typedef struct pCodeOpRegBit
char *directive;
char *arg;
+
+ pBranch *label;
} pCodeAsmDir;
unsigned int isAccess: 1; /* True if this instruction has an access RAM operand */
unsigned int isFastCall: 1; /* True if this instruction has a fast call/return mode select operand */
unsigned int is2MemOp: 1; /* True is second operand is a memory operand VR - support for MOVFF */
+ unsigned int is2LitOp: 1; /* True if instruction takes 2 literal operands VR - support for LFSR */
PIC_OPCODE inverted_op; /* Opcode of instruction that's the opposite of this one */
unsigned int inCond; // Input conditions for this instruction
unsigned int outCond; // Output conditions for this instruction
+#define PCI_MAGIC 0x6e12
+ unsigned int pci_magic; // sanity check for pci initialization
} pCodeInstruction;
#define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS)
#define isBSR_REG(r) ((r)->pc_type == PO_BSR)
+#if 0
+/* these are deprecated since when creating relocatable code, the register
+ address is not known (except of course of the SFRs and the Fixed registers)
+*/
+
+
#define isACCESS_LOW(r) ((pic16_finalMapping[REG_ADDR(r)].bank == \
PIC_BANK_FIRST) && (REG_ADDR(r) < 0x80))
#define isACCESS_HI(r) (pic16_finalMapping[REG_ADDR(r)].bank == PIC_BANK_LAST)
+#define isACCESS_BANK(r) (isACCESS_LOW(r) || isACCESS_HI(r))
+
+#endif
+
+//#define isACCESS_BANK(r) (REG_ADDR(r)!= 0)
+#define isACCESS_BANK(r) (r->accessBank)
+// && pic16_finalMapping[REG_ADDR(r)].isSFR)
+// || (pic16_finalMapping[(r)->rIdx].reg && pic16_finalMapping[(r)->rIdx].reg->isFixed))
-/*
-#define isACCESS_BANK(r)(isACCESS_LOW(r) || isACCESS_HI(r))
-*/
-#define isACCESS_BANK(r) (pic16_finalMapping[(r)->rIdx].isSFR \
- || (pic16_finalMapping[(r)->rIdx].reg && pic16_finalMapping[(r)->rIdx].reg->isFixed))
#define isPCOLAB(x) ((PCOP(x)->type) == PO_LABEL)
void pic16_copypCode(FILE *of, char dbName); // Write all pBlocks with dbName to *of
void pic16_movepBlock2Head(char dbName); // move pBlocks around
void pic16_AnalyzepCode(char dbName);
+void pic16_AssignRegBanks(void);
void pic16_printCallTree(FILE *of);
void pCodePeepInit(void);
void pic16_pBlockConvert2ISR(pBlock *pb);
pCodeOp *pic16_newpCodeOpLabel(char *name, int key);
pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space);
pCodeOp *pic16_newpCodeOpLit(int lit);
+pCodeOp *pic16_newpCodeOpLit2(int lit, int lit2);
pCodeOp *pic16_newpCodeOpBit(char *name, int bit,int inBitSpace);
pCodeOp *pic16_newpCodeOpRegFromStr(char *name);
pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE p);
extern pCodeOpReg pic16_pc_pcl;
extern pCodeOpReg pic16_pc_pclath;
extern pCodeOpReg pic16_pc_wreg;
+extern pCodeOpReg pic16_pc_fsr1l;
+extern pCodeOpReg pic16_pc_fsr1h;
+extern pCodeOpReg pic16_pc_fsr2l;
+extern pCodeOpReg pic16_pc_fsr2h;
+extern pCodeOpReg pic16_pc_postinc1;
+extern pCodeOpReg pic16_pc_postdec1;
+extern pCodeOpReg pic16_pc_preinc2;
+extern pCodeOpReg pic16_pc_plusw2;
+
extern pCodeOpReg pic16_pc_kzero;
extern pCodeOpReg pic16_pc_wsave; /* wsave and ssave are used to save W and the Status */
extern pCodeOpReg pic16_pc_ssave; /* registers during an interrupt */
if(!pcops || !pcopd)
return 0;
-#if 1
+#if 0
fprintf(stderr," Comparing operands %s",
pic16_get_op( pcops,NULL,0));
pc = setFirstItem(reg->reglives.usedpCodes);
if(reg->type == REG_SFR) {
- //fprintf(stderr, "not removing SFR reg %s even though used only once\n",reg->name);
+ fprintf(stderr, "not removing SFR reg %s even though used only once\n",reg->name);
continue;
}
reg = fregs->item;
fregs = fregs->next;
- if(reg->type == REG_SFR) {
- //fprintf(stderr,"skipping SFR: %s\n",reg->name);
- continue;
- }
+ if(reg->type == REG_SFR) {
+// fprintf(stderr,"skipping SFR: %s\n",reg->name);
+ continue;
+ }
pcfl_used = setFirstItem(reg->reglives.usedpFlows);
pcfl_assigned = setFirstItem(reg->reglives.assignedpFlows);
if(used && !pcfl_used && pcfl_assigned) {
pCode *pc;
- //fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
+// fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
pc = setFirstItem(reg->reglives.usedpCodes);
while(pc) {
static hTab *dynDirectRegNames= NULL;
//static hTab *regHash = NULL; /* a hash table containing ALL registers */
+set *pic16_rel_udata=NULL;
+set *pic16_fix_udata=NULL;
+
+
static int dynrIdx=0x20;
static int rDirectIdx=0;
/*-----------------------------------------------------------------*/
/* newReg - allocate and init memory for a new register */
/*-----------------------------------------------------------------*/
-static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
+static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
{
regs *dReg;
- dReg = Safe_calloc(1,sizeof(regs));
- dReg->type = type;
- dReg->pc_type = pc_type;
- dReg->rIdx = rIdx;
- if(name)
- dReg->name = Safe_strdup(name);
- else {
- sprintf(buffer,"r0x%02X", dReg->rIdx);
- if(type == REG_STK)
- *buffer = 's';
- dReg->name = Safe_strdup(buffer);
- }
- //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
- dReg->isFree = 0;
- dReg->wasUsed = 1;
- if(type == REG_SFR) {
- dReg->isFixed = 1;
- dReg->address = rIdx;
- } else {
- dReg->isFixed = 0;
- dReg->address = 0;
- }
+ dReg = Safe_calloc(1,sizeof(regs));
+ dReg->type = type;
+ dReg->pc_type = pc_type;
+ dReg->rIdx = rIdx;
+ if(name)
+ dReg->name = Safe_strdup(name);
+ else {
+ sprintf(buffer,"r0x%02X", dReg->rIdx);
+ if(type == REG_STK)
+ *buffer = 's';
+ dReg->name = Safe_strdup(buffer);
+ }
- dReg->isMapped = 0;
- dReg->isEmitted = 0;
- dReg->size = size;
- dReg->alias = alias;
- dReg->reg_alias = NULL;
- dReg->reglives.usedpFlows = newSet();
- dReg->reglives.assignedpFlows = newSet();
+// fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
+ dReg->isFree = 0;
+ dReg->wasUsed = 1;
- hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
+// dReg->isMapped = 0;
+ dReg->isEmitted = 0;
+ dReg->accessBank = 0;
+
+ if(type == REG_SFR) {
+ dReg->isFixed = 1;
+ dReg->address = rIdx;
+ } else {
+ dReg->isFixed = 0;
+ dReg->address = 0;
+ }
+
+ dReg->size = size;
+ dReg->alias = alias;
+ dReg->reg_alias = NULL;
+ dReg->reglives.usedpFlows = newSet();
+ dReg->reglives.assignedpFlows = newSet();
+ dReg->regop = refop;
+
+ hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
return dReg;
}
//fprintf(stderr,"initStack");
for(i = 0; i<size; i++)
- addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
+ addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
}
/*-----------------------------------------------------------------*
regs *
pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
{
- regs * reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias);
+ regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
+
+// fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
+
+ reg->wasUsed = 0; // we do not know if they are going to be used at all
+ reg->accessBank = 1; // implicit add access Bank
- if(reg)reg->wasUsed = 0;
-
- //fprintf(stderr,"pic16_allocProcessorRegister %s addr =0x%x\n",name,rIdx);
return addSet(&pic16_dynProcessorRegs, reg);
}
regs *
pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
{
- regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
+ regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
+
+// fprintf(stderr,"pic16_allocInternalRegister %s addr =0x%x\n",name,rIdx);
- //fprintf(stderr,"pic16_allocInternalRegister %s addr =0x%x\n",name,rIdx);
if(reg) {
reg->wasUsed = 0;
return addSet(&pic16_dynInternalRegs,reg);
//fprintf(stderr,"allocReg\n");
- return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
+ return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
}
//if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
//name++;
+ /* The above hack is not necessery anymore, since .asm include files are not
+ * used by current implementation of the port -- VR 03-Jan-04 */
+
debugLog ("%s symbol name %s\n", __FUNCTION__,name);
+// fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
{
if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
debugLog(" %d const char\n",__LINE__);
debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
+// fprintf(stderr, " %d const char\n",__LINE__);
+// fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
}
debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
* a new one and put it in the hash table AND in the
* dynDirectRegNames set */
if(!IS_CONFIG_ADDRESS(address)) {
- //fprintf(stderr,"allocating new reg %s\n",name);
+ //fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
- reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
- debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
+ reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
+ debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
- //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+ //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* commented out */
if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
} else {
debugLog (" -- %s is declared at address 0x30000x\n",name);
+ fprintf(stderr, " -- %s is declared at address 0x30000x\n",name);
+
+/*
+ fprintf(stderr, " setting config word to %x\n",
+ (int) floatFromVal (op->operand.valOperand)); //IC_RIGHT(ic)->operand.valOperand));
+
+ pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
+ (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
+*/
+
+ return NULL;
}
}
* a new one and put it in the hash table AND in the
* dynDirectRegNames set */
//fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
- reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
+ reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, NULL);
- debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
+ debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
+ //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
- //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+ //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
addSet(&pic16_dynDirectRegs, reg);
}
debugLog ("Found a Stack Register!\n");
} else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
debugLog ("Found a Processor Register!\n");
+ fprintf(stderr, "Found a processor register! %s\n", dReg->name);
} else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
debugLog ("Found an Internal Register!\n");
} else {
case REG_GPR:
if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
return dReg;
- return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
+ return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
case REG_STK:
static void
freeReg (regs * reg)
{
- debugLog ("%s\n", __FUNCTION__);
- reg->isFree = 1;
+ debugLog ("%s\n", __FUNCTION__);
+ reg->isFree = 1;
}
}
#endif
-extern void pic16_assignFixedRegisters(set *regset);
-extern void pic16_assignRelocatableRegisters(set *regset,int used);
+extern void pic16_groupRegistersInSection(set *regset);
+
extern void pic16_dump_map(void);
-extern void pic16_dump_cblock(FILE *of);
+extern void pic16_dump_section(FILE *of, char *sname, set *section, int fix);
static void packBits(set *bregs)
if(!bitfield) {
sprintf (buffer, "fbitfield%02x", breg->address);
//fprintf(stderr,"new bit field\n");
- bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
+ bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
bitfield->isBitField = 1;
bitfield->isFixed = 1;
bitfield->address = breg->address;
bit_no=0;
sprintf (buffer, "bitfield%d", byte_no);
//fprintf(stderr,"new relocatable bit field\n");
- relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
+ relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
relocbitfield->isBitField = 1;
addSet(&pic16_dynDirectRegs,relocbitfield);
//hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
void pic16_writeUsedRegs(FILE *of)
{
- packBits(pic16_dynDirectBitRegs);
-
+ packBits(pic16_dynDirectBitRegs);
- pic16_assignFixedRegisters(pic16_dynAllocRegs);
- pic16_assignFixedRegisters(pic16_dynStackRegs);
- pic16_assignFixedRegisters(pic16_dynDirectRegs);
- pic16_assignFixedRegisters(pic16_dynProcessorRegs);
-
- pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
- pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
- pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
- pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
+ pic16_groupRegistersInSection(pic16_dynAllocRegs);
+ pic16_groupRegistersInSection(pic16_dynInternalRegs);
+ pic16_groupRegistersInSection(pic16_dynStackRegs);
+ pic16_groupRegistersInSection(pic16_dynDirectRegs);
+ pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
+ pic16_groupRegistersInSection(pic16_dynProcessorRegs);
+
+
+#if 0
+ pic16_assignFixedRegisters(pic16_dynAllocRegs);
+ pic16_assignFixedRegisters(pic16_dynStackRegs);
+ pic16_assignFixedRegisters(pic16_dynDirectRegs);
+ pic16_assignFixedRegisters(pic16_dynProcessorRegs);
+
+ pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0);
+ pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
+ pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
+ pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
+ pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
+#endif
- //pic16_dump_map();
+// pic16_dump_map();
+// pic16_dump_cblock(of);
- pic16_dump_cblock(of);
+ pic16_dump_section(of, "ud1", pic16_rel_udata, 0);
+ pic16_dump_section(of, "ud2", pic16_fix_udata, 1);
#if 0
- bitEQUs(of,pic16_dynDirectBitRegs);
- aliasEQUs(of,pic16_dynAllocRegs,0);
- aliasEQUs(of,pic16_dynDirectRegs,0);
- aliasEQUs(of,pic16_dynStackRegs,0);
- aliasEQUs(of,pic16_dynProcessorRegs,1);
+ bitEQUs(of,pic16_dynDirectBitRegs);
+ aliasEQUs(of,pic16_dynAllocRegs,0);
+ aliasEQUs(of,pic16_dynDirectRegs,0);
+ aliasEQUs(of,pic16_dynStackRegs,0);
+ aliasEQUs(of,pic16_dynProcessorRegs,1);
#endif
}
sym = hTabNextItem (liveRanges, &k)) {
debugLog (" %d - %s\n", __LINE__, sym->rname);
+ //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
/* if used zero times then no registers needed */
if ((sym->liveTo - sym->liveFrom) == 0)
iCode *dic, *sic;
- debugLog ("%s\n", __FUNCTION__);
-
+ debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
+ debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
debugAopGet (" result:", IC_RESULT (ic));
debugAopGet (" left:", IC_LEFT (ic));
debugAopGet (" right:", IC_RIGHT (ic));
if(IS_VALOP(IC_RIGHT(ic))) {
debugLog (" setting config word to %x\n",
(int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
+ fprintf(stderr, " setting config word to %x\n",
+ (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
(int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
}
+
+ debugLog(" %d\n", __LINE__);
+
/* remove the assignment from the iCode chain. */
remiCodeFromeBBlock (ebp, ic);
}
}
+ debugLog(" %d - actuall processing\n", __LINE__ );
if (!IS_ITEMP (IC_RESULT (ic))) {
pic16_allocDirReg(IC_RESULT (ic));
debugLog (" %d - result is not temp\n", __LINE__);
}
-/*
+
+#if 0
if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
debugLog (" %d - left is not temp, allocating\n", __LINE__);
pic16_allocDirReg(IC_LEFT (ic));
}
-*/
+#endif
+/* See BUGLOG0001 - VR */
+#if 1
if (!IS_ITEMP (IC_RIGHT (ic))) {
debugLog (" %d - not packing - right is not temp\n", __LINE__);
pic16_allocDirReg(IC_RIGHT (ic));
return 0;
}
+#endif
if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
if (SKIP_IC2 (dic))
continue;
+ debugLog("%d\tSearching for iTempNN\n", __LINE__);
+
+#if 0
+ if(IS_TRUE_SYMOP( IC_RESULT(dic))) {
+ debugLog("%d - dic result is a TRUE_SYMOP\n", __LINE__);
+ debugAopGet(" result is ", IC_RESULT(dic));
+ }
+ if(IS_TRUE_SYMOP( IC_LEFT(dic))) {
+ debugLog("%d - dic left is a SYMOP\n", __LINE__);
+ debugAopGet(" left is ", IC_LEFT(dic));
+ }
+ if(IS_TRUE_SYMOP( IC_RIGHT(dic))) {
+ debugLog("%d - dic right is a SYMOP\n", __LINE__);
+ debugAopGet(" right is ", IC_RIGHT(dic));
+ }
+#endif
+
if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
IS_OP_VOLATILE (IC_RESULT (dic)))
{
break;
}
+#if 0
+ if (IS_TRUE_SYMOP( IC_RIGHT (dic)) &&
+ IS_OP_VOLATILE (IC_RIGHT(dic)))
+ {
+ debugLog (" %d - dic right is VOLATILE\n", __LINE__);
+ dic = NULL;
+ break;
+ }
+#endif
+
+#if 0
+ if (IS_TRUE_SYMOP( IC_LEFT (dic)) &&
+ IS_OP_VOLATILE (IC_LEFT(dic)))
+ {
+ debugLog (" %d - dic left is VOLATILE\n", __LINE__);
+ dic = NULL;
+ break;
+ }
+#endif
+
if (IS_SYMOP (IC_RESULT (dic)) &&
IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
{
remiCodeFromeBBlock (ebp, ic);
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+
+ debugLog(" %d\n", __LINE__ );
hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
return 1;
getSize (operandType (IC_RESULT (ic))) > 1))
return;
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
if (ic->op == LEFT_OP &&
(isOperandLiteral (IC_RIGHT (ic)) ||
getSize (operandType (IC_RESULT (ic))) > 1))
return;
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
if (IS_BITWISE_OP (ic) &&
getSize (operandType (IC_RESULT (ic))) > 1)
return;
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
/* has only one definition */
if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
return;
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
/* has only one use */
if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
return;
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
/* and the usage immediately follows this iCode */
if (!(uic = hTabItemWithKey (iCodehTab,
bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
}
}
+
/*--------------------------------------------------------------------*/
/* pic16_packRegisters - does some transformations to reduce */
/* register pressure */
/* TrueSym := iTempNN:1 */
for (ic = ebp->sch; ic; ic = ic->next)
{
-
+// debugLog("%d\n", __LINE__);
/* find assignment of the form TrueSym := iTempNN:1 */
/* see BUGLOG0001 for workaround with the CAST - VR */
if ((ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic))
if(IS_SYMOP ( IC_LEFT(ic))) {
sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
- debugAopGet (" left:", IC_LEFT (ic));
-#if 0
+ debugAopGet ("x left:", IC_LEFT (ic));
+#if 1
if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
#else
if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
#endif
debugLog (" is a pointer\n");
+ if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
+ debugLog (" is a ptr\n");
+
if(IS_OP_VOLATILE(IC_LEFT(ic)))
debugLog (" is volatile\n");
isData(etype);
- printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
+ if(IS_OP_VOLATILE(IC_LEFT(ic))) {
+ debugLog (" %d - left is not temp, allocating\n", __LINE__);
+ pic16_allocDirReg(IC_LEFT (ic));
+ }
+
+ printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
}
if(IS_SYMOP ( IC_RIGHT(ic))) {
debugAopGet (" left:", IC_LEFT (ic));
}
+ //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
+
if (!SKIP_IC2 (ic))
{
+ //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
/* if we are using a symbol on the stack
then we should say pic16_ptrRegReq */
if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
else
{
+
+ //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
if (IS_SYMOP (IC_LEFT (ic)))
pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
continue;
}
+ debugLog(" %d\n", __LINE__);
+
/* reduce for support function calls */
if (ic->supportRtn || ic->op == '+' || ic->op == '-')
packRegsForSupport (ic, ebp);
getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-
+ debugLog("%d - return from packRegsForOneuse\n", __LINE__);
/* if this is cast for intergral promotion then
check if only use of the definition of the
if (dic) {
if (IS_ARITHMETIC_OP (dic)) {
+ debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
IC_RESULT (dic) = IC_RESULT (ic);
iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
if (dic) {
-
+
+ debugLog(" %d\n", __LINE__);
+
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
IC_RESULT (dic) = IC_RESULT (ic);
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
while(reg) {
debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
+// fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
reg = hTabNextItem(dynDirectRegNames, &hkey);
}
#include "pcoderegs.h"
+/* set STACK_SUPPORT to 1 to compile code for stack */
+#define STACK_SUPPORT 1
+extern unsigned int stackPos;
enum
{
unsigned isFree:1; /* is currently unassigned */
unsigned wasUsed:1; /* becomes true if register has been used */
unsigned isFixed:1; /* True if address can't change */
- unsigned isMapped:1; /* The Register's address has been mapped to physical RAM */
+// unsigned isMapped:1; /* The Register's address has been mapped to physical RAM */
unsigned isBitField:1; /* True if reg is type bit OR is holder for several bits */
unsigned isEmitted:1; /* True if the reg has been written to a .asm file */
+ unsigned accessBank:1; /* True if the reg is explicit placed in access bank */
unsigned address; /* reg's address if isFixed | isMapped is true */
unsigned size; /* 0 for byte, 1 for int, 4 for long */
unsigned alias; /* Alias mask if register appears in multiple banks */
struct regs *reg_alias; /* If more than one register share the same address
* then they'll point to each other. (primarily for bits)*/
+ operand *regop; /* reference to the operand used to create the register */
pCodeRegLives reglives; /* live range mapping */
}
regs;
extern set *pic16_dynDirectBitRegs;
extern set *pic16_dynInternalRegs;
+extern set *pic16_rel_udata;
+extern set *pic16_fix_udata;
regs *pic16_regWithIdx (int);
regs *pic16_dirregWithName (char *name );
#define IDX_INTCON 0xff2
#define IDX_WREG 0xfe8
+#define IDX_FSR1L 0xfe1
+#define IDX_FSR1H 0xfe2
+#define IDX_FSR2L 0xfd9
+#define IDX_FSR2H 0xfda
+#define IDX_POSTINC1 0xfe6
+#define IDX_POSTDEC1 0xfe5
+#define IDX_PREINC2 0xfdc
+#define IDX_PLUSW2 0xfdb
+
#define IDX_KZ 0x7fff /* Known zero - actually just a general purpose reg. */
#define IDX_WSAVE 0x7ffe
#define IDX_SSAVE 0x7ffd