From 958a651d053c089412d87ab75101812383d03f19 Mon Sep 17 00:00:00 2001 From: michaelh Date: Sun, 23 Jan 2000 02:05:00 +0000 Subject: [PATCH] * Added common.h * Began making the ports self contained (ie static or uniquely named globals) * Made it so you can select the port at run time (-mmcs51, -mz80...) git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@21 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/Makefile.in | 18 +- src/SDCCBBlock.c | 13 +- src/SDCCast.c | 11 +- src/SDCCbitv.c | 8 +- src/SDCCcflow.c | 16 +- src/SDCCcse.c | 16 +- src/SDCCdflow.c | 18 +- src/SDCCerr.c | 7 +- src/SDCCgen51.c | 7383 -------------------------------------------- src/SDCCglobl.h | 54 - src/SDCCglue.c | 15 +- src/SDCChasht.c | 6 +- src/SDCCicode.c | 11 +- src/SDCClabel.c | 13 +- src/SDCCloop.c | 16 +- src/SDCClrange.c | 18 +- src/SDCCmain.c | 85 +- src/SDCCmem.c | 12 +- src/SDCCopt.c | 23 +- src/SDCCpeeph.c | 8 +- src/SDCCptropt.c | 17 +- src/SDCCralloc.c | 2313 -------------- src/SDCCset.c | 4 +- src/SDCCsymt.c | 9 +- src/SDCCval.c | 9 +- src/common.h | 26 + src/mcs51/gen.c | 159 +- src/mcs51/main.c | 26 +- src/mcs51/ralloc.c | 162 +- src/z80/gen.c | 10 +- src/z80/main.c | 58 +- src/z80/ralloc.c | 2 +- 32 files changed, 360 insertions(+), 10186 deletions(-) delete mode 100644 src/SDCCgen51.c delete mode 100644 src/SDCCralloc.c create mode 100644 src/common.h diff --git a/src/Makefile.in b/src/Makefile.in index dc6aa1fe..ea00049d 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -6,7 +6,10 @@ PRJDIR = .. include $(PRJDIR)/Makefile.common -LIBS = $(PORT)/port.a -lgc @LIBS@ +PORTS = mcs51 +PORT_LIBS = $(PORTS:%=%/port.a) + +LIBS = -lgc @LIBS@ LIBDIRS = -L$(PRJDIR)/support/gc OBJECTS = SDCCy.o SDCClex.o SDCCerr.o SDCChasht.o SDCCmain.o \ @@ -18,13 +21,12 @@ SOURCES = $(patsubst %.o,%.c,$(OBJECTS)) TARGET = $(PRJDIR)/bin/sdcc - # Compiling entire program or any subproject # ------------------------------------------ -all: port checkconf $(PRJDIR)/support/gc/libgc.a $(TARGET) +all: ports checkconf $(PRJDIR)/support/gc/libgc.a $(TARGET) -port: - $(MAKE) -C $(PORT) +ports: + for i in $(PORTS); do $(MAKE) -C $$i; done $(PRJDIR)/support/gc/libgc.a: cd $(PRJDIR)/support/gc && $(MAKE) @@ -71,12 +73,14 @@ include clean.mk # My rules # -------- -$(TARGET): $(OBJECTS) - $(CC) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS) +$(TARGET): $(OBJECTS) $(PORT_LIBS) + $(CC) -o $@ $(OBJECTS) $(PORT_LIBS) $(LIBDIRS) $(LIBS) .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ +SDCCy.h: SDCCy.c + SDCCy.c: SDCC.y $(YACC) -d -v -o $@ $< diff --git a/src/SDCCBBlock.c b/src/SDCCBBlock.c index 1b4eac79..fd24f4ed 100644 --- a/src/SDCCBBlock.c +++ b/src/SDCCBBlock.c @@ -21,19 +21,8 @@ You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include -#include "SDCCglobl.h" -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCCBBlock.h" +#include "common.h" int eBBNum = 0; set *graphEdges = NULL ; /* list of edges in this flow graph */ diff --git a/src/SDCCast.c b/src/SDCCast.c index 9d534163..f985dc55 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -22,16 +22,7 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include "SDCCglobl.h" -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCicode.h" -#include "SDCCopt.h" - +#include "common.h" int currLineno = 0; set *astList = NULL ; diff --git a/src/SDCCbitv.c b/src/SDCCbitv.c index 8796bcc4..c75f7389 100644 --- a/src/SDCCbitv.c +++ b/src/SDCCbitv.c @@ -21,11 +21,9 @@ You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include "SDCCbitv.h" -#ifndef ALLOC -#include "SDCCglobl.h" -#endif + +#include "common.h" + int bitVectDefault = 1024; /* genernal note about a bitvectors: diff --git a/src/SDCCcflow.c b/src/SDCCcflow.c index 0b379494..9c6ac3bb 100644 --- a/src/SDCCcflow.c +++ b/src/SDCCcflow.c @@ -22,20 +22,8 @@ You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include "SDCCglobl.h" -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCClabel.h" -#include "SDCCBBlock.h" -#include "SDCCcse.h" -#include "SDCCcflow.h" + +#include "common.h" /*-----------------------------------------------------------------*/ /* domSetFromVect - creates a domset from the vector */ diff --git a/src/SDCCcse.c b/src/SDCCcse.c index 210f8c1c..dad1084b 100644 --- a/src/SDCCcse.c +++ b/src/SDCCcse.c @@ -22,21 +22,7 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include "SDCCglobl.h" -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCClabel.h" -#include "SDCCBBlock.h" -#include "SDCCcflow.h" -#include "SDCCloop.h" -#include "SDCCcse.h" +#include "common.h" /*-----------------------------------------------------------------*/ /* newCseDef - new cseDef */ diff --git a/src/SDCCdflow.c b/src/SDCCdflow.c index 1e8c50c8..24d13c24 100644 --- a/src/SDCCdflow.c +++ b/src/SDCCdflow.c @@ -23,22 +23,8 @@ You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include "SDCCglobl.h" -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCClabel.h" -#include "SDCCBBlock.h" -#include "SDCCloop.h" -#include "SDCCcse.h" -#include "SDCCcflow.h" -#include "SDCCdflow.h" + +#include "common.h" /*-----------------------------------------------------------------*/ /* ifKilledInBlock - will return 1 if the symbol is redefined in B */ diff --git a/src/SDCCerr.c b/src/SDCCerr.c index 29afccaf..de85badc 100644 --- a/src/SDCCerr.c +++ b/src/SDCCerr.c @@ -1,9 +1,6 @@ /* SDCCerr.c - error handling routines */ -#include -#include -#include "SDCCglobl.h" -#include "SDCCmem.h" -#include "SDCCerr.h" + +#include "common.h" #define ERROR 0 #define WARNING 1 diff --git a/src/SDCCgen51.c b/src/SDCCgen51.c deleted file mode 100644 index b7e238f8..00000000 --- a/src/SDCCgen51.c +++ /dev/null @@ -1,7383 +0,0 @@ -/*------------------------------------------------------------------------- - SDCCgen51.c - source file for code generation for 8051 - - 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) - - 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! - --------------------------------------------------------------------------*/ - -#include -#include -#include -#include -#include "SDCCglobl.h" - -#ifdef HAVE_SYS_ISA_DEFS_H -#include -#else -#ifdef HAVE_ENDIAN_H -#include -#else -#warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN" -#warning "If you running sdcc on an INTEL 80x86 Platform you are okay" -#endif -#endif - -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCClabel.h" -#include "SDCCBBlock.h" -#include "SDCCloop.h" -#include "SDCCcse.h" -#include "SDCCcflow.h" -#include "SDCCdflow.h" -#include "SDCClrange.h" -#include "SDCCralloc.h" -#include "SDCCgen51.h" -#include "SDCCpeeph.h" - -/* this is the down and dirty file with all kinds of -kludgy & hacky stuff. This is what it is all about -CODE GENERATION for a specific MCU . some of the -routines may be reusable, will have to see */ - -static char *zero = "#0x00"; -static char *one = "#0x01"; -static char *spname ; -static char *fReturn[] = {"dpl","dph","b","a" }; -static char *accUse[] = {"a","b"}; -short r0Pushed = 0; -short r1Pushed = 0; -short rbank = -1; -short accInUse = 0 ; -short inLine = 0; -short debugLine = 0; -short nregssaved = 0; -extern int ptrRegReq ; -extern int nRegs; -extern FILE *codeOutFile; -set *sendSet = NULL; -static void saverbank (int, iCode *,bool); -#define RESULTONSTACK(x) \ - (IC_RESULT(x) && IC_RESULT(x)->aop && \ - IC_RESULT(x)->aop->type == AOP_STK ) - -#define MOVA(x) if (strcmp(x,"a") && strcmp(x,"acc")) emitcode("mov","a,%s",x); -#define CLRC emitcode("clr","c"); - -lineNode *lineHead = NULL; -lineNode *lineCurr = NULL; - -unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0, -0xE0, 0xC0, 0x80, 0x00}; -unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F, -0x07, 0x03, 0x01, 0x00}; - -#define LSB 0 -#define MSB16 1 -#define MSB24 2 -#define MSB32 3 - -/*-----------------------------------------------------------------*/ -/* emitcode - writes the code into a file : for now it is simple */ -/*-----------------------------------------------------------------*/ -void emitcode (char *inst,char *fmt, ...) -{ - va_list ap; - char lb[MAX_INLINEASM]; - char *lbp = lb; - - va_start(ap,fmt); - - if (inst && *inst) { - if (fmt && *fmt) - sprintf(lb,"%s\t",inst); - else - sprintf(lb,"%s",inst); - vsprintf(lb+(strlen(lb)),fmt,ap); - } else - vsprintf(lb,fmt,ap); - - while (isspace(*lbp)) lbp++; - - if (lbp && *lbp) - lineCurr = (lineCurr ? - connectLine(lineCurr,newLineNode(lb)) : - (lineHead = newLineNode(lb))); - lineCurr->isInline = inLine; - lineCurr->isDebug = debugLine; - va_end(ap); -} - -/*-----------------------------------------------------------------*/ -/* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/ -/*-----------------------------------------------------------------*/ -static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) -{ - bool r0iu = FALSE , r1iu = FALSE; - bool r0ou = FALSE , r1ou = FALSE; - - /* the logic: if r0 & r1 used in the instruction - then we are in trouble otherwise */ - - /* first check if r0 & r1 are used by this - instruction, in which case we are in trouble */ - if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) && - (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) - goto endOfWorld; - - - r0ou = bitVectBitValue(ic->rMask,R0_IDX); - r1ou = bitVectBitValue(ic->rMask,R1_IDX); - - /* if no usage of r0 then return it */ - if (!r0iu && !r0ou) { - ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX); - (*aopp)->type = AOP_R0; - return (*aopp)->aopu.aop_ptr = regWithIdx(R0_IDX); - } - - /* if no usage of r1 then return it */ - if (!r1iu && !r1ou) { - ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX); - (*aopp)->type = AOP_R1; - return (*aopp)->aopu.aop_ptr = regWithIdx(R1_IDX); - } - - /* now we know they both have usage */ - /* if r0 not used in this instruction */ - if (!r0iu) { - /* push it if not already pushed */ - if (!r0Pushed) { - emitcode ("push","%s", - regWithIdx(R0_IDX)->dname); - r0Pushed++ ; - } - - ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX); - (*aopp)->type = AOP_R0; - - return (*aopp)->aopu.aop_ptr = regWithIdx(R0_IDX); - } - - /* if r1 not used then */ - - if (!r1iu) { - /* push it if not already pushed */ - if (!r1Pushed) { - emitcode ("push","%s", - regWithIdx(R1_IDX)->dname); - r1Pushed++ ; - } - - ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX); - (*aopp)->type = AOP_R1; - return regWithIdx(R1_IDX); - } - - -endOfWorld : - /* I said end of world but not quite end of world yet */ - /* if this is a result then we canpush it on the stack*/ - if (result) { - (*aopp)->type = AOP_STK; - return NULL; - } - - piCode(ic,stdout); - /* other wise this is true end of the world */ - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "getFreePtr should never reach here"); - exit(0); -} - -/*-----------------------------------------------------------------*/ -/* newAsmop - creates a new asmOp */ -/*-----------------------------------------------------------------*/ -static asmop *newAsmop (short type) -{ - asmop *aop; - - ALLOC(aop,sizeof(asmop)); - aop->type = type; - return aop; -} - -/*-----------------------------------------------------------------*/ -/* pointerCode - returns the code for a pointer type */ -/*-----------------------------------------------------------------*/ -static int pointerCode (link *etype) -{ - int p_type; - if (SPEC_OCLS(etype)->codesp ) { - p_type = CPOINTER ; - } - else - if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) - p_type = FPOINTER ; - else - if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) - p_type = PPOINTER; - else - if (SPEC_OCLS(etype) == idata ) - p_type = IPOINTER; - else - p_type = POINTER ; - return p_type; -} - -/*-----------------------------------------------------------------*/ -/* aopForSym - for a true symbol */ -/*-----------------------------------------------------------------*/ -static asmop *aopForSym (iCode *ic,symbol *sym,bool result) -{ - asmop *aop; - memmap *space= SPEC_OCLS(sym->etype); - - /* if already has one */ - if (sym->aop) - return sym->aop; - - /* assign depending on the storage class */ - /* if it is on the stack or indirectly addressable */ - /* space we need to assign either r0 or r1 to it */ - if (sym->onStack || sym->iaccess) { - sym->aop = aop = newAsmop(0); - aop->aopu.aop_ptr = getFreePtr(ic,&aop,result); - aop->size = getSize(sym->type); - - /* now assign the address of the variable to - the pointer register */ - if (aop->type != AOP_STK) { - - if (sym->onStack) { - - if ( accInUse ) - emitcode("push","acc"); - - emitcode("mov","a,_bp"); - emitcode("add","a,#0x%02x", - ((sym->stack < 0) ? - ((char)(sym->stack - nregssaved )) : - ((char)sym->stack)) & 0xff); - emitcode("mov","%s,a", - aop->aopu.aop_ptr->name); - - if ( accInUse ) - emitcode("pop","acc"); - - } else - emitcode("mov","%s,#%s", - aop->aopu.aop_ptr->name, - sym->rname); - aop->paged = space->paged; - } else - aop->aopu.aop_stk = sym->stack; - return aop; - } - - /* if in bit space */ - if (IN_BITSPACE(space)) { - sym->aop = aop = newAsmop (AOP_CRY); - aop->aopu.aop_dir = sym->rname ; - aop->size = getSize(sym->type); - return aop; - } - /* if it is in direct space */ - if (IN_DIRSPACE(space)) { - sym->aop = aop = newAsmop (AOP_DIR); - aop->aopu.aop_dir = sym->rname ; - aop->size = getSize(sym->type); - return aop; - } - - /* special case for a function */ - if (IS_FUNC(sym->type)) { - sym->aop = aop = newAsmop(AOP_IMMD); - ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1); - strcpy(aop->aopu.aop_immd,sym->rname); - aop->size = 2; - return aop; - } - - /* only remaining is far space */ - /* in which case DPTR gets the address */ - sym->aop = aop = newAsmop(AOP_DPTR); - emitcode ("mov","dptr,#%s", sym->rname); - aop->size = getSize(sym->type); - - /* if it is in code space */ - if (IN_CODESPACE(space)) - aop->code = 1; - - return aop; -} - -/*-----------------------------------------------------------------*/ -/* aopForRemat - rematerialzes an object */ -/*-----------------------------------------------------------------*/ -static asmop *aopForRemat (symbol *sym) -{ - char *s = buffer; - iCode *ic = sym->rematiCode; - asmop *aop = newAsmop(AOP_IMMD); - - while (1) { - - /* if plus or minus print the right hand side */ - if (ic->op == '+' || ic->op == '-') { - sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)), - ic->op ); - s += strlen(s); - ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; - continue ; - } - - /* we reached the end */ - sprintf(s,"%s",OP_SYMBOL(IC_LEFT(ic))->rname); - break; - } - - ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(buffer)+1); - strcpy(aop->aopu.aop_immd,buffer); - return aop; -} - -/*-----------------------------------------------------------------*/ -/* regsInCommon - two operands have some registers in common */ -/*-----------------------------------------------------------------*/ -bool regsInCommon (operand *op1, operand *op2) -{ - symbol *sym1, *sym2; - int i; - - /* if they have registers in common */ - if (!IS_SYMOP(op1) || !IS_SYMOP(op2)) - return FALSE ; - - sym1 = OP_SYMBOL(op1); - sym2 = OP_SYMBOL(op2); - - if (sym1->nRegs == 0 || sym2->nRegs == 0) - return FALSE ; - - for (i = 0 ; i < sym1->nRegs ; i++) { - int j; - if (!sym1->regs[i]) - continue ; - - for (j = 0 ; j < sym2->nRegs ;j++ ) { - if (!sym2->regs[j]) - continue ; - - if (sym2->regs[j] == sym1->regs[i]) - return TRUE ; - } - } - - return FALSE ; -} - -/*-----------------------------------------------------------------*/ -/* operandsEqu - equivalent */ -/*-----------------------------------------------------------------*/ -bool operandsEqu ( operand *op1, operand *op2) -{ - symbol *sym1, *sym2; - - /* if they not symbols */ - if (!IS_SYMOP(op1) || !IS_SYMOP(op2)) - return FALSE; - - sym1 = OP_SYMBOL(op1); - sym2 = OP_SYMBOL(op2); - - /* if both are itemps & one is spilt - and the other is not then false */ - if (IS_ITEMP(op1) && IS_ITEMP(op2) && - sym1->isspilt != sym2->isspilt ) - return FALSE ; - - /* if they are the same */ - if (sym1 == sym2) - return TRUE ; - - if (strcmp(sym1->rname,sym2->rname) == 0) - return TRUE; - - - /* if left is a tmp & right is not */ - if (IS_ITEMP(op1) && - !IS_ITEMP(op2) && - sym1->isspilt && - (sym1->usl.spillLoc == sym2)) - return TRUE; - - if (IS_ITEMP(op2) && - !IS_ITEMP(op1) && - sym2->isspilt && - sym1->level > 0 && - (sym2->usl.spillLoc == sym1)) - return TRUE ; - - return FALSE ; -} - -/*-----------------------------------------------------------------*/ -/* sameRegs - two asmops have the same registers */ -/*-----------------------------------------------------------------*/ -bool sameRegs (asmop *aop1, asmop *aop2 ) -{ - int i; - - if (aop1 == aop2) - return TRUE ; - - if (aop1->type != AOP_REG || - aop2->type != AOP_REG ) - return FALSE ; - - if (aop1->size != aop2->size ) - return FALSE ; - - for (i = 0 ; i < aop1->size ; i++ ) - if (aop1->aopu.aop_reg[i] != - aop2->aopu.aop_reg[i] ) - return FALSE ; - - return TRUE ; -} - -/*-----------------------------------------------------------------*/ -/* aopOp - allocates an asmop for an operand : */ -/*-----------------------------------------------------------------*/ -static void aopOp (operand *op, iCode *ic, bool result) -{ - asmop *aop; - symbol *sym; - int i; - - if (!op) - return ; - - /* if this a literal */ - if (IS_OP_LITERAL(op)) { - op->aop = aop = newAsmop(AOP_LIT); - aop->aopu.aop_lit = op->operand.valOperand; - aop->size = getSize(operandType(op)); - return; - } - - /* if already has a asmop then continue */ - if (op->aop) - return ; - - /* if the underlying symbol has a aop */ - if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) { - op->aop = OP_SYMBOL(op)->aop; - return; - } - - /* if this is a true symbol */ - if (IS_TRUE_SYMOP(op)) { - op->aop = aopForSym(ic,OP_SYMBOL(op),result); - return ; - } - - /* this is a temporary : this has - only four choices : - a) register - b) spillocation - c) rematerialize - d) conditional - e) can be a return use only */ - - sym = OP_SYMBOL(op); - - - /* if the type is a conditional */ - if (sym->regType == REG_CND) { - aop = op->aop = sym->aop = newAsmop(AOP_CRY); - aop->size = 0; - return; - } - - /* if it is spilt then two situations - a) is rematerialize - b) has a spill location */ - if (sym->isspilt || sym->nRegs == 0) { - - /* rematerialize it NOW */ - if (sym->remat) { - sym->aop = op->aop = aop = - aopForRemat (sym); - aop->size = getSize(sym->type); - return; - } - - if (sym->accuse) { - int i; - aop = op->aop = sym->aop = newAsmop(AOP_ACC); - aop->size = getSize(sym->type); - for ( i = 0 ; i < 2 ; i++ ) - aop->aopu.aop_str[i] = accUse[i]; - return; - } - - if (sym->ruonly ) { - int i; - aop = op->aop = sym->aop = newAsmop(AOP_STR); - aop->size = getSize(sym->type); - for ( i = 0 ; i < 4 ; i++ ) - aop->aopu.aop_str[i] = fReturn[i]; - return; - } - - /* else spill location */ - sym->aop = op->aop = aop = - aopForSym(ic,sym->usl.spillLoc,result); - aop->size = getSize(sym->type); - return; - } - - /* must be in a register */ - sym->aop = op->aop = aop = newAsmop(AOP_REG); - aop->size = sym->nRegs; - for ( i = 0 ; i < sym->nRegs ;i++) - aop->aopu.aop_reg[i] = sym->regs[i]; -} - -/*-----------------------------------------------------------------*/ -/* freeAsmop - free up the asmop given to an operand */ -/*----------------------------------------------------------------*/ -static void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) -{ - asmop *aop ; - - if (!op) - aop = aaop; - else - aop = op->aop; - - if (!aop) - return ; - - if (aop->freed) - goto dealloc; - - aop->freed = 1; - - /* depending on the asmop type only three cases need work AOP_RO - , AOP_R1 && AOP_STK */ - switch (aop->type) { - case AOP_R0 : - if (r0Pushed ) { - if (pop) { - emitcode ("pop","ar0"); - r0Pushed--; - } - } - bitVectUnSetBit(ic->rUsed,R0_IDX); - break; - - case AOP_R1 : - if (r1Pushed ) { - if (pop) { - emitcode ("pop","ar1"); - r1Pushed--; - } - } - bitVectUnSetBit(ic->rUsed,R1_IDX); - break; - - case AOP_STK : - { - int sz = aop->size; - int stk = aop->aopu.aop_stk + aop->size; - bitVectUnSetBit(ic->rUsed,R0_IDX); - bitVectUnSetBit(ic->rUsed,R1_IDX); - - getFreePtr(ic,&aop,FALSE); - if (stk) { - emitcode ("mov","a,_bp"); - emitcode ("add","a,#0x%02x",((char)stk) & 0xff); - emitcode ("mov","%s,a",aop->aopu.aop_ptr->name); - } else - emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name); - - while (sz--) { - emitcode("pop","acc"); - emitcode("mov","@%s,a",aop->aopu.aop_ptr->name); - if (!sz) break; - emitcode("dec","%s",aop->aopu.aop_ptr->name); - } - op->aop = aop; - freeAsmop(op,NULL,ic,TRUE); - if (r0Pushed) { - emitcode("pop","ar0"); - r0Pushed--; - } - - if (r1Pushed) { - emitcode("pop","ar1"); - r1Pushed--; - } - } - } - -dealloc: - /* all other cases just dealloc */ - if (op ) { - op->aop = NULL; - if (IS_SYMOP(op)) { - OP_SYMBOL(op)->aop = NULL; - /* if the symbol has a spill */ - if (SPIL_LOC(op)) - SPIL_LOC(op)->aop = NULL; - } - } -} - -/*-----------------------------------------------------------------*/ -/* aopLiteral - string from a literal value */ -/*-----------------------------------------------------------------*/ -char *aopLiteral (value *val, int offset) -{ - char *rs; - union { - float f; - unsigned char c[4]; - } fl; - - /* if it is a float then it gets tricky */ - /* otherwise it is fairly simple */ - if (!IS_FLOAT(val->type)) { - unsigned long v = floatFromVal(val); - - v >>= (offset * 8); - sprintf(buffer,"#0x%02x",((char) v) & 0xff); - ALLOC_ATOMIC(rs,strlen(buffer)+1); - return strcpy (rs,buffer); - } - - /* it is type float */ - fl.f = (float) floatFromVal(val); -#ifdef _BIG_ENDIAN - sprintf(buffer,"#0x%02x",fl.c[3-offset]); -#else - sprintf(buffer,"#0x%02x",fl.c[offset]); -#endif - ALLOC_ATOMIC(rs,strlen(buffer)+1); - return strcpy (rs,buffer); -} - -/*-----------------------------------------------------------------*/ -/* aopGet - for fetching value of the aop */ -/*-----------------------------------------------------------------*/ -static char *aopGet (asmop *aop, int offset, bool bit16, bool dname) -{ - char *s = buffer ; - char *rs; - - /* offset is greater than - size then zero */ - if (offset > (aop->size - 1) && - aop->type != AOP_LIT) - return zero; - - /* depending on type */ - switch (aop->type) { - - case AOP_R0: - case AOP_R1: - /* if we need to increment it */ - while (offset > aop->coff) { - emitcode ("inc","%s",aop->aopu.aop_ptr->name); - aop->coff++; - } - - while (offset < aop->coff) { - emitcode("dec","%s",aop->aopu.aop_ptr->name); - aop->coff--; - } - - aop->coff = offset ; - if (aop->paged) { - emitcode("movx","a,@%s",aop->aopu.aop_ptr->name); - return (dname ? "acc" : "a"); - } - sprintf(s,"@%s",aop->aopu.aop_ptr->name); - ALLOC_ATOMIC(rs,strlen(s)+1); - strcpy(rs,s); - return rs; - - case AOP_DPTR: - while (offset > aop->coff) { - emitcode ("inc","dptr"); - aop->coff++; - } - - while (offset < aop->coff) { - emitcode("lcall","__decdptr"); - aop->coff--; - } - - aop->coff = offset; - if (aop->code) { - emitcode("clr","a"); - emitcode("movc","a,@a+dptr"); - } - else - emitcode("movx","a,@dptr"); - return (dname ? "acc" : "a"); - - - case AOP_IMMD: - if (bit16) - sprintf (s,"#(%s)",aop->aopu.aop_immd); - else - if (offset) - sprintf(s,"#(%s >> %d)", - aop->aopu.aop_immd, - offset*8); - else - sprintf(s,"#%s", - aop->aopu.aop_immd); - ALLOC_ATOMIC(rs,strlen(s)+1); - strcpy(rs,s); - return rs; - - case AOP_DIR: - if (offset) - sprintf(s,"(%s + %d)", - aop->aopu.aop_dir, - offset); - else - sprintf(s,"%s",aop->aopu.aop_dir); - ALLOC_ATOMIC(rs,strlen(s)+1); - strcpy(rs,s); - return rs; - - case AOP_REG: - if (dname) - return aop->aopu.aop_reg[offset]->dname; - else - return aop->aopu.aop_reg[offset]->name; - - case AOP_CRY: - emitcode("clr","a"); - emitcode("mov","c,%s",aop->aopu.aop_dir); - emitcode("rlc","a") ; - return (dname ? "acc" : "a"); - - case AOP_ACC: - if (!offset && dname) - return "acc"; - return aop->aopu.aop_str[offset]; - - case AOP_LIT: - return aopLiteral (aop->aopu.aop_lit,offset); - - case AOP_STR: - aop->coff = offset ; - if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && - dname) - return "acc"; - - return aop->aopu.aop_str[offset]; - - } - - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "aopget got unsupported aop->type"); - exit(0); -} -/*-----------------------------------------------------------------*/ -/* aopPut - puts a string for a aop */ -/*-----------------------------------------------------------------*/ -static void aopPut (asmop *aop, char *s, int offset) -{ - char *d = buffer ; - symbol *lbl ; - - if (aop->size && offset > ( aop->size - 1)) { - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "aopPut got offset > aop->size"); - exit(0); - } - - /* will assign value to value */ - /* depending on where it is ofcourse */ - switch (aop->type) { - case AOP_DIR: - if (offset) - sprintf(d,"(%s + %d)", - aop->aopu.aop_dir,offset); - else - sprintf(d,"%s",aop->aopu.aop_dir); - - if (strcmp(d,s)) - emitcode("mov","%s,%s",d,s); - - break; - - case AOP_REG: - if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 && - strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){ - if (*s == '@' || - strcmp(s,"r0") == 0 || - strcmp(s,"r1") == 0 || - strcmp(s,"r2") == 0 || - strcmp(s,"r3") == 0 || - strcmp(s,"r4") == 0 || - strcmp(s,"r5") == 0 || - strcmp(s,"r6") == 0 || - strcmp(s,"r7") == 0 ) - emitcode("mov","%s,%s", - aop->aopu.aop_reg[offset]->dname,s); - else - emitcode("mov","%s,%s", - aop->aopu.aop_reg[offset]->name,s); - } - break; - - case AOP_DPTR: - if (aop->code) { - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "aopPut writting to code space"); - exit(0); - } - - while (offset > aop->coff) { - aop->coff++; - emitcode ("inc","dptr"); - } - - while (offset < aop->coff) { - aop->coff-- ; - emitcode("lcall","__decdptr"); - } - - aop->coff = offset; - - /* if not in accumulater */ - MOVA(s); - - emitcode ("movx","@dptr,a"); - break; - - case AOP_R0: - case AOP_R1: - while (offset > aop->coff) { - aop->coff++; - emitcode("inc","%s",aop->aopu.aop_ptr->name); - } - while (offset < aop->coff) { - aop->coff-- ; - emitcode ("dec","%s",aop->aopu.aop_ptr->name); - } - aop->coff = offset; - - if (aop->paged) { - MOVA(s); - emitcode("movx","@%s,a",aop->aopu.aop_ptr->name); - - } else - if (*s == '@') { - MOVA(s); - emitcode("mov","@%s,a",aop->aopu.aop_ptr->name); - } else - if (strcmp(s,"r0") == 0 || - strcmp(s,"r1") == 0 || - strcmp(s,"r2") == 0 || - strcmp(s,"r3") == 0 || - strcmp(s,"r4") == 0 || - strcmp(s,"r5") == 0 || - strcmp(s,"r6") == 0 || - strcmp(s,"r7") == 0 ) { - char buffer[10]; - sprintf(buffer,"a%s",s); - emitcode("mov","@%s,%s", - aop->aopu.aop_ptr->name,buffer); - } else - emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s); - - break; - - case AOP_STK: - if (strcmp(s,"a") == 0) - emitcode("push","acc"); - else - emitcode("push","%s",s); - - break; - - case AOP_CRY: - /* if bit variable */ - if (!aop->aopu.aop_dir) { - emitcode("clr","a"); - emitcode("rlc","a"); - } else { - if (s == zero) - emitcode("clr","%s",aop->aopu.aop_dir); - else - if (s == one) - emitcode("setb","%s",aop->aopu.aop_dir); - else - if (!strcmp(s,"c")) - emitcode("mov","%s,c",aop->aopu.aop_dir); - else { - lbl = newiTempLabel(NULL); - - if (strcmp(s,"a")) { - MOVA(s); - } - emitcode("cjne","a,#0x01,%05d$",lbl->key+100); - emitcode("","%05d$:",lbl->key+100); - emitcode("cpl","c"); - emitcode("mov","%s,c",aop->aopu.aop_dir); - } - } - break; - - case AOP_STR: - aop->coff = offset; - if (strcmp(aop->aopu.aop_str[offset],s)) - emitcode ("mov","%s,%s",aop->aopu.aop_str[offset],s); - break; - - case AOP_ACC: - aop->coff = offset; - if (!offset && (strcmp(s,"acc") == 0)) - break; - - if (strcmp(aop->aopu.aop_str[offset],s)) - emitcode ("mov","%s,%s",aop->aopu.aop_str[offset],s); - break; - - default : - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "aopPut got unsupported aop->type"); - exit(0); - } - -} - - -#if 0 -/*-----------------------------------------------------------------*/ -/* pointToEnd :- points to the last byte of the operand */ -/*-----------------------------------------------------------------*/ -static void pointToEnd (asmop *aop) -{ - int count ; - if (!aop) - return ; - - aop->coff = count = (aop->size - 1); - switch (aop->type) { - case AOP_R0 : - case AOP_R1 : - while (count--) - emitcode("inc","%s",aop->aopu.aop_ptr->name); - break; - case AOP_DPTR : - while (count--) - emitcode("inc","dptr"); - break; - } - -} -#endif - -/*-----------------------------------------------------------------*/ -/* reAdjustPreg - points a register back to where it should */ -/*-----------------------------------------------------------------*/ -static void reAdjustPreg (asmop *aop) -{ - int size ; - - aop->coff = 0; - if ((size = aop->size) <= 1) - return ; - size-- ; - switch (aop->type) { - case AOP_R0 : - case AOP_R1 : - while (size--) - emitcode("dec","%s",aop->aopu.aop_ptr->name); - break; - case AOP_DPTR : - while (size--) - emitcode("lcall","__decdptr"); - break; - - } - -} - -#define AOP(op) op->aop -#define AOP_TYPE(op) AOP(op)->type -#define AOP_SIZE(op) AOP(op)->size -#define IS_AOP_PREG(x) (AOP(x) && (AOP_TYPE(x) == AOP_R1 || \ - AOP_TYPE(x) == AOP_R0)) - -#define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY || \ - AOP_TYPE(x) == AOP_DPTR || AOP(x)->paged)) - -#define AOP_INPREG(x) (x && (x->type == AOP_REG && \ - (x->aopu.aop_reg[0] == regWithIdx(R0_IDX) || \ - x->aopu.aop_reg[0] == regWithIdx(R1_IDX) ))) - -/*-----------------------------------------------------------------*/ -/* genNotFloat - generates not for float operations */ -/*-----------------------------------------------------------------*/ -static void genNotFloat (operand *op, operand *res) -{ - int size, offset; - char *l; - symbol *tlbl ; - - /* we will put 127 in the first byte of - the result */ - aopPut(AOP(res),"#127",0); - size = AOP_SIZE(op) - 1; - offset = 1; - - l = aopGet(op->aop,offset++,FALSE,FALSE); - MOVA(l); - - while(size--) { - emitcode("orl","a,%s", - aopGet(op->aop, - offset++,FALSE,FALSE)); - } - tlbl = newiTempLabel(NULL); - - tlbl = newiTempLabel(NULL); - aopPut(res->aop,one,1); - emitcode("jz","%05d$",(tlbl->key+100)); - aopPut(res->aop,zero,1); - emitcode("","%05d$:",(tlbl->key+100)); - - size = res->aop->size - 2; - offset = 2; - /* put zeros in the rest */ - while (size--) - aopPut(res->aop,zero,offset++); -} - -/*-----------------------------------------------------------------*/ -/* getDataSize - get the operand data size */ -/*-----------------------------------------------------------------*/ -int getDataSize(operand *op) -{ - int size; - size = AOP_SIZE(op); - if(size == 3) - /* pointer */ - size--; - return size; -} - -/*-----------------------------------------------------------------*/ -/* outAcc - output Acc */ -/*-----------------------------------------------------------------*/ -void outAcc(operand *result) -{ - int size, offset; - size = getDataSize(result); - if(size){ - aopPut(AOP(result),"a",0); - size--; - offset = 1; - /* unsigned or positive */ - while(size--){ - aopPut(AOP(result),zero,offset++); - } - } -} - -/*-----------------------------------------------------------------*/ -/* outBitC - output a bit C */ -/*-----------------------------------------------------------------*/ -void outBitC(operand *result) -{ - /* if the result is bit */ - if (AOP_TYPE(result) == AOP_CRY) - aopPut(AOP(result),"c",0); - else { - emitcode("clr","a"); - emitcode("rlc","a"); - outAcc(result); - } -} - -/*-----------------------------------------------------------------*/ -/* toBoolean - emit code for orl a,operator(sizeop) */ -/*-----------------------------------------------------------------*/ -void toBoolean(operand *oper) -{ - int size = AOP_SIZE(oper) - 1; - int offset = 1; - MOVA(aopGet(AOP(oper),0,FALSE,FALSE)); - while (size--) - emitcode("orl","a,%s",aopGet(AOP(oper),offset++,FALSE,FALSE)); -} - - -/*-----------------------------------------------------------------*/ -/* genNot - generate code for ! operation */ -/*-----------------------------------------------------------------*/ -static void genNot (iCode *ic) -{ - symbol *tlbl; - link *optype = operandType(IC_LEFT(ic)); - - /* assign asmOps to operand & result */ - aopOp (IC_LEFT(ic),ic,FALSE); - aopOp (IC_RESULT(ic),ic,TRUE); - - /* if in bit space then a special case */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) { - emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); - emitcode("cpl","c"); - outBitC(IC_RESULT(ic)); - goto release; - } - - /* if type float then do float */ - if (IS_FLOAT(optype)) { - genNotFloat(IC_LEFT(ic),IC_RESULT(ic)); - goto release; - } - - toBoolean(IC_LEFT(ic)); - - tlbl = newiTempLabel(NULL); - emitcode("cjne","a,#0x01,%05d$",tlbl->key+100); - emitcode("","%05d$:",tlbl->key+100); - outBitC(IC_RESULT(ic)); - -release: - /* release the aops */ - freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1)); - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); -} - - -/*-----------------------------------------------------------------*/ -/* genCpl - generate code for complement */ -/*-----------------------------------------------------------------*/ -static void genCpl (iCode *ic) -{ - int offset = 0; - int size ; - - - /* assign asmOps to operand & result */ - aopOp (IC_LEFT(ic),ic,FALSE); - aopOp (IC_RESULT(ic),ic,TRUE); - - /* 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 ) { - - emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); - emitcode("cpl","c"); - emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); - goto release; - } - - size = AOP_SIZE(IC_RESULT(ic)); - while (size--) { - char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE); - MOVA(l); - emitcode("cpl","a"); - aopPut(AOP(IC_RESULT(ic)),"a",offset++); - } - - -release: - /* release the aops */ - freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1)); - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genUminusFloat - unary minus for floating points */ -/*-----------------------------------------------------------------*/ -static void genUminusFloat(operand *op,operand *result) -{ - int size ,offset =0 ; - char *l; - /* for this we just need to flip the - first it then copy the rest in place */ - size = AOP_SIZE(op) - 1; - l = aopGet(AOP(op),3,FALSE,FALSE); - - MOVA(l); - - emitcode("cpl","acc.7"); - aopPut(AOP(result),"a",3); - - while(size--) { - aopPut(AOP(result), - aopGet(AOP(op),offset,FALSE,FALSE), - offset); - offset++; - } -} - -/*-----------------------------------------------------------------*/ -/* genUminus - unary minus code generation */ -/*-----------------------------------------------------------------*/ -static void genUminus (iCode *ic) -{ - int offset ,size ; - link *optype, *rtype; - - - /* assign asmops */ - aopOp(IC_LEFT(ic),ic,FALSE); - aopOp(IC_RESULT(ic),ic,TRUE); - - /* if both in bit space then special - case */ - if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY && - AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { - - emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); - emitcode("cpl","c"); - emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); - goto release; - } - - optype = operandType(IC_LEFT(ic)); - rtype = operandType(IC_RESULT(ic)); - - /* if float then do float stuff */ - if (IS_FLOAT(optype)) { - genUminusFloat(IC_LEFT(ic),IC_RESULT(ic)); - goto release; - } - - /* otherwise subtract from zero */ - size = AOP_SIZE(IC_LEFT(ic)); - offset = 0 ; - CLRC ; - while(size--) { - char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE); - if (!strcmp(l,"a")) { - emitcode("cpl","a"); - emitcode("inc","a"); - } else { - emitcode("clr","a"); - emitcode("subb","a,%s",l); - } - aopPut(AOP(IC_RESULT(ic)),"a",offset++); - } - - /* if any remaining bytes in the result */ - /* we just need to propagate the sign */ - if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) { - emitcode("rlc","a"); - emitcode("subb","a,acc"); - while (size--) - aopPut(AOP(IC_RESULT(ic)),"a",offset++); - } - -release: - /* release the aops */ - freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1)); - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* saveRegisters - will look for a call and save the registers */ -/*-----------------------------------------------------------------*/ -static void saveRegisters(iCode *lic) -{ - int i; - iCode *ic; - bitVect *rsave; - link *detype; - - /* look for call */ - for (ic = lic ; ic ; ic = ic->next) - if (ic->op == CALL || ic->op == PCALL) - break; - - if (!ic) { - fprintf(stderr,"found parameter push with no function call\n"); - return ; - } - - /* if the registers have been saved already then - do nothing */ - if (ic->regsSaved || (OP_SYMBOL(IC_LEFT(ic))->calleeSave)) - return ; - - /* find the registers in use at this time - and push them away to safety */ - rsave = bitVectCplAnd(bitVectCopy(ic->rMask), - ic->rUsed); - - ic->regsSaved = 1; - if (options.useXstack) { - if (bitVectBitValue(rsave,R0_IDX)) - emitcode("mov","b,r0"); - emitcode("mov","r0,%s",spname); - for (i = 0 ; i < nRegs ; i++) { - if (bitVectBitValue(rsave,i)) { - if (i == R0_IDX) - emitcode("mov","a,b"); - else - emitcode("mov","a,%s",regWithIdx(i)->name); - emitcode("movx","@r0,a"); - emitcode("inc","r0"); - } - } - emitcode("mov","%s,r0",spname); - if (bitVectBitValue(rsave,R0_IDX)) - emitcode("mov","r0,b"); - } else - for (i = 0 ; i < nRegs ; i++) { - if (bitVectBitValue(rsave,i)) - emitcode("push","%s",regWithIdx(i)->dname); - } - - detype = getSpec(operandType(IC_LEFT(ic))); - if (detype && - (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) && - IS_ISR(currFunc->etype) && - !ic->bankSaved) - - saverbank(SPEC_BANK(detype),ic,TRUE); - -} -/*-----------------------------------------------------------------*/ -/* unsaveRegisters - pop the pushed registers */ -/*-----------------------------------------------------------------*/ -static void unsaveRegisters (iCode *ic) -{ - int i; - bitVect *rsave; - /* find the registers in use at this time - and push them away to safety */ - rsave = bitVectCplAnd(bitVectCopy(ic->rMask), - ic->rUsed); - - if (options.useXstack) { - emitcode("mov","r0,%s",spname); - for (i = nRegs ; i >= 0 ; i--) { - if (bitVectBitValue(rsave,i)) { - emitcode("dec","r0"); - emitcode("movx","a,@r0"); - if (i == R0_IDX) - emitcode("mov","b,a"); - else - emitcode("mov","%s,a",regWithIdx(i)->name); - } - - } - emitcode("mov","%s,r0",spname); - if (bitVectBitValue(rsave,R0_IDX)) - emitcode("mov","r0,b"); - } else - for (i = nRegs ; i >= 0 ; i--) { - if (bitVectBitValue(rsave,i)) - emitcode("pop","%s",regWithIdx(i)->dname); - } - -} - - -/*-----------------------------------------------------------------*/ -/* pushSide - */ -/*-----------------------------------------------------------------*/ -void pushSide(operand * oper, int size) -{ - int offset = 0; - while (size--) { - char *l = aopGet(AOP(oper),offset++,FALSE,TRUE); - if (AOP_TYPE(oper) != AOP_REG && - AOP_TYPE(oper) != AOP_DIR && - strcmp(l,"a") ) { - emitcode("mov","a,%s",l); - emitcode("push","acc"); - } else - emitcode("push","%s",l); - } -} - -/*-----------------------------------------------------------------*/ -/* assignResultValue - */ -/*-----------------------------------------------------------------*/ -void assignResultValue(operand * oper) -{ - int offset = 0; - int size = AOP_SIZE(oper); - while (size--) { - aopPut(AOP(oper),fReturn[offset],offset); - offset++; - } -} - - -/*-----------------------------------------------------------------*/ -/* genXpush - pushes onto the external stack */ -/*-----------------------------------------------------------------*/ -static void genXpush (iCode *ic) -{ - asmop *aop = newAsmop(0); - regs *r ; - int size,offset = 0; - - aopOp(IC_LEFT(ic),ic,FALSE); - r = getFreePtr(ic,&aop,FALSE); - - - emitcode("mov","%s,_spx",r->name); - - size = AOP_SIZE(IC_LEFT(ic)); - while(size--) { - - char *l = aopGet(AOP(IC_LEFT(ic)), - offset++,FALSE,FALSE); - MOVA(l); - emitcode("movx","@%s,a",r->name); - emitcode("inc","%s",r->name); - - } - - - emitcode("mov","_spx,%s",r->name); - - freeAsmop(NULL,aop,ic,TRUE); - freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genIpush - genrate code for pushing this gets a little complex */ -/*-----------------------------------------------------------------*/ -static void genIpush (iCode *ic) -{ - int size, offset = 0 ; - char *l; - - - /* if this is not a parm push : ie. it is spill push - and spill push is always done on the local stack */ - if (!ic->parmPush) { - - /* and the item is spilt then do nothing */ - if (OP_SYMBOL(IC_LEFT(ic))->isspilt) - return ; - - aopOp(IC_LEFT(ic),ic,FALSE); - size = AOP_SIZE(IC_LEFT(ic)); - /* push it on the stack */ - while(size--) { - l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE); - if (*l == '#') { - MOVA(l); - l = "acc"; - } - emitcode("push","%s",l); - } - return ; - } - - /* this is a paramter push: in this case we call - the routine to find the call and save those - registers that need to be saved */ - saveRegisters(ic); - - /* if use external stack then call the external - stack pushing routine */ - if (options.useXstack) { - genXpush(ic); - return ; - } - - /* then do the push */ - aopOp(IC_LEFT(ic),ic,FALSE); - - - // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic))); - size = AOP_SIZE(IC_LEFT(ic)); - - while (size--) { - l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE); - if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && - AOP_TYPE(IC_LEFT(ic)) != AOP_DIR && - strcmp(l,"a") ) { - emitcode("mov","a,%s",l); - emitcode("push","acc"); - } else - emitcode("push","%s",l); - } - - freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genIpop - recover the registers: can happen only for spilling */ -/*-----------------------------------------------------------------*/ -static void genIpop (iCode *ic) -{ - int size,offset ; - - - /* if the temp was not pushed then */ - if (OP_SYMBOL(IC_LEFT(ic))->isspilt) - return ; - - aopOp(IC_LEFT(ic),ic,FALSE); - size = AOP_SIZE(IC_LEFT(ic)); - offset = (size-1); - while (size--) - emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--, - FALSE,TRUE)); - - freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* unsaverbank - restores the resgister bank from stack */ -/*-----------------------------------------------------------------*/ -static void unsaverbank (int bank,iCode *ic,bool popPsw) -{ - int i; - asmop *aop ; - regs *r = NULL; - - if (popPsw) { - if (options.useXstack) { - aop = newAsmop(0); - r = getFreePtr(ic,&aop,FALSE); - - - emitcode("mov","%s,_spx",r->name); - emitcode("movx","a,@%s",r->name); - emitcode("mov","psw,a"); - emitcode("dec","%s",r->name); - - }else - emitcode ("pop","psw"); - } - - for (i = (nRegs - 1) ; i >= 0 ;i--) { - if (options.useXstack) { - emitcode("movx","a,@%s",r->name); - emitcode("mov","(%s+%d),a", - regs8051[i].base,8*bank+regs8051[i].offset); - emitcode("dec","%s",r->name); - - } else - emitcode("pop","(%s+%d)", - regs8051[i].base,8*bank+regs8051[i].offset); - } - - if (options.useXstack) { - - emitcode("mov","_spx,%s",r->name); - freeAsmop(NULL,aop,ic,TRUE); - - } -} - -/*-----------------------------------------------------------------*/ -/* saverbank - saves an entire register bank on the stack */ -/*-----------------------------------------------------------------*/ -static void saverbank (int bank, iCode *ic, bool pushPsw) -{ - int i; - asmop *aop ; - regs *r = NULL; - - if (options.useXstack) { - - aop = newAsmop(0); - r = getFreePtr(ic,&aop,FALSE); - emitcode("mov","%s,_spx",r->name); - - } - - for (i = 0 ; i < nRegs ;i++) { - if (options.useXstack) { - emitcode("inc","%s",r->name); - emitcode("mov","a,(%s+%d)", - regs8051[i].base,8*bank+regs8051[i].offset); - emitcode("movx","@%s,a",r->name); - } else - emitcode("push","(%s+%d)", - regs8051[i].base,8*bank+regs8051[i].offset); - } - - if (pushPsw) { - if (options.useXstack) { - emitcode("mov","a,psw"); - emitcode("movx","@%s,a",r->name); - emitcode("inc","%s",r->name); - emitcode("mov","_spx,%s",r->name); - freeAsmop (NULL,aop,ic,TRUE); - - } else - emitcode("push","psw"); - - emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff); - } - ic->bankSaved = 1; - -} - -/*-----------------------------------------------------------------*/ -/* genCall - generates a call statement */ -/*-----------------------------------------------------------------*/ -static void genCall (iCode *ic) -{ - link *detype; - - /* 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 */ - detype = getSpec(operandType(IC_LEFT(ic))); - if (detype && - (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) && - IS_ISR(currFunc->etype) && - !ic->bankSaved) - - saverbank(SPEC_BANK(detype),ic,TRUE); - - /* if send set is not empty the assign */ - if (sendSet) { - iCode *sic ; - - for (sic = setFirstItem(sendSet) ; sic ; - sic = setNextItem(sendSet)) { - int size, offset = 0; - aopOp(IC_LEFT(sic),sic,FALSE); - size = AOP_SIZE(IC_LEFT(sic)); - while (size--) { - char *l = aopGet(AOP(IC_LEFT(sic)),offset, - FALSE,FALSE); - if (strcmp(l,fReturn[offset])) - emitcode("mov","%s,%s", - fReturn[offset], - l); - offset++; - } - freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); - } - sendSet = NULL; - } - /* make the call */ - emitcode("lcall","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ? - OP_SYMBOL(IC_LEFT(ic))->rname : - OP_SYMBOL(IC_LEFT(ic))->name)); - - /* 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)) ) { - - accInUse++; - aopOp(IC_RESULT(ic),ic,FALSE); - accInUse--; - - assignResultValue(IC_RESULT(ic)); - - freeAsmop(IC_RESULT(ic),NULL, ic,TRUE); - } - - /* adjust the stack for parameters if - required */ - if (IC_LEFT(ic)->parmBytes) { - int i; - if (IC_LEFT(ic)->parmBytes > 3) { - emitcode("mov","a,%s",spname); - emitcode("add","a,#0x%02x", (- IC_LEFT(ic)->parmBytes) & 0xff); - emitcode("mov","%s,a",spname); - } else - for ( i = 0 ; i < IC_LEFT(ic)->parmBytes ;i++) - emitcode("dec","%s",spname); - - } - - /* if register bank was saved then pop them */ - if (ic->bankSaved) - unsaverbank(SPEC_BANK(detype),ic,TRUE); - - /* if we hade saved some registers then unsave them */ - if (ic->regsSaved && !(OP_SYMBOL(IC_LEFT(ic))->calleeSave)) - unsaveRegisters (ic); - - -} - -/*-----------------------------------------------------------------*/ -/* genPcall - generates a call by pointer statement */ -/*-----------------------------------------------------------------*/ -static void genPcall (iCode *ic) -{ - link *detype; - symbol *rlbl = newiTempLabel(NULL); - - - /* 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 */ - detype = getSpec(operandType(IC_LEFT(ic))); - if (detype && - IS_ISR(currFunc->etype) && - (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype))) - saverbank(SPEC_BANK(detype),ic,TRUE); - - - /* push the return address on to the stack */ - emitcode("mov","a,#%05d$",(rlbl->key+100)); - emitcode("push","acc"); - emitcode("mov","a,#(%05d$ >> 8)",(rlbl->key+100)); - emitcode("push","acc"); - - /* now push the calling address */ - aopOp(IC_LEFT(ic),ic,FALSE); - - pushSide(IC_LEFT(ic), 2); - - freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); - - /* if send set is not empty the assign */ - if (sendSet) { - iCode *sic ; - - for (sic = setFirstItem(sendSet) ; sic ; - sic = setNextItem(sendSet)) { - int size, offset = 0; - aopOp(IC_LEFT(sic),sic,FALSE); - size = AOP_SIZE(IC_LEFT(sic)); - while (size--) { - char *l = aopGet(AOP(IC_LEFT(sic)),offset, - FALSE,FALSE); - if (strcmp(l,fReturn[offset])) - emitcode("mov","%s,%s", - fReturn[offset], - l); - offset++; - } - freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); - } - sendSet = NULL; - } - - emitcode("ret",""); - emitcode("","%05d$:",(rlbl->key+100)); - - - /* 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)) ) { - - accInUse++; - aopOp(IC_RESULT(ic),ic,FALSE); - accInUse--; - - assignResultValue(IC_RESULT(ic)); - - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); - } - - /* adjust the stack for parameters if - required */ - if (IC_LEFT(ic)->parmBytes) { - int i; - if (IC_LEFT(ic)->parmBytes > 3) { - emitcode("mov","a,%s",spname); - emitcode("add","a,#0x%02x", (- IC_LEFT(ic)->parmBytes) & 0xff); - emitcode("mov","%s,a",spname); - } else - for ( i = 0 ; i < IC_LEFT(ic)->parmBytes ;i++) - emitcode("dec","%s",spname); - - } - - /* if register bank was saved then unsave them */ - if (detype && - (SPEC_BANK(currFunc->etype) != - SPEC_BANK(detype))) - unsaverbank(SPEC_BANK(detype),ic,TRUE); - - /* if we hade saved some registers then - unsave them */ - if (ic->regsSaved) - unsaveRegisters (ic); - -} - -/*-----------------------------------------------------------------*/ -/* resultRemat - result is rematerializable */ -/*-----------------------------------------------------------------*/ -static int resultRemat (iCode *ic) -{ - if (SKIP_IC(ic) || ic->op == IFX) - return 0; - - if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) { - symbol *sym = OP_SYMBOL(IC_RESULT(ic)); - if (sym->remat && !POINTER_SET(ic)) - return 1; - } - - return 0; -} - -/*-----------------------------------------------------------------*/ -/* inExcludeList - return 1 if the string is in exclude Reg list */ -/*-----------------------------------------------------------------*/ -static bool inExcludeList(char *s) -{ - int i =0; - - if (options.excludeRegs[i] && - strcasecmp(options.excludeRegs[i],"none") == 0) - return FALSE ; - - for ( i = 0 ; options.excludeRegs[i]; i++) { - if (options.excludeRegs[i] && - strcasecmp(s,options.excludeRegs[i]) == 0) - return TRUE; - } - return FALSE ; -} - -/*-----------------------------------------------------------------*/ -/* genFunction - generated code for function entry */ -/*-----------------------------------------------------------------*/ -static void genFunction (iCode *ic) -{ - symbol *sym; - link *fetype; - - nregssaved = 0; - /* create the function header */ - emitcode(";","-----------------------------------------"); - emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name); - emitcode(";","-----------------------------------------"); - - emitcode("","%s:",sym->rname); - fetype = getSpec(operandType(IC_LEFT(ic))); - - /* if critical function then turn interrupts off */ - if (SPEC_CRTCL(fetype)) - emitcode("clr","ea"); - - /* here we need to generate the equates for the - register bank if required */ - if (SPEC_BANK(fetype) != rbank) { - int i ; - - rbank = SPEC_BANK(fetype); - for ( i = 0 ; i < nRegs ; i++ ) { - if (strcmp(regs8051[i].base,"0") == 0) - emitcode("","%s = 0x%02x", - regs8051[i].dname, - 8*rbank+regs8051[i].offset); - else - emitcode ("","%s = %s + 0x%02x", - regs8051[i].dname, - regs8051[i].base, - 8*rbank+regs8051[i].offset); - } - } - - /* if this is an interrupt service routine then - save acc, b, dpl, dph */ - if (IS_ISR(sym->etype)) { - - if (!inExcludeList("acc")) - emitcode ("push","acc"); - if (!inExcludeList("b")) - emitcode ("push","b"); - if (!inExcludeList("dpl")) - emitcode ("push","dpl"); - if (!inExcludeList("dph")) - emitcode ("push","dph"); - - /* if this isr has no bank i.e. is going to - run with bank 0 , then we need to save more - registers :-) */ - if (!SPEC_BANK(sym->etype)) { - - /* if this function does not call any other - function then we can be economical and - save only those registers that are used */ - if (! sym->hasFcall) { - int i; - - /* if any registers used */ - if (sym->regsUsed) { - /* save the registers used */ - for ( i = 0 ; i < sym->regsUsed->size ; i++) { - if (bitVectBitValue(sym->regsUsed,i) || - (ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) - emitcode("push","%s",regWithIdx(i)->dname); - } - } - - } else { - /* this function has a function call cannot - determines register usage so we will have the - entire bank */ - saverbank(0,ic,FALSE); - } - } - } else { - /* if callee-save to be used for this function - then save the registers being used in this function */ - if (sym->calleeSave) { - int i; - - /* if any registers used */ - if (sym->regsUsed) { - /* save the registers used */ - for ( i = 0 ; i < sym->regsUsed->size ; i++) { - if (bitVectBitValue(sym->regsUsed,i) || - (ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) { - emitcode("push","%s",regWithIdx(i)->dname); - nregssaved++; - } - } - } - } - } - - /* set the register bank to the desired value */ - if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) { - emitcode("push","psw"); - emitcode("mov","psw,#0x%02x",(SPEC_BANK(sym->etype) << 3)&0x00ff); - } - - if (IS_RENT(sym->etype) || options.stackAuto) { - - if (options.useXstack) { - emitcode("mov","r0,%s",spname); - emitcode("mov","a,_bp"); - emitcode("movx","@r0,a"); - emitcode("inc","%s",spname); - } - else - /* set up the stack */ - emitcode ("push","_bp"); /* save the callers stack */ - emitcode ("mov","_bp,%s",spname); - } - - /* adjust the stack for the function */ - if (sym->stack) { - - int i = sym->stack; - if (i > 256 ) - werror(W_STACK_OVERFLOW,sym->name); - - if (i > 3 && sym->recvSize < 4) { - - emitcode ("mov","a,sp"); - emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff)); - emitcode ("mov","sp,a"); - - } - else - while(i--) - emitcode("inc","sp"); - } - - if (sym->xstack) { - - emitcode ("mov","a,_spx"); - emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff)); - emitcode ("mov","_spx,a"); - } - -} - -/*-----------------------------------------------------------------*/ -/* genEndFunction - generates epilogue for functions */ -/*-----------------------------------------------------------------*/ -static void genEndFunction (iCode *ic) -{ - symbol *sym = OP_SYMBOL(IC_LEFT(ic)); - - if (IS_RENT(sym->etype) || options.stackAuto) - emitcode ("mov","%s,_bp",spname); - - /* if use external stack but some variables were - added to the local stack then decrement the - local stack */ - if (options.useXstack && sym->stack) { - emitcode("mov","a,sp"); - emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff); - emitcode("mov","sp,a"); - } - - - if ((IS_RENT(sym->etype) || options.stackAuto)) { - if (options.useXstack) { - emitcode("mov","r0,%s",spname); - emitcode("movx","a,@r0"); - emitcode("mov","_bp,a"); - emitcode("dec","%s",spname); - } - else - emitcode ("pop","_bp"); - } - - /* restore the register bank */ - if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) - emitcode ("pop","psw"); - - if (IS_ISR(sym->etype)) { - - /* now we need to restore the registers */ - /* if this isr has no bank i.e. is going to - run with bank 0 , then we need to save more - registers :-) */ - if (!SPEC_BANK(sym->etype)) { - - /* if this function does not call any other - function then we can be economical and - save only those registers that are used */ - if (! sym->hasFcall) { - int i; - - /* if any registers used */ - if (sym->regsUsed) { - /* save the registers used */ - for ( i = sym->regsUsed->size ; i >= 0 ; i--) { - if (bitVectBitValue(sym->regsUsed,i) || - (ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) - emitcode("pop","%s",regWithIdx(i)->dname); - } - } - - } else { - /* this function has a function call cannot - determines register usage so we will have the - entire bank */ - unsaverbank(0,ic,FALSE); - } - } - - if (!inExcludeList("dph")) - emitcode ("pop","dph"); - if (!inExcludeList("dpl")) - emitcode ("pop","dpl"); - if (!inExcludeList("b")) - emitcode ("pop","b"); - if (!inExcludeList("acc")) - emitcode ("pop","acc"); - - if (SPEC_CRTCL(sym->etype)) - emitcode("setb","ea"); - - /* if debug then send end of function */ -/* if (options.debug && currFunc) { */ - if (currFunc) { - debugLine = 1; - emitcode("","C$%s$%d$%d$%d ==.", - ic->filename,currFunc->lastLine, - ic->level,ic->block); - if (IS_STATIC(currFunc->etype)) - emitcode("","XF%s$%s$0$0 ==.",moduleName,currFunc->name); - else - emitcode("","XG$%s$0$0 ==.",currFunc->name); - debugLine = 0; - } - - emitcode ("reti",""); - } - else { - if (SPEC_CRTCL(sym->etype)) - emitcode("setb","ea"); - - if (sym->calleeSave) { - int i; - - /* if any registers used */ - if (sym->regsUsed) { - /* save the registers used */ - for ( i = sym->regsUsed->size ; i >= 0 ; i--) { - if (bitVectBitValue(sym->regsUsed,i) || - (ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) - emitcode("pop","%s",regWithIdx(i)->dname); - } - } - - } - - /* if debug then send end of function */ -/* if (options.debug && currFunc) { */ - if (currFunc) { - debugLine = 1; - emitcode("","C$%s$%d$%d$%d ==.", - ic->filename,currFunc->lastLine, - ic->level,ic->block); - if (IS_STATIC(currFunc->etype)) - emitcode("","XF%s$%s$0$0 ==.",moduleName,currFunc->name); - else - emitcode("","XG$%s$0$0 ==.",currFunc->name); - debugLine = 0; - } - - emitcode ("ret",""); - } - -} - -/*-----------------------------------------------------------------*/ -/* genRet - generate code for return statement */ -/*-----------------------------------------------------------------*/ -static void genRet (iCode *ic) -{ - int size,offset = 0 , pushed = 0; - - /* if we have no return value then - just generate the "ret" */ - if (!IC_LEFT(ic)) - goto jumpret; - - /* we have something to return then - move the return value into place */ - aopOp(IC_LEFT(ic),ic,FALSE); - size = AOP_SIZE(IC_LEFT(ic)); - - while (size--) { - char *l ; - if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) { - l = aopGet(AOP(IC_LEFT(ic)),offset++, - FALSE,TRUE); - emitcode("push","%s",l); - pushed++; - } else { - l = aopGet(AOP(IC_LEFT(ic)),offset, - FALSE,FALSE); - if (strcmp(fReturn[offset],l)) - emitcode("mov","%s,%s",fReturn[offset++],l); - } - } - - if (pushed) { - while(pushed) { - pushed--; - if (strcmp(fReturn[pushed],"a")) - emitcode("pop",fReturn[pushed]); - else - emitcode("pop","acc"); - } - } - freeAsmop (IC_LEFT(ic),NULL,ic,TRUE); - - jumpret: - /* generate a jump to the return label - if the next is not the return statement */ - if (!(ic->next && ic->next->op == LABEL && - IC_LABEL(ic->next) == returnLabel)) - - emitcode("ljmp","%05d$",(returnLabel->key+100)); - -} - -/*-----------------------------------------------------------------*/ -/* genLabel - generates a label */ -/*-----------------------------------------------------------------*/ -static void genLabel (iCode *ic) -{ - /* special case never generate */ - if (IC_LABEL(ic) == entryLabel) - return ; - - emitcode("","%05d$:",(IC_LABEL(ic)->key+100)); -} - -/*-----------------------------------------------------------------*/ -/* genGoto - generates a ljmp */ -/*-----------------------------------------------------------------*/ -static void genGoto (iCode *ic) -{ - emitcode ("ljmp","%05d$",(IC_LABEL(ic)->key+100)); -} - -/*-----------------------------------------------------------------*/ -/* genPlusIncr :- does addition with increment if possible */ -/*-----------------------------------------------------------------*/ -static bool genPlusIncr (iCode *ic) -{ - unsigned int icount ; - unsigned int size = getDataSize(IC_RESULT(ic)); - - /* will try to generate an increment */ - /* if the right side is not a literal - we cannot */ - if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) - return FALSE ; - - /* if the literal value of the right hand side - is greater than 4 then it is not worth it */ - if ((icount = floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 4) - return FALSE ; - - /* if increment 16 bits in register */ - if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) && - (size > 1) && - (icount == 1)) { - symbol *tlbl = newiTempLabel(NULL); - emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); - if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG || - IS_AOP_PREG(IC_RESULT(ic))) - emitcode("cjne","%s,#0x00,%05d$" - ,aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE) - ,tlbl->key+100); - else { - emitcode("clr","a"); - emitcode("cjne","a,%s,%05d$" - ,aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE) - ,tlbl->key+100); - } - - emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE)); - if(size == 4){ - if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG || - IS_AOP_PREG(IC_RESULT(ic))) - emitcode("cjne","%s,#0x00,%05d$" - ,aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE) - ,tlbl->key+100); - else - emitcode("cjne","a,%s,%05d$" - ,aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE) - ,tlbl->key+100); - - emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE)); - if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG || - IS_AOP_PREG(IC_RESULT(ic))) - emitcode("cjne","%s,#0x00,%05d$" - ,aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE) - ,tlbl->key+100); - else{ - emitcode("cjne","a,%s,%05d$" - ,aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE) - ,tlbl->key+100); - } - emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE)); - } - emitcode("","%05d$:",tlbl->key+100); - return TRUE; - } - - /* if the sizes are greater than 1 then we cannot */ - if (AOP_SIZE(IC_RESULT(ic)) > 1 || - AOP_SIZE(IC_LEFT(ic)) > 1 ) - return FALSE ; - - /* we can if the aops of the left & result match or - if they are in registers and the registers are the - same */ - if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - - if (icount > 3) { - MOVA(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - emitcode("add","a,#0x%02x",((char) icount) & 0xff); - aopPut(AOP(IC_RESULT(ic)),"a",0); - } else { - - while (icount--) - emitcode ("inc","%s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE)); - } - - return TRUE ; - } - - return FALSE ; -} - -/*-----------------------------------------------------------------*/ -/* outBitAcc - output a bit in acc */ -/*-----------------------------------------------------------------*/ -void outBitAcc(operand *result) -{ - symbol *tlbl = newiTempLabel(NULL); - /* if the result is a bit */ - if (AOP_TYPE(result) == AOP_CRY){ - aopPut(AOP(result),"a",0); - } - else { - emitcode("jz","%05d$",tlbl->key+100); - emitcode("mov","a,%s",one); - emitcode("","%05d$:",tlbl->key+100); - outAcc(result); - } -} - -/*-----------------------------------------------------------------*/ -/* genPlusBits - generates code for addition of two bits */ -/*-----------------------------------------------------------------*/ -static void genPlusBits (iCode *ic) -{ - if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){ - symbol *lbl = newiTempLabel(NULL); - emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir); - emitcode("jnb","%s,%05d$",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100)); - emitcode("cpl","c"); - emitcode("","%05d$:",(lbl->key+100)); - outBitC(IC_RESULT(ic)); - } - else{ - emitcode("clr","a"); - emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir); - emitcode("rlc","a"); - emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir); - emitcode("addc","a,#0x00"); - outAcc(IC_RESULT(ic)); - } -} - -/*-----------------------------------------------------------------*/ -/* genPlus - generates code for addition */ -/*-----------------------------------------------------------------*/ -static void genPlus (iCode *ic) -{ - int size, offset = 0; - - /* special cases :- */ - - aopOp (IC_LEFT(ic),ic,FALSE); - aopOp (IC_RIGHT(ic),ic,FALSE); - aopOp (IC_RESULT(ic),ic,TRUE); - - /* if literal, literal on the right or - if left requires ACC or right is already - in ACC */ - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || - (AOP_NEEDSACC(IC_LEFT(ic))) || - AOP_TYPE(IC_RIGHT(ic)) == AOP_ACC ){ - operand *t = IC_RIGHT(ic); - IC_RIGHT(ic) = IC_LEFT(ic); - IC_LEFT(ic) = t; - } - - /* if both left & right are in bit - space */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && - AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { - genPlusBits (ic); - goto release ; - } - - /* if left in bit space & right literal */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && - AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) { - emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir); - /* if result in bit space */ - if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){ - if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) - emitcode("cpl","c"); - outBitC(IC_RESULT(ic)); - } else { - size = getDataSize(IC_RESULT(ic)); - while (size--) { - MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - emitcode("addc","a,#00"); - aopPut(AOP(IC_RESULT(ic)),"a",offset++); - } - } - goto release ; - } - - /* if I can do an increment instead - of add then GOOD for ME */ - if (genPlusIncr (ic) == TRUE) - goto release; - - size = getDataSize(IC_RESULT(ic)); - - while(size--){ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { - MOVA(aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - if(offset == 0) - emitcode("add","a,%s", - aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - else - emitcode("addc","a,%s", - aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - } else { - MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - if(offset == 0) - emitcode("add","a,%s", - aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - else - emitcode("addc","a,%s", - aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - } - aopPut(AOP(IC_RESULT(ic)),"a",offset++); - } - - if (AOP_SIZE(IC_RESULT(ic)) == 3 && - AOP_SIZE(IC_LEFT(ic)) == 3 && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic)))) - aopPut(AOP(IC_RESULT(ic)), - aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE), - 2); - - if (AOP_SIZE(IC_RESULT(ic)) == 3 && - AOP_SIZE(IC_RIGHT(ic)) == 3 && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) - aopPut(AOP(IC_RESULT(ic)), - aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE), - 2); - - if (AOP_SIZE(IC_RESULT(ic)) == 3 && - AOP_SIZE(IC_LEFT(ic)) < 3 && - AOP_SIZE(IC_RIGHT(ic)) < 3 && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) { - char buffer[5]; - sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic))))); - aopPut(AOP(IC_RESULT(ic)),buffer,2); - } -release: - freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genMinusDec :- does subtraction with deccrement if possible */ -/*-----------------------------------------------------------------*/ -static bool genMinusDec (iCode *ic) -{ - unsigned int icount ; - unsigned int size = getDataSize(IC_RESULT(ic)); - - /* will try to generate an increment */ - /* if the right side is not a literal - we cannot */ - if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) - return FALSE ; - - /* if the literal value of the right hand side - is greater than 4 then it is not worth it */ - if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 4) - return FALSE ; - - size = getDataSize(IC_RESULT(ic)); - /* if decrement 16 bits in register */ - if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) && - (size > 1) && - (icount == 1)) { - symbol *tlbl = newiTempLabel(NULL); - emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)); - if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG || - IS_AOP_PREG(IC_RESULT(ic))) - emitcode("cjne","%s,#0xff,%05d$" - ,aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE) - ,tlbl->key+100); - else{ - emitcode("mov","a,#0xff"); - emitcode("cjne","a,%s,%05d$" - ,aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE) - ,tlbl->key+100); - } - emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE)); - if(size == 4){ - if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG || - IS_AOP_PREG(IC_RESULT(ic))) - emitcode("cjne","%s,#0xff,%05d$" - ,aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE) - ,tlbl->key+100); - else{ - emitcode("cjne","a,%s,%05d$" - ,aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE) - ,tlbl->key+100); - } - emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE)); - if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG || - IS_AOP_PREG(IC_RESULT(ic))) - emitcode("cjne","%s,#0xff,%05d$" - ,aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE) - ,tlbl->key+100); - else{ - emitcode("cjne","a,%s,%05d$" - ,aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE) - ,tlbl->key+100); - } - emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE)); - } - emitcode("","%05d$:",tlbl->key+100); - return TRUE; - } - - /* if the sizes are greater than 1 then we cannot */ - if (AOP_SIZE(IC_RESULT(ic)) > 1 || - AOP_SIZE(IC_LEFT(ic)) > 1 ) - return FALSE ; - - /* we can if the aops of the left & result match or - if they are in registers and the registers are the - same */ - if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) { - - while (icount--) - emitcode ("dec","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - - return TRUE ; - } - - return FALSE ; -} - -/*-----------------------------------------------------------------*/ -/* addSign - complete with sign */ -/*-----------------------------------------------------------------*/ -static void addSign(operand *result, int offset, int sign) -{ - int size = (getDataSize(result) - offset); - if(size > 0){ - if(sign){ - emitcode("rlc","a"); - emitcode("subb","a,acc"); - while(size--) - aopPut(AOP(result),"a",offset++); - } else - while(size--) - aopPut(AOP(result),zero,offset++); - } -} - -/*-----------------------------------------------------------------*/ -/* genMinusBits - generates code for subtraction of two bits */ -/*-----------------------------------------------------------------*/ -static void genMinusBits (iCode *ic) -{ - symbol *lbl = newiTempLabel(NULL); - if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){ - emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir); - emitcode("jnb","%s,%05d$",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100)); - emitcode("cpl","c"); - emitcode("","%05d$:",(lbl->key+100)); - outBitC(IC_RESULT(ic)); - } - else{ - emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir); - emitcode("subb","a,acc"); - emitcode("jnb","%s,%05d$",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100)); - emitcode("inc","a"); - emitcode("","%05d$:",(lbl->key+100)); - aopPut(AOP(IC_RESULT(ic)),"a",0); - addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic))))); - } -} - -/*-----------------------------------------------------------------*/ -/* genMinus - generates code for subtraction */ -/*-----------------------------------------------------------------*/ -static void genMinus (iCode *ic) -{ - int size, offset = 0; - unsigned long lit = 0L; - - aopOp (IC_LEFT(ic),ic,FALSE); - aopOp (IC_RIGHT(ic),ic,FALSE); - aopOp (IC_RESULT(ic),ic,TRUE); - - /* special cases :- */ - /* if both left & right are in bit space */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && - AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { - genMinusBits (ic); - goto release ; - } - - /* if I can do an decrement instead - of subtract then GOOD for ME */ - if (genMinusDec (ic) == TRUE) - goto release; - - size = getDataSize(IC_RESULT(ic)); - - if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT){ - CLRC; - } - else{ - lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); - lit = - (long)lit; - } - - /* if literal, add a,#-lit, else normal subb */ - while (size--) { - MOVA(aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE)); - if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) - emitcode("subb","a,%s", - aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE)); - else{ - /* first add without previous c */ - if(!offset) - emitcode("add","a,#0x%02x", - (unsigned int)(lit & 0x0FFL)); - else - emitcode("addc","a,#0x%02x", - (unsigned int)((lit >> (offset*8)) & 0x0FFL)); - } - aopPut(AOP(IC_RESULT(ic)),"a",offset++); - } - - if (AOP_SIZE(IC_RESULT(ic)) == 3 && - AOP_SIZE(IC_LEFT(ic)) == 3 && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic)))) - aopPut(AOP(IC_RESULT(ic)), - aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE), - 2); - - if (AOP_SIZE(IC_RESULT(ic)) == 3 && - AOP_SIZE(IC_RIGHT(ic)) == 3 && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) - aopPut(AOP(IC_RESULT(ic)), - aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE), - 2); - - if (AOP_SIZE(IC_RESULT(ic)) == 3 && - AOP_SIZE(IC_LEFT(ic)) < 3 && - AOP_SIZE(IC_RIGHT(ic)) < 3 && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) && - !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) { - char buffer[5]; - sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic))))); - aopPut(AOP(IC_RESULT(ic)),buffer,2); - } -release: - freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); -} - - -/*-----------------------------------------------------------------*/ -/* genMultbits :- multiplication of bits */ -/*-----------------------------------------------------------------*/ -static void genMultbits (operand *left, - operand *right, - operand *result) -{ - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); - outBitC(result); -} - - -/*-----------------------------------------------------------------*/ -/* genMultOneByte : 8 bit multiplication & division */ -/*-----------------------------------------------------------------*/ -static void genMultOneByte (operand *left, - operand *right, - operand *result) -{ - link *opetype = operandType(result); - char *l ; - symbol *lbl ; - int size,offset; - - /* (if two literals, the value is computed before) */ - /* if one literal, literal on the right */ - if (AOP_TYPE(left) == AOP_LIT){ - operand *t = right; - right = left; - left = t; - } - - size = AOP_SIZE(result); - /* signed or unsigned */ - emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE)); - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("mul","ab"); - /* if result size = 1, mul signed = mul unsigned */ - aopPut(AOP(result),"a",0); - if (size > 1){ - if (SPEC_USIGN(opetype)){ - aopPut(AOP(result),"b",1); - if (size > 2) - /* for filling the MSBs */ - emitcode("clr","a"); - } - else{ - emitcode("mov","a,b"); - - /* adjust the MSB if left or right neg */ - - /* if one literal */ - if (AOP_TYPE(right) == AOP_LIT){ - /* AND literal negative */ - if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){ - /* adjust MSB (c==0 after mul) */ - emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE)); - } - } - else{ - lbl = newiTempLabel(NULL); - emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE)); - emitcode("cjne","a,#0x80,%05d$", (lbl->key+100)); - emitcode("","%05d$:",(lbl->key+100)); - emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE)); - lbl = newiTempLabel(NULL); - emitcode("jc","%05d$",(lbl->key+100)); - emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE)); - emitcode("","%05d$:",(lbl->key+100)); - } - - lbl = newiTempLabel(NULL); - emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE)); - emitcode("cjne","a,#0x80,%05d$", (lbl->key+100)); - emitcode("","%05d$:",(lbl->key+100)); - emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE)); - lbl = newiTempLabel(NULL); - emitcode("jc","%05d$",(lbl->key+100)); - emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE)); - emitcode("","%05d$:",(lbl->key+100)); - - aopPut(AOP(result),"a",1); - if(size > 2){ - /* get the sign */ - emitcode("rlc","a"); - emitcode("subb","a,acc"); - } - } - size -= 2; - offset = 2; - if (size > 0) - while (size--) - aopPut(AOP(result),"a",offset++); - } -} - -/*-----------------------------------------------------------------*/ -/* genMult - generates code for multiplication */ -/*-----------------------------------------------------------------*/ -static void genMult (iCode *ic) -{ - operand *left = IC_LEFT(ic); - operand *right = IC_RIGHT(ic); - operand *result= IC_RESULT(ic); - - /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); - - /* special cases first */ - /* both are bits */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right)== AOP_CRY) { - genMultbits(left,right,result); - goto release ; - } - - /* if both are of size == 1 */ - if (AOP_SIZE(left) == 1 && - AOP_SIZE(right) == 1 ) { - genMultOneByte(left,right,result); - goto release ; - } - - /* should have been converted to function call */ - assert(1) ; - -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genDivbits :- division of bits */ -/*-----------------------------------------------------------------*/ -static void genDivbits (operand *left, - operand *right, - operand *result) -{ - - char *l; - - /* the result must be bit */ - emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); - l = aopGet(AOP(left),0,FALSE,FALSE); - - MOVA(l); - - emitcode("div","ab"); - emitcode("rrc","a"); - aopPut(AOP(result),"c",0); -} - -/*-----------------------------------------------------------------*/ -/* genDivOneByte : 8 bit division */ -/*-----------------------------------------------------------------*/ -static void genDivOneByte (operand *left, - operand *right, - operand *result) -{ - link *opetype = operandType(result); - char *l ; - symbol *lbl ; - int size,offset; - - size = AOP_SIZE(result) - 1; - offset = 1; - /* signed or unsigned */ - if (SPEC_USIGN(opetype)) { - /* unsigned is easy */ - emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE)); - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("div","ab"); - aopPut(AOP(result),"a",0); - while (size--) - aopPut(AOP(result),zero,offset++); - return ; - } - - /* signed is a little bit more difficult */ - - /* save the signs of the operands */ - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE)); - emitcode("push","acc"); /* save it on the stack */ - - /* now sign adjust for both left & right */ - l = aopGet(AOP(right),0,FALSE,FALSE); - MOVA(l); - lbl = newiTempLabel(NULL); - emitcode("jnb","acc.7,%05d$",(lbl->key+100)); - emitcode("cpl","a"); - emitcode("inc","a"); - emitcode("","%05d$:",(lbl->key+100)); - emitcode("mov","b,a"); - - /* sign adjust left side */ - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - - lbl = newiTempLabel(NULL); - emitcode("jnb","acc.7,%05d$",(lbl->key+100)); - emitcode("cpl","a"); - emitcode("inc","a"); - emitcode("","%05d$:",(lbl->key+100)); - - /* now the division */ - emitcode("div","ab"); - /* we are interested in the lower order - only */ - emitcode("mov","b,a"); - lbl = newiTempLabel(NULL); - emitcode("pop","acc"); - /* if there was an over flow we don't - adjust the sign of the result */ - emitcode("jb","ov,%05d$",(lbl->key+100)); - emitcode("jnb","acc.7,%05d$",(lbl->key+100)); - CLRC; - emitcode("clr","a"); - emitcode("subb","a,b"); - emitcode("mov","b,a"); - emitcode("","%05d$:",(lbl->key+100)); - - /* now we are done */ - aopPut(AOP(result),"b",0); - if(size > 0){ - emitcode("mov","c,b.7"); - emitcode("subb","a,acc"); - } - while (size--) - aopPut(AOP(result),"a",offset++); - -} - -/*-----------------------------------------------------------------*/ -/* genDiv - generates code for division */ -/*-----------------------------------------------------------------*/ -static void genDiv (iCode *ic) -{ - operand *left = IC_LEFT(ic); - operand *right = IC_RIGHT(ic); - operand *result= IC_RESULT(ic); - - /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); - - /* special cases first */ - /* both are bits */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right)== AOP_CRY) { - genDivbits(left,right,result); - goto release ; - } - - /* if both are of size == 1 */ - if (AOP_SIZE(left) == 1 && - AOP_SIZE(right) == 1 ) { - genDivOneByte(left,right,result); - goto release ; - } - - /* should have been converted to function call */ - assert(1); -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genModbits :- modulus of bits */ -/*-----------------------------------------------------------------*/ -static void genModbits (operand *left, - operand *right, - operand *result) -{ - - char *l; - - /* the result must be bit */ - emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); - l = aopGet(AOP(left),0,FALSE,FALSE); - - MOVA(l); - - emitcode("div","ab"); - emitcode("mov","a,b"); - emitcode("rrc","a"); - aopPut(AOP(result),"c",0); -} - -/*-----------------------------------------------------------------*/ -/* genModOneByte : 8 bit modulus */ -/*-----------------------------------------------------------------*/ -static void genModOneByte (operand *left, - operand *right, - operand *result) -{ - link *opetype = operandType(result); - char *l ; - symbol *lbl ; - - /* signed or unsigned */ - if (SPEC_USIGN(opetype)) { - /* unsigned is easy */ - emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE)); - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("div","ab"); - aopPut(AOP(result),"b",0); - return ; - } - - /* signed is a little bit more difficult */ - - /* save the signs of the operands */ - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - - emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE)); - emitcode("push","acc"); /* save it on the stack */ - - /* now sign adjust for both left & right */ - l = aopGet(AOP(right),0,FALSE,FALSE); - MOVA(l); - - lbl = newiTempLabel(NULL); - emitcode("jnb","acc.7,%05d$",(lbl->key+100)); - emitcode("cpl","a"); - emitcode("inc","a"); - emitcode("","%05d$:",(lbl->key+100)); - emitcode("mov","b,a"); - - /* sign adjust left side */ - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - - lbl = newiTempLabel(NULL); - emitcode("jnb","acc.7,%05d$",(lbl->key+100)); - emitcode("cpl","a"); - emitcode("inc","a"); - emitcode("","%05d$:",(lbl->key+100)); - - /* now the multiplication */ - emitcode("div","ab"); - /* we are interested in the lower order - only */ - lbl = newiTempLabel(NULL); - emitcode("pop","acc"); - /* if there was an over flow we don't - adjust the sign of the result */ - emitcode("jb","ov,%05d$",(lbl->key+100)); - emitcode("jnb","acc.7,%05d$",(lbl->key+100)); - CLRC ; - emitcode("clr","a"); - emitcode("subb","a,b"); - emitcode("mov","b,a"); - emitcode("","%05d$:",(lbl->key+100)); - - /* now we are done */ - aopPut(AOP(result),"b",0); - -} - -/*-----------------------------------------------------------------*/ -/* genMod - generates code for division */ -/*-----------------------------------------------------------------*/ -static void genMod (iCode *ic) -{ - operand *left = IC_LEFT(ic); - operand *right = IC_RIGHT(ic); - operand *result= IC_RESULT(ic); - - /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); - - /* special cases first */ - /* both are bits */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right)== AOP_CRY) { - genModbits(left,right,result); - goto release ; - } - - /* if both are of size == 1 */ - if (AOP_SIZE(left) == 1 && - AOP_SIZE(right) == 1 ) { - genModOneByte(left,right,result); - goto release ; - } - - /* should have been converted to function call */ - assert(1); - -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genIfxJump :- will create a jump depending on the ifx */ -/*-----------------------------------------------------------------*/ -static void genIfxJump (iCode *ic, char *jval) -{ - symbol *jlbl ; - symbol *tlbl = newiTempLabel(NULL); - char *inst; - - /* if true label then we jump if condition - supplied is true */ - if ( IC_TRUE(ic) ) { - jlbl = IC_TRUE(ic); - inst = ((strcmp(jval,"a") == 0 ? "jz" : - (strcmp(jval,"c") == 0 ? "jnc" : "jnb" ))); - } - else { - /* false label is present */ - jlbl = IC_FALSE(ic) ; - inst = ((strcmp(jval,"a") == 0 ? "jnz" : - (strcmp(jval,"c") == 0 ? "jc" : "jb" ))); - } - if (strcmp(inst,"jb") == 0 || strcmp(inst,"jnb") == 0) - emitcode(inst,"%s,%05d$",jval,(tlbl->key+100)); - else - emitcode(inst,"%05d$",tlbl->key+100); - emitcode("ljmp","%05d$",jlbl->key+100); - emitcode("","%05d$:",tlbl->key+100); - - /* mark the icode as generated */ - ic->generated = 1; -} - -/*-----------------------------------------------------------------*/ -/* genCmp :- greater or less than comparison */ -/*-----------------------------------------------------------------*/ -static void genCmp (operand *left,operand *right, - operand *result, iCode *ifx, int sign) -{ - int size, offset = 0 ; - unsigned long lit = 0L; - - /* if left & right are bit variables */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right) == AOP_CRY ) { - emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir); - } else { - /* subtract right from left if at the - end the carry flag is set then we know that - left is greater than right */ - size = max(AOP_SIZE(left),AOP_SIZE(right)); - - /* if unsigned char cmp with lit, do cjne left,#right,zz */ - if((size == 1) && !sign && - (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){ - symbol *lbl = newiTempLabel(NULL); - emitcode("cjne","%s,%s,%05d$", - aopGet(AOP(left),offset,FALSE,FALSE), - aopGet(AOP(right),offset,FALSE,FALSE), - lbl->key+100); - emitcode("","%05d$:",lbl->key+100); - } else { - if(AOP_TYPE(right) == AOP_LIT){ - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - /* optimize if(x < 0) or if(x >= 0) */ - if(lit == 0L){ - if(!sign){ - CLRC; - } - else{ - MOVA(aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE)); - if(!(AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) && ifx){ - genIfxJump (ifx,"acc.7"); - return; - } - else - emitcode("rlc","a"); - } - goto release; - } - } - CLRC; - while (size--) { - MOVA(aopGet(AOP(left),offset,FALSE,FALSE)); - if (sign && size == 0) { - emitcode("xrl","a,#0x80"); - if (AOP_TYPE(right) == AOP_LIT){ - unsigned long lit = (unsigned long) - floatFromVal(AOP(right)->aopu.aop_lit); - emitcode("subb","a,#0x%02x", - 0x80 ^ (unsigned int)((lit >> (offset*8)) & 0x0FFL)); - } else { - emitcode("mov","b,%s",aopGet(AOP(right),offset++,FALSE,FALSE)); - emitcode("xrl","b,#0x80"); - emitcode("subb","a,b"); - } - } else - emitcode("subb","a,%s",aopGet(AOP(right),offset++,FALSE,FALSE)); - } - } - } - -release: - if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) { - outBitC(result); - } else { - /* if the result is used in the next - ifx conditional branch then generate - code a little differently */ - if (ifx ) - genIfxJump (ifx,"c"); - else - outBitC(result); - /* leave the result in acc */ - } -} - -/*-----------------------------------------------------------------*/ -/* genCmpGt :- greater than comparison */ -/*-----------------------------------------------------------------*/ -static void genCmpGt (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - link *letype , *retype; - int sign ; - - left = IC_LEFT(ic); - right= IC_RIGHT(ic); - result = IC_RESULT(ic); - - letype = getSpec(operandType(left)); - retype =getSpec(operandType(right)); - sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype)); - /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); - - genCmp(right, left, result, ifx, sign); - - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genCmpLt - less than comparisons */ -/*-----------------------------------------------------------------*/ -static void genCmpLt (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - link *letype , *retype; - int sign ; - - left = IC_LEFT(ic); - right= IC_RIGHT(ic); - result = IC_RESULT(ic); - - letype = getSpec(operandType(left)); - retype =getSpec(operandType(right)); - sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype)); - - /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); - - genCmp(left, right, result, ifx, sign); - - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* gencjneshort - compare and jump if not equal */ -/*-----------------------------------------------------------------*/ -static void gencjneshort(operand *left, operand *right, symbol *lbl) -{ - int size = max(AOP_SIZE(left),AOP_SIZE(right)); - int offset = 0; - unsigned long lit = 0L; - - /* if the left side is a literal or - if the right is in a pointer register and left - is not */ - if ((AOP_TYPE(left) == AOP_LIT) || - (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) { - operand *t = right; - right = left; - left = t; - } - if(AOP_TYPE(right) == AOP_LIT) - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - - /* if the right side is a literal then anything goes */ - if (AOP_TYPE(right) == AOP_LIT && - AOP_TYPE(left) != AOP_DIR ) { - while (size--) { - emitcode("cjne","%s,%s,%05d$", - aopGet(AOP(left),offset,FALSE,FALSE), - aopGet(AOP(right),offset,FALSE,FALSE), - lbl->key+100); - offset++; - } - } - - /* if the right side is in a register or in direct space or - if the left is a pointer register & right is not */ - else if (AOP_TYPE(right) == AOP_REG || - AOP_TYPE(right) == AOP_DIR || - (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) || - (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) { - while (size--) { - MOVA(aopGet(AOP(left),offset,FALSE,FALSE)); - if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) && - ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0)) - emitcode("jnz","%05d$",lbl->key+100); - else - emitcode("cjne","a,%s,%05d$", - aopGet(AOP(right),offset,FALSE,TRUE), - lbl->key+100); - offset++; - } - } else { - /* right is a pointer reg need both a & b */ - while(size--) { - char *l = aopGet(AOP(left),offset,FALSE,FALSE); - if(strcmp(l,"b")) - emitcode("mov","b,%s",l); - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("cjne","a,b,%05d$",lbl->key+100); - offset++; - } - } -} - -/*-----------------------------------------------------------------*/ -/* gencjne - compare and jump if not equal */ -/*-----------------------------------------------------------------*/ -static void gencjne(operand *left, operand *right, symbol *lbl) -{ - symbol *tlbl = newiTempLabel(NULL); - - gencjneshort(left, right, lbl); - - emitcode("mov","a,%s",one); - emitcode("sjmp","%05d$",tlbl->key+100); - emitcode("","%05d$:",lbl->key+100); - emitcode("clr","a"); - emitcode("","%05d$:",tlbl->key+100); -} - -/*-----------------------------------------------------------------*/ -/* genCmpEq - generates code for equal to */ -/*-----------------------------------------------------------------*/ -static void genCmpEq (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - - aopOp((left=IC_LEFT(ic)),ic,FALSE); - aopOp((right=IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); - - /* if literal, literal on the right or - if the right is in a pointer register and left - is not */ - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || - (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) { - operand *t = IC_RIGHT(ic); - IC_RIGHT(ic) = IC_LEFT(ic); - IC_LEFT(ic) = t; - } - - if(ifx && !AOP_SIZE(result)){ - symbol *tlbl; - /* if they are both bit variables */ - if (AOP_TYPE(left) == AOP_CRY && - ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) { - if(AOP_TYPE(right) == AOP_LIT){ - unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); - if(lit == 0L){ - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("cpl","c"); - } else if(lit == 1L) { - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - } else { - emitcode("clr","c"); - } - /* AOP_TYPE(right) == AOP_CRY */ - } else { - symbol *lbl = newiTempLabel(NULL); - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("jb","%s,%05d$",AOP(right)->aopu.aop_dir,(lbl->key+100)); - emitcode("cpl","c"); - emitcode("","%05d$:",(lbl->key+100)); - } - /* if true label then we jump if condition - supplied is true */ - tlbl = newiTempLabel(NULL); - if ( IC_TRUE(ifx) ) { - emitcode("jnc","%05d$",tlbl->key+100); - emitcode("ljmp","%05d$",IC_TRUE(ifx)->key+100); - } else { - emitcode("jc","%05d$",tlbl->key+100); - emitcode("ljmp","%05d$",IC_FALSE(ifx)->key+100); - } - emitcode("","%05d$:",tlbl->key+100); - } else { - tlbl = newiTempLabel(NULL); - gencjneshort(left, right, tlbl); - if ( IC_TRUE(ifx) ) { - emitcode("ljmp","%05d$",IC_TRUE(ifx)->key+100); - emitcode("","%05d$:",tlbl->key+100); - } else { - symbol *lbl = newiTempLabel(NULL); - emitcode("sjmp","%05d$",lbl->key+100); - emitcode("","%05d$:",tlbl->key+100); - emitcode("ljmp","%05d$",IC_FALSE(ifx)->key+100); - emitcode("","%05d$:",lbl->key+100); - } - } - /* mark the icode as generated */ - ifx->generated = 1; - goto release ; - } - - /* if they are both bit variables */ - if (AOP_TYPE(left) == AOP_CRY && - ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) { - if(AOP_TYPE(right) == AOP_LIT){ - unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); - if(lit == 0L){ - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("cpl","c"); - } else if(lit == 1L) { - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - } else { - emitcode("clr","c"); - } - /* AOP_TYPE(right) == AOP_CRY */ - } else { - symbol *lbl = newiTempLabel(NULL); - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("jb","%s,%05d$",AOP(right)->aopu.aop_dir,(lbl->key+100)); - emitcode("cpl","c"); - emitcode("","%05d$:",(lbl->key+100)); - } - /* c = 1 if egal */ - if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){ - outBitC(result); - goto release ; - } - if (ifx) { - genIfxJump (ifx,"c"); - goto release ; - } - /* if the result is used in an arithmetic operation - then put the result in place */ - outBitC(result); - } else { - gencjne(left,right,newiTempLabel(NULL)); - if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) { - aopPut(AOP(result),"a",0); - goto release ; - } - if (ifx) { - genIfxJump (ifx,"a"); - goto release ; - } - /* if the result is used in an arithmetic operation - then put the result in place */ - if (AOP_TYPE(result) != AOP_CRY) - outAcc(result); - /* leave the result in acc */ - } - -release: - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* ifxForOp - returns the icode containing the ifx for operand */ -/*-----------------------------------------------------------------*/ -static iCode *ifxForOp ( operand *op, iCode *ic ) -{ - /* if true symbol then needs to be assigned */ - if (IS_TRUE_SYMOP(op)) - return NULL ; - - /* if this has register type condition and - the next instruction is ifx with the same operand - and live to of the operand is upto the ifx only then */ - if (ic->next && - ic->next->op == IFX && - IC_COND(ic->next)->key == op->key && - OP_SYMBOL(op)->liveTo <= ic->next->seq ) - return ic->next; - - return NULL; -} -/*-----------------------------------------------------------------*/ -/* genAndOp - for && operation */ -/*-----------------------------------------------------------------*/ -static void genAndOp (iCode *ic) -{ - operand *left,*right, *result; - symbol *tlbl; - - /* note here that && operations that are in an - if statement are taken away by backPatchLabels - only those used in arthmetic operations remain */ - aopOp((left=IC_LEFT(ic)),ic,FALSE); - aopOp((right=IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,FALSE); - - /* if both are bit variables */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right) == AOP_CRY ) { - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); - outBitC(result); - } else { - tlbl = newiTempLabel(NULL); - toBoolean(left); - emitcode("jz","%05d$",tlbl->key+100); - toBoolean(right); - emitcode("","%05d$:",tlbl->key+100); - outBitAcc(result); - } - - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - - -/*-----------------------------------------------------------------*/ -/* genOrOp - for || operation */ -/*-----------------------------------------------------------------*/ -static void genOrOp (iCode *ic) -{ - operand *left,*right, *result; - symbol *tlbl; - - /* note here that || operations that are in an - if statement are taken away by backPatchLabels - only those used in arthmetic operations remain */ - aopOp((left=IC_LEFT(ic)),ic,FALSE); - aopOp((right=IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,FALSE); - - /* if both are bit variables */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right) == AOP_CRY ) { - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("orl","c,%s",AOP(right)->aopu.aop_dir); - outBitC(result); - } else { - tlbl = newiTempLabel(NULL); - toBoolean(left); - emitcode("jnz","%05d$",tlbl->key+100); - toBoolean(right); - emitcode("","%05d$:",tlbl->key+100); - outBitAcc(result); - } - - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* isLiteralBit - test if lit == 2^n */ -/*-----------------------------------------------------------------*/ -int isLiteralBit(unsigned long lit) -{ - unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L, - 0x100L,0x200L,0x400L,0x800L, - 0x1000L,0x2000L,0x4000L,0x8000L, - 0x10000L,0x20000L,0x40000L,0x80000L, - 0x100000L,0x200000L,0x400000L,0x800000L, - 0x1000000L,0x2000000L,0x4000000L,0x8000000L, - 0x10000000L,0x20000000L,0x40000000L,0x80000000L}; - int idx; - - for(idx = 0; idx < 32; idx++) - if(lit == pw[idx]) - return idx+1; - return 0; -} - -/*-----------------------------------------------------------------*/ -/* continueIfTrue - */ -/*-----------------------------------------------------------------*/ -static void continueIfTrue (iCode *ic) -{ - if(IC_TRUE(ic)) - emitcode("ljmp","%05d$",IC_TRUE(ic)->key+100); - ic->generated = 1; -} - -/*-----------------------------------------------------------------*/ -/* jmpIfTrue - */ -/*-----------------------------------------------------------------*/ -static void jumpIfTrue (iCode *ic) -{ - if(!IC_TRUE(ic)) - emitcode("ljmp","%05d$",IC_FALSE(ic)->key+100); - ic->generated = 1; -} - -/*-----------------------------------------------------------------*/ -/* jmpTrueOrFalse - */ -/*-----------------------------------------------------------------*/ -static void jmpTrueOrFalse (iCode *ic, symbol *tlbl) -{ - // ugly but optimized by peephole - if(IC_TRUE(ic)){ - symbol *nlbl = newiTempLabel(NULL); - emitcode("sjmp","%05d$",nlbl->key+100); - emitcode("","%05d$:",tlbl->key+100); - emitcode("ljmp","%05d$",IC_TRUE(ic)->key+100); - emitcode("","%05d$:",nlbl->key+100); - } - else{ - emitcode("ljmp","%05d$",IC_FALSE(ic)->key+100); - emitcode("","%05d$:",tlbl->key+100); - } - ic->generated = 1; -} - -/*-----------------------------------------------------------------*/ -/* genAnd - code for and */ -/*-----------------------------------------------------------------*/ -static void genAnd (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - int size, offset=0; - unsigned long lit = 0L; - int bytelit = 0; - char buffer[10]; - - aopOp((left = IC_LEFT(ic)),ic,FALSE); - aopOp((right= IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); - -#ifdef DEBUG_TYPE - emitcode("","; Type res[%d] = l[%d]&r[%d]", - AOP_TYPE(result), - AOP_TYPE(left), AOP_TYPE(right)); - emitcode("","; Size res[%d] = l[%d]&r[%d]", - AOP_SIZE(result), - AOP_SIZE(left), AOP_SIZE(right)); -#endif - - /* if left is a literal & right is not then exchange them */ - if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) || - AOP_NEEDSACC(left)) { - operand *tmp = right ; - right = left; - left = tmp; - } - - /* if result = right then exchange them */ - if(sameRegs(AOP(result),AOP(right))){ - operand *tmp = right ; - right = left; - left = tmp; - } - - /* if right is bit then exchange them */ - if (AOP_TYPE(right) == AOP_CRY && - AOP_TYPE(left) != AOP_CRY){ - operand *tmp = right ; - right = left; - left = tmp; - } - if(AOP_TYPE(right) == AOP_LIT) - lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit); - - size = AOP_SIZE(result); - - // if(bit & yy) - // result = bit & yy; - if (AOP_TYPE(left) == AOP_CRY){ - // c = bit & literal; - if(AOP_TYPE(right) == AOP_LIT){ - if(lit & 1) { - if(size && sameRegs(AOP(result),AOP(left))) - // no change - goto release; - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - } else { - // bit(result) = 0; - if(size && (AOP_TYPE(result) == AOP_CRY)){ - emitcode("clr","%s",AOP(result)->aopu.aop_dir); - goto release; - } - if((AOP_TYPE(result) == AOP_CRY) && ifx){ - jumpIfTrue(ifx); - goto release; - } - emitcode("clr","c"); - } - } else { - if (AOP_TYPE(right) == AOP_CRY){ - // c = bit & bit; - emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - emitcode("anl","c,%s",AOP(left)->aopu.aop_dir); - } else { - // c = bit & val; - MOVA(aopGet(AOP(right),0,FALSE,FALSE)); - // c = lsb - emitcode("rrc","a"); - emitcode("anl","c,%s",AOP(left)->aopu.aop_dir); - } - } - // bit = c - // val = c - if(size) - outBitC(result); - // if(bit & ...) - else if((AOP_TYPE(result) == AOP_CRY) && ifx) - genIfxJump(ifx, "c"); - goto release ; - } - - // if(val & 0xZZ) - size = 0, ifx != FALSE - - // bit = val & 0xZZ - size = 1, ifx = FALSE - - if((AOP_TYPE(right) == AOP_LIT) && - (AOP_TYPE(result) == AOP_CRY) && - (AOP_TYPE(left) != AOP_CRY)){ - int posbit = isLiteralBit(lit); - /* left & 2^n */ - if(posbit){ - posbit--; - MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE)); - // bit = left & 2^n - if(size) - emitcode("mov","c,acc.%d",posbit&0x07); - // if(left & 2^n) - else{ - if(ifx){ - sprintf(buffer,"acc.%d",posbit&0x07); - genIfxJump(ifx, buffer); - } - goto release; - } - } else { - symbol *tlbl = newiTempLabel(NULL); - int sizel = AOP_SIZE(left); - if(size) - emitcode("setb","c"); - while(sizel--){ - if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){ - MOVA( aopGet(AOP(left),offset,FALSE,FALSE)); - // byte == 2^n ? - if((posbit = isLiteralBit(bytelit)) != 0) - emitcode("jb","acc.%d,%05d$",(posbit-1)&0x07,tlbl->key+100); - else{ - if(bytelit != 0x0FFL) - emitcode("anl","a,%s", - aopGet(AOP(right),offset,FALSE,TRUE)); - emitcode("jnz","%05d$",tlbl->key+100); - } - } - offset++; - } - // bit = left & literal - if(size){ - emitcode("clr","c"); - emitcode("","%05d$:",tlbl->key+100); - } - // if(left & literal) - else{ - if(ifx) - jmpTrueOrFalse(ifx, tlbl); - goto release ; - } - } - outBitC(result); - goto release ; - } - - /* if left is same as result */ - if(sameRegs(AOP(result),AOP(left))){ - for(;size--; offset++) { - if(AOP_TYPE(right) == AOP_LIT){ - if((bytelit = (int)((lit >> (offset*8)) & 0x0FFL)) == 0x0FF) - continue; - else - if (bytelit == 0) - aopPut(AOP(result),zero,offset); - else - if (IS_AOP_PREG(result)) { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("anl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE)); - aopPut(AOP(result),"a",offset); - } else - emitcode("anl","%s,%s", - aopGet(AOP(left),offset,FALSE,TRUE), - aopGet(AOP(right),offset,FALSE,FALSE)); - } else { - if (AOP_TYPE(left) == AOP_ACC) - emitcode("anl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE)); - else { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - if (IS_AOP_PREG(result)) { - emitcode("anl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE)); - aopPut(AOP(result),"a",offset); - - } else - emitcode("anl","%s,a", - aopGet(AOP(left),offset,FALSE,TRUE)); - } - } - } - } else { - // left & result in different registers - if(AOP_TYPE(result) == AOP_CRY){ - // result = bit - // if(size), result in bit - // if(!size && ifx), conditional oper: if(left & right) - symbol *tlbl = newiTempLabel(NULL); - int sizer = min(AOP_SIZE(left),AOP_SIZE(right)); - if(size) - emitcode("setb","c"); - while(sizer--){ - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("anl","a,%s", - aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("jnz","%05d$",tlbl->key+100); - offset++; - } - if(size){ - CLRC; - emitcode("","%05d$:",tlbl->key+100); - outBitC(result); - } else if(ifx) - jmpTrueOrFalse(ifx, tlbl); - } else { - for(;(size--);offset++) { - // normal case - // result = left & right - if(AOP_TYPE(right) == AOP_LIT){ - if((bytelit = (int)((lit >> (offset*8)) & 0x0FFL)) == 0x0FF){ - aopPut(AOP(result), - aopGet(AOP(left),offset,FALSE,FALSE), - offset); - continue; - } else if(bytelit == 0){ - aopPut(AOP(result),zero,offset); - continue; - } - } - // faster than result <- left, anl result,right - // and better if result is SFR - if (AOP_TYPE(left) == AOP_ACC) - emitcode("anl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE)); - else { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("anl","a,%s", - aopGet(AOP(left),offset,FALSE,FALSE)); - } - aopPut(AOP(result),"a",offset); - } - } - } - -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genOr - code for or */ -/*-----------------------------------------------------------------*/ -static void genOr (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - int size, offset=0; - unsigned long lit = 0L; - - aopOp((left = IC_LEFT(ic)),ic,FALSE); - aopOp((right= IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); - -#ifdef DEBUG_TYPE - emitcode("","; Type res[%d] = l[%d]&r[%d]", - AOP_TYPE(result), - AOP_TYPE(left), AOP_TYPE(right)); - emitcode("","; Size res[%d] = l[%d]&r[%d]", - AOP_SIZE(result), - AOP_SIZE(left), AOP_SIZE(right)); -#endif - - /* if left is a literal & right is not then exchange them */ - if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) || - AOP_NEEDSACC(left)) { - operand *tmp = right ; - right = left; - left = tmp; - } - - /* if result = right then exchange them */ - if(sameRegs(AOP(result),AOP(right))){ - operand *tmp = right ; - right = left; - left = tmp; - } - - /* if right is bit then exchange them */ - if (AOP_TYPE(right) == AOP_CRY && - AOP_TYPE(left) != AOP_CRY){ - operand *tmp = right ; - right = left; - left = tmp; - } - if(AOP_TYPE(right) == AOP_LIT) - lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit); - - size = AOP_SIZE(result); - - // if(bit | yy) - // xx = bit | yy; - if (AOP_TYPE(left) == AOP_CRY){ - if(AOP_TYPE(right) == AOP_LIT){ - // c = bit & literal; - if(lit){ - // lit != 0 => result = 1 - if(AOP_TYPE(result) == AOP_CRY){ - if(size) - emitcode("setb","%s",AOP(result)->aopu.aop_dir); - else if(ifx) - continueIfTrue(ifx); - goto release; - } - emitcode("setb","c"); - } else { - // lit == 0 => result = left - if(size && sameRegs(AOP(result),AOP(left))) - goto release; - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - } - } else { - if (AOP_TYPE(right) == AOP_CRY){ - // c = bit | bit; - emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - emitcode("orl","c,%s",AOP(left)->aopu.aop_dir); - } - else{ - // c = bit | val; - symbol *tlbl = newiTempLabel(NULL); - if(!((AOP_TYPE(result) == AOP_CRY) && ifx)) - emitcode("setb","c"); - emitcode("jb","%s,%05d$", - AOP(left)->aopu.aop_dir,tlbl->key+100); - toBoolean(right); - emitcode("jnz","%05d$",tlbl->key+100); - if((AOP_TYPE(result) == AOP_CRY) && ifx){ - jmpTrueOrFalse(ifx, tlbl); - goto release; - } else { - CLRC; - emitcode("","%05d$:",tlbl->key+100); - } - } - } - // bit = c - // val = c - if(size) - outBitC(result); - // if(bit | ...) - else if((AOP_TYPE(result) == AOP_CRY) && ifx) - genIfxJump(ifx, "c"); - goto release ; - } - - // if(val | 0xZZ) - size = 0, ifx != FALSE - - // bit = val | 0xZZ - size = 1, ifx = FALSE - - if((AOP_TYPE(right) == AOP_LIT) && - (AOP_TYPE(result) == AOP_CRY) && - (AOP_TYPE(left) != AOP_CRY)){ - if(lit){ - // result = 1 - if(size) - emitcode("setb","%s",AOP(result)->aopu.aop_dir); - else - continueIfTrue(ifx); - goto release; - } else { - // lit = 0, result = boolean(left) - if(size) - emitcode("setb","c"); - toBoolean(right); - if(size){ - symbol *tlbl = newiTempLabel(NULL); - emitcode("jnz","%05d$",tlbl->key+100); - CLRC; - emitcode("","%05d$:",tlbl->key+100); - } else { - genIfxJump (ifx,"a"); - goto release; - } - } - outBitC(result); - goto release ; - } - - /* if left is same as result */ - if(sameRegs(AOP(result),AOP(left))){ - for(;size--; offset++) { - if(AOP_TYPE(right) == AOP_LIT){ - if(((lit >> (offset*8)) & 0x0FFL) == 0x00L) - continue; - else - if (IS_AOP_PREG(left)) { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("orl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE)); - aopPut(AOP(result),"a",offset); - } else - emitcode("orl","%s,%s", - aopGet(AOP(left),offset,FALSE,TRUE), - aopGet(AOP(right),offset,FALSE,FALSE)); - } else { - if (AOP_TYPE(left) == AOP_ACC) - emitcode("orl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE)); - else { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - if (IS_AOP_PREG(left)) { - emitcode("orl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE)); - aopPut(AOP(result),"a",offset); - } else - emitcode("orl","%s,a", - aopGet(AOP(left),offset,FALSE,TRUE)); - } - } - } - } else { - // left & result in different registers - if(AOP_TYPE(result) == AOP_CRY){ - // result = bit - // if(size), result in bit - // if(!size && ifx), conditional oper: if(left | right) - symbol *tlbl = newiTempLabel(NULL); - int sizer = max(AOP_SIZE(left),AOP_SIZE(right)); - if(size) - emitcode("setb","c"); - while(sizer--){ - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("orl","a,%s", - aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("jnz","%05d$",tlbl->key+100); - offset++; - } - if(size){ - CLRC; - emitcode("","%05d$:",tlbl->key+100); - outBitC(result); - } else if(ifx) - jmpTrueOrFalse(ifx, tlbl); - } else for(;(size--);offset++){ - // normal case - // result = left & right - if(AOP_TYPE(right) == AOP_LIT){ - if(((lit >> (offset*8)) & 0x0FFL) == 0x00L){ - aopPut(AOP(result), - aopGet(AOP(left),offset,FALSE,FALSE), - offset); - continue; - } - } - // faster than result <- left, anl result,right - // and better if result is SFR - if (AOP_TYPE(left) == AOP_ACC) - emitcode("orl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE)); - else { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("orl","a,%s", - aopGet(AOP(left),offset,FALSE,FALSE)); - } - aopPut(AOP(result),"a",offset); - } - } - -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genXor - code for xclusive or */ -/*-----------------------------------------------------------------*/ -static void genXor (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - int size, offset=0; - unsigned long lit = 0L; - - aopOp((left = IC_LEFT(ic)),ic,FALSE); - aopOp((right= IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); - -#ifdef DEBUG_TYPE - emitcode("","; Type res[%d] = l[%d]&r[%d]", - AOP_TYPE(result), - AOP_TYPE(left), AOP_TYPE(right)); - emitcode("","; Size res[%d] = l[%d]&r[%d]", - AOP_SIZE(result), - AOP_SIZE(left), AOP_SIZE(right)); -#endif - - /* if left is a literal & right is not || - if left needs acc & right does not */ - if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) || - (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) { - operand *tmp = right ; - right = left; - left = tmp; - } - - /* if result = right then exchange them */ - if(sameRegs(AOP(result),AOP(right))){ - operand *tmp = right ; - right = left; - left = tmp; - } - - /* if right is bit then exchange them */ - if (AOP_TYPE(right) == AOP_CRY && - AOP_TYPE(left) != AOP_CRY){ - operand *tmp = right ; - right = left; - left = tmp; - } - if(AOP_TYPE(right) == AOP_LIT) - lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit); - - size = AOP_SIZE(result); - - // if(bit ^ yy) - // xx = bit ^ yy; - if (AOP_TYPE(left) == AOP_CRY){ - if(AOP_TYPE(right) == AOP_LIT){ - // c = bit & literal; - if(lit>>1){ - // lit>>1 != 0 => result = 1 - if(AOP_TYPE(result) == AOP_CRY){ - if(size) - emitcode("setb","%s",AOP(result)->aopu.aop_dir); - else if(ifx) - continueIfTrue(ifx); - goto release; - } - emitcode("setb","c"); - } else{ - // lit == (0 or 1) - if(lit == 0){ - // lit == 0, result = left - if(size && sameRegs(AOP(result),AOP(left))) - goto release; - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - } else{ - // lit == 1, result = not(left) - if(size && sameRegs(AOP(result),AOP(left))){ - emitcode("cpl","%s",AOP(result)->aopu.aop_dir); - goto release; - } else { - emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - emitcode("cpl","c"); - } - } - } - - } else { - // right != literal - symbol *tlbl = newiTempLabel(NULL); - if (AOP_TYPE(right) == AOP_CRY){ - // c = bit ^ bit; - emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - } - else{ - int sizer = AOP_SIZE(right); - // c = bit ^ val - // if val>>1 != 0, result = 1 - emitcode("setb","c"); - while(sizer--){ - MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE)); - if(sizer == 1) - // test the msb of the lsb - emitcode("anl","a,#0xfe"); - emitcode("jnz","%05d$",tlbl->key+100); - } - // val = (0,1) - emitcode("rrc","a"); - } - emitcode("jnb","%s,%05d$",AOP(left)->aopu.aop_dir,(tlbl->key+100)); - emitcode("cpl","c"); - emitcode("","%05d$:",(tlbl->key+100)); - } - // bit = c - // val = c - if(size) - outBitC(result); - // if(bit | ...) - else if((AOP_TYPE(result) == AOP_CRY) && ifx) - genIfxJump(ifx, "c"); - goto release ; - } - - if(sameRegs(AOP(result),AOP(left))){ - /* if left is same as result */ - for(;size--; offset++) { - if(AOP_TYPE(right) == AOP_LIT){ - if(((lit >> (offset*8)) & 0x0FFL) == 0x00L) - continue; - else - if (IS_AOP_PREG(left)) { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE)); - aopPut(AOP(result),"a",offset); - } else - emitcode("xrl","%s,%s", - aopGet(AOP(left),offset,FALSE,TRUE), - aopGet(AOP(right),offset,FALSE,FALSE)); - } else { - if (AOP_TYPE(left) == AOP_ACC) - emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE)); - else { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - if (IS_AOP_PREG(left)) { - emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE)); - aopPut(AOP(result),"a",offset); - } else - emitcode("xrl","%s,a", - aopGet(AOP(left),offset,FALSE,TRUE)); - } - } - } - } else { - // left & result in different registers - if(AOP_TYPE(result) == AOP_CRY){ - // result = bit - // if(size), result in bit - // if(!size && ifx), conditional oper: if(left ^ right) - symbol *tlbl = newiTempLabel(NULL); - int sizer = max(AOP_SIZE(left),AOP_SIZE(right)); - if(size) - emitcode("setb","c"); - while(sizer--){ - if((AOP_TYPE(right) == AOP_LIT) && - (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){ - MOVA(aopGet(AOP(left),offset,FALSE,FALSE)); - } else { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("xrl","a,%s", - aopGet(AOP(left),offset,FALSE,FALSE)); - } - emitcode("jnz","%05d$",tlbl->key+100); - offset++; - } - if(size){ - CLRC; - emitcode("","%05d$:",tlbl->key+100); - outBitC(result); - } else if(ifx) - jmpTrueOrFalse(ifx, tlbl); - } else for(;(size--);offset++){ - // normal case - // result = left & right - if(AOP_TYPE(right) == AOP_LIT){ - if(((lit >> (offset*8)) & 0x0FFL) == 0x00L){ - aopPut(AOP(result), - aopGet(AOP(left),offset,FALSE,FALSE), - offset); - continue; - } - } - // faster than result <- left, anl result,right - // and better if result is SFR - if (AOP_TYPE(left) == AOP_ACC) - emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE)); - else { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - emitcode("xrl","a,%s", - aopGet(AOP(left),offset,FALSE,TRUE)); - } - aopPut(AOP(result),"a",offset); - } - } - -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genInline - write the inline code out */ -/*-----------------------------------------------------------------*/ -static void genInline (iCode *ic) -{ - char buffer[MAX_INLINEASM]; - char *bp = buffer; - char *bp1= buffer; - - inLine += (!options.asmpeep); - strcpy(buffer,IC_INLINE(ic)); - - /* emit each line as a code */ - while (*bp) { - if (*bp == '\n') { - *bp++ = '\0'; - emitcode(bp1,""); - bp1 = bp; - } else { - if (*bp == ':') { - bp++; - *bp = '\0'; - bp++; - emitcode(bp1,""); - bp1 = bp; - } else - bp++; - } - } - if (bp1 != bp) - emitcode(bp1,""); - /* emitcode("",buffer); */ - inLine -= (!options.asmpeep); -} - -/*-----------------------------------------------------------------*/ -/* genRRC - rotate right with carry */ -/*-----------------------------------------------------------------*/ -static void genRRC (iCode *ic) -{ - operand *left , *result ; - int size, offset = 0; - char *l; - - /* rotate right with carry */ - left = IC_LEFT(ic); - result=IC_RESULT(ic); - aopOp (left,ic,FALSE); - aopOp (result,ic,FALSE); - - /* move it to the result */ - size = AOP_SIZE(result); - offset = size - 1 ; - CLRC; - while (size--) { - l = aopGet(AOP(left),offset,FALSE,FALSE); - MOVA(l); - emitcode("rrc","a"); - if (AOP_SIZE(result) > 1) - aopPut(AOP(result),"a",offset--); - } - /* now we need to put the carry into the - highest order byte of the result */ - if (AOP_SIZE(result) > 1) { - l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE); - MOVA(l); - } - emitcode("mov","acc.7,c"); - aopPut(AOP(result),"a",AOP_SIZE(result)-1); - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genRLC - generate code for rotate left with carry */ -/*-----------------------------------------------------------------*/ -static void genRLC (iCode *ic) -{ - operand *left , *result ; - int size, offset = 0; - char *l; - - /* rotate right with carry */ - left = IC_LEFT(ic); - result=IC_RESULT(ic); - aopOp (left,ic,FALSE); - aopOp (result,ic,FALSE); - - /* move it to the result */ - size = AOP_SIZE(result); - offset = 0 ; - if (size--) { - l = aopGet(AOP(left),offset,FALSE,FALSE); - MOVA(l); - emitcode("add","a,acc"); - if (AOP_SIZE(result) > 1) - aopPut(AOP(result),"a",offset++); - while (size--) { - l = aopGet(AOP(left),offset,FALSE,FALSE); - MOVA(l); - emitcode("rlc","a"); - if (AOP_SIZE(result) > 1) - aopPut(AOP(result),"a",offset++); - } - } - /* now we need to put the carry into the - highest order byte of the result */ - if (AOP_SIZE(result) > 1) { - l = aopGet(AOP(result),0,FALSE,FALSE); - MOVA(l); - } - emitcode("mov","acc.0,c"); - aopPut(AOP(result),"a",0); - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genGetHbit - generates code get highest order bit */ -/*-----------------------------------------------------------------*/ -static void genGetHbit (iCode *ic) -{ - operand *left, *result; - left = IC_LEFT(ic); - result=IC_RESULT(ic); - aopOp (left,ic,FALSE); - aopOp (result,ic,FALSE); - - /* get the highest order byte into a */ - MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE)); - if(AOP_TYPE(result) == AOP_CRY){ - emitcode("rlc","a"); - outBitC(result); - } - else{ - emitcode("rl","a"); - emitcode("anl","a,#0x01"); - outAcc(result); - } - - - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* AccRol - rotate left accumulator by known count */ -/*-----------------------------------------------------------------*/ -static void AccRol (int shCount) -{ - shCount &= 0x0007; // shCount : 0..7 - switch(shCount){ - case 0 : - break; - case 1 : - emitcode("rl","a"); - break; - case 2 : - emitcode("rl","a"); - emitcode("rl","a"); - break; - case 3 : - emitcode("swap","a"); - emitcode("rr","a"); - break; - case 4 : - emitcode("swap","a"); - break; - case 5 : - emitcode("swap","a"); - emitcode("rl","a"); - break; - case 6 : - emitcode("rr","a"); - emitcode("rr","a"); - break; - case 7 : - emitcode("rr","a"); - break; - } -} - -/*-----------------------------------------------------------------*/ -/* AccLsh - left shift accumulator by known count */ -/*-----------------------------------------------------------------*/ -static void AccLsh (int shCount) -{ - if(shCount != 0){ - if(shCount == 1) - emitcode("add","a,acc"); - else - if(shCount == 2) { - emitcode("add","a,acc"); - emitcode("add","a,acc"); - } else { - /* rotate left accumulator */ - AccRol(shCount); - /* and kill the lower order bits */ - emitcode("anl","a,#0x%02x", SLMask[shCount]); - } - } -} - -/*-----------------------------------------------------------------*/ -/* AccRsh - right shift accumulator by known count */ -/*-----------------------------------------------------------------*/ -static void AccRsh (int shCount) -{ - if(shCount != 0){ - if(shCount == 1){ - CLRC; - emitcode("rrc","a"); - } else { - /* rotate right accumulator */ - AccRol(8 - shCount); - /* and kill the higher order bits */ - emitcode("anl","a,#0x%02x", SRMask[shCount]); - } - } -} - -/*-----------------------------------------------------------------*/ -/* AccSRsh - signed right shift accumulator by known count */ -/*-----------------------------------------------------------------*/ -static void AccSRsh (int shCount) -{ - symbol *tlbl ; - if(shCount != 0){ - if(shCount == 1){ - emitcode("mov","c,acc.7"); - emitcode("rrc","a"); - } else if(shCount == 2){ - emitcode("mov","c,acc.7"); - emitcode("rrc","a"); - emitcode("mov","c,acc.7"); - emitcode("rrc","a"); - } else { - tlbl = newiTempLabel(NULL); - /* rotate right accumulator */ - AccRol(8 - shCount); - /* and kill the higher order bits */ - emitcode("anl","a,#0x%02x", SRMask[shCount]); - emitcode("jnb","acc.%d,%05d$",7-shCount,tlbl->key+100); - emitcode("orl","a,#0x%02x", - (unsigned char)~SRMask[shCount]); - emitcode("","%05d$:",tlbl->key+100); - } - } -} - -/*-----------------------------------------------------------------*/ -/* shiftR1Left2Result - shift right one byte from left to result */ -/*-----------------------------------------------------------------*/ -static void shiftR1Left2Result (operand *left, int offl, - operand *result, int offr, - int shCount, int sign) -{ - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); - /* shift right accumulator */ - if(sign) - AccSRsh(shCount); - else - AccRsh(shCount); - aopPut(AOP(result),"a",offr); -} - -/*-----------------------------------------------------------------*/ -/* shiftL1Left2Result - shift left one byte from left to result */ -/*-----------------------------------------------------------------*/ -static void shiftL1Left2Result (operand *left, int offl, - operand *result, int offr, int shCount) -{ - char *l; - l = aopGet(AOP(left),offl,FALSE,FALSE); - MOVA(l); - /* shift left accumulator */ - AccLsh(shCount); - aopPut(AOP(result),"a",offr); -} - -/*-----------------------------------------------------------------*/ -/* movLeft2Result - move byte from left to result */ -/*-----------------------------------------------------------------*/ -static void movLeft2Result (operand *left, int offl, - operand *result, int offr, int sign) -{ - char *l; - if(!sameRegs(AOP(left),AOP(result)) || (offl != offr)){ - l = aopGet(AOP(left),offl,FALSE,FALSE); - - if (*l == '@' && (IS_AOP_PREG(result))) { - emitcode("mov","a,%s",l); - aopPut(AOP(result),"a",offr); - } else { - if(!sign) - aopPut(AOP(result),l,offr); - else{ - /* MSB sign in acc.7 ! */ - if(getDataSize(left) == offl+1){ - emitcode("mov","a,%s",l); - aopPut(AOP(result),"a",offr); - } - } - } - } -} - -/*-----------------------------------------------------------------*/ -/* AccAXRrl1 - right rotate c->a:x->c by 1 */ -/*-----------------------------------------------------------------*/ -static void AccAXRrl1 (char *x) -{ - emitcode("rrc","a"); - emitcode("xch","a,%s", x); - emitcode("rrc","a"); - emitcode("xch","a,%s", x); -} - -/*-----------------------------------------------------------------*/ -/* AccAXLrl1 - left rotate c<-a:x<-c by 1 */ -/*-----------------------------------------------------------------*/ -static void AccAXLrl1 (char *x) -{ - emitcode("xch","a,%s",x); - emitcode("rlc","a"); - emitcode("xch","a,%s",x); - emitcode("rlc","a"); -} - -/*-----------------------------------------------------------------*/ -/* AccAXLsh1 - left shift a:x<-0 by 1 */ -/*-----------------------------------------------------------------*/ -static void AccAXLsh1 (char *x) -{ - emitcode("xch","a,%s",x); - emitcode("add","a,acc"); - emitcode("xch","a,%s",x); - emitcode("rlc","a"); -} - -/*-----------------------------------------------------------------*/ -/* AccAXLsh - left shift a:x by known count (0..7) */ -/*-----------------------------------------------------------------*/ -static void AccAXLsh (char *x, int shCount) -{ - switch(shCount){ - case 0 : - break; - case 1 : - AccAXLsh1(x); - break; - case 2 : - AccAXLsh1(x); - AccAXLsh1(x); - break; - case 3 : - case 4 : - case 5 : // AAAAABBB:CCCCCDDD - AccRol(shCount); // BBBAAAAA:CCCCCDDD - emitcode("anl","a,#0x%02x", - SLMask[shCount]); // BBB00000:CCCCCDDD - emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000 - AccRol(shCount); // DDDCCCCC:BBB00000 - emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC - emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC - emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC - emitcode("anl","a,#0x%02x", - SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC - emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000 - emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000 - break; - case 6 : // AAAAAABB:CCCCCCDD - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000000BB:CCCCCCDD - emitcode("mov","c,acc.0"); // c = B - emitcode("xch","a,%s",x); // CCCCCCDD:000000BB - AccAXRrl1(x); // BCCCCCCD:D000000B - AccAXRrl1(x); // BBCCCCCC:DD000000 - break; - case 7 : // a:x <<= 7 - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 0000000B:CCCCCCCD - emitcode("mov","c,acc.0"); // c = B - emitcode("xch","a,%s",x); // CCCCCCCD:0000000B - AccAXRrl1(x); // BCCCCCCC:D0000000 - break; - default : - break; - } -} - -/*-----------------------------------------------------------------*/ -/* AccAXRsh - right shift a:x known count (0..7) */ -/*-----------------------------------------------------------------*/ -static void AccAXRsh (char *x, int shCount) -{ - switch(shCount){ - case 0 : - break; - case 1 : - CLRC; - AccAXRrl1(x); // 0->a:x - break; - case 2 : - CLRC; - AccAXRrl1(x); // 0->a:x - CLRC; - AccAXRrl1(x); // 0->a:x - break; - case 3 : - case 4 : - case 5 : // AAAAABBB:CCCCCDDD = a:x - AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC - emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA - AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000CCCCC:BBBAAAAA - emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA - emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA) - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA) - emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA - emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA - emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC - break; - case 6 : // AABBBBBB:CCDDDDDD - emitcode("mov","c,acc.7"); - AccAXLrl1(x); // ABBBBBBC:CDDDDDDA - AccAXLrl1(x); // BBBBBBCC:DDDDDDAA - emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000000AA:BBBBBBCC - break; - case 7 : // ABBBBBBB:CDDDDDDD - emitcode("mov","c,acc.7"); // c = A - AccAXLrl1(x); // BBBBBBBC:DDDDDDDA - emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 0000000A:BBBBBBBC - break; - default : - break; - } -} - -/*-----------------------------------------------------------------*/ -/* AccAXRshS - right shift signed a:x known count (0..7) */ -/*-----------------------------------------------------------------*/ -static void AccAXRshS (char *x, int shCount) -{ - symbol *tlbl ; - switch(shCount){ - case 0 : - break; - case 1 : - emitcode("mov","c,acc.7"); - AccAXRrl1(x); // s->a:x - break; - case 2 : - emitcode("mov","c,acc.7"); - AccAXRrl1(x); // s->a:x - emitcode("mov","c,acc.7"); - AccAXRrl1(x); // s->a:x - break; - case 3 : - case 4 : - case 5 : // AAAAABBB:CCCCCDDD = a:x - tlbl = newiTempLabel(NULL); - AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD - emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA - AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000CCCCC:BBBAAAAA - emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA - emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA) - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA) - emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA - emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA - emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC - emitcode("jnb","acc.%d,%05d$",7-shCount,tlbl->key+100); - emitcode("orl","a,#0x%02x", - (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC - emitcode("","%05d$:",tlbl->key+100); - break; // SSSSAAAA:BBBCCCCC - case 6 : // AABBBBBB:CCDDDDDD - tlbl = newiTempLabel(NULL); - emitcode("mov","c,acc.7"); - AccAXLrl1(x); // ABBBBBBC:CDDDDDDA - AccAXLrl1(x); // BBBBBBCC:DDDDDDAA - emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 000000AA:BBBBBBCC - emitcode("jnb","acc.%d,%05d$",7-shCount,tlbl->key+100); - emitcode("orl","a,#0x%02x", - (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC - emitcode("","%05d$:",tlbl->key+100); - break; - case 7 : // ABBBBBBB:CDDDDDDD - tlbl = newiTempLabel(NULL); - emitcode("mov","c,acc.7"); // c = A - AccAXLrl1(x); // BBBBBBBC:DDDDDDDA - emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC - emitcode("anl","a,#0x%02x", - SRMask[shCount]); // 0000000A:BBBBBBBC - emitcode("jnb","acc.%d,%05d$",7-shCount,tlbl->key+100); - emitcode("orl","a,#0x%02x", - (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC - emitcode("","%05d$:",tlbl->key+100); - break; - default : - break; - } -} - -/*-----------------------------------------------------------------*/ -/* shiftL2Left2Result - shift left two bytes from left to result */ -/*-----------------------------------------------------------------*/ -static void shiftL2Left2Result (operand *left, int offl, - operand *result, int offr, int shCount) -{ - if(sameRegs(AOP(result), AOP(left)) && - ((offl + MSB16) == offr)){ - /* don't crash result[offr] */ - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); - emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); - } else { - movLeft2Result(left,offl, result, offr, 0); - MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); - } - /* ax << shCount (x = lsb(result))*/ - AccAXLsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount); - aopPut(AOP(result),"a",offr+MSB16); -} - - -/*-----------------------------------------------------------------*/ -/* shiftR2Left2Result - shift right two bytes from left to result */ -/*-----------------------------------------------------------------*/ -static void shiftR2Left2Result (operand *left, int offl, - operand *result, int offr, - int shCount, int sign) -{ - if(sameRegs(AOP(result), AOP(left)) && - ((offl + MSB16) == offr)){ - /* don't crash result[offr] */ - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); - emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); - } else { - movLeft2Result(left,offl, result, offr, 0); - MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); - } - /* a:x >> shCount (x = lsb(result))*/ - if(sign) - AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount); - else - AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount); - if(getDataSize(result) > 1) - aopPut(AOP(result),"a",offr+MSB16); -} - -/*-----------------------------------------------------------------*/ -/* shiftLLeftOrResult - shift left one byte from left, or to result*/ -/*-----------------------------------------------------------------*/ -static void shiftLLeftOrResult (operand *left, int offl, - operand *result, int offr, int shCount) -{ - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); - /* shift left accumulator */ - AccLsh(shCount); - /* or with result */ - emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE)); - /* back to result */ - aopPut(AOP(result),"a",offr); -} - -/*-----------------------------------------------------------------*/ -/* shiftRLeftOrResult - shift right one byte from left,or to result*/ -/*-----------------------------------------------------------------*/ -static void shiftRLeftOrResult (operand *left, int offl, - operand *result, int offr, int shCount) -{ - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); - /* shift right accumulator */ - AccRsh(shCount); - /* or with result */ - emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE)); - /* back to result */ - aopPut(AOP(result),"a",offr); -} - -/*-----------------------------------------------------------------*/ -/* genlshOne - left shift a one byte quantity by known count */ -/*-----------------------------------------------------------------*/ -static void genlshOne (operand *result, operand *left, int shCount) -{ - shiftL1Left2Result(left, LSB, result, LSB, shCount); -} - -/*-----------------------------------------------------------------*/ -/* genlshTwo - left shift two bytes by known amount != 0 */ -/*-----------------------------------------------------------------*/ -static void genlshTwo (operand *result,operand *left, int shCount) -{ - int size = AOP_SIZE(result); - - if (size == 3) - size--; - - /* if shCount >= 8 */ - if (shCount >= 8) { - shCount -= 8 ; - - if (size > 1){ - if (shCount) - shiftL1Left2Result(left, LSB, result, MSB16, shCount); - else - movLeft2Result(left, LSB, result, MSB16, 0); - } - aopPut(AOP(result),zero,LSB); - } - - /* 1 <= shCount <= 7 */ - else { - if(size == 1) - shiftL1Left2Result(left, LSB, result, LSB, shCount); - else - shiftL2Left2Result(left, LSB, result, LSB, shCount); - } -} - -/*-----------------------------------------------------------------*/ -/* shiftLLong - shift left one long from left to result */ -/* offl = LSB or MSB16 */ -/*-----------------------------------------------------------------*/ -static void shiftLLong (operand *left, operand *result, int offr ) -{ - char *l; - int size = AOP_SIZE(result); - - if(size >= LSB+offr){ - l = aopGet(AOP(left),LSB,FALSE,FALSE); - MOVA(l); - emitcode("add","a,acc"); - if (sameRegs(AOP(left),AOP(result)) && - size >= MSB16+offr && offr != LSB ) - emitcode("xch","a,%s", - aopGet(AOP(left),LSB+offr,FALSE,FALSE)); - else - aopPut(AOP(result),"a",LSB+offr); - } - - if(size >= MSB16+offr){ - if (!(sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) { - l = aopGet(AOP(left),MSB16,FALSE,FALSE); - MOVA(l); - } - emitcode("rlc","a"); - if (sameRegs(AOP(left),AOP(result)) && - size >= MSB24+offr && offr != LSB) - emitcode("xch","a,%s", - aopGet(AOP(left),MSB16+offr,FALSE,FALSE)); - else - aopPut(AOP(result),"a",MSB16+offr); - } - - if(size >= MSB24+offr){ - if (!(sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) { - l = aopGet(AOP(left),MSB24,FALSE,FALSE); - MOVA(l); - } - emitcode("rlc","a"); - if (sameRegs(AOP(left),AOP(result)) && - size >= MSB32+offr && offr != LSB ) - emitcode("xch","a,%s", - aopGet(AOP(left),MSB24+offr,FALSE,FALSE)); - else - aopPut(AOP(result),"a",MSB24+offr); - } - - if(size > MSB32+offr){ - if (!(sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) { - l = aopGet(AOP(left),MSB32,FALSE,FALSE); - MOVA(l); - } - emitcode("rlc","a"); - aopPut(AOP(result),"a",MSB32+offr); - } - if(offr != LSB) - aopPut(AOP(result),zero,LSB); -} - -/*-----------------------------------------------------------------*/ -/* genlshFour - shift four byte by a known amount != 0 */ -/*-----------------------------------------------------------------*/ -static void genlshFour (operand *result, operand *left, int shCount) -{ - int size; - - size = AOP_SIZE(result); - - /* if shifting more that 3 bytes */ - if (shCount >= 24 ) { - shCount -= 24; - if (shCount) - /* lowest order of left goes to the highest - order of the destination */ - shiftL1Left2Result(left, LSB, result, MSB32, shCount); - else - movLeft2Result(left, LSB, result, MSB32, 0); - aopPut(AOP(result),zero,LSB); - aopPut(AOP(result),zero,MSB16); - aopPut(AOP(result),zero,MSB32); - return; - } - - /* more than two bytes */ - else if ( shCount >= 16 ) { - /* lower order two bytes goes to higher order two bytes */ - shCount -= 16; - /* if some more remaining */ - if (shCount) - shiftL2Left2Result(left, LSB, result, MSB24, shCount); - else { - movLeft2Result(left, MSB16, result, MSB32, 0); - movLeft2Result(left, LSB, result, MSB24, 0); - } - aopPut(AOP(result),zero,MSB16); - aopPut(AOP(result),zero,LSB); - return; - } - - /* if more than 1 byte */ - else if ( shCount >= 8 ) { - /* lower order three bytes goes to higher order three bytes */ - shCount -= 8; - if(size == 2){ - if(shCount) - shiftL1Left2Result(left, LSB, result, MSB16, shCount); - else - movLeft2Result(left, LSB, result, MSB16, 0); - } - else{ /* size = 4 */ - if(shCount == 0){ - movLeft2Result(left, MSB24, result, MSB32, 0); - movLeft2Result(left, MSB16, result, MSB24, 0); - movLeft2Result(left, LSB, result, MSB16, 0); - aopPut(AOP(result),zero,LSB); - } - else if(shCount == 1) - shiftLLong(left, result, MSB16); - else{ - shiftL2Left2Result(left, MSB16, result, MSB24, shCount); - shiftL1Left2Result(left, LSB, result, MSB16, shCount); - shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount); - aopPut(AOP(result),zero,LSB); - } - } - } - - /* 1 <= shCount <= 7 */ - else if(shCount <= 2){ - shiftLLong(left, result, LSB); - if(shCount == 2) - shiftLLong(result, result, LSB); - } - /* 3 <= shCount <= 7, optimize */ - else{ - shiftL2Left2Result(left, MSB24, result, MSB24, shCount); - shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount); - shiftL2Left2Result(left, LSB, result, LSB, shCount); - } -} - -/*-----------------------------------------------------------------*/ -/* genLeftShiftLiteral - left shifting by known count */ -/*-----------------------------------------------------------------*/ -static void genLeftShiftLiteral (operand *left, - operand *right, - operand *result, - iCode *ic) -{ - int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit); - int size; - - freeAsmop(right,NULL,ic,TRUE); - - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); - - size = getSize(operandType(result)); - -#if VIEW_SIZE - emitcode("; shift left ","result %d, left %d",size, - AOP_SIZE(left)); -#endif - - /* I suppose that the left size >= result size */ - if(shCount == 0){ - while(size--){ - movLeft2Result(left, size, result, size, 0); - } - } - - else if(shCount >= (size * 8)) - while(size--) - aopPut(AOP(result),zero,size); - else{ - switch (size) { - case 1: - genlshOne (result,left,shCount); - break; - - case 2: - case 3: - genlshTwo (result,left,shCount); - break; - - case 4: - genlshFour (result,left,shCount); - break; - } - } - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genLeftShift - generates code for left shifting */ -/*-----------------------------------------------------------------*/ -static void genLeftShift (iCode *ic) -{ - operand *left,*right, *result; - int size, offset; - char *l; - symbol *tlbl , *tlbl1; - - right = IC_RIGHT(ic); - left = IC_LEFT(ic); - result = IC_RESULT(ic); - - aopOp(right,ic,FALSE); - - /* if the shift count is known then do it - as efficiently as possible */ - if (AOP_TYPE(right) == AOP_LIT) { - genLeftShiftLiteral (left,right,result,ic); - return ; - } - - /* shift count is unknown then we have to form - a loop get the loop count in B : Note: we take - only the lower order byte since shifting - more that 32 bits make no sense anyway, ( the - largest size of an object can be only 32 bits ) */ - - emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); - emitcode("inc","b"); - freeAsmop (right,NULL,ic,TRUE); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); - - /* now move the left to the result if they are not the - same */ - if (!sameRegs(AOP(left),AOP(result)) && - AOP_SIZE(result) > 1) { - - size = AOP_SIZE(result); - offset=0; - while (size--) { - l = aopGet(AOP(left),offset,FALSE,TRUE); - if (*l == '@' && (IS_AOP_PREG(result))) { - - emitcode("mov","a,%s",l); - aopPut(AOP(result),"a",offset); - } else - aopPut(AOP(result),l,offset); - offset++; - } - } - - tlbl = newiTempLabel(NULL); - size = AOP_SIZE(result); - offset = 0 ; - tlbl1 = newiTempLabel(NULL); - - /* if it is only one byte then */ - if (size == 1) { - symbol *tlbl1 = newiTempLabel(NULL); - - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("sjmp","%05d$",tlbl1->key+100); - emitcode("","%05d$:",tlbl->key+100); - emitcode("add","a,acc"); - emitcode("","%05d$:",tlbl1->key+100); - emitcode("djnz","b,%05d$",tlbl->key+100); - aopPut(AOP(result),"a",0); - goto release ; - } - - reAdjustPreg(AOP(result)); - - emitcode("sjmp","%05d$",tlbl1->key+100); - emitcode("","%05d$:",tlbl->key+100); - l = aopGet(AOP(result),offset,FALSE,FALSE); - MOVA(l); - emitcode("add","a,acc"); - aopPut(AOP(result),"a",offset++); - while (--size) { - l = aopGet(AOP(result),offset,FALSE,FALSE); - MOVA(l); - emitcode("rlc","a"); - aopPut(AOP(result),"a",offset++); - } - reAdjustPreg(AOP(result)); - - emitcode("","%05d$:",tlbl1->key+100); - emitcode("djnz","b,%05d$",tlbl->key+100); -release: - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genrshOne - right shift a one byte quantity by known count */ -/*-----------------------------------------------------------------*/ -static void genrshOne (operand *result, operand *left, - int shCount, int sign) -{ - shiftR1Left2Result(left, LSB, result, LSB, shCount, sign); -} - -/*-----------------------------------------------------------------*/ -/* genrshTwo - right shift two bytes by known amount != 0 */ -/*-----------------------------------------------------------------*/ -static void genrshTwo (operand *result,operand *left, - int shCount, int sign) -{ - /* if shCount >= 8 */ - if (shCount >= 8) { - shCount -= 8 ; - if (shCount) - shiftR1Left2Result(left, MSB16, result, LSB, - shCount, sign); - else - movLeft2Result(left, MSB16, result, LSB, sign); - addSign(result, MSB16, sign); - } - - /* 1 <= shCount <= 7 */ - else - shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); -} - -/*-----------------------------------------------------------------*/ -/* shiftRLong - shift right one long from left to result */ -/* offl = LSB or MSB16 */ -/*-----------------------------------------------------------------*/ -static void shiftRLong (operand *left, int offl, - operand *result, int sign) -{ - if(!sign) - emitcode("clr","c"); - MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE)); - if(sign) - emitcode("mov","c,acc.7"); - emitcode("rrc","a"); - aopPut(AOP(result),"a",MSB32-offl); - if(offl == MSB16) - /* add sign of "a" */ - addSign(result, MSB32, sign); - - MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE)); - emitcode("rrc","a"); - aopPut(AOP(result),"a",MSB24-offl); - - MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE)); - emitcode("rrc","a"); - aopPut(AOP(result),"a",MSB16-offl); - - if(offl == LSB){ - MOVA(aopGet(AOP(left),LSB,FALSE,FALSE)); - emitcode("rrc","a"); - aopPut(AOP(result),"a",LSB); - } -} - -/*-----------------------------------------------------------------*/ -/* genrshFour - shift four byte by a known amount != 0 */ -/*-----------------------------------------------------------------*/ -static void genrshFour (operand *result, operand *left, - int shCount, int sign) -{ - /* if shifting more that 3 bytes */ - if(shCount >= 24 ) { - shCount -= 24; - if(shCount) - shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign); - else - movLeft2Result(left, MSB32, result, LSB, sign); - addSign(result, MSB16, sign); - } - else if(shCount >= 16){ - shCount -= 16; - if(shCount) - shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign); - else{ - movLeft2Result(left, MSB24, result, LSB, 0); - movLeft2Result(left, MSB32, result, MSB16, sign); - } - addSign(result, MSB24, sign); - } - else if(shCount >= 8){ - shCount -= 8; - if(shCount == 1) - shiftRLong(left, MSB16, result, sign); - else if(shCount == 0){ - movLeft2Result(left, MSB16, result, LSB, 0); - movLeft2Result(left, MSB24, result, MSB16, 0); - movLeft2Result(left, MSB32, result, MSB24, sign); - addSign(result, MSB32, sign); - } - else{ - shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0); - shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount); - /* the last shift is signed */ - shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign); - addSign(result, MSB32, sign); - } - } - else{ /* 1 <= shCount <= 7 */ - if(shCount <= 2){ - shiftRLong(left, LSB, result, sign); - if(shCount == 2) - shiftRLong(result, LSB, result, sign); - } - else{ - shiftR2Left2Result(left, LSB, result, LSB, shCount, 0); - shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount); - shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign); - } - } -} - -/*-----------------------------------------------------------------*/ -/* genRightShiftLiteral - right shifting by known count */ -/*-----------------------------------------------------------------*/ -static void genRightShiftLiteral (operand *left, - operand *right, - operand *result, - iCode *ic, - int sign) -{ - int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit); - int size; - - freeAsmop(right,NULL,ic,TRUE); - - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); - -#if VIEW_SIZE - emitcode("; shift right ","result %d, left %d",AOP_SIZE(result), - AOP_SIZE(left)); -#endif - - size = getDataSize(left); - /* test the LEFT size !!! */ - - /* I suppose that the left size >= result size */ - if(shCount == 0){ - size = getDataSize(result); - while(size--) - movLeft2Result(left, size, result, size, 0); - } - - else if(shCount >= (size * 8)){ - if(sign) - /* get sign in acc.7 */ - MOVA(aopGet(AOP(left),size-1,FALSE,FALSE)); - addSign(result, LSB, sign); - } else{ - switch (size) { - case 1: - genrshOne (result,left,shCount,sign); - break; - - case 2: - genrshTwo (result,left,shCount,sign); - break; - - case 4: - genrshFour (result,left,shCount,sign); - break; - default : - break; - } - - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); - } -} - -/*-----------------------------------------------------------------*/ -/* genSignedRightShift - right shift of signed number */ -/*-----------------------------------------------------------------*/ -static void genSignedRightShift (iCode *ic) -{ - operand *right, *left, *result; - int size, offset; - char *l; - symbol *tlbl, *tlbl1 ; - - /* we do it the hard way put the shift count in b - and loop thru preserving the sign */ - - right = IC_RIGHT(ic); - left = IC_LEFT(ic); - result = IC_RESULT(ic); - - aopOp(right,ic,FALSE); - - - if ( AOP_TYPE(right) == AOP_LIT) { - genRightShiftLiteral (left,right,result,ic,1); - return ; - } - /* shift count is unknown then we have to form - a loop get the loop count in B : Note: we take - only the lower order byte since shifting - more that 32 bits make no sense anyway, ( the - largest size of an object can be only 32 bits ) */ - - emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); - emitcode("inc","b"); - freeAsmop (right,NULL,ic,TRUE); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); - - /* now move the left to the result if they are not the - same */ - if (!sameRegs(AOP(left),AOP(result)) && - AOP_SIZE(result) > 1) { - - size = AOP_SIZE(result); - offset=0; - while (size--) { - l = aopGet(AOP(left),offset,FALSE,TRUE); - if (*l == '@' && IS_AOP_PREG(result)) { - - emitcode("mov","a,%s",l); - aopPut(AOP(result),"a",offset); - } else - aopPut(AOP(result),l,offset); - offset++; - } - } - - /* mov the highest order bit to OVR */ - tlbl = newiTempLabel(NULL); - tlbl1= newiTempLabel(NULL); - - size = AOP_SIZE(result); - offset = size - 1; - emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE)); - emitcode("rlc","a"); - emitcode("mov","ov,c"); - /* if it is only one byte then */ - if (size == 1) { - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("sjmp","%05d$",tlbl1->key+100); - emitcode("","%05d$:",tlbl->key+100); - emitcode("mov","c,ov"); - emitcode("rrc","a"); - emitcode("","%05d$:",tlbl1->key+100); - emitcode("djnz","b,%05d$",tlbl->key+100); - aopPut(AOP(result),"a",0); - goto release ; - } - - reAdjustPreg(AOP(result)); - emitcode("sjmp","%05d$",tlbl1->key+100); - emitcode("","%05d$:",tlbl->key+100); - emitcode("mov","c,ov"); - while (size--) { - l = aopGet(AOP(result),offset,FALSE,FALSE); - MOVA(l); - emitcode("rrc","a"); - aopPut(AOP(result),"a",offset--); - } - reAdjustPreg(AOP(result)); - emitcode("","%05d$:",tlbl1->key+100); - emitcode("djnz","b,%05d$",tlbl->key+100); - -release: - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genRightShift - generate code for right shifting */ -/*-----------------------------------------------------------------*/ -static void genRightShift (iCode *ic) -{ - operand *right, *left, *result; - link *retype ; - int size, offset; - char *l; - symbol *tlbl, *tlbl1 ; - - /* if signed then we do it the hard way preserve the - sign bit moving it inwards */ - retype = getSpec(operandType(IC_RESULT(ic))); - - if (!SPEC_USIGN(retype)) { - genSignedRightShift (ic); - return ; - } - - /* signed & unsigned types are treated the same : i.e. the - signed is NOT propagated inwards : quoting from the - ANSI - standard : "for E1 >> E2, is equivalent to division - by 2**E2 if unsigned or if it has a non-negative value, - otherwise the result is implementation defined ", MY definition - is that the sign does not get propagated */ - - right = IC_RIGHT(ic); - left = IC_LEFT(ic); - result = IC_RESULT(ic); - - aopOp(right,ic,FALSE); - - /* if the shift count is known then do it - as efficiently as possible */ - if (AOP_TYPE(right) == AOP_LIT) { - genRightShiftLiteral (left,right,result,ic, 0); - return ; - } - - /* shift count is unknown then we have to form - a loop get the loop count in B : Note: we take - only the lower order byte since shifting - more that 32 bits make no sense anyway, ( the - largest size of an object can be only 32 bits ) */ - - emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); - emitcode("inc","b"); - freeAsmop (right,NULL,ic,TRUE); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); - - /* now move the left to the result if they are not the - same */ - if (!sameRegs(AOP(left),AOP(result)) && - AOP_SIZE(result) > 1) { - - size = AOP_SIZE(result); - offset=0; - while (size--) { - l = aopGet(AOP(left),offset,FALSE,TRUE); - if (*l == '@' && IS_AOP_PREG(result)) { - - emitcode("mov","a,%s",l); - aopPut(AOP(result),"a",offset); - } else - aopPut(AOP(result),l,offset); - offset++; - } - } - - tlbl = newiTempLabel(NULL); - tlbl1= newiTempLabel(NULL); - size = AOP_SIZE(result); - offset = size - 1; - - /* if it is only one byte then */ - if (size == 1) { - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - emitcode("sjmp","%05d$",tlbl1->key+100); - emitcode("","%05d$:",tlbl->key+100); - CLRC; - emitcode("rrc","a"); - emitcode("","%05d$:",tlbl1->key+100); - emitcode("djnz","b,%05d$",tlbl->key+100); - aopPut(AOP(result),"a",0); - goto release ; - } - - reAdjustPreg(AOP(result)); - emitcode("sjmp","%05d$",tlbl1->key+100); - emitcode("","%05d$:",tlbl->key+100); - CLRC; - while (size--) { - l = aopGet(AOP(result),offset,FALSE,FALSE); - MOVA(l); - emitcode("rrc","a"); - aopPut(AOP(result),"a",offset--); - } - reAdjustPreg(AOP(result)); - - emitcode("","%05d$:",tlbl1->key+100); - emitcode("djnz","b,%05d$",tlbl->key+100); - -release: - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genUnpackBits - generates code for unpacking bits */ -/*-----------------------------------------------------------------*/ -static void genUnpackBits (operand *result, char *rname, int ptype) -{ - int shCnt ; - int rlen = 0 ; - link *etype; - int offset = 0 ; - - etype = getSpec(operandType(result)); - - /* read the first byte */ - switch (ptype) { - - case POINTER: - case IPOINTER: - emitcode("mov","a,@%s",rname); - break; - - case PPOINTER: - emitcode("movx","a,@%s",rname); - break; - - case FPOINTER: - emitcode("movx","a,@dptr"); - break; - - case CPOINTER: - emitcode("clr","a"); - emitcode("movc","a","@a+dptr"); - break; - - case GPOINTER: - emitcode("lcall","__gptrget"); - break; - } - - /* if we have bitdisplacement then it fits */ - /* into this byte completely or if length is */ - /* less than a byte */ - if ((shCnt = SPEC_BSTR(etype)) || - (SPEC_BLEN(etype) <= 8)) { - - /* shift right acc */ - AccRsh(shCnt); - - emitcode("anl","a,#0x%02x", - ((unsigned char) -1)>>(8 - SPEC_BLEN(etype))); - aopPut(AOP(result),"a",offset); - return ; - } - - /* bit field did not fit in a byte */ - rlen = SPEC_BLEN(etype) - 8; - aopPut(AOP(result),"a",offset++); - - while (1) { - - switch (ptype) { - case POINTER: - case IPOINTER: - emitcode("inc","%s",rname); - emitcode("mov","a,@%s",rname); - break; - - case PPOINTER: - emitcode("inc","%s",rname); - emitcode("movx","a,@%s",rname); - break; - - case FPOINTER: - emitcode("inc","dptr"); - emitcode("movx","a,@dptr"); - break; - - case CPOINTER: - emitcode("clr","a"); - emitcode("inc","dptr"); - emitcode("movc","a","@a+dptr"); - break; - - case GPOINTER: - emitcode("inc","dptr"); - emitcode("lcall","__gptrget"); - break; - } - - rlen -= 8; - /* if we are done */ - if ( rlen <= 0 ) - break ; - - aopPut(AOP(result),"a",offset++); - - } - - if (rlen) { - emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen)); - aopPut(AOP(result),"a",offset); - } - - return ; -} - - -/*-----------------------------------------------------------------*/ -/* genDataPointerGet - generates code when ptr offset is known */ -/*-----------------------------------------------------------------*/ -static void genDataPointerGet (operand *left, - operand *result, - iCode *ic) -{ - char *l; - char buffer[256]; - int size , offset = 0; - aopOp(result,ic,TRUE); - - /* get the string representation of the name */ - l = aopGet(AOP(left),0,FALSE,TRUE); - size = AOP_SIZE(result); - while (size--) { - if (offset) - sprintf(buffer,"(%s + %d)",l+1,offset); - else - sprintf(buffer,"%s",l+1); - aopPut(AOP(result),buffer,offset++); - } - - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genNearPointerGet - emitcode for near pointer fetch */ -/*-----------------------------------------------------------------*/ -static void genNearPointerGet (operand *left, - operand *result, - iCode *ic) -{ - asmop *aop = NULL; - regs *preg = NULL ; - char *rname ; - link *rtype, *retype; - link *ltype = operandType(left); - char buffer[80]; - - rtype = operandType(result); - retype= getSpec(rtype); - - aopOp(left,ic,FALSE); - - /* if left is rematerialisable and - result is not bit variable type and - the left is pointer to data space i.e - lower 128 bytes of space */ - if (AOP_TYPE(left) == AOP_IMMD && - !IS_BITVAR(retype) && - DCL_TYPE(ltype) == POINTER) { - genDataPointerGet (left,result,ic); - return ; - } - - /* if the value is already in a pointer register - then don't need anything more */ - if (!AOP_INPREG(AOP(left))) { - /* otherwise get a free pointer register */ - aop = newAsmop(0); - preg = getFreePtr(ic,&aop,FALSE); - emitcode("mov","%s,%s", - preg->name, - aopGet(AOP(left),0,FALSE,TRUE)); - rname = preg->name ; - } else - rname = aopGet(AOP(left),0,FALSE,FALSE); - - freeAsmop(left,NULL,ic,TRUE); - aopOp (result,ic,FALSE); - - /* if bitfield then unpack the bits */ - if (IS_BITVAR(retype)) - genUnpackBits (result,rname,POINTER); - else { - /* we have can just get the values */ - int size = AOP_SIZE(result); - int offset = 0 ; - - while (size--) { - if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) { - - emitcode("mov","a,@%s",rname); - aopPut(AOP(result),"a",offset); - } else { - sprintf(buffer,"@%s",rname); - aopPut(AOP(result),buffer,offset); - } - offset++ ; - if (size) - emitcode("inc","%s",rname); - } - } - - /* now some housekeeping stuff */ - if (aop) { - /* we had to allocate for this iCode */ - freeAsmop(NULL,aop,ic,TRUE); - } else { - /* we did not allocate which means left - already in a pointer register, then - if size > 0 && this could be used again - we have to point it back to where it - belongs */ - if (AOP_SIZE(result) > 1 && - !OP_SYMBOL(left)->remat && - ( OP_SYMBOL(left)->liveTo > ic->seq || - ic->depth )) { - int size = AOP_SIZE(result) - 1; - while (size--) - emitcode("dec","%s",rname); - } - } - - /* done */ - freeAsmop(result,NULL,ic,TRUE); - -} - -/*-----------------------------------------------------------------*/ -/* genPagedPointerGet - emitcode for paged pointer fetch */ -/*-----------------------------------------------------------------*/ -static void genPagedPointerGet (operand *left, - operand *result, - iCode *ic) -{ - asmop *aop = NULL; - regs *preg = NULL ; - char *rname ; - link *rtype, *retype; - - rtype = operandType(result); - retype= getSpec(rtype); - - aopOp(left,ic,FALSE); - - /* if the value is already in a pointer register - then don't need anything more */ - if (!AOP_INPREG(AOP(left))) { - /* otherwise get a free pointer register */ - aop = newAsmop(0); - preg = getFreePtr(ic,&aop,FALSE); - emitcode("mov","%s,%s", - preg->name, - aopGet(AOP(left),0,FALSE,TRUE)); - rname = preg->name ; - } else - rname = aopGet(AOP(left),0,FALSE,FALSE); - - freeAsmop(left,NULL,ic,TRUE); - aopOp (result,ic,FALSE); - - /* if bitfield then unpack the bits */ - if (IS_BITVAR(retype)) - genUnpackBits (result,rname,PPOINTER); - else { - /* we have can just get the values */ - int size = AOP_SIZE(result); - int offset = 0 ; - - while (size--) { - - emitcode("movx","a,@%s",rname); - aopPut(AOP(result),"a",offset); - - offset++ ; - - if (size) - emitcode("inc","%s",rname); - } - } - - /* now some housekeeping stuff */ - if (aop) { - /* we had to allocate for this iCode */ - freeAsmop(NULL,aop,ic,TRUE); - } else { - /* we did not allocate which means left - already in a pointer register, then - if size > 0 && this could be used again - we have to point it back to where it - belongs */ - if (AOP_SIZE(result) > 1 && - !OP_SYMBOL(left)->remat && - ( OP_SYMBOL(left)->liveTo > ic->seq || - ic->depth )) { - int size = AOP_SIZE(result) - 1; - while (size--) - emitcode("dec","%s",rname); - } - } - - /* done */ - freeAsmop(result,NULL,ic,TRUE); - - -} - -/*-----------------------------------------------------------------*/ -/* genFarPointerGet - gget value from far space */ -/*-----------------------------------------------------------------*/ -static void genFarPointerGet (operand *left, - operand *result, iCode *ic) -{ - int size, offset ; - link *retype = getSpec(operandType(result)); - - aopOp(left,ic,FALSE); - - /* if the operand is already in dptr - then we do nothing else we move the value to dptr */ - if (AOP_TYPE(left) != AOP_STR) { - /* if this is remateriazable */ - if (AOP_TYPE(left) == AOP_IMMD) - emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE)); - else { /* we need to get it byte by byte */ - emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE)); - emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE)); - } - } - /* so dptr know contains the address */ - freeAsmop(left,NULL,ic,TRUE); - aopOp(result,ic,FALSE); - - /* if bit then unpack */ - if (IS_BITVAR(retype)) - genUnpackBits(result,"dptr",FPOINTER); - else { - size = AOP_SIZE(result); - offset = 0 ; - - while (size--) { - emitcode("movx","a,@dptr"); - aopPut(AOP(result),"a",offset++); - if (size) - emitcode("inc","dptr"); - } - } - - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* emitcodePointerGet - gget value from code space */ -/*-----------------------------------------------------------------*/ -static void emitcodePointerGet (operand *left, - operand *result, iCode *ic) -{ - int size, offset ; - link *retype = getSpec(operandType(result)); - - aopOp(left,ic,FALSE); - - /* if the operand is already in dptr - then we do nothing else we move the value to dptr */ - if (AOP_TYPE(left) != AOP_STR) { - /* if this is remateriazable */ - if (AOP_TYPE(left) == AOP_IMMD) - emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE)); - else { /* we need to get it byte by byte */ - emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE)); - emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE)); - } - } - /* so dptr know contains the address */ - freeAsmop(left,NULL,ic,TRUE); - aopOp(result,ic,FALSE); - - /* if bit then unpack */ - if (IS_BITVAR(retype)) - genUnpackBits(result,"dptr",CPOINTER); - else { - size = AOP_SIZE(result); - offset = 0 ; - - while (size--) { - emitcode("clr","a"); - emitcode("movc","a,@a+dptr"); - aopPut(AOP(result),"a",offset++); - if (size) - emitcode("inc","dptr"); - } - } - - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genGenPointerGet - gget value from generic pointer space */ -/*-----------------------------------------------------------------*/ -static void genGenPointerGet (operand *left, - operand *result, iCode *ic) -{ - int size, offset ; - link *retype = getSpec(operandType(result)); - - aopOp(left,ic,FALSE); - - /* if the operand is already in dptr - then we do nothing else we move the value to dptr */ - if (AOP_TYPE(left) != AOP_STR) { - /* if this is remateriazable */ - if (AOP_TYPE(left) == AOP_IMMD) { - emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE)); - emitcode("mov","b,#%d",pointerCode(retype)); - } - else { /* we need to get it byte by byte */ - emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE)); - emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE)); - emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE)); - } - } - /* so dptr know contains the address */ - freeAsmop(left,NULL,ic,TRUE); - aopOp(result,ic,FALSE); - - /* if bit then unpack */ - if (IS_BITVAR(retype)) - genUnpackBits(result,"dptr",GPOINTER); - else { - size = AOP_SIZE(result); - offset = 0 ; - - while (size--) { - emitcode("lcall","__gptrget"); - aopPut(AOP(result),"a",offset++); - if (size) - emitcode("inc","dptr"); - } - } - - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genPointerGet - generate code for pointer get */ -/*-----------------------------------------------------------------*/ -static void genPointerGet (iCode *ic) -{ - operand *left, *result ; - link *type, *etype; - int p_type; - - left = IC_LEFT(ic); - result = IC_RESULT(ic) ; - - /* depending on the type of pointer we need to - move it to the correct pointer register */ - type = operandType(left); - etype = getSpec(type); - /* if left is of type of pointer then it is simple */ - if (IS_PTR(type) && !IS_FUNC(type->next)) - p_type = DCL_TYPE(type); - else { - - /* we have to go by the storage class */ - if (SPEC_OCLS(etype)->codesp ) { - p_type = CPOINTER ; - } - else - if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) - p_type = FPOINTER ; - else - if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) - p_type = PPOINTER; - else - if (SPEC_OCLS(etype) == idata ) - p_type = IPOINTER; - else - p_type = POINTER ; - } - - /* now that we have the pointer type we assign - the pointer values */ - switch (p_type) { - - case POINTER: - case IPOINTER: - genNearPointerGet (left,result,ic); - break; - - case PPOINTER: - genPagedPointerGet(left,result,ic); - break; - - case FPOINTER: - genFarPointerGet (left,result,ic); - break; - - case CPOINTER: - emitcodePointerGet (left,result,ic); - break; - - case GPOINTER: - genGenPointerGet (left,result,ic); - break; - } - -} - -/*-----------------------------------------------------------------*/ -/* genPackBits - generates code for packed bit storage */ -/*-----------------------------------------------------------------*/ -static void genPackBits (link *etype , - operand *right , - char *rname, int p_type) -{ - int shCount = 0 ; - int offset = 0 ; - int rLen = 0 ; - int blen, bstr ; - char *l ; - - blen = SPEC_BLEN(etype); - bstr = SPEC_BSTR(etype); - - l = aopGet(AOP(right),offset++,FALSE,FALSE); - MOVA(l); - - /* if the bit lenth is less than or */ - /* it exactly fits a byte then */ - if (SPEC_BLEN(etype) <= 8 ) { - shCount = SPEC_BSTR(etype) ; - - /* shift left acc */ - AccLsh(shCount); - - if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */ - - - switch (p_type) { - case POINTER: - emitcode ("mov","b,a"); - emitcode("mov","a,@%s",rname); - break; - - case FPOINTER: - emitcode ("mov","b,a"); - emitcode("movx","a,@dptr"); - break; - - case GPOINTER: - emitcode ("push","b"); - emitcode ("push","acc"); - emitcode ("lcall","__gptrget"); - emitcode ("pop","b"); - break; - } - - emitcode ("anl","a,#0x%02x",(unsigned char) - ((unsigned char)(0xFF << (blen+bstr)) | - (unsigned char)(0xFF >> (8-bstr)) ) ); - emitcode ("orl","a,b"); - if (p_type == GPOINTER) - emitcode("pop","b"); - } - } - - switch (p_type) { - case POINTER: - emitcode("mov","@%s,a",rname); - break; - - case FPOINTER: - emitcode("movx","@dptr,a"); - break; - - case GPOINTER: - emitcode("lcall","__gptrput"); - break; - } - - /* if we r done */ - if ( SPEC_BLEN(etype) <= 8 ) - return ; - - emitcode("inc","%s",rname); - rLen = SPEC_BLEN(etype) ; - - /* now generate for lengths greater than one byte */ - while (1) { - - l = aopGet(AOP(right),offset++,FALSE,TRUE); - - rLen -= 8 ; - if (rLen <= 0 ) - break ; - - switch (p_type) { - case POINTER: - if (*l == '@') { - MOVA(l); - emitcode("mov","@%s,a",rname); - } else - emitcode("mov","@%s,%s",rname,l); - break; - - case FPOINTER: - MOVA(l); - emitcode("movx","@dptr,a"); - break; - - case GPOINTER: - MOVA(l); - emitcode("lcall","__gptrput"); - break; - } - emitcode ("inc","%s",rname); - } - - MOVA(l); - - /* last last was not complete */ - if (rLen) { - /* save the byte & read byte */ - switch (p_type) { - case POINTER: - emitcode ("mov","b,a"); - emitcode("mov","a,@%s",rname); - break; - - case FPOINTER: - emitcode ("mov","b,a"); - emitcode("movx","a,@dptr"); - break; - - case GPOINTER: - emitcode ("push","b"); - emitcode ("push","acc"); - emitcode ("lcall","__gptrget"); - emitcode ("pop","b"); - break; - } - - emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) ); - emitcode ("orl","a,b"); - } - - if (p_type == GPOINTER) - emitcode("pop","b"); - - switch (p_type) { - - case POINTER: - emitcode("mov","@%s,a",rname); - break; - - case FPOINTER: - emitcode("movx","@dptr,a"); - break; - - case GPOINTER: - emitcode("lcall","__gptrput"); - break; - } -} -/*-----------------------------------------------------------------*/ -/* genDataPointerSet - remat pointer to data space */ -/*-----------------------------------------------------------------*/ -static void genDataPointerSet(operand *right, - operand *result, - iCode *ic) -{ - int size, offset = 0 ; - char *l, buffer[256]; - - aopOp(right,ic,FALSE); - - l = aopGet(AOP(result),0,FALSE,TRUE); - size = AOP_SIZE(right); - while (size--) { - if (offset) - sprintf(buffer,"(%s + %d)",l+1,offset); - else - sprintf(buffer,"%s",l+1); - emitcode("mov","%s,%s",buffer, - aopGet(AOP(right),offset++,FALSE,FALSE)); - } - - freeAsmop(right,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genNearPointerSet - emitcode for near pointer put */ -/*-----------------------------------------------------------------*/ -static void genNearPointerSet (operand *right, - operand *result, - iCode *ic) -{ - asmop *aop = NULL; - regs *preg = NULL ; - char *rname , *l; - link *retype; - link *ptype = operandType(result); - - retype= getSpec(operandType(right)); - - aopOp(result,ic,FALSE); - - /* if the result is rematerializable & - in data space & not a bit variable */ - if (AOP_TYPE(result) == AOP_IMMD && - DCL_TYPE(ptype) == POINTER && - !IS_BITVAR(retype)) { - genDataPointerSet (right,result,ic); - return; - } - - /* if the value is already in a pointer register - then don't need anything more */ - if (!AOP_INPREG(AOP(result))) { - /* otherwise get a free pointer register */ - aop = newAsmop(0); - preg = getFreePtr(ic,&aop,FALSE); - emitcode("mov","%s,%s", - preg->name, - aopGet(AOP(result),0,FALSE,TRUE)); - rname = preg->name ; - } else - rname = aopGet(AOP(result),0,FALSE,FALSE); - - freeAsmop(result,NULL,ic,TRUE); - aopOp (right,ic,FALSE); - - /* if bitfield then unpack the bits */ - if (IS_BITVAR(retype)) - genPackBits (retype,right,rname,POINTER); - else { - /* we have can just get the values */ - int size = AOP_SIZE(right); - int offset = 0 ; - - while (size--) { - l = aopGet(AOP(right),offset,FALSE,TRUE); - if (*l == '@' ) { - MOVA(l); - emitcode("mov","@%s,a",rname); - } else - emitcode("mov","@%s,%s",rname,l); - if (size) - emitcode("inc","%s",rname); - offset++; - } - } - - /* now some housekeeping stuff */ - if (aop) { - /* we had to allocate for this iCode */ - freeAsmop(NULL,aop,ic,TRUE); - } else { - /* we did not allocate which means left - already in a pointer register, then - if size > 0 && this could be used again - we have to point it back to where it - belongs */ - if (AOP_SIZE(right) > 1 && - !OP_SYMBOL(result)->remat && - ( OP_SYMBOL(result)->liveTo > ic->seq || - ic->depth )) { - int size = AOP_SIZE(right) - 1; - while (size--) - emitcode("dec","%s",rname); - } - } - - /* done */ - freeAsmop(right,NULL,ic,TRUE); - - -} - -/*-----------------------------------------------------------------*/ -/* genPagedPointerSet - emitcode for Paged pointer put */ -/*-----------------------------------------------------------------*/ -static void genPagedPointerSet (operand *right, - operand *result, - iCode *ic) -{ - asmop *aop = NULL; - regs *preg = NULL ; - char *rname , *l; - link *retype; - - retype= getSpec(operandType(right)); - - aopOp(result,ic,FALSE); - - /* if the value is already in a pointer register - then don't need anything more */ - if (!AOP_INPREG(AOP(result))) { - /* otherwise get a free pointer register */ - aop = newAsmop(0); - preg = getFreePtr(ic,&aop,FALSE); - emitcode("mov","%s,%s", - preg->name, - aopGet(AOP(result),0,FALSE,TRUE)); - rname = preg->name ; - } else - rname = aopGet(AOP(result),0,FALSE,FALSE); - - freeAsmop(result,NULL,ic,TRUE); - aopOp (right,ic,FALSE); - - /* if bitfield then unpack the bits */ - if (IS_BITVAR(retype)) - genPackBits (retype,right,rname,PPOINTER); - else { - /* we have can just get the values */ - int size = AOP_SIZE(right); - int offset = 0 ; - - while (size--) { - l = aopGet(AOP(right),offset,FALSE,TRUE); - - MOVA(l); - emitcode("movx","@%s,a",rname); - - if (size) - emitcode("inc","%s",rname); - - offset++; - } - } - - /* now some housekeeping stuff */ - if (aop) { - /* we had to allocate for this iCode */ - freeAsmop(NULL,aop,ic,TRUE); - } else { - /* we did not allocate which means left - already in a pointer register, then - if size > 0 && this could be used again - we have to point it back to where it - belongs */ - if (AOP_SIZE(right) > 1 && - !OP_SYMBOL(result)->remat && - ( OP_SYMBOL(result)->liveTo > ic->seq || - ic->depth )) { - int size = AOP_SIZE(right) - 1; - while (size--) - emitcode("dec","%s",rname); - } - } - - /* done */ - freeAsmop(right,NULL,ic,TRUE); - - -} - -/*-----------------------------------------------------------------*/ -/* genFarPointerSet - set value from far space */ -/*-----------------------------------------------------------------*/ -static void genFarPointerSet (operand *right, - operand *result, iCode *ic) -{ - int size, offset ; - link *retype = getSpec(operandType(right)); - - aopOp(result,ic,FALSE); - - /* if the operand is already in dptr - then we do nothing else we move the value to dptr */ - if (AOP_TYPE(result) != AOP_STR) { - /* if this is remateriazable */ - if (AOP_TYPE(result) == AOP_IMMD) - emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE)); - else { /* we need to get it byte by byte */ - emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE)); - emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE)); - } - } - /* so dptr know contains the address */ - freeAsmop(result,NULL,ic,TRUE); - aopOp(right,ic,FALSE); - - /* if bit then unpack */ - if (IS_BITVAR(retype)) - genPackBits(retype,right,"dptr",FPOINTER); - else { - size = AOP_SIZE(right); - offset = 0 ; - - while (size--) { - char *l = aopGet(AOP(right),offset++,FALSE,FALSE); - MOVA(l); - emitcode("movx","@dptr,a"); - if (size) - emitcode("inc","dptr"); - } - } - - freeAsmop(right,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genGenPointerSet - set value from generic pointer space */ -/*-----------------------------------------------------------------*/ -static void genGenPointerSet (operand *right, - operand *result, iCode *ic) -{ - int size, offset ; - link *retype = getSpec(operandType(right)); - - aopOp(result,ic,FALSE); - - /* if the operand is already in dptr - then we do nothing else we move the value to dptr */ - if (AOP_TYPE(result) != AOP_STR) { - /* if this is remateriazable */ - if (AOP_TYPE(result) == AOP_IMMD) { - emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE)); - emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE)); - } - else { /* we need to get it byte by byte */ - emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE)); - emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE)); - emitcode("mov","b,%s",aopGet(AOP(result),2,FALSE,FALSE)); - } - } - /* so dptr know contains the address */ - freeAsmop(result,NULL,ic,TRUE); - aopOp(right,ic,FALSE); - - /* if bit then unpack */ - if (IS_BITVAR(retype)) - genPackBits(retype,right,"dptr",GPOINTER); - else { - size = AOP_SIZE(right); - offset = 0 ; - - while (size--) { - char *l = aopGet(AOP(right),offset++,FALSE,FALSE); - MOVA(l); - emitcode("lcall","__gptrput"); - if (size) - emitcode("inc","dptr"); - } - } - - freeAsmop(right,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genPointerSet - stores the value into a pointer location */ -/*-----------------------------------------------------------------*/ -static void genPointerSet (iCode *ic) -{ - operand *right, *result ; - link *type, *etype; - int p_type; - - right = IC_RIGHT(ic); - result = IC_RESULT(ic) ; - - /* depending on the type of pointer we need to - move it to the correct pointer register */ - type = operandType(result); - etype = getSpec(type); - /* if left is of type of pointer then it is simple */ - if (IS_PTR(type) && !IS_FUNC(type->next)) { - p_type = DCL_TYPE(type); - } - else { - - /* we have to go by the storage class */ - if (SPEC_OCLS(etype)->codesp ) { - p_type = CPOINTER ; - } - else - if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) - p_type = FPOINTER ; - else - if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) - p_type = PPOINTER ; - else - if (SPEC_OCLS(etype) == idata ) - p_type = IPOINTER ; - else - p_type = POINTER ; - } - - /* now that we have the pointer type we assign - the pointer values */ - switch (p_type) { - - case POINTER: - case IPOINTER: - genNearPointerSet (right,result,ic); - break; - - case PPOINTER: - genPagedPointerSet (right,result,ic); - break; - - case FPOINTER: - genFarPointerSet (right,result,ic); - break; - - case GPOINTER: - genGenPointerSet (right,result,ic); - break; - } - -} - -/*-----------------------------------------------------------------*/ -/* genIfx - generate code for Ifx statement */ -/*-----------------------------------------------------------------*/ -static void genIfx (iCode *ic, iCode *popIc) -{ - operand *cond = IC_COND(ic); - int isbit =0; - - aopOp(cond,ic,FALSE); - - /* get the value into acc */ - if (AOP_TYPE(cond) != AOP_CRY) - toBoolean(cond); - else - isbit = 1; - /* the result is now in the accumulator */ - freeAsmop(cond,NULL,ic,TRUE); - - /* if there was something to be popped then do it */ - if (popIc) - genIpop(popIc); - - /* if the condition is a bit variable */ - if (isbit && IS_ITEMP(cond) && - SPIL_LOC(cond)) - genIfxJump(ic,SPIL_LOC(cond)->rname); - else - if (isbit && !IS_ITEMP(cond)) - genIfxJump(ic,OP_SYMBOL(cond)->rname); - else - genIfxJump(ic,"a"); - - ic->generated = 1; -} - -/*-----------------------------------------------------------------*/ -/* genAddrOf - generates code for address of */ -/*-----------------------------------------------------------------*/ -static void genAddrOf (iCode *ic) -{ - symbol *sym = OP_SYMBOL(IC_LEFT(ic)); - int size, offset ; - - aopOp(IC_RESULT(ic),ic,FALSE); - - /* if the operand is on the stack then we - need to get the stack offset of this - variable */ - if (sym->onStack) { - /* if it has an offset then we need to compute - it */ - if (sym->stack) { - emitcode("mov","a,_bp"); - emitcode("add","a,#0x%02x",((char) sym->stack & 0xff)); - aopPut(AOP(IC_RESULT(ic)),"a",0); - } else - /* we can just move _bp */ - aopPut(AOP(IC_RESULT(ic)),"_bp",0); - /* fill the result with zero */ - size = AOP_SIZE(IC_RESULT(ic)) - 1; - offset = 1; - while (size--) - aopPut(AOP(IC_RESULT(ic)),zero,offset++); - - goto release; - } - - /* object not on stack then we need the name */ - size = AOP_SIZE(IC_RESULT(ic)); - offset = 0; - - while (size--) { - char s[SDCC_NAME_MAX]; - if (offset) - sprintf(s,"#(%s >> %d)", - sym->rname, - offset*8); - else - sprintf(s,"#%s",sym->rname); - aopPut(AOP(IC_RESULT(ic)),s,offset++); - } - -release: - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); - -} - -/*-----------------------------------------------------------------*/ -/* genFarFarAssign - assignment when both are in far space */ -/*-----------------------------------------------------------------*/ -static void genFarFarAssign (operand *result, operand *right, iCode *ic) -{ - int size = AOP_SIZE(right); - int offset = 0; - char *l ; - /* first push the right side on to the stack */ - while (size--) { - l = aopGet(AOP(right),offset++,FALSE,FALSE); - MOVA(l); - emitcode ("push","acc"); - } - - freeAsmop(right,NULL,ic,FALSE); - /* now assign DPTR to result */ - aopOp(result,ic,FALSE); - size = AOP_SIZE(result); - while (size--) { - emitcode ("pop","acc"); - aopPut(AOP(result),"a",--offset); - } - freeAsmop(result,NULL,ic,FALSE); - -} - -/*-----------------------------------------------------------------*/ -/* genAssign - generate code for assignment */ -/*-----------------------------------------------------------------*/ -static void genAssign (iCode *ic) -{ - operand *result, *right; - int size, offset ; - unsigned long lit = 0L; - - result = IC_RESULT(ic); - right = IC_RIGHT(ic) ; - - /* if they are the same */ - if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic))) - return ; - - aopOp(right,ic,FALSE); - - /* special case both in far space */ - if (AOP_TYPE(right) == AOP_DPTR && - IS_TRUE_SYMOP(result) && - isOperandInFarSpace(result)) { - - genFarFarAssign (result,right,ic); - return ; - } - - aopOp(result,ic,TRUE); - - /* if they are the same registers */ - if (sameRegs(AOP(right),AOP(result))) - goto release; - - /* if the result is a bit */ - if (AOP_TYPE(result) == AOP_CRY) { - - /* if the right size is a literal then - we know what the value is */ - if (AOP_TYPE(right) == AOP_LIT) { - if (((int) operandLitValue(right))) - aopPut(AOP(result),one,0); - else - aopPut(AOP(result),zero,0); - goto release; - } - - /* the right is also a bit variable */ - if (AOP_TYPE(right) == AOP_CRY) { - emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - aopPut(AOP(result),"c",0); - goto release ; - } - - /* we need to or */ - toBoolean(right); - aopPut(AOP(result),"a",0); - goto release ; - } - - /* bit variables done */ - /* general case */ - size = AOP_SIZE(result); - offset = 0 ; - if(AOP_TYPE(right) == AOP_LIT) - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - if((size > 1) && - (AOP_TYPE(result) != AOP_REG) && - (AOP_TYPE(right) == AOP_LIT) && - !IS_FLOAT(operandType(right)) && - (lit < 256L)){ - emitcode("clr","a"); - while (size--) { - if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) - aopPut(AOP(result),"a",size); - else - aopPut(AOP(result), - aopGet(AOP(right),size,FALSE,FALSE), - size); - } - } else { - while (size--) { - aopPut(AOP(result), - aopGet(AOP(right),offset,FALSE,FALSE), - offset); - offset++; - } - } - -release: - freeAsmop (right,NULL,ic,FALSE); - freeAsmop (result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genJumpTab - genrates code for jump table */ -/*-----------------------------------------------------------------*/ -static void genJumpTab (iCode *ic) -{ - symbol *jtab; - char *l; - - aopOp(IC_JTCOND(ic),ic,FALSE); - /* get the condition into accumulator */ - l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE); - MOVA(l); - /* multiply by three */ - emitcode("add","a,acc"); - emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE)); - freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE); - - jtab = newiTempLabel(NULL); - emitcode("mov","dptr,#%05d$",jtab->key+100); - emitcode("jmp","@a+dptr"); - emitcode("","%05d$:",jtab->key+100); - /* now generate the jump labels */ - for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab; - jtab = setNextItem(IC_JTLABELS(ic))) - emitcode("ljmp","%05d$",jtab->key+100); - -} - -/*-----------------------------------------------------------------*/ -/* genCast - gen code for casting */ -/*-----------------------------------------------------------------*/ -static void genCast (iCode *ic) -{ - operand *result = IC_RESULT(ic); - link *ctype = operandType(IC_LEFT(ic)); - operand *right = IC_RIGHT(ic); - int size, offset ; - - /* if they are equivalent then do nothing */ - if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic))) - return ; - - aopOp(right,ic,FALSE) ; - aopOp(result,ic,FALSE); - - /* if the result is a bit */ - if (AOP_TYPE(result) == AOP_CRY) { - /* if the right size is a literal then - we know what the value is */ - if (AOP_TYPE(right) == AOP_LIT) { - if (((int) operandLitValue(right))) - aopPut(AOP(result),one,0); - else - aopPut(AOP(result),zero,0); - - goto release; - } - - /* the right is also a bit variable */ - if (AOP_TYPE(right) == AOP_CRY) { - emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - aopPut(AOP(result),"c",0); - goto release ; - } - - /* we need to or */ - toBoolean(right); - aopPut(AOP(result),"a",0); - goto release ; - } - - /* if they are the same size : or less */ - if (AOP_SIZE(result) <= AOP_SIZE(right)) { - - /* if they are in the same place */ - if (sameRegs(AOP(right),AOP(result))) - goto release; - - /* if they in different places then copy */ - size = AOP_SIZE(result); - offset = 0 ; - while (size--) { - aopPut(AOP(result), - aopGet(AOP(right),offset,FALSE,FALSE), - offset); - offset++; - } - goto release; - } - - - /* if the result is of type pointer */ - if (IS_PTR(ctype)) { - - int p_type; - link *type = operandType(right); - link *etype = getSpec(type); - - /* pointer to generic pointer */ - if (IS_GENPTR(ctype)) { - char *l = zero; - - if (IS_PTR(type)) - p_type = DCL_TYPE(type); - else { - /* we have to go by the storage class */ - if (SPEC_OCLS(etype)->codesp ) - p_type = CPOINTER ; - else - if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) - p_type = FPOINTER ; - else - if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) - p_type = PPOINTER; - else - if (SPEC_OCLS(etype) == idata ) - p_type = IPOINTER ; - else - p_type = POINTER ; - } - - /* the first two bytes are known */ - size = 2; - offset = 0 ; - while (size--) { - aopPut(AOP(result), - aopGet(AOP(right),offset,FALSE,FALSE), - offset); - offset++; - } - /* the last byte depending on type */ - switch (p_type) { - case IPOINTER: - case POINTER: - l = zero; - break; - case FPOINTER: - l = one; - break; - case CPOINTER: - l = "#0x02"; - break; - case PPOINTER: - l = "#0x03"; - break; - - default: - /* this should never happen */ - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "got unknown pointer type"); - exit(1); - } - aopPut(AOP(result),l,2); - goto release ; - } - - /* just copy the pointers */ - size = AOP_SIZE(result); - offset = 0 ; - while (size--) { - aopPut(AOP(result), - aopGet(AOP(right),offset,FALSE,FALSE), - offset); - offset++; - } - goto release ; - } - - /* so we now know that the size of destination is greater - than the size of the source */ - /* we move to result for the size of source */ - size = AOP_SIZE(right); - offset = 0 ; - while (size--) { - aopPut(AOP(result), - aopGet(AOP(right),offset,FALSE,FALSE), - offset); - offset++; - } - - /* now depending on the sign of the destination */ - size = AOP_SIZE(result) - AOP_SIZE(right); - /* if unsigned or not an integral type */ - if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) { - while (size--) - aopPut(AOP(result),zero,offset++); - } else { - /* we need to extend the sign :{ */ - char *l = aopGet(AOP(right),AOP_SIZE(right) - 1, - FALSE,FALSE); - MOVA(l); - emitcode("rlc","a"); - emitcode("subb","a,acc"); - while (size--) - aopPut(AOP(result),"a",offset++); - } - - /* we are done hurray !!!! */ - -release: - freeAsmop(right,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); - -} - -/*-----------------------------------------------------------------*/ -/* genDjnz - generate decrement & jump if not zero instrucion */ -/*-----------------------------------------------------------------*/ -static int genDjnz (iCode *ic, iCode *ifx) -{ - symbol *lbl, *lbl1; - if (!ifx) - return 0; - - /* if the if condition has a false label - then we cannot save */ - if (IC_FALSE(ifx)) - return 0; - - /* if the minus is not of the form - a = a - 1 */ - if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) || - !IS_OP_LITERAL(IC_RIGHT(ic))) - return 0; - - if (operandLitValue(IC_RIGHT(ic)) != 1) - return 0; - - /* if the size of this greater than one then no - saving */ - if (getSize(operandType(IC_RESULT(ic))) > 1) - return 0; - - /* otherwise we can save BIG */ - lbl = newiTempLabel(NULL); - lbl1= newiTempLabel(NULL); - - aopOp(IC_RESULT(ic),ic,FALSE); - - if (IS_AOP_PREG(IC_RESULT(ic))) { - emitcode("dec","%s", - aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - emitcode("jnz","%05d$",lbl->key+100); - } else { - emitcode ("djnz","%s,%05d$",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE), - lbl->key+100); - } - emitcode ("sjmp","%05d$",lbl1->key+100); - emitcode ("","%05d$:",lbl->key+100); - emitcode ("ljmp","%05d$",IC_TRUE(ifx)->key+100); - emitcode ("","%05d$:",lbl1->key+100); - - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); - ifx->generated = 1; - return 1; -} - -/*-----------------------------------------------------------------*/ -/* genReceive - generate code for a receive iCode */ -/*-----------------------------------------------------------------*/ -static void genReceive (iCode *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 = 4 - size; - while (size--) { - emitcode ("push","%s", (strcmp(fReturn[3 - offset],"a") ? - fReturn[3 - offset] : "acc")); - offset++; - } - aopOp(IC_RESULT(ic),ic,FALSE); - size = AOP_SIZE(IC_RESULT(ic)); - offset = 0; - while (size--) { - emitcode ("pop","acc"); - aopPut (AOP(IC_RESULT(ic)),"a",offset++); - } - - } else { - accInUse++; - aopOp(IC_RESULT(ic),ic,FALSE); - accInUse--; - assignResultValue(IC_RESULT(ic)); - } - - freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* gen51Code - generate code for 8051 based controllers */ -/*-----------------------------------------------------------------*/ -void gen51Code (iCode *lic) -{ - iCode *ic; - int cln = 0; - - lineHead = lineCurr = NULL; - - /* if debug information required */ -/* if (options.debug && currFunc) { */ - if (currFunc) { - cdbSymbol(currFunc,cdbFile,FALSE,TRUE); - debugLine = 1; - if (IS_STATIC(currFunc->etype)) - emitcode("","F%s$%s$0$0 ==.",moduleName,currFunc->name); - else - emitcode("","G$%s$0$0 ==.",currFunc->name); - debugLine = 0; - } - /* stack pointer name */ - if (options.useXstack) - spname = "_spx"; - else - spname = "sp"; - - - for (ic = lic ; ic ; ic = ic->next ) { - - if ( cln != ic->lineno ) { - if ( options.debug ) { - debugLine = 1; - emitcode("","C$%s$%d$%d$%d ==.", - ic->filename,ic->lineno, - ic->level,ic->block); - debugLine = 0; - } - emitcode(";","%s %d",ic->filename,ic->lineno); - cln = ic->lineno ; - } - /* if the result is marked as - spilt and rematerializable or code for - this has already been generated then - do nothing */ - if (resultRemat(ic) || ic->generated ) - continue ; - - /* depending on the operation */ - switch (ic->op) { - case '!' : - genNot(ic); - break; - - case '~' : - genCpl(ic); - break; - - case UNARYMINUS: - genUminus (ic); - break; - - case IPUSH: - genIpush (ic); - break; - - case IPOP: - /* IPOP happens only when trying to restore a - spilt live range, if there is an ifx statement - following this pop then the if statement might - be using some of the registers being popped which - would destory the contents of the register so - we need to check for this condition and handle it */ - if (ic->next && - ic->next->op == IFX && - regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) - genIfx (ic->next,ic); - else - genIpop (ic); - break; - - case CALL: - genCall (ic); - break; - - case PCALL: - genPcall (ic); - break; - - case FUNCTION: - genFunction (ic); - break; - - case ENDFUNCTION: - genEndFunction (ic); - break; - - case RETURN: - genRet (ic); - break; - - case LABEL: - genLabel (ic); - break; - - case GOTO: - genGoto (ic); - break; - - case '+' : - genPlus (ic) ; - break; - - case '-' : - if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic))) - genMinus (ic); - break; - - case '*' : - genMult (ic); - break; - - case '/' : - genDiv (ic) ; - break; - - case '%' : - genMod (ic); - break; - - case '>' : - genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic)); - break; - - case '<' : - genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic)); - break; - - case LE_OP: - case GE_OP: - case NE_OP: - - /* note these two are xlated by algebraic equivalence - during parsing SDCC.y */ - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "got '>=' or '<=' shouldn't have come here"); - break; - - case EQ_OP: - genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic)); - break; - - case AND_OP: - genAndOp (ic); - break; - - case OR_OP: - genOrOp (ic); - break; - - case '^' : - genXor (ic,ifxForOp(IC_RESULT(ic),ic)); - break; - - case '|' : - genOr (ic,ifxForOp(IC_RESULT(ic),ic)); - break; - - case BITWISEAND: - genAnd (ic,ifxForOp(IC_RESULT(ic),ic)); - break; - - case INLINEASM: - genInline (ic); - break; - - case RRC: - genRRC (ic); - break; - - case RLC: - genRLC (ic); - break; - - case GETHBIT: - genGetHbit (ic); - break; - - case LEFT_OP: - genLeftShift (ic); - break; - - case RIGHT_OP: - genRightShift (ic); - break; - - case GET_VALUE_AT_ADDRESS: - genPointerGet(ic); - break; - - case '=' : - if (POINTER_SET(ic)) - genPointerSet(ic); - else - genAssign(ic); - break; - - case IFX: - genIfx (ic,NULL); - break; - - case ADDRESS_OF: - genAddrOf (ic); - break; - - case JUMPTABLE: - genJumpTab (ic); - break; - - case CAST: - genCast (ic); - break; - - case RECEIVE: - genReceive(ic); - break; - - case SEND: - addSet(&sendSet,ic); - break; - - default : - ic = ic; - /* piCode(ic,stdout); */ - - } - } - - - /* now we are ready to call the - peep hole optimizer */ - if (!options.nopeep) - peepHole (&lineHead); - - /* now do the actual printing */ - printLine (lineHead,codeOutFile); - return; -} diff --git a/src/SDCCglobl.h b/src/SDCCglobl.h index c4e9c977..f7fa682f 100644 --- a/src/SDCCglobl.h +++ b/src/SDCCglobl.h @@ -204,60 +204,6 @@ struct options { int iram_size ; /* internal ram size (used only for error checking) */ } ; -/* Processor specific names */ -typedef struct { - /** Target name string, used for --help */ - const char *target_name; - struct { - /** Command to run (eg as-z80) */ - const char *exec_name; - /** Arguments for debug mode */ - const char *debug_opts; - /** Arguments for normal assembly mode */ - const char *plain_opts; - /** TRUE if the output file name should be pre-pended to the args */ - bool requires_output_name; - } assembler; - struct { - /** Command to run (eg link-z80) */ - const char *exec_name; - } linker; - /** Basic type sizes */ - struct { - int char_size; - int short_size; - int int_size; - int long_size; - int ptr_size; - int fptr_size; - int gptr_size; - int bit_size; - int float_size; - int max_base_size; - } s; - struct { - /** -1 for grows down (z80), +1 for grows up (mcs51) */ - int direction; - /** Extra overhead when calling between banks */ - int bank_overhead; - /** Extra overhead when the function is an ISR */ - int isr_overhead; - /** Standard overhead for a function call */ - int call_overhead; - /** Initial SP offset */ - int start_sp; - } stack; - struct { - /** One more than the smallest mul/div operation the processor can do nativley - Eg if the processor has an 8 bit mul, nativebelow is 2 */ - int nativebelow; - - } muldiv; - -} PROCESSOR_CONSTANTS; - -extern const PROCESSOR_CONSTANTS port; - /* forward definition for variables accessed globally */ extern char *currFname ; extern char *srcFileName; /* source file name without the extenstion */ diff --git a/src/SDCCglue.c b/src/SDCCglue.c index a5d1e194..eb574a35 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -21,20 +21,9 @@ You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include + +#include "common.h" #include -#include "SDCCglobl.h" -#include "SDCCsymt.h" -#include "SDCCmem.h" -#include "SDCCval.h" -#include "SDCCast.h" -#include "SDCChasht.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCCopt.h" -#include "SDCCy.h" -#include "SDCCglue.h" symbol *interrupts[256]; extern char *aopLiteral (value *, int); diff --git a/src/SDCChasht.c b/src/SDCChasht.c index 1bf0af52..eb6ed86e 100644 --- a/src/SDCChasht.c +++ b/src/SDCChasht.c @@ -22,11 +22,7 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include -#include "SDCChasht.h" - +#include "common.h" #define DEFAULT_HTAB_SIZE 128 diff --git a/src/SDCCicode.c b/src/SDCCicode.c index c405c1af..733aaa53 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -21,15 +21,8 @@ You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include "SDCCglobl.h" -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCicode.h" -#include "SDCCerr.h" -#include "SDCCralloc.h" + +#include "common.h" /*-----------------------------------------------------------------*/ /* global variables */ diff --git a/src/SDCClabel.c b/src/SDCClabel.c index 99d3080e..d579fe9a 100644 --- a/src/SDCClabel.c +++ b/src/SDCClabel.c @@ -21,17 +21,8 @@ You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include "SDCCglobl.h" -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCClabel.h" + +#include "common.h" hTab *labelRef = NULL ; hTab *labelDef = NULL ; diff --git a/src/SDCCloop.c b/src/SDCCloop.c index 73782f3f..8eb38af3 100644 --- a/src/SDCCloop.c +++ b/src/SDCCloop.c @@ -22,20 +22,8 @@ You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include "SDCCglobl.h" -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCClabel.h" -#include "SDCCBBlock.h" -#include "SDCCdflow.h" -#include "SDCCloop.h" + +#include "common.h" DEFSETFUNC(isDefAlive); diff --git a/src/SDCClrange.c b/src/SDCClrange.c index 5dd93356..73b636b1 100644 --- a/src/SDCClrange.c +++ b/src/SDCClrange.c @@ -23,23 +23,7 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include "SDCCglobl.h" -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCClabel.h" -#include "SDCCBBlock.h" -#include "SDCCloop.h" -#include "SDCCcse.h" -#include "SDCCcflow.h" -#include "SDCCdflow.h" -#include "SDCClrange.h" +#include "common.h" int iCodeSeq = 0 ; hTab *liveRanges = NULL; diff --git a/src/SDCCmain.c b/src/SDCCmain.c index 8ebfa26c..1a4ba193 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -21,14 +21,17 @@ You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include -#include +#include "common.h" +#include #include "spawn.h" -#include "SDCCglobl.h" -#include "config.h" + +/* This is a bit messy. We cant include unistd.h as it defines + 'link' which we also use. +*/ +int access(const char *path, int mode); +#define X_OK 1 +int unlink(const char *path); extern void initSymt (); extern void initMem (); @@ -112,6 +115,35 @@ char *preOutName; #define OPTION_HELP "-help" #define OPTION_CALLEE_SAVES "-callee-saves" #define OPTION_NOREGPARMS "-noregparms" + +extern PORT mcs51_port; +extern PORT z80_port; + +PORT *port; + +static PORT *_ports[] = { + &mcs51_port, +}; + +#define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0])) + +/** Sets the port to the one given by the command line option. + @param The name minus the option (eg 'mcs51') + @return 0 on success. +*/ +static int _setPort(const char *name) +{ + int i; + for (i=0; itarget, name)) { + port = _ports[i]; + return 0; + } + } + /* Error - didnt find */ + return 1; +} + /*-----------------------------------------------------------------*/ /* printVersionInfo - prints the version info */ /*-----------------------------------------------------------------*/ @@ -222,6 +254,8 @@ static void setDefaultOptions() optimize.label4 = 1; optimize.loopInvariant = 1; optimize.loopInduction = 1; + + port->setDefaultOptions(); } /*-----------------------------------------------------------------*/ @@ -605,7 +639,8 @@ int parseCmdLine ( int argc, char **argv ) continue; } - werror(W_UNKNOWN_OPTION,argv[i]); + if (!port->parseOption(&argc, argv)) + werror(W_UNKNOWN_OPTION,argv[i]); } /* these are undocumented options */ @@ -675,7 +710,10 @@ int parseCmdLine ( int argc, char **argv ) break; case 'm': - werror(W_UNSUPP_OPTION,"-mL/-mS","use --model-large/--model-small instead"); + /* Used to select the port */ + if (_setPort(argv[i] + 2)) { + werror(W_UNSUPP_OPTION,"-m","Unrecognised processor"); + } break; case 'a' : @@ -799,15 +837,16 @@ int parseCmdLine ( int argc, char **argv ) break ; default: - werror(W_UNKNOWN_OPTION,argv[i]); + if (!port->parseOption(&argc, argv)) + werror(W_UNKNOWN_OPTION,argv[i]); } continue ; } - /* no option must be a filename */ - processFile(argv[i]); - - + if (!port->parseOption(&argc, argv)) { + /* no option must be a filename */ + processFile(argv[i]); + } } /* set up external stack location if not explicitly specified */ @@ -824,6 +863,7 @@ int parseCmdLine ( int argc, char **argv ) fprintf(cdbFile,"M:%s\n",moduleName); } } + port->finaliseOptions(); return 0; } @@ -987,7 +1027,6 @@ static void assemble (char **envp) } } - /*-----------------------------------------------------------------*/ /* preProcess - spawns the preprocessor with arguments */ /*-----------------------------------------------------------------*/ @@ -1033,6 +1072,21 @@ static int preProcess (char **envp) return 0; } +static void _findPort(int argc, char **argv) +{ + argc--; + while (argc) { + if (!strncmp(*argv, "-m", 2)) { + _setPort(*argv + 2); + return; + } + argv++; + argc--; + } + /* Assume mcs51 */ + port = &mcs51_port; +} + /* * main routine * initialises and calls the parser @@ -1045,8 +1099,9 @@ int main ( int argc, char **argv , char **envp) /*printVersionInfo ();*/ + _findPort(argc, argv); setDefaultOptions(); - parseCmdLine (argc,argv); + parseCmdLine(argc,argv); /* if no input then printUsage & exit */ if (!srcFileName && !nrelFiles) { diff --git a/src/SDCCmem.c b/src/SDCCmem.c index df35a568..6ba284b9 100644 --- a/src/SDCCmem.c +++ b/src/SDCCmem.c @@ -2,17 +2,7 @@ /* SDCCmem.c - 8051 memory management routines */ /*-----------------------------------------------------------------*/ -#include -#include -#include "SDCCglobl.h" -#include "SDCCsymt.h" -#include "SDCCmem.h" -#include "SDCCval.h" -#include "SDCCast.h" -#include "SDCChasht.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCCopt.h" +#include "common.h" /* memory segments */ memmap *xstack= NULL ; /* xternal stack data */ diff --git a/src/SDCCopt.c b/src/SDCCopt.c index 23899f89..25b44b9b 100644 --- a/src/SDCCopt.c +++ b/src/SDCCopt.c @@ -25,27 +25,8 @@ You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include "SDCCglobl.h" -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCClabel.h" -#include "SDCCBBlock.h" -#include "SDCCloop.h" -#include "SDCCcse.h" -#include "SDCCcflow.h" -#include "SDCCdflow.h" -#include "SDCClrange.h" -#include "SDCCralloc.h" -#include "SDCCptropt.h" -#include "SDCCopt.h" +#include "common.h" /*-----------------------------------------------------------------*/ /* global variables */ @@ -814,7 +795,7 @@ eBBlock **eBBlockFromiCode (iCode *ic) dumpEbbsToFileExt(".dumprange",ebbs,count); /* allocate registers & generate code */ - assignRegisters (ebbs,count); + port->assignRegisters(ebbs,count); /* throw away blocks */ setToNull ((void **)&graphEdges); diff --git a/src/SDCCpeeph.c b/src/SDCCpeeph.c index b9298508..6450d7ac 100644 --- a/src/SDCCpeeph.c +++ b/src/SDCCpeeph.c @@ -23,15 +23,9 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include -#include "SDCCglobl.h" -#include "SDCChasht.h" -#include "SDCCset.h" +#include "common.h" #include "SDCCpeeph.h" - peepRule *rootRules = NULL; peepRule *currRule = NULL; diff --git a/src/SDCCptropt.c b/src/SDCCptropt.c index 24e7ccc1..9aa40566 100644 --- a/src/SDCCptropt.c +++ b/src/SDCCptropt.c @@ -23,22 +23,7 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include "SDCCglobl.h" -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCClabel.h" -#include "SDCCBBlock.h" -#include "SDCCcflow.h" -#include "SDCCloop.h" -#include "SDCCcse.h" - +#include "common.h" /*-----------------------------------------------------------------*/ /* pointerArithOpts - does some pointer arithmetic operations */ diff --git a/src/SDCCralloc.c b/src/SDCCralloc.c deleted file mode 100644 index 2a7dc805..00000000 --- a/src/SDCCralloc.c +++ /dev/null @@ -1,2313 +0,0 @@ -/*------------------------------------------------------------------------ - - SDCCralloc.c - source file for register allocation. (8051) specific - - Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) - - 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! --------------------------------------------------------------------------*/ -#include -#include -#include "SDCCglobl.h" -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCClabel.h" -#include "SDCCBBlock.h" -#include "SDCCloop.h" -#include "SDCCcse.h" -#include "SDCCcflow.h" -#include "SDCCdflow.h" -#include "SDCClrange.h" -#include "SDCCralloc.h" - -/*-----------------------------------------------------------------*/ -/* At this point we start getting processor specific although */ -/* some routines are non-processor specific & can be reused when */ -/* targetting other processors. The decision for this will have */ -/* to be made on a routine by routine basis */ -/* routines used to pack registers are most definitely not reusable*/ -/* since the pack the registers depending strictly on the MCU */ -/*-----------------------------------------------------------------*/ - -bitVect *spiltSet = NULL ; -set *stackSpil = NULL; -bitVect *regAssigned = NULL; -short blockSpil = 0; -int slocNum = 0 ; -extern void gen51Code(iCode *); -int ptrRegReq = 0; /* one byte pointer register required */ -bitVect *funcrUsed = NULL; /* registers used in a function */ -int stackExtend = 0; -int dataExtend = 0; - -/* 8051 registers */ -regs regs8051[] = -{ - - { REG_GPR ,R2_IDX , REG_GPR , "r2", "ar2", "0", 2, 1 }, - { REG_GPR ,R3_IDX , REG_GPR , "r3", "ar3", "0", 3, 1 }, - { REG_GPR ,R4_IDX , REG_GPR , "r4", "ar4", "0", 4, 1 }, - { REG_GPR ,R5_IDX , REG_GPR , "r5", "ar5", "0", 5, 1 }, - { REG_GPR ,R6_IDX , REG_GPR , "r6", "ar6", "0", 6, 1 }, - { REG_GPR ,R7_IDX , REG_GPR , "r7", "ar7", "0", 7, 1 }, - { REG_PTR ,R0_IDX , REG_PTR , "r0" , "ar0", "0", 0, 1 }, - { REG_PTR ,R1_IDX , REG_PTR , "r1" , "ar1", "0", 1, 1 }, - { REG_GPR ,X8_IDX , REG_GPR , "x8", "x8" , "xreg", 0, 1 }, - { REG_GPR ,X9_IDX , REG_GPR , "x9", "x9" , "xreg", 1, 1 }, - { REG_GPR ,X10_IDX,REG_GPR , "x10", "x10", "xreg", 2, 1 }, - { REG_GPR ,X11_IDX,REG_GPR , "x11", "x11", "xreg", 3, 1 }, - { REG_GPR ,X12_IDX,REG_GPR , "x12", "x12", "xreg", 4, 1 }, - { REG_CND ,CND_IDX,REG_CND , "C" , "C" , "xreg", 0, 1 }, -}; -int nRegs = 13; -void spillThis (symbol *); - -/*-----------------------------------------------------------------*/ -/* allocReg - allocates register of given type */ -/*-----------------------------------------------------------------*/ -regs *allocReg (short type) -{ - int i; - - for ( i = 0 ; i < nRegs ; i++ ) { - - /* if type is given as 0 then any - free register will do */ - if (!type && - regs8051[i].isFree ) { - regs8051[i].isFree = 0; - if (currFunc) - currFunc->regsUsed = - bitVectSetBit(currFunc->regsUsed,i); - return ®s8051[i]; - } - /* other wise look for specific type - of register */ - if (regs8051[i].isFree && - regs8051[i].type == type) { - regs8051[i].isFree = 0; - if (currFunc) - currFunc->regsUsed = - bitVectSetBit(currFunc->regsUsed,i); - return ®s8051[i]; - } - } - return NULL; -} - -/*-----------------------------------------------------------------*/ -/* regWithIdx - returns pointer to register wit index number */ -/*-----------------------------------------------------------------*/ -regs *regWithIdx (int idx) -{ - int i ; - - for (i=0;i < nRegs;i++) - if (regs8051[i].rIdx == idx) - return ®s8051[i]; - - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "regWithIdx not found"); - exit(1); -} - -/*-----------------------------------------------------------------*/ -/* freeReg - frees a register */ -/*-----------------------------------------------------------------*/ -void freeReg (regs *reg) -{ - reg->isFree = 1; -} - - -/*-----------------------------------------------------------------*/ -/* nFreeRegs - returns number of free registers */ -/*-----------------------------------------------------------------*/ -int nFreeRegs (int type) -{ - int i; - int nfr=0; - - for (i = 0 ; i < nRegs; i++ ) - if (regs8051[i].isFree && regs8051[i].type == type) - nfr++; - return nfr; -} - -/*-----------------------------------------------------------------*/ -/* nfreeRegsType - free registers with type */ -/*-----------------------------------------------------------------*/ -int nfreeRegsType (int type) -{ - int nfr ; - if (type == REG_PTR) { - if ((nfr = nFreeRegs(type)) == 0) - return nFreeRegs(REG_GPR); - } - - return nFreeRegs(type); -} - - -/*-----------------------------------------------------------------*/ -/* allDefsOutOfRange - all definitions are out of a range */ -/*-----------------------------------------------------------------*/ -bool allDefsOutOfRange (bitVect *defs,int fseq, int toseq) -{ - int i ; - - if (!defs) - return TRUE ; - - for ( i = 0 ;i < defs->size ; i++ ) { - iCode *ic; - - if (bitVectBitValue(defs,i) && - (ic = hTabItemWithKey(iCodehTab,i)) && - ( ic->seq >= fseq && ic->seq <= toseq)) - - return FALSE; - - } - - return TRUE; -} - -/*-----------------------------------------------------------------*/ -/* computeSpillable - given a point find the spillable live ranges */ -/*-----------------------------------------------------------------*/ -bitVect *computeSpillable (iCode *ic) -{ - bitVect *spillable ; - - /* spillable live ranges are those that are live at this - point . the following categories need to be subtracted - from this set. - a) - those that are already spilt - b) - if being used by this one - c) - defined by this one */ - - spillable = bitVectCopy(ic->rlive); - spillable = - bitVectCplAnd(spillable,spiltSet); /* those already spilt */ - spillable = - bitVectCplAnd(spillable,ic->uses); /* used in this one */ - bitVectUnSetBit(spillable,ic->defKey); - spillable = bitVectIntersect(spillable,regAssigned); - return spillable; - -} - -/*-----------------------------------------------------------------*/ -/* noSpilLoc - return true if a variable has no spil location */ -/*-----------------------------------------------------------------*/ -int noSpilLoc (symbol *sym, eBBlock *ebp,iCode *ic) -{ - return (sym->usl.spillLoc ? 0 : 1); -} - -/*-----------------------------------------------------------------*/ -/* hasSpilLoc - will return 1 if the symbol has spil location */ -/*-----------------------------------------------------------------*/ -int hasSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic) -{ - return (sym->usl.spillLoc ? 1 : 0); -} - -/*-----------------------------------------------------------------*/ -/* directSpilLoc - will return 1 if the splilocation is in direct */ -/*-----------------------------------------------------------------*/ -int directSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic) -{ - if ( sym->usl.spillLoc && - (IN_DIRSPACE(SPEC_OCLS(sym->usl.spillLoc->etype)))) - return 1; - else - return 0; -} - -/*-----------------------------------------------------------------*/ -/* hasSpilLocnoUptr - will return 1 if the symbol has spil location*/ -/* but is not used as a pointer */ -/*-----------------------------------------------------------------*/ -int hasSpilLocnoUptr (symbol *sym, eBBlock *ebp, iCode *ic) -{ - return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0); -} - -/*-----------------------------------------------------------------*/ -/* rematable - will return 1 if the remat flag is set */ -/*-----------------------------------------------------------------*/ -int rematable (symbol *sym, eBBlock *ebp, iCode *ic) -{ - return sym->remat; -} - -/*-----------------------------------------------------------------*/ -/* notUsedInBlock - not used in this block */ -/*-----------------------------------------------------------------*/ -int notUsedInBlock (symbol *sym, eBBlock *ebp, iCode *ic) -{ - return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs) && - allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq)); -/* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */ -} - -/*-----------------------------------------------------------------*/ -/* notUsedInRemaining - not used or defined in remain of the block */ -/*-----------------------------------------------------------------*/ -int notUsedInRemaining (symbol *sym, eBBlock *ebp, iCode *ic) -{ - return ((usedInRemaining (operandFromSymbol(sym),ic) ? 0 : 1) && - allDefsOutOfRange (sym->defs,ic->seq,ebp->lSeq)); -} - -/*-----------------------------------------------------------------*/ -/* allLRs - return true for all */ -/*-----------------------------------------------------------------*/ -int allLRs (symbol *sym, eBBlock *ebp, iCode *ic) -{ - return 1; -} - -/*-----------------------------------------------------------------*/ -/* liveRangesWith - applies function to a given set of live range */ -/*-----------------------------------------------------------------*/ -set *liveRangesWith (bitVect *lrs, int (func)(symbol *,eBBlock *, iCode *), - eBBlock *ebp, iCode *ic) -{ - set *rset = NULL; - int i; - - if (!lrs || !lrs->size) - return NULL; - - for ( i = 1 ; i < lrs->size ; i++ ) { - symbol *sym; - if (!bitVectBitValue(lrs,i)) - continue ; - - /* if we don't find it in the live range - hash table we are in serious trouble */ - if (!(sym = hTabItemWithKey(liveRanges,i))) { - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "liveRangesWith could not find liveRange"); - exit(1); - } - - if (func(sym,ebp,ic) && bitVectBitValue(regAssigned,sym->key)) - addSetHead(&rset,sym); - } - - return rset; -} - - -/*-----------------------------------------------------------------*/ -/* leastUsedLR - given a set determines which is the least used */ -/*-----------------------------------------------------------------*/ -symbol *leastUsedLR (set *sset) -{ - symbol *sym = NULL, *lsym = NULL ; - - sym = lsym = setFirstItem(sset); - - if (!lsym) - return NULL; - - for (; lsym; lsym = setNextItem(sset)) { - - /* if usage is the same then prefer - the spill the smaller of the two */ - if ( lsym->used == sym->used ) - if (getSize(lsym->type) < getSize(sym->type)) - sym = lsym; - - /* if less usage */ - if (lsym->used < sym->used ) - sym = lsym; - - } - - setToNull((void **)&sset); - sym->blockSpil = 0; - return sym; -} - -/*-----------------------------------------------------------------*/ -/* noOverLap - will iterate through the list looking for over lap */ -/*-----------------------------------------------------------------*/ -int noOverLap (set *itmpStack, symbol *fsym) -{ - symbol *sym; - - - for (sym = setFirstItem(itmpStack); sym; - sym = setNextItem(itmpStack)) { - if (sym->liveTo > fsym->liveFrom ) - return 0; - - } - - return 1; -} - -/*-----------------------------------------------------------------*/ -/* isFree - will return 1 if the a free spil location is found */ -/*-----------------------------------------------------------------*/ -DEFSETFUNC(isFree) -{ - symbol *sym = item; - V_ARG(symbol **,sloc); - V_ARG(symbol *,fsym); - - /* if already found */ - if (*sloc) - return 0; - - /* if it is free && and the itmp assigned to - this does not have any overlapping live ranges - with the one currently being assigned and - the size can be accomodated */ - if (sym->isFree && - noOverLap(sym->usl.itmpStack,fsym) && - getSize(sym->type) >= getSize(fsym->type)) { - *sloc = sym; - return 1; - } - - return 0; -} - -/*-----------------------------------------------------------------*/ -/* spillLRWithPtrReg :- will spil those live ranges which use PTR */ -/*-----------------------------------------------------------------*/ -void spillLRWithPtrReg (symbol *forSym) -{ - symbol *lrsym; - regs *r0,*r1; - int k; - - if (!regAssigned || - bitVectIsZero(regAssigned)) - return; - - r0 = regWithIdx(R0_IDX); - r1 = regWithIdx(R1_IDX); - - /* for all live ranges */ - for (lrsym = hTabFirstItem(liveRanges,&k) ; lrsym ; - lrsym = hTabNextItem(liveRanges,&k) ) { - int j; - - /* if no registers assigned to it or - spilt */ - /* if it does not overlap with this then - not need to spill it */ - - if (lrsym->isspilt || !lrsym->nRegs || - (lrsym->liveTo < forSym->liveFrom)) - continue ; - - /* go thru the registers : if it is either - r0 or r1 then spil it */ - for (j = 0 ; j < lrsym->nRegs ; j++ ) - if (lrsym->regs[j] == r0 || - lrsym->regs[j] == r1 ) { - spillThis (lrsym); - break; - } - } - -} - -/*-----------------------------------------------------------------*/ -/* createStackSpil - create a location on the stack to spil */ -/*-----------------------------------------------------------------*/ -symbol *createStackSpil (symbol *sym) -{ - symbol *sloc= NULL; - int useXstack, model, noOverlay; - int stackAuto; - - /* first go try and find a free one that is already - existing on the stack */ - if (applyToSet(stackSpil,isFree,&sloc, sym)) { - /* found a free one : just update & return */ - sym->usl.spillLoc = sloc; - sym->stackSpil= 1; - sloc->isFree = 0; - addSetHead(&sloc->usl.itmpStack,sym); - return sym; - } - - /* could not then have to create one , this is the hard part - we need to allocate this on the stack : this is really a - hack!! but cannot think of anything better at this time */ - - sprintf(buffer,"sloc%d",slocNum++); - sloc = newiTemp(buffer); - - /* set the type to the spilling symbol */ - sloc->type = copyLinkChain(sym->type); - sloc->etype = getSpec(sloc->type); - SPEC_SCLS(sloc->etype) = S_AUTO ; - SPEC_EXTR(sloc->etype) = 0; - - /* we don't allow it to be allocated` - onto the external stack since : so we - temporarily turn it off ; we also - turn off memory model to prevent - the spil from going to the external storage - and turn off overlaying - */ - - useXstack = options.useXstack; - model = options.model; - noOverlay = options.noOverlay; - stackAuto = options.stackAuto; - options.noOverlay = 1; - options.model = options.useXstack = 0; - - allocLocal(sloc); - - options.useXstack = useXstack; - options.model = model; - options.noOverlay = noOverlay; - options.stackAuto = stackAuto; - sloc->isref = 1; /* to prevent compiler warning */ - - /* if it is on the stack then update the stack */ - if (IN_STACK(sloc->etype)) { - currFunc->stack += getSize(sloc->type); - stackExtend += getSize(sloc->type); - } else - dataExtend += getSize(sloc->type); - - /* add it to the stackSpil set */ - addSetHead(&stackSpil,sloc); - sym->usl.spillLoc = sloc; - sym->stackSpil = 1; - - /* add it to the set of itempStack set - of the spill location */ - addSetHead(&sloc->usl.itmpStack,sym); - return sym; -} - -/*-----------------------------------------------------------------*/ -/* isSpiltOnStack - returns true if the spil location is on stack */ -/*-----------------------------------------------------------------*/ -bool isSpiltOnStack (symbol *sym) -{ - link *etype; - - if (!sym) - return FALSE ; - - if (!sym->isspilt) - return FALSE ; - -/* if (sym->stackSpil) */ -/* return TRUE; */ - - if (!sym->usl.spillLoc) - return FALSE; - - etype = getSpec(sym->usl.spillLoc->type); - if (IN_STACK(etype)) - return TRUE; - - return FALSE ; -} - -/*-----------------------------------------------------------------*/ -/* spillThis - spils a specific operand */ -/*-----------------------------------------------------------------*/ -void spillThis (symbol *sym) -{ - int i; - /* if this is rematerializable or has a spillLocation - we are okay, else we need to create a spillLocation - for it */ - if (!(sym->remat || sym->usl.spillLoc)) - createStackSpil (sym); - - - /* mark it has spilt & put it in the spilt set */ - sym->isspilt = 1; - spiltSet = bitVectSetBit(spiltSet,sym->key); - - bitVectUnSetBit(regAssigned,sym->key); - - for (i = 0 ; i < sym->nRegs ; i++) - - if (sym->regs[i]) { - freeReg(sym->regs[i]); - sym->regs[i] = NULL; - } - - /* if spilt on stack then free up r0 & r1 - if they could have been assigned to some - LIVE ranges */ - if (!ptrRegReq && isSpiltOnStack(sym)) { - ptrRegReq++ ; - spillLRWithPtrReg(sym); - } - - if (sym->usl.spillLoc && !sym->remat) - sym->usl.spillLoc->allocreq = 1; - return; -} - -/*-----------------------------------------------------------------*/ -/* selectSpil - select a iTemp to spil : rather a simple procedure */ -/*-----------------------------------------------------------------*/ -symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym) -{ - bitVect *lrcs= NULL ; - set *selectS ; - symbol *sym; - - /* get the spillable live ranges */ - lrcs = computeSpillable (ic); - - /* get all live ranges that are rematerizable */ - if ((selectS = liveRangesWith(lrcs,rematable,ebp,ic))) { - - /* return the least used of these */ - return leastUsedLR(selectS); - } - - /* get live ranges with spillLocations in direct space */ - if ((selectS = liveRangesWith(lrcs,directSpilLoc,ebp,ic))) { - sym = leastUsedLR(selectS); - strcpy(sym->rname,(sym->usl.spillLoc->rname[0] ? - sym->usl.spillLoc->rname : - sym->usl.spillLoc->name)); - sym->spildir = 1; - /* mark it as allocation required */ - sym->usl.spillLoc->allocreq = 1; - return sym; - } - - /* if the symbol is local to the block then */ - if (forSym->liveTo < ebp->lSeq ) { - - /* check if there are any live ranges allocated - to registers that are not used in this block */ - if (!blockSpil && (selectS = liveRangesWith(lrcs,notUsedInBlock,ebp,ic))) { - sym = leastUsedLR(selectS); - /* if this is not rematerializable */ - if (!sym->remat) { - blockSpil++; - sym->blockSpil = 1; - } - return sym; - } - - /* check if there are any live ranges that not - used in the remainder of the block */ - if (!blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) { - sym = leastUsedLR (selectS); - if (!sym->remat) { - sym->remainSpil = 1; - blockSpil++; - } - return sym; - } - } - - /* find live ranges with spillocation && not used as pointers */ - if ((selectS = liveRangesWith(lrcs,hasSpilLocnoUptr,ebp,ic))) { - - sym = leastUsedLR(selectS); - /* mark this as allocation required */ - sym->usl.spillLoc->allocreq = 1; - return sym; - } - - /* find live ranges with spillocation */ - if ((selectS = liveRangesWith(lrcs,hasSpilLoc,ebp,ic))) { - - sym = leastUsedLR(selectS); - sym->usl.spillLoc->allocreq = 1; - return sym; - } - - /* couldn't find then we need to create a spil - location on the stack , for which one? the least - used ofcourse */ - if ((selectS = liveRangesWith(lrcs,noSpilLoc,ebp,ic))) { - - /* return a created spil location */ - sym = createStackSpil(leastUsedLR(selectS)); - sym->usl.spillLoc->allocreq = 1; - return sym; - } - - /* this is an extreme situation we will spill - this one : happens very rarely but it does happen */ - spillThis ( forSym ); - return forSym ; - -} - -/*-----------------------------------------------------------------*/ -/* spilSomething - spil some variable & mark registers as free */ -/*-----------------------------------------------------------------*/ -bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym) -{ - symbol *ssym; - int i ; - - /* get something we can spil */ - ssym = selectSpil(ic,ebp,forSym); - - /* mark it as spilt */ - ssym->isspilt = 1; - spiltSet = bitVectSetBit(spiltSet,ssym->key); - - /* mark it as not register assigned & - take it away from the set */ - bitVectUnSetBit(regAssigned,ssym->key); - - /* mark the registers as free */ - for (i = 0 ; i < ssym->nRegs ;i++ ) - if (ssym->regs[i]) - freeReg(ssym->regs[i]); - - /* if spilt on stack then free up r0 & r1 - if they could have been assigned to as gprs */ - if (!ptrRegReq && isSpiltOnStack(ssym) ) { - ptrRegReq++ ; - spillLRWithPtrReg(ssym); - } - - /* if this was a block level spil then insert push & pop - at the start & end of block respectively */ - if (ssym->blockSpil) { - iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL); - /* add push to the start of the block */ - addiCodeToeBBlock(ebp,nic,( ebp->sch->op == LABEL ? - ebp->sch->next : ebp->sch)); - nic = newiCode(IPOP,operandFromSymbol(ssym),NULL); - /* add pop to the end of the block */ - addiCodeToeBBlock(ebp,nic,NULL); - } - - /* if spilt because not used in the remainder of the - block then add a push before this instruction and - a pop at the end of the block */ - if (ssym->remainSpil) { - - iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL); - /* add push just before this instruction */ - addiCodeToeBBlock(ebp,nic,ic); - - nic = newiCode(IPOP,operandFromSymbol(ssym),NULL); - /* add pop to the end of the block */ - addiCodeToeBBlock(ebp,nic,NULL); - } - - if (ssym == forSym ) - return FALSE ; - else - return TRUE ; -} - -/*-----------------------------------------------------------------*/ -/* getRegPtr - will try for PTR if not a GPR type if not spil */ -/*-----------------------------------------------------------------*/ -regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym) -{ - regs *reg; - - tryAgain: - /* try for a ptr type */ - if ((reg = allocReg(REG_PTR))) - return reg; - - /* try for gpr type */ - if ((reg = allocReg(REG_GPR))) - return reg; - - /* we have to spil */ - if (!spilSomething (ic,ebp,sym)) - return NULL ; - - /* this looks like an infinite loop but - in really selectSpil will abort */ - goto tryAgain ; -} - -/*-----------------------------------------------------------------*/ -/* getRegGpr - will try for GPR if not spil */ -/*-----------------------------------------------------------------*/ -regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym) -{ - regs *reg; - - tryAgain: - /* try for gpr type */ - if ((reg = allocReg(REG_GPR))) - return reg; - - if (!ptrRegReq) - if ((reg = allocReg(REG_PTR))) - return reg ; - - /* we have to spil */ - if (!spilSomething (ic,ebp,sym)) - return NULL ; - - /* this looks like an infinite loop but - in really selectSpil will abort */ - goto tryAgain ; -} - -/*-----------------------------------------------------------------*/ -/* symHasReg - symbol has a given register */ -/*-----------------------------------------------------------------*/ -static bool symHasReg(symbol *sym,regs *reg) -{ - int i; - - for ( i = 0 ; i < sym->nRegs ; i++) - if (sym->regs[i] == reg) - return TRUE; - - return FALSE; -} - -/*-----------------------------------------------------------------*/ -/* deassignLRs - check the live to and if they have registers & are*/ -/* not spilt then free up the registers */ -/*-----------------------------------------------------------------*/ -void deassignLRs (iCode *ic, eBBlock *ebp) -{ - symbol *sym; - int k; - symbol *result; - - for (sym = hTabFirstItem(liveRanges,&k); sym; - sym = hTabNextItem(liveRanges,&k)) { - - symbol *psym= NULL; - /* if it does not end here */ - if (sym->liveTo > ic->seq ) - continue ; - - /* if it was spilt on stack then we can - mark the stack spil location as free */ - if (sym->isspilt ) { - if (sym->stackSpil) { - sym->usl.spillLoc->isFree = 1; - sym->stackSpil = 0; - } - continue ; - } - - if (!bitVectBitValue(regAssigned,sym->key)) - continue; - - /* special case check if this is an IFX & - the privious one was a pop and the - previous one was not spilt then keep track - of the symbol */ - if (ic->op == IFX && ic->prev && - ic->prev->op == IPOP && - !ic->prev->parmPush && - !OP_SYMBOL(IC_LEFT(ic->prev))->isspilt) - psym = OP_SYMBOL(IC_LEFT(ic->prev)); - - if (sym->nRegs) { - int i = 0; - - bitVectUnSetBit(regAssigned,sym->key); - - /* if the result of this one needs registers - and does not have it then assign it right - away */ - if (IC_RESULT(ic) && - ! (SKIP_IC2(ic) || /* not a special icode */ - ic->op == JUMPTABLE || - ic->op == IFX || - ic->op == IPUSH || - ic->op == IPOP || - ic->op == RETURN || - POINTER_SET(ic)) && - (result = OP_SYMBOL(IC_RESULT(ic))) && /* has a result */ - result->liveTo > ic->seq && /* and will live beyond this */ - result->liveTo <= ebp->lSeq && /* does not go beyond this block */ - result->regType == sym->regType && /* same register types */ - result->nRegs && /* which needs registers */ - ! result->isspilt && /* and does not already have them */ - ! result->remat && - ! bitVectBitValue(regAssigned,result->key) && - /* the number of free regs + number of regs in this LR - can accomodate the what result Needs */ - ((nfreeRegsType(result->regType) + - sym->nRegs) >= result->nRegs) - ) { - - for (i = 0 ; i < max(sym->nRegs,result->nRegs) ; i++) - if (i < sym->nRegs ) - result->regs[i] = sym->regs[i] ; - else - result->regs[i] = getRegGpr (ic,ebp,result); - - regAssigned = bitVectSetBit(regAssigned,result->key); - - } - - /* free the remaining */ - for (; i < sym->nRegs ; i++) { - if (psym) { - if (!symHasReg(psym,sym->regs[i])) - freeReg(sym->regs[i]); - } else - freeReg(sym->regs[i]); - } - } - } -} - - -/*-----------------------------------------------------------------*/ -/* reassignLR - reassign this to registers */ -/*-----------------------------------------------------------------*/ -void reassignLR (operand *op) -{ - symbol *sym = OP_SYMBOL(op); - int i; - - /* not spilt any more */ - sym->isspilt = sym->blockSpil = sym->remainSpil = 0; - bitVectUnSetBit(spiltSet,sym->key); - - regAssigned = bitVectSetBit(regAssigned,sym->key); - - blockSpil--; - - for (i=0;inRegs;i++) - sym->regs[i]->isFree = 0; -} - -/*-----------------------------------------------------------------*/ -/* willCauseSpill - determines if allocating will cause a spill */ -/*-----------------------------------------------------------------*/ -int willCauseSpill ( int nr, int rt) -{ - /* first check if there are any avlb registers - of te type required */ - if (rt == REG_PTR) { - /* special case for pointer type - if pointer type not avlb then - check for type gpr */ - if (nFreeRegs(rt) >= nr) - return 0; - if (nFreeRegs(REG_GPR) >= nr) - return 0; - } else { - if (ptrRegReq) { - if (nFreeRegs(rt) >= nr) - return 0; - } else { - if (nFreeRegs(REG_PTR) + - nFreeRegs(REG_GPR) >= nr) - return 0; - } - } - - /* it will cause a spil */ - return 1; -} - -/*-----------------------------------------------------------------*/ -/* positionRegs - the allocator can allocate same registers to res-*/ -/* ult and operand, if this happens make sure they are in the same */ -/* position as the operand otherwise chaos results */ -/*-----------------------------------------------------------------*/ -static void positionRegs (symbol *result, symbol *opsym, int lineno) -{ - int count = min(result->nRegs,opsym->nRegs); - int i , j = 0, shared = 0; - - /* if the result has been spilt then cannot share */ - if (opsym->isspilt) - return ; - again: - shared = 0; - /* first make sure that they actually share */ - for ( i = 0 ; i < count; i++ ) { - for (j = 0 ; j < count ; j++ ) { - if (result->regs[i] == opsym->regs[j] && i !=j) { - shared = 1; - goto xchgPositions; - } - } - } - xchgPositions: - if (shared) { - regs *tmp = result->regs[i]; - result->regs[i] = result->regs[j]; - result->regs[j] = tmp; - goto again; - } -} - -/*-----------------------------------------------------------------*/ -/* serialRegAssign - serially allocate registers to the variables */ -/*-----------------------------------------------------------------*/ -void serialRegAssign (eBBlock **ebbs, int count) -{ - int i; - - /* for all blocks */ - for (i = 0; i < count ; i++ ) { - - iCode *ic; - - if (ebbs[i]->noPath && - (ebbs[i]->entryLabel != entryLabel && - ebbs[i]->entryLabel != returnLabel )) - continue ; - - /* of all instructions do */ - for (ic = ebbs[i]->sch ; ic ; ic = ic->next) { - - /* if this is an ipop that means some live - range will have to be assigned again */ - if (ic->op == IPOP) - reassignLR (IC_LEFT(ic)); - - /* if result is present && is a true symbol */ - if (IC_RESULT(ic) && ic->op != IFX && - IS_TRUE_SYMOP(IC_RESULT(ic))) - OP_SYMBOL(IC_RESULT(ic))->allocreq = 1; - - /* take away registers from live - ranges that end at this instruction */ - deassignLRs (ic, ebbs[i]) ; - - /* some don't need registers */ - if (SKIP_IC2(ic) || - ic->op == JUMPTABLE || - ic->op == IFX || - ic->op == IPUSH || - ic->op == IPOP || - (IC_RESULT(ic) &&POINTER_SET(ic)) ) - continue; - - /* now we need to allocate registers - only for the result */ - if (IC_RESULT(ic)) { - symbol *sym = OP_SYMBOL(IC_RESULT(ic)); - bitVect *spillable; - int willCS ; - int j; - int ptrRegSet = 0; - - /* if it does not need or is spilt - or is already assigned to registers - or will not live beyond this instructions */ - if (!sym->nRegs || - sym->isspilt || - bitVectBitValue(regAssigned,sym->key) || - sym->liveTo <= ic->seq) - continue ; - - /* if some liverange has been spilt at the block level - and this one live beyond this block then spil this - to be safe */ - if (blockSpil && sym->liveTo > ebbs[i]->lSeq) { - spillThis (sym); - continue ; - } - /* if trying to allocate this will cause - a spill and there is nothing to spill - or this one is rematerializable then - spill this one */ - willCS = willCauseSpill(sym->nRegs,sym->regType); - spillable = computeSpillable(ic); - if ( sym->remat || - (willCS && bitVectIsZero(spillable) ) ) { - - spillThis (sym) ; - continue ; - - } - - /* if it has a spillocation & is used less than - all other live ranges then spill this */ - if ( willCS && sym->usl.spillLoc ) { - - symbol *leastUsed = - leastUsedLR(liveRangesWith (spillable , - allLRs, - ebbs[i], - ic)); - if (leastUsed && - leastUsed->used > sym->used) { - spillThis (sym); - continue; - } - } - - /* if we need ptr regs for the right side - then mark it */ - if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) < 2) { - ptrRegReq++; - ptrRegSet = 1; - } - /* else we assign registers to it */ - regAssigned = bitVectSetBit(regAssigned,sym->key); - - for (j = 0 ; j < sym->nRegs ;j++ ) { - if (sym->regType == REG_PTR) - sym->regs[j] = getRegPtr(ic,ebbs[i],sym); - else - sym->regs[j] = getRegGpr(ic,ebbs[i],sym); - - /* if the allocation falied which means - this was spilt then break */ - if (!sym->regs[j]) - break; - } - /* if it shares registers with operands make sure - that they are in the same position */ - if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && - OP_SYMBOL(IC_LEFT(ic))->nRegs && ic->op != '=') - positionRegs(OP_SYMBOL(IC_RESULT(ic)), - OP_SYMBOL(IC_LEFT(ic)),ic->lineno); - /* do the same for the right operand */ - if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && - OP_SYMBOL(IC_RIGHT(ic))->nRegs && ic->op != '=') - positionRegs(OP_SYMBOL(IC_RESULT(ic)), - OP_SYMBOL(IC_RIGHT(ic)),ic->lineno); - - if (ptrRegSet) { - ptrRegReq--; - ptrRegSet = 0; - } - - } - } - } -} - -/*-----------------------------------------------------------------*/ -/* rUmaskForOp :- returns register mask for an operand */ -/*-----------------------------------------------------------------*/ -bitVect *rUmaskForOp (operand *op) -{ - bitVect *rumask; - symbol *sym; - int j; - - /* only temporaries are assigned registers */ - if (!IS_ITEMP(op)) - return NULL; - - sym = OP_SYMBOL(op); - - /* if spilt or no registers assigned to it - then nothing */ - if (sym->isspilt || !sym->nRegs) - return NULL; - - rumask = newBitVect(nRegs); - - for (j = 0; j < sym->nRegs; j++) { - rumask = bitVectSetBit(rumask, - sym->regs[j]->rIdx); - } - - return rumask; -} - -/*-----------------------------------------------------------------*/ -/* regsUsedIniCode :- returns bit vector of registers used in iCode*/ -/*-----------------------------------------------------------------*/ -bitVect *regsUsedIniCode (iCode *ic) -{ - bitVect *rmask = newBitVect(nRegs); - - /* do the special cases first */ - if (ic->op == IFX ) { - rmask = bitVectUnion(rmask, - rUmaskForOp(IC_COND(ic))); - goto ret; - } - - /* for the jumptable */ - if (ic->op == JUMPTABLE) { - rmask = bitVectUnion(rmask, - rUmaskForOp(IC_JTCOND(ic))); - - goto ret; - } - - /* of all other cases */ - if (IC_LEFT(ic)) - rmask = bitVectUnion(rmask, - rUmaskForOp(IC_LEFT(ic))); - - - if (IC_RIGHT(ic)) - rmask = bitVectUnion(rmask, - rUmaskForOp(IC_RIGHT(ic))); - - if (IC_RESULT(ic)) - rmask = bitVectUnion(rmask, - rUmaskForOp(IC_RESULT(ic))); - - ret: - return rmask; -} - -/*-----------------------------------------------------------------*/ -/* createRegMask - for each instruction will determine the regsUsed*/ -/*-----------------------------------------------------------------*/ -void createRegMask (eBBlock **ebbs, int count) -{ - int i; - - /* for all blocks */ - for (i = 0; i < count ; i++ ) { - iCode *ic ; - - if ( ebbs[i]->noPath && - ( ebbs[i]->entryLabel != entryLabel && - ebbs[i]->entryLabel != returnLabel )) - continue ; - - /* for all instructions */ - for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) { - - int j; - - if (SKIP_IC2(ic) || !ic->rlive) - continue ; - - /* first mark the registers used in this - instruction */ - ic->rUsed = regsUsedIniCode(ic); - funcrUsed = bitVectUnion(funcrUsed,ic->rUsed); - - /* now create the register mask for those - registers that are in use : this is a - super set of ic->rUsed */ - ic->rMask = newBitVect(nRegs+1); - - /* for all live Ranges alive at this point */ - for (j = 1; j < ic->rlive->size; j++ ) { - symbol *sym; - int k; - - /* if not alive then continue */ - if (!bitVectBitValue(ic->rlive,j)) - continue ; - - /* find the live range we are interested in */ - if (!(sym = hTabItemWithKey(liveRanges,j))) { - werror (E_INTERNAL_ERROR,__FILE__,__LINE__, - "createRegMask cannot find live range"); - exit(0); - } - - /* if no register assigned to it */ - if (!sym->nRegs || sym->isspilt) - continue ; - - /* for all the registers allocated to it */ - for (k = 0 ; k < sym->nRegs ;k++) - if (sym->regs[k]) - ic->rMask = - bitVectSetBit(ic->rMask,sym->regs[k]->rIdx); - } - } - } -} - -/*-----------------------------------------------------------------*/ -/* rematStr - returns the rematerialized string for a remat var */ -/*-----------------------------------------------------------------*/ -char *rematStr (symbol *sym) -{ - char *s = buffer; - iCode *ic = sym->rematiCode; - - while (1) { - - /* if plus or minus print the right hand side */ - if (ic->op == '+' || ic->op == '-') { - sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)), - ic->op ); - s += strlen(s); - ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; - continue ; - } - - /* we reached the end */ - sprintf(s,"%s",OP_SYMBOL(IC_LEFT(ic))->rname); - break; - } - - return buffer ; -} - -/*-----------------------------------------------------------------*/ -/* regTypeNum - computes the type & number of registers required */ -/*-----------------------------------------------------------------*/ -void regTypeNum () -{ - symbol *sym; - int k; - iCode *ic; - - /* for each live range do */ - for ( sym = hTabFirstItem(liveRanges,&k); sym ; - sym = hTabNextItem(liveRanges,&k)) { - - /* if used zero times then no registers needed */ - if ((sym->liveTo - sym->liveFrom) == 0) - continue ; - - - /* if the live range is a temporary */ - if (sym->isitmp) { - - /* if the type is marked as a conditional */ - if (sym->regType == REG_CND) - continue ; - - /* if used in return only then we don't - need registers */ - if (sym->ruonly || sym->accuse) { - if (IS_AGGREGATE(sym->type) || sym->isptr) - sym->type = aggrToPtr(sym->type,FALSE); - continue ; - } - - /* if the symbol has only one definition & - that definition is a get_pointer and the - pointer we are getting is rematerializable and - in "data" space */ - - if (bitVectnBitsOn(sym->defs) == 1 && - (ic = hTabItemWithKey(iCodehTab, - bitVectFirstBit(sym->defs))) && - POINTER_GET(ic) && - !IS_BITVAR(sym->etype)) { - - - /* if remat in data space */ - if (OP_SYMBOL(IC_LEFT(ic))->remat && - DCL_TYPE(aggrToPtr(sym->type,FALSE)) == POINTER) { - - /* create a psuedo symbol & force a spil */ - symbol *psym = newSymbol(rematStr(OP_SYMBOL(IC_LEFT(ic))),1); - psym->type = sym->type; - psym->etype = sym->etype; - strcpy(psym->rname,psym->name); - sym->isspilt = 1; - sym->usl.spillLoc = psym; - continue ; - } - - /* if in data space or idata space then try to - allocate pointer register */ - - } - - /* if not then we require registers */ - sym->nRegs = ((IS_AGGREGATE(sym->type) || sym->isptr ) ? - getSize(sym->type = aggrToPtr(sym->type,FALSE)) : - getSize(sym->type)); - - if (sym->nRegs > 4) { - fprintf(stderr,"allocated more than 4 or 0 registers for type "); - printTypeChain(sym->type,stderr);fprintf(stderr,"\n"); - } - - /* determine the type of register required */ - if (sym->nRegs == 1 && - IS_PTR(sym->type) && - sym->uptr) - sym->regType = REG_PTR ; - else - sym->regType = REG_GPR ; - - } else - /* for the first run we don't provide */ - /* registers for true symbols we will */ - /* see how things go */ - sym->nRegs = 0 ; - } - -} - -/*-----------------------------------------------------------------*/ -/* freeAllRegs - mark all registers as free */ -/*-----------------------------------------------------------------*/ -void freeAllRegs() -{ - int i; - - for (i=0;i< nRegs;i++ ) - regs8051[i].isFree = 1; -} - -/*-----------------------------------------------------------------*/ -/* deallocStackSpil - this will set the stack pointer back */ -/*-----------------------------------------------------------------*/ -DEFSETFUNC(deallocStackSpil) -{ - symbol *sym = item; - - deallocLocal(sym); - return 0; -} - -/*-----------------------------------------------------------------*/ -/* farSpacePackable - returns the packable icode for far variables */ -/*-----------------------------------------------------------------*/ -static iCode *farSpacePackable (iCode *ic) -{ - iCode *dic ; - - /* go thru till we find a definition for the - symbol on the right */ - for ( dic = ic->prev ; dic ; dic = dic->prev) { - - /* if the definition is a call then no */ - if ((dic->op == CALL || dic->op == PCALL) && - IC_RESULT(dic)->key == IC_RIGHT(ic)->key) { - return NULL; - } - - /* if shift by unknown amount then not */ - if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) && - IC_RESULT(dic)->key == IC_RIGHT(ic)->key) - return NULL; - - /* if pointer get and size > 1 */ - if (POINTER_GET(dic) && - getSize(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)) > 1) - return NULL ; - - if (POINTER_SET(dic) && - getSize(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)) > 1) - return NULL ; - - /* if any three is a true symbol in far space */ - if (IC_RESULT(dic) && - IS_TRUE_SYMOP(IC_RESULT(dic)) && - isOperandInFarSpace(IC_RESULT(dic))) - return NULL; - - if (IC_RIGHT(dic) && - IS_TRUE_SYMOP(IC_RIGHT(dic)) && - isOperandInFarSpace(IC_RIGHT(dic)) && - !isOperandEqual(IC_RIGHT(dic),IC_RESULT(ic))) - return NULL; - - if (IC_LEFT(dic) && - IS_TRUE_SYMOP(IC_LEFT(dic)) && - isOperandInFarSpace(IC_LEFT(dic)) && - !isOperandEqual(IC_LEFT(dic),IC_RESULT(ic))) - return NULL; - - if (isOperandEqual(IC_RIGHT(ic),IC_RESULT(dic))) { - if ( (dic->op == LEFT_OP || - dic->op == RIGHT_OP || - dic->op == '-') && - IS_OP_LITERAL(IC_RIGHT(dic))) - return NULL; - else - return dic; - } - } - - return NULL; -} - -/*-----------------------------------------------------------------*/ -/* packRegsForAssign - register reduction for assignment */ -/*-----------------------------------------------------------------*/ -int packRegsForAssign (iCode *ic,eBBlock *ebp) -{ - iCode *dic, *sic; - - if ( -/* !IS_TRUE_SYMOP(IC_RESULT(ic)) || */ - !IS_ITEMP(IC_RIGHT(ic)) || - OP_LIVETO(IC_RIGHT(ic)) > ic->seq || - OP_SYMBOL(IC_RIGHT(ic))->isind) - return 0; - - /* if the true symbol is defined in far space or on stack - then we should not since this will increase register pressure */ - if (isOperandInFarSpace(IC_RESULT(ic))) { - if ((dic = farSpacePackable(ic))) - goto pack; - else - return 0; - - } - /* find the definition of iTempNN scanning backwards if we find a - a use of the true symbol in before we find the definition then - we cannot */ - for ( dic = ic->prev ; dic ; dic = dic->prev) { - - /* if there is a function call and this is - a parameter & not my parameter then don't pack it */ - if ( (dic->op == CALL || dic->op == PCALL) && - (OP_SYMBOL(IC_RESULT(ic))->_isparm && - !OP_SYMBOL(IC_RESULT(ic))->ismyparm)) { - dic = NULL; - break; - } - - if (SKIP_IC2(dic)) - continue; - - if (IS_SYMOP(IC_RESULT(dic)) && - IC_RESULT(dic)->key == IC_RIGHT(ic)->key) { - if (POINTER_SET(dic)) - dic = NULL; - - break; - } - - if (IS_SYMOP(IC_RIGHT(dic)) && - (IC_RIGHT(dic)->key == IC_RESULT(ic)->key || - IC_RIGHT(dic)->key == IC_RIGHT(ic)->key)) { - dic = NULL; - break; - } - - if (IS_SYMOP(IC_LEFT(dic)) && - (IC_LEFT(dic)->key == IC_RESULT(ic)->key || - IC_LEFT(dic)->key == IC_RIGHT(ic)->key)) { - dic = NULL; - break; - } - - if (POINTER_SET(dic) && - IC_RESULT(dic)->key == IC_RESULT(ic)->key ) { - dic = NULL ; - break; - } - } - - if (!dic) - return 0 ; /* did not find */ - - /* if the result is on stack or iaccess then it must be - the same atleast one of the operands */ - if (OP_SYMBOL(IC_RESULT(ic))->onStack || - OP_SYMBOL(IC_RESULT(ic))->iaccess ) { - - /* the operation has only one symbol - operator then we can pack */ - if ((IC_LEFT(dic) && !IS_SYMOP(IC_LEFT(dic))) || - (IC_RIGHT(dic) && !IS_SYMOP(IC_RIGHT(dic)))) - goto pack; - - if (!((IC_LEFT(dic) && - IC_RESULT(ic)->key == IC_LEFT(dic)->key) || - (IC_RIGHT(dic) && - IC_RESULT(ic)->key == IC_RIGHT(dic)->key))) - return 0; - } -pack: - /* found the definition */ - /* replace the result with the result of */ - /* this assignment and remove this assignment */ - IC_RESULT(dic) = IC_RESULT(ic) ; - - if (IS_ITEMP(IC_RESULT(dic)) && OP_SYMBOL(IC_RESULT(dic))->liveFrom > dic->seq) { - OP_SYMBOL(IC_RESULT(dic))->liveFrom = dic->seq; - } - /* delete from liverange table also - delete from all the points inbetween and the new - one */ - for ( sic = dic; sic != ic ; sic = sic->next ) { - bitVectUnSetBit(sic->rlive,IC_RESULT(ic)->key); - if (IS_ITEMP(IC_RESULT(dic))) - bitVectSetBit(sic->rlive,IC_RESULT(dic)->key); - } - - remiCodeFromeBBlock(ebp,ic); - return 1; - -} - -/*-----------------------------------------------------------------*/ -/* findAssignToSym : scanning backwards looks for first assig found*/ -/*-----------------------------------------------------------------*/ -iCode *findAssignToSym (operand *op,iCode *ic) -{ - iCode *dic; - - for (dic = ic->prev ; dic ; dic = dic->prev) { - - /* if definition by assignment */ - if (dic->op == '=' && - !POINTER_SET(dic) && - IC_RESULT(dic)->key == op->key -/* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */ - ) { - - /* we are interested only if defined in far space */ - /* or in stack space in case of + & - */ - - /* if assigned to a non-symbol then return - true */ - if (!IS_SYMOP(IC_RIGHT(dic))) - break ; - - /* if the symbol is in far space then - we should not */ - if (isOperandInFarSpace(IC_RIGHT(dic))) - return NULL ; - - /* for + & - operations make sure that - if it is on the stack it is the same - as one of the three operands */ - if ((ic->op == '+' || ic->op == '-') && - OP_SYMBOL(IC_RIGHT(dic))->onStack) { - - if ( IC_RESULT(ic)->key != IC_RIGHT(dic)->key && - IC_LEFT(ic)->key != IC_RIGHT(dic)->key && - IC_RIGHT(ic)->key != IC_RIGHT(dic)->key) - return NULL; - } - - break ; - - } - - /* if we find an usage then we cannot delete it */ - if (IC_LEFT(dic) && IC_LEFT(dic)->key == op->key) - return NULL; - - if (IC_RIGHT(dic) && IC_RIGHT(dic)->key == op->key) - return NULL; - - if (POINTER_SET(dic) && IC_RESULT(dic)->key == op->key) - return NULL; - } - - /* now make sure that the right side of dic - is not defined between ic & dic */ - if (dic) { - iCode *sic = dic->next ; - - for (; sic != ic ; sic = sic->next) - if (IC_RESULT(sic) && - IC_RESULT(sic)->key == IC_RIGHT(dic)->key) - return NULL; - } - - return dic; - - -} - -/*-----------------------------------------------------------------*/ -/* packRegsForSupport :- reduce some registers for support calls */ -/*-----------------------------------------------------------------*/ -int packRegsForSupport (iCode *ic, eBBlock *ebp) -{ - int change = 0 ; - /* for the left & right operand :- look to see if the - left was assigned a true symbol in far space in that - case replace them */ - if (IS_ITEMP(IC_LEFT(ic)) && - OP_SYMBOL(IC_LEFT(ic))->liveTo <= ic->seq) { - iCode *dic = findAssignToSym(IC_LEFT(ic),ic); - iCode *sic; - - if (!dic) - goto right ; - - /* found it we need to remove it from the - block */ - for ( sic = dic; sic != ic ; sic = sic->next ) - bitVectUnSetBit(sic->rlive,IC_LEFT(ic)->key); - - IC_LEFT(ic)->operand.symOperand = - IC_RIGHT(dic)->operand.symOperand; - IC_LEFT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key; - remiCodeFromeBBlock(ebp,dic); - change++; - } - - /* do the same for the right operand */ - right: - if (!change && - IS_ITEMP(IC_RIGHT(ic)) && - OP_SYMBOL(IC_RIGHT(ic))->liveTo <= ic->seq) { - iCode *dic = findAssignToSym(IC_RIGHT(ic),ic); - iCode *sic; - - if (!dic) - return change ; - - /* if this is a subtraction & the result - is a true symbol in far space then don't pack */ - if (ic->op == '-' && IS_TRUE_SYMOP(IC_RESULT(dic))) { - link *etype =getSpec(operandType(IC_RESULT(dic))); - if (IN_FARSPACE(SPEC_OCLS(etype))) - return change ; - } - /* found it we need to remove it from the - block */ - for ( sic = dic; sic != ic ; sic = sic->next ) - bitVectUnSetBit(sic->rlive,IC_RIGHT(ic)->key); - - IC_RIGHT(ic)->operand.symOperand = - IC_RIGHT(dic)->operand.symOperand; - IC_RIGHT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key; - - remiCodeFromeBBlock(ebp,dic); - change ++; - } - - return change ; -} - -#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly) - - -/*-----------------------------------------------------------------*/ -/* packRegsForOneuse : - will reduce some registers for single Use */ -/*-----------------------------------------------------------------*/ -static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp) -{ - bitVect *uses ; - iCode *dic, *sic; - - /* if returning a literal then do nothing */ - if (!IS_SYMOP(op)) - return NULL; - - /* only upto 2 bytes since we cannot predict - the usage of b, & acc */ - if (getSize(operandType(op)) > 2 && - ic->op != RETURN && - ic->op != SEND) - return NULL; - - /* this routine will mark the a symbol as used in one - instruction use only && if the defintion is local - (ie. within the basic block) && has only one definition && - that definiion is either a return value from a - function or does not contain any variables in - far space */ - uses = bitVectCopy(OP_USES(op)); - bitVectUnSetBit(uses,ic->key); /* take away this iCode */ - if (!bitVectIsZero(uses)) /* has other uses */ - return NULL ; - - /* if it has only one defintion */ - if (bitVectnBitsOn(OP_DEFS(op)) > 1) - return NULL ; /* has more than one definition */ - - /* get the that definition */ - if (!(dic = - hTabItemWithKey(iCodehTab, - bitVectFirstBit(OP_DEFS(op))))) - return NULL ; - - /* found the definition now check if it is local */ - if (dic->seq < ebp->fSeq || - dic->seq > ebp->lSeq) - return NULL ; /* non-local */ - - /* now check if it is the return from - a function call */ - if (dic->op == CALL || dic->op == PCALL ) { - if (ic->op != SEND && ic->op != RETURN) { - OP_SYMBOL(op)->ruonly = 1; - return dic; - } - dic = dic->next ; - } - - - /* otherwise check that the definition does - not contain any symbols in far space */ - if (isOperandInFarSpace(IC_LEFT(dic)) || - isOperandInFarSpace(IC_RIGHT(dic)) || - IS_OP_RUONLY(IC_LEFT(ic)) || - IS_OP_RUONLY(IC_RIGHT(ic)) ) { - return NULL; - } - - /* if pointer set then make sure the pointer - is one byte */ - if (POINTER_SET(dic) && - !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE))) - return NULL ; - - if (POINTER_GET(dic) && - !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE))) - return NULL ; - - sic = dic; - - /* also make sure the intervenening instructions - don't have any thing in far space */ - for (dic = dic->next ; dic && dic != ic ; dic = dic->next) { - - /* if there is an intervening function call then no */ - if (dic->op == CALL || dic->op == PCALL) - return NULL; - /* if pointer set then make sure the pointer - is one byte */ - if (POINTER_SET(dic) && - !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE))) - return NULL ; - - if (POINTER_GET(dic) && - !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE))) - return NULL ; - - /* if address of & the result is remat the okay */ - if (dic->op == ADDRESS_OF && - OP_SYMBOL(IC_RESULT(dic))->remat) - continue ; - - /* if operand has size of three or more & this - operation is a '*','/' or '%' then 'b' may - cause a problem */ - if (( dic->op == '%' || dic->op == '/' || dic->op == '*') && - getSize(aggrToPtr(operandType(op),FALSE)) >= 3) - return NULL; - - /* if left or right or result is in far space */ - if (isOperandInFarSpace(IC_LEFT(dic)) || - isOperandInFarSpace(IC_RIGHT(dic)) || - isOperandInFarSpace(IC_RESULT(dic)) || - IS_OP_RUONLY(IC_LEFT(dic)) || - IS_OP_RUONLY(IC_RIGHT(dic)) || - IS_OP_RUONLY(IC_RESULT(dic)) ) { - return NULL; - } - } - - OP_SYMBOL(op)->ruonly = 1; - return sic; - -} - -/*-----------------------------------------------------------------*/ -/* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */ -/*-----------------------------------------------------------------*/ -static bool isBitwiseOptimizable (iCode *ic) -{ - link *ltype = getSpec(operandType(IC_LEFT(ic))); - link *rtype = getSpec(operandType(IC_RIGHT(ic))); - - /* bitwise operations are considered optimizable - under the following conditions (Jean-Louis VERN) - - x & lit - bit & bit - bit & x - bit ^ bit - bit ^ x - x ^ lit - x | lit - bit | bit - bit | x - */ - if ( IS_LITERAL(rtype) || - (IS_BITVAR(ltype) && IN_BITSPACE(SPEC_OCLS(ltype)))) - return TRUE ; - else - return FALSE ; -} - -/*-----------------------------------------------------------------*/ -/* packRegsForAccUse - pack registers for acc use */ -/*-----------------------------------------------------------------*/ -void packRegsForAccUse (iCode *ic) -{ - iCode *uic; - - /* if + or - then it has to be one byte result */ - if ((ic->op == '+' || ic->op == '-') - && getSize(operandType(IC_RESULT(ic))) > 1) - return ; - - /* if shift operation make sure right side is not a literal */ - if (ic->op == RIGHT_OP && - ( isOperandLiteral(IC_RIGHT(ic)) || - getSize(operandType(IC_RESULT(ic))) > 1)) - return ; - - if (ic->op == LEFT_OP && - ( isOperandLiteral(IC_RIGHT(ic)) || - getSize(operandType(IC_RESULT(ic))) > 1)) - return ; - - - /* has only one definition */ - if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1) - return ; - - /* has only one use */ - if (bitVectnBitsOn(OP_USES(IC_RESULT(ic))) > 1) - return ; - - /* and the usage immediately follows this iCode */ - if (!(uic = hTabItemWithKey(iCodehTab, - bitVectFirstBit(OP_USES(IC_RESULT(ic)))))) - return ; - - if (ic->next != uic) - return ; - - /* if it is a conditional branch then we definitely can */ - if (uic->op == IFX ) - goto accuse; - - if ( uic->op == JUMPTABLE ) - return ; - - /* if the usage is not is an assignment - or an arithmetic / bitwise / shift operation then not */ - if (POINTER_SET(uic) && - getSize(aggrToPtr(operandType(IC_RESULT(uic)),FALSE)) > 1) - return; - - if (uic->op != '=' && - !IS_ARITHMETIC_OP(uic) && - !IS_BITWISE_OP(uic) && - uic->op != LEFT_OP && - uic->op != RIGHT_OP ) - return; - - /* if used in ^ operation then make sure right is not a - literl */ - if (uic->op == '^' && isOperandLiteral(IC_RIGHT(uic))) - return ; - - /* if shift operation make sure right side is not a literal */ - if (uic->op == RIGHT_OP && - ( isOperandLiteral(IC_RIGHT(uic)) || - getSize(operandType(IC_RESULT(uic))) > 1)) - return ; - - if (uic->op == LEFT_OP && - ( isOperandLiteral(IC_RIGHT(uic)) || - getSize(operandType(IC_RESULT(uic))) > 1)) - return ; - - /* make sure that the result of this icode is not on the - stack, since acc is used to compute stack offset */ - if (IS_TRUE_SYMOP(IC_RESULT(uic)) && - OP_SYMBOL(IC_RESULT(uic))->onStack) - return ; - - /* if either one of them in far space then we cannot */ - if ((IS_TRUE_SYMOP(IC_LEFT(uic)) && - isOperandInFarSpace(IC_LEFT(uic))) || - (IS_TRUE_SYMOP(IC_RIGHT(uic)) && - isOperandInFarSpace(IC_RIGHT(uic)))) - return ; - - /* if the usage has only one operand then we can */ - if (IC_LEFT(uic) == NULL || - IC_RIGHT(uic) == NULL) - goto accuse; - - /* make sure this is on the left side if not - a '+' since '+' is commutative */ - if (ic->op != '+' && - IC_LEFT(uic)->key != IC_RESULT(ic)->key) - return; - - /* if one of them is a literal then we can */ - if ((IC_LEFT(uic) && IS_OP_LITERAL(IC_LEFT(uic))) || - (IC_RIGHT(uic) && IS_OP_LITERAL(IC_RIGHT(uic)))) { - OP_SYMBOL(IC_RESULT(ic))->accuse = 1; - return ; - } - - /* if the other one is not on stack then we can */ - if (IC_LEFT(uic)->key == IC_RESULT(ic)->key && - (IS_ITEMP(IC_RIGHT(uic)) || - (IS_TRUE_SYMOP(IC_RIGHT(uic)) && - !OP_SYMBOL(IC_RIGHT(uic))->onStack))) - goto accuse; - - if (IC_RIGHT(uic)->key == IC_RESULT(ic)->key && - (IS_ITEMP(IC_LEFT(uic)) || - (IS_TRUE_SYMOP(IC_LEFT(uic)) && - !OP_SYMBOL(IC_LEFT(uic))->onStack))) - goto accuse ; - - return ; - - accuse: - OP_SYMBOL(IC_RESULT(ic))->accuse = 1; - - -} - -/*-----------------------------------------------------------------*/ -/* packForPush - hueristics to reduce iCode for pushing */ -/*-----------------------------------------------------------------*/ -static void packForPush(iCode *ic, eBBlock *ebp) -{ - iCode *dic; - - if (ic->op != IPUSH || !IS_ITEMP(IC_LEFT(ic))) - return ; - - /* must have only definition & one usage */ - if (bitVectnBitsOn(OP_DEFS(IC_LEFT(ic))) != 1 || - bitVectnBitsOn(OP_USES(IC_LEFT(ic))) != 1 ) - return ; - - /* find the definition */ - if (!(dic = hTabItemWithKey(iCodehTab, - bitVectFirstBit(OP_DEFS(IC_LEFT(ic)))))) - return ; - - if (dic->op != '=' || POINTER_SET(dic)) - return; - - /* we now we know that it has one & only one def & use - and the that the definition is an assignment */ - IC_LEFT(ic) = IC_RIGHT(dic); - - remiCodeFromeBBlock(ebp,dic); -} - -/*-----------------------------------------------------------------*/ -/* packRegisters - does some transformations to reduce register */ -/* pressure */ -/*-----------------------------------------------------------------*/ -static void packRegisters (eBBlock *ebp) -{ - iCode *ic ; - int change = 0 ; - - while (1) { - - change = 0; - - /* look for assignments of the form */ - /* iTempNN = TRueSym (someoperation) SomeOperand */ - /* .... */ - /* TrueSym := iTempNN:1 */ - for ( ic = ebp->sch ; ic ; ic = ic->next ) { - - - /* find assignment of the form TrueSym := iTempNN:1 */ - if (ic->op == '=' && !POINTER_SET(ic)) - change += packRegsForAssign(ic,ebp); - } - - if (!change) - break; - } - - for ( ic = ebp->sch ; ic ; ic = ic->next ) { - - /* if this is an itemp & result of a address of a true sym - then mark this as rematerialisable */ - if (ic->op == ADDRESS_OF && - IS_ITEMP(IC_RESULT(ic)) && - IS_TRUE_SYMOP(IC_LEFT(ic)) && - bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 && - !OP_SYMBOL(IC_LEFT(ic))->onStack ) { - - OP_SYMBOL(IC_RESULT(ic))->remat = 1; - OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic; - OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL; - - } - - /* if straight assignment then carry remat flag if - this is the only definition */ - if (ic->op == '=' && - !POINTER_SET(ic) && - IS_SYMOP(IC_RIGHT(ic)) && - OP_SYMBOL(IC_RIGHT(ic))->remat && - bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->defs) <= 1) { - - OP_SYMBOL(IC_RESULT(ic))->remat = - OP_SYMBOL(IC_RIGHT(ic))->remat; - OP_SYMBOL(IC_RESULT(ic))->rematiCode = - OP_SYMBOL(IC_RIGHT(ic))->rematiCode ; - } - - /* if this is a +/- operation with a rematerizable - then mark this as rematerializable as well only - if the literal value is within the range -255 and + 255 - the assembler cannot handle it other wise */ - if ((ic->op == '+' || ic->op == '-') && - - (IS_SYMOP(IC_LEFT(ic)) && - IS_ITEMP(IC_RESULT(ic)) && - OP_SYMBOL(IC_LEFT(ic))->remat && - bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 && - IS_OP_LITERAL(IC_RIGHT(ic))) ) { - - int i = operandLitValue(IC_RIGHT(ic)); - if ( i < 255 && i > -255) { - OP_SYMBOL(IC_RESULT(ic))->remat = 1; - OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic; - OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL; - } - } - - /* mark the pointer usages */ - if (POINTER_SET(ic)) - OP_SYMBOL(IC_RESULT(ic))->uptr = 1; - - if (POINTER_GET(ic)) - OP_SYMBOL(IC_LEFT(ic))->uptr = 1; - - if (!SKIP_IC2(ic)) { - /* if we are using a symbol on the stack - then we should say ptrRegReq */ - if (ic->op == IFX && IS_SYMOP(IC_COND(ic))) - ptrRegReq += ((OP_SYMBOL(IC_COND(ic))->onStack || - OP_SYMBOL(IC_COND(ic))->iaccess) ? 1 : 0); - else - if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic))) - ptrRegReq += ((OP_SYMBOL(IC_JTCOND(ic))->onStack || - OP_SYMBOL(IC_JTCOND(ic))->iaccess) ? 1 : 0); - else { - if (IS_SYMOP(IC_LEFT(ic))) - ptrRegReq += ((OP_SYMBOL(IC_LEFT(ic))->onStack || - OP_SYMBOL(IC_LEFT(ic))->iaccess) ? 1 : 0); - if (IS_SYMOP(IC_RIGHT(ic))) - ptrRegReq += ((OP_SYMBOL(IC_RIGHT(ic))->onStack || - OP_SYMBOL(IC_RIGHT(ic))->iaccess) ? 1 : 0); - if (IS_SYMOP(IC_RESULT(ic))) - ptrRegReq += ((OP_SYMBOL(IC_RESULT(ic))->onStack || - OP_SYMBOL(IC_RESULT(ic))->iaccess) ? 1 : 0); - } - } - - /* if the condition of an if instruction - is defined in the previous instruction then - mark the itemp as a conditional */ - if ((IS_CONDITIONAL(ic) || - ( ( ic->op == BITWISEAND || - ic->op == '|' || - ic->op == '^' ) && - isBitwiseOptimizable(ic))) && - ic->next && ic->next->op == IFX && - isOperandEqual(IC_RESULT(ic),IC_COND(ic->next)) && - OP_SYMBOL(IC_RESULT(ic))->liveTo <= ic->next->seq) { - - OP_SYMBOL(IC_RESULT(ic))->regType = REG_CND; - continue ; - } - - /* reduce for support function calls */ - if (ic->supportRtn || ic->op == '+' || ic->op == '-' ) - packRegsForSupport (ic,ebp); - - /* some cases the redundant moves can - can be eliminated for return statements */ - if ((ic->op == RETURN || ic->op == SEND) && - !isOperandInFarSpace(IC_LEFT(ic)) && - !options.model) - packRegsForOneuse (ic,IC_LEFT(ic),ebp); - - /* if pointer set & left has a size more than - one and right is not in far space */ - if (POINTER_SET(ic) && - !isOperandInFarSpace(IC_RIGHT(ic)) && - !OP_SYMBOL(IC_RESULT(ic))->remat && - !IS_OP_RUONLY(IC_RIGHT(ic)) && - getSize(aggrToPtr(operandType(IC_RESULT(ic)),FALSE)) > 1 ) - - packRegsForOneuse (ic,IC_RESULT(ic),ebp); - - /* if pointer get */ - if (POINTER_GET(ic) && - !isOperandInFarSpace(IC_RESULT(ic))&& - !OP_SYMBOL(IC_LEFT(ic))->remat && - !IS_OP_RUONLY(IC_RESULT(ic)) && - getSize(aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) > 1 ) - - packRegsForOneuse (ic,IC_LEFT(ic),ebp); - - - /* if this is cast for intergral promotion then - check if only use of the definition of the - operand being casted/ if yes then replace - the result of that arithmetic operation with - this result and get rid of the cast */ - if (ic->op == CAST) { - link *fromType = operandType(IC_RIGHT(ic)); - link *toType = operandType(IC_LEFT(ic)); - - if (IS_INTEGRAL(fromType) && IS_INTEGRAL(toType) && - getSize(fromType) != getSize(toType) ) { - - iCode *dic = packRegsForOneuse(ic,IC_RIGHT(ic),ebp); - if (dic) { - if (IS_ARITHMETIC_OP(dic)) { - IC_RESULT(dic) = IC_RESULT(ic); - remiCodeFromeBBlock(ebp,ic); - ic = ic->prev; - } else - OP_SYMBOL(IC_RIGHT(ic))->ruonly = 0; - } - } else { - - /* if the type from and type to are the same - then if this is the only use then packit */ - if (checkType(operandType(IC_RIGHT(ic)), - operandType(IC_LEFT(ic))) == 1) { - iCode *dic = packRegsForOneuse (ic,IC_RIGHT(ic),ebp); - if (dic) { - IC_RESULT(dic) = IC_RESULT(ic); - remiCodeFromeBBlock(ebp,ic); - ic = ic->prev; - } - } - } - } - - /* pack for PUSH - iTempNN := (some variable in farspace) V1 - push iTempNN ; - ------------- - push V1 - */ - if (ic->op == IPUSH ) { - packForPush(ic,ebp); - } - - - /* pack registers for accumulator use, when the - result of an arithmetic or bit wise operation - has only one use, that use is immediately following - the defintion and the using iCode has only one - operand or has two operands but one is literal & - the result of that operation is not on stack then - we can leave the result of this operation in acc:b - combination */ - if ((IS_ARITHMETIC_OP(ic) - - || IS_BITWISE_OP(ic) - - || ic->op == LEFT_OP || ic->op == RIGHT_OP - - ) && - IS_ITEMP(IC_RESULT(ic)) && - getSize(operandType(IC_RESULT(ic))) <= 2) - - packRegsForAccUse (ic); - - } -} - -/*-----------------------------------------------------------------*/ -/* assignRegisters - assigns registers to each live range as need */ -/*-----------------------------------------------------------------*/ -void assignRegisters (eBBlock **ebbs, int count) -{ - iCode *ic; - int i ; - - setToNull((void *)&funcrUsed); - ptrRegReq = stackExtend = dataExtend = 0; - /* if not register extentions then reduce number - of registers */ - if (options.regExtend) - nRegs = 13; - else - nRegs = 8; - - /* change assignments this will remove some - live ranges reducing some register pressure */ - for (i = 0 ; i < count ;i++ ) - packRegisters (ebbs[i]); - - if (options.dump_pack) - dumpEbbsToFileExt(".dumppack",ebbs,count); - - /* first determine for each live range the number of - registers & the type of registers required for each */ - regTypeNum (); - - /* and serially allocate registers */ - serialRegAssign(ebbs,count); - - /* if stack was extended then tell the user */ - if (stackExtend) { -/* werror(W_TOOMANY_SPILS,"stack", */ -/* stackExtend,currFunc->name,""); */ - stackExtend = 0 ; - } - - if (dataExtend) { -/* werror(W_TOOMANY_SPILS,"data space", */ -/* dataExtend,currFunc->name,""); */ - dataExtend = 0 ; - } - - /* after that create the register mask - for each of the instruction */ - createRegMask (ebbs,count); - - /* redo that offsets for stacked automatic variables */ - redoStackOffsets (); - - if (options.dump_rassgn) - dumpEbbsToFileExt(".dumprassgn",ebbs,count); - - /* now get back the chain */ - ic = iCodeLabelOptimize(iCodeFromeBBlock (ebbs,count)); - - - gen51Code(ic); - - /* free up any stackSpil locations allocated */ - applyToSet(stackSpil,deallocStackSpil); - slocNum = 0; - setToNull((void **)&stackSpil); - setToNull((void **)&spiltSet); - /* mark all registers as free */ - freeAllRegs(); - - return ; -} diff --git a/src/SDCCset.c b/src/SDCCset.c index a4844a37..049a3e38 100644 --- a/src/SDCCset.c +++ b/src/SDCCset.c @@ -22,9 +22,7 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include "SDCCset.h" +#include "common.h" /*-----------------------------------------------------------------*/ /* newSet - will allocate & return a new set entry */ diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 45cb114c..009cd4a5 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -21,14 +21,7 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include -#include "SDCCglobl.h" -#include "SDCCsymt.h" -#include "SDCCval.h" -#include "SDCCast.h" -#include "SDCCy.h" -#include "SDCCset.h" +#include "common.h" bucket *SymbolTab [256] ; /* the symbol table */ bucket *StructTab [256] ; /* the structure table */ diff --git a/src/SDCCval.c b/src/SDCCval.c index 3c20fe8a..5818c726 100644 --- a/src/SDCCval.c +++ b/src/SDCCval.c @@ -22,16 +22,11 @@ You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include -#include + +#include "common.h" #include #include #include -#include "SDCCglobl.h" -#include "SDCCsymt.h" -#include "SDCCval.h" -#include "SDCCast.h" -#include "SDCCy.h" int cNestLevel ; diff --git a/src/common.h b/src/common.h new file mode 100644 index 00000000..2e6f0319 --- /dev/null +++ b/src/common.h @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +#include "SDCCglobl.h" +#include "SDCCast.h" +#include "SDCCmem.h" +#include "SDCCy.h" +#include "SDCChasht.h" +#include "SDCCbitv.h" +#include "SDCCset.h" +#include "SDCCicode.h" +#include "SDCClabel.h" +#include "SDCCBBlock.h" +#include "SDCCloop.h" +#include "SDCCcse.h" +#include "SDCCcflow.h" +#include "SDCCdflow.h" +#include "SDCClrange.h" +#include "SDCCralloc.h" +#include "SDCCptropt.h" +#include "SDCCopt.h" + +#include "port.h" +#include "config.h" diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index b7e238f8..b4dccfd0 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -42,45 +42,36 @@ #endif #endif -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCClabel.h" -#include "SDCCBBlock.h" -#include "SDCCloop.h" -#include "SDCCcse.h" -#include "SDCCcflow.h" -#include "SDCCdflow.h" -#include "SDCClrange.h" -#include "SDCCralloc.h" -#include "SDCCgen51.h" +#include "common.h" #include "SDCCpeeph.h" +#include "gen.h" /* this is the down and dirty file with all kinds of -kludgy & hacky stuff. This is what it is all about -CODE GENERATION for a specific MCU . some of the -routines may be reusable, will have to see */ + kludgy & hacky stuff. This is what it is all about + CODE GENERATION for a specific MCU . some of the + routines may be reusable, will have to see */ static char *zero = "#0x00"; static char *one = "#0x01"; static char *spname ; static char *fReturn[] = {"dpl","dph","b","a" }; static char *accUse[] = {"a","b"}; -short r0Pushed = 0; -short r1Pushed = 0; -short rbank = -1; -short accInUse = 0 ; -short inLine = 0; -short debugLine = 0; -short nregssaved = 0; -extern int ptrRegReq ; -extern int nRegs; + +static short rbank = -1; + +static struct { + short r0Pushed; + short r1Pushed; + short accInUse; + short inLine; + short debugLine; + short nRegsSaved; + set *sendSet; +} _G; + +extern int mcs51_ptrRegReq ; +extern int mcs51_nRegs; extern FILE *codeOutFile; -set *sendSet = NULL; static void saverbank (int, iCode *,bool); #define RESULTONSTACK(x) \ (IC_RESULT(x) && IC_RESULT(x)->aop && \ @@ -128,8 +119,8 @@ void emitcode (char *inst,char *fmt, ...) lineCurr = (lineCurr ? connectLine(lineCurr,newLineNode(lb)) : (lineHead = newLineNode(lb))); - lineCurr->isInline = inLine; - lineCurr->isDebug = debugLine; + lineCurr->isInline = _G.inLine; + lineCurr->isDebug = _G.debugLine; va_end(ap); } @@ -172,10 +163,10 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) /* if r0 not used in this instruction */ if (!r0iu) { /* push it if not already pushed */ - if (!r0Pushed) { + if (!_G.r0Pushed) { emitcode ("push","%s", regWithIdx(R0_IDX)->dname); - r0Pushed++ ; + _G.r0Pushed++ ; } ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX); @@ -188,10 +179,10 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) if (!r1iu) { /* push it if not already pushed */ - if (!r1Pushed) { + if (!_G.r1Pushed) { emitcode ("push","%s", regWithIdx(R1_IDX)->dname); - r1Pushed++ ; + _G.r1Pushed++ ; } ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX); @@ -276,18 +267,18 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) if (sym->onStack) { - if ( accInUse ) + if ( _G.accInUse ) emitcode("push","acc"); emitcode("mov","a,_bp"); emitcode("add","a,#0x%02x", ((sym->stack < 0) ? - ((char)(sym->stack - nregssaved )) : + ((char)(sym->stack - _G.nRegsSaved )) : ((char)sym->stack)) & 0xff); emitcode("mov","%s,a", aop->aopu.aop_ptr->name); - if ( accInUse ) + if ( _G.accInUse ) emitcode("pop","acc"); } else @@ -595,20 +586,20 @@ static void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) , AOP_R1 && AOP_STK */ switch (aop->type) { case AOP_R0 : - if (r0Pushed ) { + if (_G.r0Pushed ) { if (pop) { emitcode ("pop","ar0"); - r0Pushed--; + _G.r0Pushed--; } } bitVectUnSetBit(ic->rUsed,R0_IDX); break; case AOP_R1 : - if (r1Pushed ) { + if (_G.r1Pushed ) { if (pop) { emitcode ("pop","ar1"); - r1Pushed--; + _G.r1Pushed--; } } bitVectUnSetBit(ic->rUsed,R1_IDX); @@ -637,14 +628,14 @@ static void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) } op->aop = aop; freeAsmop(op,NULL,ic,TRUE); - if (r0Pushed) { + if (_G.r0Pushed) { emitcode("pop","ar0"); - r0Pushed--; + _G.r0Pushed--; } - if (r1Pushed) { + if (_G.r1Pushed) { emitcode("pop","ar1"); - r1Pushed--; + _G.r1Pushed--; } } } @@ -1353,7 +1344,7 @@ static void saveRegisters(iCode *lic) if (bitVectBitValue(rsave,R0_IDX)) emitcode("mov","b,r0"); emitcode("mov","r0,%s",spname); - for (i = 0 ; i < nRegs ; i++) { + for (i = 0 ; i < mcs51_nRegs ; i++) { if (bitVectBitValue(rsave,i)) { if (i == R0_IDX) emitcode("mov","a,b"); @@ -1367,7 +1358,7 @@ static void saveRegisters(iCode *lic) if (bitVectBitValue(rsave,R0_IDX)) emitcode("mov","r0,b"); } else - for (i = 0 ; i < nRegs ; i++) { + for (i = 0 ; i < mcs51_nRegs ; i++) { if (bitVectBitValue(rsave,i)) emitcode("push","%s",regWithIdx(i)->dname); } @@ -1395,7 +1386,7 @@ static void unsaveRegisters (iCode *ic) if (options.useXstack) { emitcode("mov","r0,%s",spname); - for (i = nRegs ; i >= 0 ; i--) { + for (i = mcs51_nRegs ; i >= 0 ; i--) { if (bitVectBitValue(rsave,i)) { emitcode("dec","r0"); emitcode("movx","a,@r0"); @@ -1410,7 +1401,7 @@ static void unsaveRegisters (iCode *ic) if (bitVectBitValue(rsave,R0_IDX)) emitcode("mov","r0,b"); } else - for (i = nRegs ; i >= 0 ; i--) { + for (i = mcs51_nRegs ; i >= 0 ; i--) { if (bitVectBitValue(rsave,i)) emitcode("pop","%s",regWithIdx(i)->dname); } @@ -1593,7 +1584,7 @@ static void unsaverbank (int bank,iCode *ic,bool popPsw) emitcode ("pop","psw"); } - for (i = (nRegs - 1) ; i >= 0 ;i--) { + for (i = (mcs51_nRegs - 1) ; i >= 0 ;i--) { if (options.useXstack) { emitcode("movx","a,@%s",r->name); emitcode("mov","(%s+%d),a", @@ -1630,7 +1621,7 @@ static void saverbank (int bank, iCode *ic, bool pushPsw) } - for (i = 0 ; i < nRegs ;i++) { + for (i = 0 ; i < mcs51_nRegs ;i++) { if (options.useXstack) { emitcode("inc","%s",r->name); emitcode("mov","a,(%s+%d)", @@ -1681,11 +1672,11 @@ static void genCall (iCode *ic) saverbank(SPEC_BANK(detype),ic,TRUE); /* if send set is not empty the assign */ - if (sendSet) { + if (_G.sendSet) { iCode *sic ; - for (sic = setFirstItem(sendSet) ; sic ; - sic = setNextItem(sendSet)) { + for (sic = setFirstItem(_G.sendSet) ; sic ; + sic = setNextItem(_G.sendSet)) { int size, offset = 0; aopOp(IC_LEFT(sic),sic,FALSE); size = AOP_SIZE(IC_LEFT(sic)); @@ -1700,7 +1691,7 @@ static void genCall (iCode *ic) } freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); } - sendSet = NULL; + _G.sendSet = NULL; } /* make the call */ emitcode("lcall","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ? @@ -1713,9 +1704,9 @@ static void genCall (iCode *ic) OP_SYMBOL(IC_RESULT(ic))->spildir )) || IS_TRUE_SYMOP(IC_RESULT(ic)) ) { - accInUse++; + _G.accInUse++; aopOp(IC_RESULT(ic),ic,FALSE); - accInUse--; + _G.accInUse--; assignResultValue(IC_RESULT(ic)); @@ -1784,11 +1775,11 @@ static void genPcall (iCode *ic) freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); /* if send set is not empty the assign */ - if (sendSet) { + if (_G.sendSet) { iCode *sic ; - for (sic = setFirstItem(sendSet) ; sic ; - sic = setNextItem(sendSet)) { + for (sic = setFirstItem(_G.sendSet) ; sic ; + sic = setNextItem(_G.sendSet)) { int size, offset = 0; aopOp(IC_LEFT(sic),sic,FALSE); size = AOP_SIZE(IC_LEFT(sic)); @@ -1803,7 +1794,7 @@ static void genPcall (iCode *ic) } freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); } - sendSet = NULL; + _G.sendSet = NULL; } emitcode("ret",""); @@ -1816,9 +1807,9 @@ static void genPcall (iCode *ic) OP_SYMBOL(IC_RESULT(ic))->spildir)) || IS_TRUE_SYMOP(IC_RESULT(ic)) ) { - accInUse++; + _G.accInUse++; aopOp(IC_RESULT(ic),ic,FALSE); - accInUse--; + _G.accInUse--; assignResultValue(IC_RESULT(ic)); @@ -1896,7 +1887,7 @@ static void genFunction (iCode *ic) symbol *sym; link *fetype; - nregssaved = 0; + _G.nRegsSaved = 0; /* create the function header */ emitcode(";","-----------------------------------------"); emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name); @@ -1915,7 +1906,7 @@ static void genFunction (iCode *ic) int i ; rbank = SPEC_BANK(fetype); - for ( i = 0 ; i < nRegs ; i++ ) { + for ( i = 0 ; i < mcs51_nRegs ; i++ ) { if (strcmp(regs8051[i].base,"0") == 0) emitcode("","%s = 0x%02x", regs8051[i].dname, @@ -1957,7 +1948,7 @@ static void genFunction (iCode *ic) /* save the registers used */ for ( i = 0 ; i < sym->regsUsed->size ; i++) { if (bitVectBitValue(sym->regsUsed,i) || - (ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) + (mcs51_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) emitcode("push","%s",regWithIdx(i)->dname); } } @@ -1980,9 +1971,9 @@ static void genFunction (iCode *ic) /* save the registers used */ for ( i = 0 ; i < sym->regsUsed->size ; i++) { if (bitVectBitValue(sym->regsUsed,i) || - (ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) { + (mcs51_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) { emitcode("push","%s",regWithIdx(i)->dname); - nregssaved++; + _G.nRegsSaved++; } } } @@ -2091,7 +2082,7 @@ static void genEndFunction (iCode *ic) /* save the registers used */ for ( i = sym->regsUsed->size ; i >= 0 ; i--) { if (bitVectBitValue(sym->regsUsed,i) || - (ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) + (mcs51_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) emitcode("pop","%s",regWithIdx(i)->dname); } } @@ -2119,7 +2110,7 @@ static void genEndFunction (iCode *ic) /* if debug then send end of function */ /* if (options.debug && currFunc) { */ if (currFunc) { - debugLine = 1; + _G.debugLine = 1; emitcode("","C$%s$%d$%d$%d ==.", ic->filename,currFunc->lastLine, ic->level,ic->block); @@ -2127,7 +2118,7 @@ static void genEndFunction (iCode *ic) emitcode("","XF%s$%s$0$0 ==.",moduleName,currFunc->name); else emitcode("","XG$%s$0$0 ==.",currFunc->name); - debugLine = 0; + _G.debugLine = 0; } emitcode ("reti",""); @@ -2144,7 +2135,7 @@ static void genEndFunction (iCode *ic) /* save the registers used */ for ( i = sym->regsUsed->size ; i >= 0 ; i--) { if (bitVectBitValue(sym->regsUsed,i) || - (ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) + (mcs51_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) emitcode("pop","%s",regWithIdx(i)->dname); } } @@ -2154,7 +2145,7 @@ static void genEndFunction (iCode *ic) /* if debug then send end of function */ /* if (options.debug && currFunc) { */ if (currFunc) { - debugLine = 1; + _G.debugLine = 1; emitcode("","C$%s$%d$%d$%d ==.", ic->filename,currFunc->lastLine, ic->level,ic->block); @@ -2162,7 +2153,7 @@ static void genEndFunction (iCode *ic) emitcode("","XF%s$%s$0$0 ==.",moduleName,currFunc->name); else emitcode("","XG$%s$0$0 ==.",currFunc->name); - debugLine = 0; + _G.debugLine = 0; } emitcode ("ret",""); @@ -4317,7 +4308,7 @@ static void genInline (iCode *ic) char *bp = buffer; char *bp1= buffer; - inLine += (!options.asmpeep); + _G.inLine += (!options.asmpeep); strcpy(buffer,IC_INLINE(ic)); /* emit each line as a code */ @@ -4340,7 +4331,7 @@ static void genInline (iCode *ic) if (bp1 != bp) emitcode(bp1,""); /* emitcode("",buffer); */ - inLine -= (!options.asmpeep); + _G.inLine -= (!options.asmpeep); } /*-----------------------------------------------------------------*/ @@ -7124,9 +7115,9 @@ static void genReceive (iCode *ic) } } else { - accInUse++; + _G.accInUse++; aopOp(IC_RESULT(ic),ic,FALSE); - accInUse--; + _G.accInUse--; assignResultValue(IC_RESULT(ic)); } @@ -7147,12 +7138,12 @@ void gen51Code (iCode *lic) /* if (options.debug && currFunc) { */ if (currFunc) { cdbSymbol(currFunc,cdbFile,FALSE,TRUE); - debugLine = 1; + _G.debugLine = 1; if (IS_STATIC(currFunc->etype)) emitcode("","F%s$%s$0$0 ==.",moduleName,currFunc->name); else emitcode("","G$%s$0$0 ==.",currFunc->name); - debugLine = 0; + _G.debugLine = 0; } /* stack pointer name */ if (options.useXstack) @@ -7165,11 +7156,11 @@ void gen51Code (iCode *lic) if ( cln != ic->lineno ) { if ( options.debug ) { - debugLine = 1; + _G.debugLine = 1; emitcode("","C$%s$%d$%d$%d ==.", ic->filename,ic->lineno, ic->level,ic->block); - debugLine = 0; + _G.debugLine = 0; } emitcode(";","%s %d",ic->filename,ic->lineno); cln = ic->lineno ; @@ -7361,7 +7352,7 @@ void gen51Code (iCode *lic) break; case SEND: - addSet(&sendSet,ic); + addSet(&_G.sendSet,ic); break; default : diff --git a/src/mcs51/main.c b/src/mcs51/main.c index dfba2348..6dd76d92 100644 --- a/src/mcs51/main.c +++ b/src/mcs51/main.c @@ -1,8 +1,24 @@ -#include "SDCCglobl.h" +#include "common.h" #include "main.h" +void mcs51_assignRegisters (eBBlock **ebbs, int count); + +static bool _mcs51_parseOptions(int *pargc, char **argv) +{ + return FALSE; +} + +static void _mcs51_finaliseOptions(void) +{ +} + +static void _mcs51_setDefaultOptions(void) +{ +} + /* Globals */ -PROCESSOR_CONSTANTS port = { +PORT mcs51_port = { + "mcs51", "MCU 8051", /* Target name */ { "asx8051", /* Assembler executable name */ @@ -23,6 +39,10 @@ PROCESSOR_CONSTANTS port = { /* mcs51 has an 8 bit mul */ { 1 - } + }, + _mcs51_parseOptions, + _mcs51_finaliseOptions, + _mcs51_setDefaultOptions, + mcs51_assignRegisters }; diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index f768d1d4..1154d534 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -50,16 +50,22 @@ /* since the pack the registers depending strictly on the MCU */ /*-----------------------------------------------------------------*/ -bitVect *spiltSet = NULL ; -set *stackSpil = NULL; -bitVect *regAssigned = NULL; -short blockSpil = 0; -int slocNum = 0 ; extern void gen51Code(iCode *); -int ptrRegReq = 0; /* one byte pointer register required */ -bitVect *funcrUsed = NULL; /* registers used in a function */ -int stackExtend = 0; -int dataExtend = 0; + +/* Global data */ +static struct { + bitVect *spiltSet; + set *stackSpil; + bitVect *regAssigned; + short blockSpil; + int slocNum; + bitVect *funcrUsed; /* registers used in a function */ + int stackExtend; + int dataExtend; +} _G; + +/* Shared with gen.c */ +int mcs51_ptrRegReq; /* one byte pointer register required */ /* 8051 registers */ regs regs8051[] = @@ -80,7 +86,7 @@ regs regs8051[] = { REG_GPR ,X12_IDX,REG_GPR , "x12", "x12", "xreg", 4, 1 }, { REG_CND ,CND_IDX,REG_CND , "C" , "C" , "xreg", 0, 1 }, }; -int nRegs = 13; +int mcs51_nRegs = 13; void spillThis (symbol *); /*-----------------------------------------------------------------*/ @@ -90,7 +96,7 @@ regs *allocReg (short type) { int i; - for ( i = 0 ; i < nRegs ; i++ ) { + for ( i = 0 ; i < mcs51_nRegs ; i++ ) { /* if type is given as 0 then any free register will do */ @@ -123,7 +129,7 @@ regs *regWithIdx (int idx) { int i ; - for (i=0;i < nRegs;i++) + for (i=0;i < mcs51_nRegs;i++) if (regs8051[i].rIdx == idx) return ®s8051[i]; @@ -149,7 +155,7 @@ int nFreeRegs (int type) int i; int nfr=0; - for (i = 0 ; i < nRegs; i++ ) + for (i = 0 ; i < mcs51_nRegs; i++ ) if (regs8051[i].isFree && regs8051[i].type == type) nfr++; return nfr; @@ -210,11 +216,11 @@ bitVect *computeSpillable (iCode *ic) spillable = bitVectCopy(ic->rlive); spillable = - bitVectCplAnd(spillable,spiltSet); /* those already spilt */ + bitVectCplAnd(spillable,_G.spiltSet); /* those already spilt */ spillable = bitVectCplAnd(spillable,ic->uses); /* used in this one */ bitVectUnSetBit(spillable,ic->defKey); - spillable = bitVectIntersect(spillable,regAssigned); + spillable = bitVectIntersect(spillable,_G.regAssigned); return spillable; } @@ -316,7 +322,7 @@ set *liveRangesWith (bitVect *lrs, int (func)(symbol *,eBBlock *, iCode *), exit(1); } - if (func(sym,ebp,ic) && bitVectBitValue(regAssigned,sym->key)) + if (func(sym,ebp,ic) && bitVectBitValue(_G.regAssigned,sym->key)) addSetHead(&rset,sym); } @@ -409,8 +415,8 @@ void spillLRWithPtrReg (symbol *forSym) regs *r0,*r1; int k; - if (!regAssigned || - bitVectIsZero(regAssigned)) + if (!_G.regAssigned || + bitVectIsZero(_G.regAssigned)) return; r0 = regWithIdx(R0_IDX); @@ -453,7 +459,7 @@ symbol *createStackSpil (symbol *sym) /* first go try and find a free one that is already existing on the stack */ - if (applyToSet(stackSpil,isFree,&sloc, sym)) { + if (applyToSet(_G.stackSpil,isFree,&sloc, sym)) { /* found a free one : just update & return */ sym->usl.spillLoc = sloc; sym->stackSpil= 1; @@ -466,7 +472,7 @@ symbol *createStackSpil (symbol *sym) we need to allocate this on the stack : this is really a hack!! but cannot think of anything better at this time */ - sprintf(buffer,"sloc%d",slocNum++); + sprintf(buffer,"sloc%d",_G.slocNum++); sloc = newiTemp(buffer); /* set the type to the spilling symbol */ @@ -501,12 +507,12 @@ symbol *createStackSpil (symbol *sym) /* if it is on the stack then update the stack */ if (IN_STACK(sloc->etype)) { currFunc->stack += getSize(sloc->type); - stackExtend += getSize(sloc->type); + _G.stackExtend += getSize(sloc->type); } else - dataExtend += getSize(sloc->type); + _G.dataExtend += getSize(sloc->type); - /* add it to the stackSpil set */ - addSetHead(&stackSpil,sloc); + /* add it to the _G.stackSpil set */ + addSetHead(&_G.stackSpil,sloc); sym->usl.spillLoc = sloc; sym->stackSpil = 1; @@ -529,7 +535,7 @@ bool isSpiltOnStack (symbol *sym) if (!sym->isspilt) return FALSE ; -/* if (sym->stackSpil) */ +/* if (sym->_G.stackSpil) */ /* return TRUE; */ if (!sym->usl.spillLoc) @@ -557,9 +563,9 @@ void spillThis (symbol *sym) /* mark it has spilt & put it in the spilt set */ sym->isspilt = 1; - spiltSet = bitVectSetBit(spiltSet,sym->key); + _G.spiltSet = bitVectSetBit(_G.spiltSet,sym->key); - bitVectUnSetBit(regAssigned,sym->key); + bitVectUnSetBit(_G.regAssigned,sym->key); for (i = 0 ; i < sym->nRegs ; i++) @@ -571,8 +577,8 @@ void spillThis (symbol *sym) /* if spilt on stack then free up r0 & r1 if they could have been assigned to some LIVE ranges */ - if (!ptrRegReq && isSpiltOnStack(sym)) { - ptrRegReq++ ; + if (!mcs51_ptrRegReq && isSpiltOnStack(sym)) { + mcs51_ptrRegReq++ ; spillLRWithPtrReg(sym); } @@ -617,11 +623,11 @@ symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym) /* check if there are any live ranges allocated to registers that are not used in this block */ - if (!blockSpil && (selectS = liveRangesWith(lrcs,notUsedInBlock,ebp,ic))) { + if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInBlock,ebp,ic))) { sym = leastUsedLR(selectS); /* if this is not rematerializable */ if (!sym->remat) { - blockSpil++; + _G.blockSpil++; sym->blockSpil = 1; } return sym; @@ -629,11 +635,11 @@ symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym) /* check if there are any live ranges that not used in the remainder of the block */ - if (!blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) { + if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) { sym = leastUsedLR (selectS); if (!sym->remat) { sym->remainSpil = 1; - blockSpil++; + _G.blockSpil++; } return sym; } @@ -687,11 +693,11 @@ bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym) /* mark it as spilt */ ssym->isspilt = 1; - spiltSet = bitVectSetBit(spiltSet,ssym->key); + _G.spiltSet = bitVectSetBit(_G.spiltSet,ssym->key); /* mark it as not register assigned & take it away from the set */ - bitVectUnSetBit(regAssigned,ssym->key); + bitVectUnSetBit(_G.regAssigned,ssym->key); /* mark the registers as free */ for (i = 0 ; i < ssym->nRegs ;i++ ) @@ -700,8 +706,8 @@ bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym) /* if spilt on stack then free up r0 & r1 if they could have been assigned to as gprs */ - if (!ptrRegReq && isSpiltOnStack(ssym) ) { - ptrRegReq++ ; + if (!mcs51_ptrRegReq && isSpiltOnStack(ssym) ) { + mcs51_ptrRegReq++ ; spillLRWithPtrReg(ssym); } @@ -774,7 +780,7 @@ regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym) if ((reg = allocReg(REG_GPR))) return reg; - if (!ptrRegReq) + if (!mcs51_ptrRegReq) if ((reg = allocReg(REG_PTR))) return reg ; @@ -829,7 +835,7 @@ void deassignLRs (iCode *ic, eBBlock *ebp) continue ; } - if (!bitVectBitValue(regAssigned,sym->key)) + if (!bitVectBitValue(_G.regAssigned,sym->key)) continue; /* special case check if this is an IFX & @@ -845,7 +851,7 @@ void deassignLRs (iCode *ic, eBBlock *ebp) if (sym->nRegs) { int i = 0; - bitVectUnSetBit(regAssigned,sym->key); + bitVectUnSetBit(_G.regAssigned,sym->key); /* if the result of this one needs registers and does not have it then assign it right @@ -865,7 +871,7 @@ void deassignLRs (iCode *ic, eBBlock *ebp) result->nRegs && /* which needs registers */ ! result->isspilt && /* and does not already have them */ ! result->remat && - ! bitVectBitValue(regAssigned,result->key) && + ! bitVectBitValue(_G.regAssigned,result->key) && /* the number of free regs + number of regs in this LR can accomodate the what result Needs */ ((nfreeRegsType(result->regType) + @@ -878,7 +884,7 @@ void deassignLRs (iCode *ic, eBBlock *ebp) else result->regs[i] = getRegGpr (ic,ebp,result); - regAssigned = bitVectSetBit(regAssigned,result->key); + _G.regAssigned = bitVectSetBit(_G.regAssigned,result->key); } @@ -905,11 +911,11 @@ void reassignLR (operand *op) /* not spilt any more */ sym->isspilt = sym->blockSpil = sym->remainSpil = 0; - bitVectUnSetBit(spiltSet,sym->key); + bitVectUnSetBit(_G.spiltSet,sym->key); - regAssigned = bitVectSetBit(regAssigned,sym->key); + _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key); - blockSpil--; + _G.blockSpil--; for (i=0;inRegs;i++) sym->regs[i]->isFree = 0; @@ -931,7 +937,7 @@ int willCauseSpill ( int nr, int rt) if (nFreeRegs(REG_GPR) >= nr) return 0; } else { - if (ptrRegReq) { + if (mcs51_ptrRegReq) { if (nFreeRegs(rt) >= nr) return 0; } else { @@ -1035,14 +1041,14 @@ void serialRegAssign (eBBlock **ebbs, int count) or will not live beyond this instructions */ if (!sym->nRegs || sym->isspilt || - bitVectBitValue(regAssigned,sym->key) || + bitVectBitValue(_G.regAssigned,sym->key) || sym->liveTo <= ic->seq) continue ; /* if some liverange has been spilt at the block level and this one live beyond this block then spil this to be safe */ - if (blockSpil && sym->liveTo > ebbs[i]->lSeq) { + if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) { spillThis (sym); continue ; } @@ -1079,11 +1085,11 @@ void serialRegAssign (eBBlock **ebbs, int count) /* if we need ptr regs for the right side then mark it */ if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) < 2) { - ptrRegReq++; + mcs51_ptrRegReq++; ptrRegSet = 1; } /* else we assign registers to it */ - regAssigned = bitVectSetBit(regAssigned,sym->key); + _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key); for (j = 0 ; j < sym->nRegs ;j++ ) { if (sym->regType == REG_PTR) @@ -1109,7 +1115,7 @@ void serialRegAssign (eBBlock **ebbs, int count) OP_SYMBOL(IC_RIGHT(ic)),ic->lineno); if (ptrRegSet) { - ptrRegReq--; + mcs51_ptrRegReq--; ptrRegSet = 0; } @@ -1138,7 +1144,7 @@ bitVect *rUmaskForOp (operand *op) if (sym->isspilt || !sym->nRegs) return NULL; - rumask = newBitVect(nRegs); + rumask = newBitVect(mcs51_nRegs); for (j = 0; j < sym->nRegs; j++) { rumask = bitVectSetBit(rumask, @@ -1153,7 +1159,7 @@ bitVect *rUmaskForOp (operand *op) /*-----------------------------------------------------------------*/ bitVect *regsUsedIniCode (iCode *ic) { - bitVect *rmask = newBitVect(nRegs); + bitVect *rmask = newBitVect(mcs51_nRegs); /* do the special cases first */ if (ic->op == IFX ) { @@ -1215,12 +1221,12 @@ void createRegMask (eBBlock **ebbs, int count) /* first mark the registers used in this instruction */ ic->rUsed = regsUsedIniCode(ic); - funcrUsed = bitVectUnion(funcrUsed,ic->rUsed); + _G.funcrUsed = bitVectUnion(_G.funcrUsed,ic->rUsed); /* now create the register mask for those registers that are in use : this is a super set of ic->rUsed */ - ic->rMask = newBitVect(nRegs+1); + ic->rMask = newBitVect(mcs51_nRegs+1); /* for all live Ranges alive at this point */ for (j = 1; j < ic->rlive->size; j++ ) { @@ -1377,7 +1383,7 @@ void freeAllRegs() { int i; - for (i=0;i< nRegs;i++ ) + for (i=0;i< mcs51_nRegs;i++ ) regs8051[i].isFree = 1; } @@ -2101,23 +2107,23 @@ static void packRegisters (eBBlock *ebp) if (!SKIP_IC2(ic)) { /* if we are using a symbol on the stack - then we should say ptrRegReq */ + then we should say mcs51_ptrRegReq */ if (ic->op == IFX && IS_SYMOP(IC_COND(ic))) - ptrRegReq += ((OP_SYMBOL(IC_COND(ic))->onStack || + mcs51_ptrRegReq += ((OP_SYMBOL(IC_COND(ic))->onStack || OP_SYMBOL(IC_COND(ic))->iaccess) ? 1 : 0); else if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic))) - ptrRegReq += ((OP_SYMBOL(IC_JTCOND(ic))->onStack || + mcs51_ptrRegReq += ((OP_SYMBOL(IC_JTCOND(ic))->onStack || OP_SYMBOL(IC_JTCOND(ic))->iaccess) ? 1 : 0); else { if (IS_SYMOP(IC_LEFT(ic))) - ptrRegReq += ((OP_SYMBOL(IC_LEFT(ic))->onStack || + mcs51_ptrRegReq += ((OP_SYMBOL(IC_LEFT(ic))->onStack || OP_SYMBOL(IC_LEFT(ic))->iaccess) ? 1 : 0); if (IS_SYMOP(IC_RIGHT(ic))) - ptrRegReq += ((OP_SYMBOL(IC_RIGHT(ic))->onStack || + mcs51_ptrRegReq += ((OP_SYMBOL(IC_RIGHT(ic))->onStack || OP_SYMBOL(IC_RIGHT(ic))->iaccess) ? 1 : 0); if (IS_SYMOP(IC_RESULT(ic))) - ptrRegReq += ((OP_SYMBOL(IC_RESULT(ic))->onStack || + mcs51_ptrRegReq += ((OP_SYMBOL(IC_RESULT(ic))->onStack || OP_SYMBOL(IC_RESULT(ic))->iaccess) ? 1 : 0); } } @@ -2243,19 +2249,19 @@ static void packRegisters (eBBlock *ebp) /*-----------------------------------------------------------------*/ /* assignRegisters - assigns registers to each live range as need */ /*-----------------------------------------------------------------*/ -void assignRegisters (eBBlock **ebbs, int count) +void mcs51_assignRegisters (eBBlock **ebbs, int count) { iCode *ic; int i ; - setToNull((void *)&funcrUsed); - ptrRegReq = stackExtend = dataExtend = 0; + setToNull((void *)&_G.funcrUsed); + mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; /* if not register extentions then reduce number of registers */ if (options.regExtend) - nRegs = 13; + mcs51_nRegs = 13; else - nRegs = 8; + mcs51_nRegs = 8; /* change assignments this will remove some live ranges reducing some register pressure */ @@ -2273,16 +2279,16 @@ void assignRegisters (eBBlock **ebbs, int count) serialRegAssign(ebbs,count); /* if stack was extended then tell the user */ - if (stackExtend) { + if (_G.stackExtend) { /* werror(W_TOOMANY_SPILS,"stack", */ -/* stackExtend,currFunc->name,""); */ - stackExtend = 0 ; +/* _G.stackExtend,currFunc->name,""); */ + _G.stackExtend = 0 ; } - if (dataExtend) { + if (_G.dataExtend) { /* werror(W_TOOMANY_SPILS,"data space", */ -/* dataExtend,currFunc->name,""); */ - dataExtend = 0 ; +/* _G.dataExtend,currFunc->name,""); */ + _G.dataExtend = 0 ; } /* after that create the register mask @@ -2301,11 +2307,11 @@ void assignRegisters (eBBlock **ebbs, int count) gen51Code(ic); - /* free up any stackSpil locations allocated */ - applyToSet(stackSpil,deallocStackSpil); - slocNum = 0; - setToNull((void **)&stackSpil); - setToNull((void **)&spiltSet); + /* free up any _G.stackSpil locations allocated */ + applyToSet(_G.stackSpil,deallocStackSpil); + _G.slocNum = 0; + setToNull((void **)&_G.stackSpil); + setToNull((void **)&_G.spiltSet); /* mark all registers as free */ freeAllRegs(); diff --git a/src/z80/gen.c b/src/z80/gen.c index 41d9cdfc..f34803e4 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -1188,16 +1188,8 @@ static void genFunction (iCode *ic) emitcode("push", "bc"); emitcode("push", "de"); emitcode("push", "hl"); - } else { - /* if callee-save to be used for this function - then save the registers being used in this function */ - if (sym->calleeSave) { - /* Handled by ncsv/csv */ - } - else { - assert(0); - } } + /* PENDING: callee-save etc */ /* adjust the stack for the function */ emitcode("push", "de"); diff --git a/src/z80/main.c b/src/z80/main.c index c22fc0c9..280ffdd8 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -1,8 +1,39 @@ -#include "SDCCglobl.h" +#include "common.h" #include "main.h" +void z80_assignRegisters (eBBlock **ebbs, int count); + +static bool _z80_parseOptions(int *pargc, char **argv) +{ + return FALSE; +} + +static void _z80_finaliseOptions(void) +{ +} + +static void _z80_setDefaultOptions(void) +{ + options.genericPtr = 1; /* default on */ + options.nopeep = 1; + options.stackAuto = 1; + options.mainreturn = 1; + options.noregparms = 1; + /* first the options part */ + options.intlong_rent = 1; + + optimize.global_cse = 0; + optimize.label1 = 0; + optimize.label2 = 0; + optimize.label3 = 0; + optimize.label4 = 0; + optimize.loopInvariant = 0; + optimize.loopInduction = 0; +} + /* Globals */ -PROCESSOR_CONSTANTS port = { +PORT z80_port = { + "z80", "Zilog Z80", /* Target name */ { "as-z80", /* Assembler executable name */ @@ -23,23 +54,10 @@ PROCESSOR_CONSTANTS port = { /* Z80 has no native mul/div commands */ { 0 - } + }, + _z80_parseOptions, + _z80_finaliseOptions, + _z80_setDefaultOptions, + z80_assignRegisters, }; -bool x_parseOptions(char **argv, int *pargc) -{ - int i = *pargc; - bool fRecognised = FALSE; - - *pargc = i; - return fRecognised; -} - -void x_finaliseOptions(void) -{ -} - -void x_setDefaultOptions(void) -{ -} - diff --git a/src/z80/ralloc.c b/src/z80/ralloc.c index 17318289..62d33494 100644 --- a/src/z80/ralloc.c +++ b/src/z80/ralloc.c @@ -1913,7 +1913,7 @@ void packRegisters (eBBlock *ebp) /*-----------------------------------------------------------------*/ /* assignRegisters - assigns registers to each live range as need */ /*-----------------------------------------------------------------*/ -void assignRegisters (eBBlock **ebbs, int count) +void z80_assignRegisters (eBBlock **ebbs, int count) { iCode *ic; int i ; -- 2.47.2