1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
57 #include "SDCCpeeph.h"
62 static int labelOffset=0;
63 static int debug_verbose=1;
64 static int optimized_for_speed = 0;
66 /* max_key keeps track of the largest label number used in
67 a function. This is then used to adjust the label offset
68 for the next function.
71 unsigned int pic14aopLiteral (value *val, int offset);
72 const char *AopType(short type);
74 /* this is the down and dirty file with all kinds of
75 kludgy & hacky stuff. This is what it is all about
76 CODE GENERATION for a specific MCU . some of the
77 routines may be reusable, will have to see */
79 static char *zero = "#0x00";
80 static char *one = "#0x01";
81 static char *spname = "sp";
83 char *fReturnpic14[] = {"FSR","dph","b","a" };
84 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
85 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
86 static char **fReturn = fReturnpic14;
88 static char *accUse[] = {"a","b"};
90 //static short rbank = -1;
102 extern int pic14_ptrRegReq ;
103 extern int pic14_nRegs;
104 extern FILE *codeOutFile;
105 static void saverbank (int, iCode *,bool);
107 static lineNode *lineHead = NULL;
108 static lineNode *lineCurr = NULL;
110 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
111 0xE0, 0xC0, 0x80, 0x00};
112 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
113 0x07, 0x03, 0x01, 0x00};
117 /*-----------------------------------------------------------------*/
118 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
119 /* exponent of 2 is returned, otherwise -1 is */
121 /* note that this is similar to the function `powof2' in SDCCsymt */
125 /*-----------------------------------------------------------------*/
126 static int my_powof2 (unsigned long num)
129 if( (num & (num-1)) == 0) {
142 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
145 char lb[INITIAL_INLINEASM];
155 sprintf(lb,"%s\t",inst);
157 sprintf(lb,"%s",inst);
158 vsprintf(lb+(strlen(lb)),fmt,ap);
162 while (isspace(*lbp)) lbp++;
165 lineCurr = (lineCurr ?
166 connectLine(lineCurr,newLineNode(lb)) :
167 (lineHead = newLineNode(lb)));
168 lineCurr->isInline = _G.inLine;
169 lineCurr->isDebug = _G.debugLine;
171 addpCode2pBlock(pb,newpCodeCharP(lb));
177 static void emitpLabel(int key)
179 addpCode2pBlock(pb,newpCodeLabel(key));
182 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
186 addpCode2pBlock(pb,newpCode(poc,pcop));
188 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
191 void emitpcodeNULLop(PIC_OPCODE poc)
194 addpCode2pBlock(pb,newpCode(poc,NULL));
198 /*-----------------------------------------------------------------*/
199 /* pic14_emitcode - writes the code into a file : for now it is simple */
200 /*-----------------------------------------------------------------*/
201 void pic14_emitcode (char *inst,char *fmt, ...)
204 char lb[INITIAL_INLINEASM];
211 sprintf(lb,"%s\t",inst);
213 sprintf(lb,"%s",inst);
214 vsprintf(lb+(strlen(lb)),fmt,ap);
218 while (isspace(*lbp)) lbp++;
221 lineCurr = (lineCurr ?
222 connectLine(lineCurr,newLineNode(lb)) :
223 (lineHead = newLineNode(lb)));
224 lineCurr->isInline = _G.inLine;
225 lineCurr->isDebug = _G.debugLine;
228 addpCode2pBlock(pb,newpCodeCharP(lb));
234 /*-----------------------------------------------------------------*/
235 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
236 /*-----------------------------------------------------------------*/
237 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
239 bool r0iu = FALSE , r1iu = FALSE;
240 bool r0ou = FALSE , r1ou = FALSE;
242 /* the logic: if r0 & r1 used in the instruction
243 then we are in trouble otherwise */
245 /* first check if r0 & r1 are used by this
246 instruction, in which case we are in trouble */
247 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
248 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
253 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
254 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
256 /* if no usage of r0 then return it */
257 if (!r0iu && !r0ou) {
258 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
259 (*aopp)->type = AOP_R0;
261 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
264 /* if no usage of r1 then return it */
265 if (!r1iu && !r1ou) {
266 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
267 (*aopp)->type = AOP_R1;
269 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
272 /* now we know they both have usage */
273 /* if r0 not used in this instruction */
275 /* push it if not already pushed */
277 pic14_emitcode ("push","%s",
278 pic14_regWithIdx(R0_IDX)->dname);
282 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
283 (*aopp)->type = AOP_R0;
285 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
288 /* if r1 not used then */
291 /* push it if not already pushed */
293 pic14_emitcode ("push","%s",
294 pic14_regWithIdx(R1_IDX)->dname);
298 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
299 (*aopp)->type = AOP_R1;
300 return pic14_regWithIdx(R1_IDX);
304 /* I said end of world but not quite end of world yet */
305 /* if this is a result then we can push it on the stack*/
307 (*aopp)->type = AOP_STK;
311 /* other wise this is true end of the world */
312 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
313 "getFreePtr should never reach here");
317 /*-----------------------------------------------------------------*/
318 /* newAsmop - creates a new asmOp */
319 /*-----------------------------------------------------------------*/
320 asmop *newAsmop (short type)
324 aop = Safe_calloc(1,sizeof(asmop));
329 static void genSetDPTR(int n)
333 pic14_emitcode(";", "Select standard DPTR");
334 pic14_emitcode("mov", "dps, #0x00");
338 pic14_emitcode(";", "Select alternate DPTR");
339 pic14_emitcode("mov", "dps, #0x01");
343 /*-----------------------------------------------------------------*/
344 /* pointerCode - returns the code for a pointer type */
345 /*-----------------------------------------------------------------*/
346 static int pointerCode (sym_link *etype)
349 return PTR_TYPE(SPEC_OCLS(etype));
353 /*-----------------------------------------------------------------*/
354 /* aopForSym - for a true symbol */
355 /*-----------------------------------------------------------------*/
356 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
359 memmap *space= SPEC_OCLS(sym->etype);
361 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
362 /* if already has one */
366 /* assign depending on the storage class */
367 /* if it is on the stack or indirectly addressable */
368 /* space we need to assign either r0 or r1 to it */
369 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
370 sym->aop = aop = newAsmop(0);
371 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
372 aop->size = getSize(sym->type);
374 /* now assign the address of the variable to
375 the pointer register */
376 if (aop->type != AOP_STK) {
380 pic14_emitcode("push","acc");
382 pic14_emitcode("mov","a,_bp");
383 pic14_emitcode("add","a,#0x%02x",
385 ((char)(sym->stack - _G.nRegsSaved )) :
386 ((char)sym->stack)) & 0xff);
387 pic14_emitcode("mov","%s,a",
388 aop->aopu.aop_ptr->name);
391 pic14_emitcode("pop","acc");
393 pic14_emitcode("mov","%s,#%s",
394 aop->aopu.aop_ptr->name,
396 aop->paged = space->paged;
398 aop->aopu.aop_stk = sym->stack;
402 if (sym->onStack && options.stack10bit)
404 /* It's on the 10 bit stack, which is located in
408 //DEBUGpic14_emitcode(";","%d",__LINE__);
411 pic14_emitcode("push","acc");
413 pic14_emitcode("mov","a,_bp");
414 pic14_emitcode("add","a,#0x%02x",
416 ((char)(sym->stack - _G.nRegsSaved )) :
417 ((char)sym->stack)) & 0xff);
420 pic14_emitcode ("mov","dpx1,#0x40");
421 pic14_emitcode ("mov","dph1,#0x00");
422 pic14_emitcode ("mov","dpl1, a");
426 pic14_emitcode("pop","acc");
428 sym->aop = aop = newAsmop(AOP_DPTR2);
429 aop->size = getSize(sym->type);
433 //DEBUGpic14_emitcode(";","%d",__LINE__);
434 /* if in bit space */
435 if (IN_BITSPACE(space)) {
436 sym->aop = aop = newAsmop (AOP_CRY);
437 aop->aopu.aop_dir = sym->rname ;
438 aop->size = getSize(sym->type);
439 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
442 /* if it is in direct space */
443 if (IN_DIRSPACE(space)) {
444 sym->aop = aop = newAsmop (AOP_DIR);
445 aop->aopu.aop_dir = sym->rname ;
446 aop->size = getSize(sym->type);
447 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
451 /* special case for a function */
452 if (IS_FUNC(sym->type)) {
453 sym->aop = aop = newAsmop(AOP_IMMD);
454 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
455 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
456 strcpy(aop->aopu.aop_immd,sym->rname);
457 aop->size = FPTRSIZE;
462 /* only remaining is far space */
463 /* in which case DPTR gets the address */
464 sym->aop = aop = newAsmop(AOP_DPTR);
465 pic14_emitcode ("mov","dptr,#%s", sym->rname);
466 aop->size = getSize(sym->type);
468 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
469 /* if it is in code space */
470 if (IN_CODESPACE(space))
476 /*-----------------------------------------------------------------*/
477 /* aopForRemat - rematerialzes an object */
478 /*-----------------------------------------------------------------*/
479 static asmop *aopForRemat (symbol *sym)
481 iCode *ic = sym->rematiCode;
482 asmop *aop = newAsmop(AOP_IMMD);
484 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
487 val += (int) operandLitValue(IC_RIGHT(ic));
488 else if (ic->op == '-')
489 val -= (int) operandLitValue(IC_RIGHT(ic));
493 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
497 sprintf(buffer,"(%s %c 0x%04x)",
498 OP_SYMBOL(IC_LEFT(ic))->rname,
499 val >= 0 ? '+' : '-',
502 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
504 //DEBUGpic14_emitcode(";","%s",buffer);
505 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
506 strcpy(aop->aopu.aop_immd,buffer);
510 /*-----------------------------------------------------------------*/
511 /* regsInCommon - two operands have some registers in common */
512 /*-----------------------------------------------------------------*/
513 static bool regsInCommon (operand *op1, operand *op2)
518 /* if they have registers in common */
519 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
522 sym1 = OP_SYMBOL(op1);
523 sym2 = OP_SYMBOL(op2);
525 if (sym1->nRegs == 0 || sym2->nRegs == 0)
528 for (i = 0 ; i < sym1->nRegs ; i++) {
533 for (j = 0 ; j < sym2->nRegs ;j++ ) {
537 if (sym2->regs[j] == sym1->regs[i])
545 /*-----------------------------------------------------------------*/
546 /* operandsEqu - equivalent */
547 /*-----------------------------------------------------------------*/
548 static bool operandsEqu ( operand *op1, operand *op2)
552 /* if they not symbols */
553 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
556 sym1 = OP_SYMBOL(op1);
557 sym2 = OP_SYMBOL(op2);
559 /* if both are itemps & one is spilt
560 and the other is not then false */
561 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
562 sym1->isspilt != sym2->isspilt )
565 /* if they are the same */
569 if (strcmp(sym1->rname,sym2->rname) == 0)
573 /* if left is a tmp & right is not */
577 (sym1->usl.spillLoc == sym2))
584 (sym2->usl.spillLoc == sym1))
590 /*-----------------------------------------------------------------*/
591 /* pic14_sameRegs - two asmops have the same registers */
592 /*-----------------------------------------------------------------*/
593 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
600 if (aop1->type != AOP_REG ||
601 aop2->type != AOP_REG )
604 if (aop1->size != aop2->size )
607 for (i = 0 ; i < aop1->size ; i++ )
608 if (aop1->aopu.aop_reg[i] !=
609 aop2->aopu.aop_reg[i] )
615 /*-----------------------------------------------------------------*/
616 /* aopOp - allocates an asmop for an operand : */
617 /*-----------------------------------------------------------------*/
618 void aopOp (operand *op, iCode *ic, bool result)
627 DEBUGpic14_emitcode(";","%d",__LINE__);
628 /* if this a literal */
629 if (IS_OP_LITERAL(op)) {
630 op->aop = aop = newAsmop(AOP_LIT);
631 aop->aopu.aop_lit = op->operand.valOperand;
632 aop->size = getSize(operandType(op));
633 DEBUGpic14_emitcode(";","%d, lit = %d",__LINE__,aop->aopu.aop_lit);
637 /* if already has a asmop then continue */
641 /* if the underlying symbol has a aop */
642 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
643 DEBUGpic14_emitcode(";","%d",__LINE__);
644 op->aop = OP_SYMBOL(op)->aop;
648 /* if this is a true symbol */
649 if (IS_TRUE_SYMOP(op)) {
650 DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
651 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
655 /* this is a temporary : this has
661 e) can be a return use only */
666 /* if the type is a conditional */
667 if (sym->regType == REG_CND) {
668 DEBUGpic14_emitcode(";","%d",__LINE__);
669 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
674 /* if it is spilt then two situations
676 b) has a spill location */
677 if (sym->isspilt || sym->nRegs == 0) {
679 DEBUGpic14_emitcode(";","%d",__LINE__);
680 /* rematerialize it NOW */
682 sym->aop = op->aop = aop =
684 aop->size = getSize(sym->type);
685 DEBUGpic14_emitcode(";","%d",__LINE__);
691 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
692 aop->size = getSize(sym->type);
693 for ( i = 0 ; i < 2 ; i++ )
694 aop->aopu.aop_str[i] = accUse[i];
695 DEBUGpic14_emitcode(";","%d",__LINE__);
701 aop = op->aop = sym->aop = newAsmop(AOP_STR);
702 aop->size = getSize(sym->type);
703 for ( i = 0 ; i < fReturnSizePic ; i++ )
704 aop->aopu.aop_str[i] = fReturn[i];
705 DEBUGpic14_emitcode(";","%d",__LINE__);
709 /* else spill location */
710 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
711 sym->aop = op->aop = aop =
712 aopForSym(ic,sym->usl.spillLoc,result);
713 aop->size = getSize(sym->type);
717 /* must be in a register */
718 sym->aop = op->aop = aop = newAsmop(AOP_REG);
719 aop->size = sym->nRegs;
720 for ( i = 0 ; i < sym->nRegs ;i++)
721 aop->aopu.aop_reg[i] = sym->regs[i];
724 /*-----------------------------------------------------------------*/
725 /* freeAsmop - free up the asmop given to an operand */
726 /*----------------------------------------------------------------*/
727 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
744 /* depending on the asmop type only three cases need work AOP_RO
745 , AOP_R1 && AOP_STK */
750 pic14_emitcode ("pop","ar0");
754 bitVectUnSetBit(ic->rUsed,R0_IDX);
760 pic14_emitcode ("pop","ar1");
764 bitVectUnSetBit(ic->rUsed,R1_IDX);
770 int stk = aop->aopu.aop_stk + aop->size;
771 bitVectUnSetBit(ic->rUsed,R0_IDX);
772 bitVectUnSetBit(ic->rUsed,R1_IDX);
774 getFreePtr(ic,&aop,FALSE);
776 if (options.stack10bit)
778 /* I'm not sure what to do here yet... */
781 "*** Warning: probably generating bad code for "
782 "10 bit stack mode.\n");
786 pic14_emitcode ("mov","a,_bp");
787 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
788 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
790 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
794 pic14_emitcode("pop","acc");
795 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
797 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
800 freeAsmop(op,NULL,ic,TRUE);
802 pic14_emitcode("pop","ar0");
807 pic14_emitcode("pop","ar1");
814 /* all other cases just dealloc */
818 OP_SYMBOL(op)->aop = NULL;
819 /* if the symbol has a spill */
821 SPIL_LOC(op)->aop = NULL;
826 /*-----------------------------------------------------------------*/
827 /* aopGet - for fetching value of the aop */
828 /*-----------------------------------------------------------------*/
829 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
834 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
835 /* offset is greater than
837 if (offset > (aop->size - 1) &&
838 aop->type != AOP_LIT)
841 /* depending on type */
846 DEBUGpic14_emitcode(";","%d",__LINE__);
847 /* if we need to increment it */
848 while (offset > aop->coff) {
849 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
853 while (offset < aop->coff) {
854 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
860 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
861 return (dname ? "acc" : "a");
863 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
864 rs = Safe_calloc(1,strlen(s)+1);
870 DEBUGpic14_emitcode(";","%d",__LINE__);
871 if (aop->type == AOP_DPTR2)
876 while (offset > aop->coff) {
877 pic14_emitcode ("inc","dptr");
881 while (offset < aop->coff) {
882 pic14_emitcode("lcall","__decdptr");
888 pic14_emitcode("clr","a");
889 pic14_emitcode("movc","a,@a+dptr");
892 pic14_emitcode("movx","a,@dptr");
895 if (aop->type == AOP_DPTR2)
900 return (dname ? "acc" : "a");
904 DEBUGpic14_emitcode(";","%d",__LINE__);
906 sprintf (s,"%s",aop->aopu.aop_immd);
909 sprintf(s,"(%s >> %d)",
915 rs = Safe_calloc(1,strlen(s)+1);
921 sprintf(s,"(%s + %d)",
925 sprintf(s,"%s",aop->aopu.aop_dir);
926 rs = Safe_calloc(1,strlen(s)+1);
931 DEBUGpic14_emitcode(";","%d",__LINE__);
933 return aop->aopu.aop_reg[offset]->dname;
935 return aop->aopu.aop_reg[offset]->name;
938 pic14_emitcode(";","%d",__LINE__);
939 //pic14_emitcode("clr","a");
940 //pic14_emitcode("mov","c,%s",aop->aopu.aop_dir);
941 //pic14_emitcode("rlc","a") ;
942 //return (dname ? "acc" : "a");
943 return aop->aopu.aop_dir;
946 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
947 //if (!offset && dname)
949 //return aop->aopu.aop_str[offset];
950 return "AOP_accumulator_bug";
953 DEBUGpic14_emitcode(";","%d",__LINE__);
954 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
955 rs = Safe_calloc(1,strlen(s)+1);
960 DEBUGpic14_emitcode(";","%d",__LINE__);
962 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
966 return aop->aopu.aop_str[offset];
970 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
971 "aopget got unsupported aop->type");
975 /*-----------------------------------------------------------------*/
976 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
977 /*-----------------------------------------------------------------*/
978 pCodeOp *popGetLabel(unsigned int key)
981 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
986 return newpCodeOpLabel(key+100+labelOffset);
989 /*-----------------------------------------------------------------*/
990 /* popCopyReg - copy a pcode operator */
991 /*-----------------------------------------------------------------*/
992 pCodeOp *popCopyReg(pCodeOpReg *pc)
996 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
997 pcor->pcop.type = pc->pcop.type;
998 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
999 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1001 pcor->rIdx = pc->rIdx;
1007 /*-----------------------------------------------------------------*/
1008 /* popCopy - copy a pcode operator */
1009 /*-----------------------------------------------------------------*/
1010 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1014 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1015 pcop->type = PO_BIT;
1016 if(!(pcop->name = Safe_strdup(pc->name)))
1017 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1018 ((pCodeOpBit *)pcop)->bit = bitval;
1020 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1025 /*-----------------------------------------------------------------*/
1026 /* popGet - asm operator to pcode operator conversion */
1027 /*-----------------------------------------------------------------*/
1028 pCodeOp *popGetLit(unsigned int lit)
1031 return newpCodeOpLit(lit);
1035 /*-----------------------------------------------------------------*/
1036 /* popGet - asm operator to pcode operator conversion */
1037 /*-----------------------------------------------------------------*/
1038 pCodeOp *popGetWithString(char *str)
1044 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1048 pcop = newpCodeOp(str,PO_STR);
1053 pCodeOp *popRegFromString(char *str)
1056 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1057 pcop->type = PO_GPR_REGISTER;
1059 PCOR(pcop)->rIdx = -1;
1060 PCOR(pcop)->r = NULL;
1062 DEBUGpic14_emitcode(";","%d",__LINE__);
1063 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1068 /*-----------------------------------------------------------------*/
1069 /* popGet - asm operator to pcode operator conversion */
1070 /*-----------------------------------------------------------------*/
1071 pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
1078 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1079 /* offset is greater than
1082 if (offset > (aop->size - 1) &&
1083 aop->type != AOP_LIT)
1084 return NULL; //zero;
1086 /* depending on type */
1087 switch (aop->type) {
1094 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1095 //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1096 //pcop->type = PO_SFR_REGISTER;
1098 //PCOR(pcop)->rIdx = -1;
1099 //PCOR(pcop)->r = NULL;
1100 // Really nasty hack to check for temporary registers
1102 //pcop->name = Safe_strdup("BAD_REGISTER");
1107 DEBUGpic14_emitcode(";","%d",__LINE__);
1108 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1109 pcop->type = PO_IMMEDIATE;
1111 sprintf (s,"%s",aop->aopu.aop_immd);
1114 sprintf(s,"(%s >> %d)",
1119 aop->aopu.aop_immd);
1120 pcop->name = Safe_calloc(1,strlen(s)+1);
1121 strcpy(pcop->name,s);
1125 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1126 pcop->type = PO_DIR;
1128 sprintf(s,"(%s + %d)",
1132 sprintf(s,"%s",aop->aopu.aop_dir);
1133 pcop->name = Safe_calloc(1,strlen(s)+1);
1134 strcpy(pcop->name,s);
1139 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1141 DEBUGpic14_emitcode(";","%d",__LINE__);
1143 pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1145 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1146 //pcop->type = PO_GPR_REGISTER;
1147 PCOR(pcop)->rIdx = rIdx;
1148 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1149 pcop->type = PCOR(pcop)->r->pc_type;
1152 rs = aop->aopu.aop_reg[offset]->dname;
1154 rs = aop->aopu.aop_reg[offset]->name;
1156 DEBUGpic14_emitcode(";","%d %s",__LINE__,rs);
1162 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1166 DEBUGpic14_emitcode(";","%d",__LINE__);
1167 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1170 DEBUGpic14_emitcode(";","%d",__LINE__);
1172 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1173 pcop->type = PO_STR;
1175 //aop->coff = offset ;
1176 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1177 sprintf(s,"%s","acc");
1179 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1180 pcop->name = Safe_calloc(1,strlen(s)+1);
1181 strcpy(pcop->name,s);
1186 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1187 "popGet got unsupported aop->type");
1190 /*-----------------------------------------------------------------*/
1191 /* aopPut - puts a string for a aop */
1192 /*-----------------------------------------------------------------*/
1193 void aopPut (asmop *aop, char *s, int offset)
1198 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1200 if (aop->size && offset > ( aop->size - 1)) {
1201 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1202 "aopPut got offset > aop->size");
1206 /* will assign value to value */
1207 /* depending on where it is ofcourse */
1208 switch (aop->type) {
1211 sprintf(d,"(%s + %d)",
1212 aop->aopu.aop_dir,offset);
1214 sprintf(d,"%s",aop->aopu.aop_dir);
1217 DEBUGpic14_emitcode(";","%d",__LINE__);
1219 pic14_emitcode("movf","%s,w",s);
1220 pic14_emitcode("movwf","%s",d);
1223 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1224 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1231 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1232 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1235 strcmp(s,"r0") == 0 ||
1236 strcmp(s,"r1") == 0 ||
1237 strcmp(s,"r2") == 0 ||
1238 strcmp(s,"r3") == 0 ||
1239 strcmp(s,"r4") == 0 ||
1240 strcmp(s,"r5") == 0 ||
1241 strcmp(s,"r6") == 0 ||
1242 strcmp(s,"r7") == 0 )
1243 pic14_emitcode("mov","%s,%s ; %d",
1244 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1249 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1251 pic14_emitcode("movwf","%s",
1252 aop->aopu.aop_reg[offset]->name);
1255 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1256 pcop->type = PO_GPR_REGISTER;
1258 PCOR(pcop)->rIdx = -1;
1259 PCOR(pcop)->r = NULL;
1261 DEBUGpic14_emitcode(";","%d",__LINE__);
1262 pcop->name = Safe_strdup(s);
1263 emitpcode(POC_MOVFW,pcop);
1265 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1273 if (aop->type == AOP_DPTR2)
1279 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1280 "aopPut writting to code space");
1284 while (offset > aop->coff) {
1286 pic14_emitcode ("inc","dptr");
1289 while (offset < aop->coff) {
1291 pic14_emitcode("lcall","__decdptr");
1296 /* if not in accumulater */
1299 pic14_emitcode ("movx","@dptr,a");
1301 if (aop->type == AOP_DPTR2)
1309 while (offset > aop->coff) {
1311 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1313 while (offset < aop->coff) {
1315 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1321 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1326 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1328 if (strcmp(s,"r0") == 0 ||
1329 strcmp(s,"r1") == 0 ||
1330 strcmp(s,"r2") == 0 ||
1331 strcmp(s,"r3") == 0 ||
1332 strcmp(s,"r4") == 0 ||
1333 strcmp(s,"r5") == 0 ||
1334 strcmp(s,"r6") == 0 ||
1335 strcmp(s,"r7") == 0 ) {
1337 sprintf(buffer,"a%s",s);
1338 pic14_emitcode("mov","@%s,%s",
1339 aop->aopu.aop_ptr->name,buffer);
1341 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1346 if (strcmp(s,"a") == 0)
1347 pic14_emitcode("push","acc");
1349 pic14_emitcode("push","%s",s);
1354 /* if bit variable */
1355 if (!aop->aopu.aop_dir) {
1356 pic14_emitcode("clr","a");
1357 pic14_emitcode("rlc","a");
1360 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1363 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1366 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1368 lbl = newiTempLabel(NULL);
1370 if (strcmp(s,"a")) {
1373 pic14_emitcode("clr","c");
1374 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1375 pic14_emitcode("cpl","c");
1376 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1377 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1384 if (strcmp(aop->aopu.aop_str[offset],s))
1385 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1390 if (!offset && (strcmp(s,"acc") == 0))
1393 if (strcmp(aop->aopu.aop_str[offset],s))
1394 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1398 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1399 "aopPut got unsupported aop->type");
1405 /*-----------------------------------------------------------------*/
1406 /* reAdjustPreg - points a register back to where it should */
1407 /*-----------------------------------------------------------------*/
1408 static void reAdjustPreg (asmop *aop)
1412 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1414 if ((size = aop->size) <= 1)
1417 switch (aop->type) {
1421 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1425 if (aop->type == AOP_DPTR2)
1431 pic14_emitcode("lcall","__decdptr");
1434 if (aop->type == AOP_DPTR2)
1444 /*-----------------------------------------------------------------*/
1445 /* genNotFloat - generates not for float operations */
1446 /*-----------------------------------------------------------------*/
1447 static void genNotFloat (operand *op, operand *res)
1453 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1454 /* we will put 127 in the first byte of
1456 aopPut(AOP(res),"#127",0);
1457 size = AOP_SIZE(op) - 1;
1460 l = aopGet(op->aop,offset++,FALSE,FALSE);
1464 pic14_emitcode("orl","a,%s",
1466 offset++,FALSE,FALSE));
1468 tlbl = newiTempLabel(NULL);
1470 tlbl = newiTempLabel(NULL);
1471 aopPut(res->aop,one,1);
1472 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1473 aopPut(res->aop,zero,1);
1474 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1476 size = res->aop->size - 2;
1478 /* put zeros in the rest */
1480 aopPut(res->aop,zero,offset++);
1484 /*-----------------------------------------------------------------*/
1485 /* opIsGptr: returns non-zero if the passed operand is */
1486 /* a generic pointer type. */
1487 /*-----------------------------------------------------------------*/
1488 static int opIsGptr(operand *op)
1490 sym_link *type = operandType(op);
1492 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1493 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1501 /*-----------------------------------------------------------------*/
1502 /* pic14_getDataSize - get the operand data size */
1503 /*-----------------------------------------------------------------*/
1504 int pic14_getDataSize(operand *op)
1506 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1509 return AOP_SIZE(op);
1511 // tsd- in the pic port, the genptr size is 1, so this code here
1512 // fails. ( in the 8051 port, the size was 4).
1515 size = AOP_SIZE(op);
1516 if (size == GPTRSIZE)
1518 sym_link *type = operandType(op);
1519 if (IS_GENPTR(type))
1521 /* generic pointer; arithmetic operations
1522 * should ignore the high byte (pointer type).
1525 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1532 /*-----------------------------------------------------------------*/
1533 /* pic14_outAcc - output Acc */
1534 /*-----------------------------------------------------------------*/
1535 void pic14_outAcc(operand *result)
1538 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1539 size = pic14_getDataSize(result);
1541 aopPut(AOP(result),"a",0);
1544 /* unsigned or positive */
1546 aopPut(AOP(result),zero,offset++);
1551 /*-----------------------------------------------------------------*/
1552 /* pic14_outBitC - output a bit C */
1553 /*-----------------------------------------------------------------*/
1554 void pic14_outBitC(operand *result)
1557 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1558 /* if the result is bit */
1559 if (AOP_TYPE(result) == AOP_CRY)
1560 aopPut(AOP(result),"c",0);
1562 pic14_emitcode("clr","a ; %d", __LINE__);
1563 pic14_emitcode("rlc","a");
1564 pic14_outAcc(result);
1568 /*-----------------------------------------------------------------*/
1569 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1570 /*-----------------------------------------------------------------*/
1571 void pic14_toBoolean(operand *oper)
1573 int size = AOP_SIZE(oper) - 1;
1576 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1578 if ( AOP_TYPE(oper) != AOP_ACC) {
1579 emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1580 pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1583 pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1584 emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1589 /*-----------------------------------------------------------------*/
1590 /* genNot - generate code for ! operation */
1591 /*-----------------------------------------------------------------*/
1592 static void genNot (iCode *ic)
1595 sym_link *optype = operandType(IC_LEFT(ic));
1597 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1598 /* assign asmOps to operand & result */
1599 aopOp (IC_LEFT(ic),ic,FALSE);
1600 aopOp (IC_RESULT(ic),ic,TRUE);
1602 /* if in bit space then a special case */
1603 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1604 pic14_emitcode("movlw","1<<%s");
1605 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1606 //pic14_emitcode("cpl","c");
1607 //pic14_outBitC(IC_RESULT(ic));
1611 /* if type float then do float */
1612 if (IS_FLOAT(optype)) {
1613 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1617 pic14_toBoolean(IC_LEFT(ic));
1619 tlbl = newiTempLabel(NULL);
1620 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1621 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1622 pic14_outBitC(IC_RESULT(ic));
1625 /* release the aops */
1626 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1627 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1631 /*-----------------------------------------------------------------*/
1632 /* genCpl - generate code for complement */
1633 /*-----------------------------------------------------------------*/
1634 static void genCpl (iCode *ic)
1640 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1641 /* assign asmOps to operand & result */
1642 aopOp (IC_LEFT(ic),ic,FALSE);
1643 aopOp (IC_RESULT(ic),ic,TRUE);
1645 /* if both are in bit space then
1647 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1648 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1650 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1651 pic14_emitcode("cpl","c");
1652 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1656 size = AOP_SIZE(IC_RESULT(ic));
1658 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1660 pic14_emitcode("cpl","a");
1661 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1666 /* release the aops */
1667 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1668 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1671 /*-----------------------------------------------------------------*/
1672 /* genUminusFloat - unary minus for floating points */
1673 /*-----------------------------------------------------------------*/
1674 static void genUminusFloat(operand *op,operand *result)
1676 int size ,offset =0 ;
1679 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1680 /* for this we just need to flip the
1681 first it then copy the rest in place */
1682 size = AOP_SIZE(op) - 1;
1683 l = aopGet(AOP(op),3,FALSE,FALSE);
1687 pic14_emitcode("cpl","acc.7");
1688 aopPut(AOP(result),"a",3);
1692 aopGet(AOP(op),offset,FALSE,FALSE),
1698 /*-----------------------------------------------------------------*/
1699 /* genUminus - unary minus code generation */
1700 /*-----------------------------------------------------------------*/
1701 static void genUminus (iCode *ic)
1704 sym_link *optype, *rtype;
1707 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1709 aopOp(IC_LEFT(ic),ic,FALSE);
1710 aopOp(IC_RESULT(ic),ic,TRUE);
1712 /* if both in bit space then special
1714 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1715 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1717 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1718 pic14_emitcode("cpl","c");
1719 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1723 optype = operandType(IC_LEFT(ic));
1724 rtype = operandType(IC_RESULT(ic));
1726 /* if float then do float stuff */
1727 if (IS_FLOAT(optype)) {
1728 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1732 /* otherwise subtract from zero */
1733 size = AOP_SIZE(IC_LEFT(ic));
1737 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1738 if (!strcmp(l,"a")) {
1739 pic14_emitcode("cpl","a");
1740 pic14_emitcode("inc","a");
1742 pic14_emitcode("clr","a");
1743 pic14_emitcode("subb","a,%s",l);
1745 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1748 /* if any remaining bytes in the result */
1749 /* we just need to propagate the sign */
1750 if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1751 pic14_emitcode("rlc","a");
1752 pic14_emitcode("subb","a,acc");
1754 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1758 /* release the aops */
1759 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1760 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1763 /*-----------------------------------------------------------------*/
1764 /* saveRegisters - will look for a call and save the registers */
1765 /*-----------------------------------------------------------------*/
1766 static void saveRegisters(iCode *lic)
1773 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1775 for (ic = lic ; ic ; ic = ic->next)
1776 if (ic->op == CALL || ic->op == PCALL)
1780 fprintf(stderr,"found parameter push with no function call\n");
1784 /* if the registers have been saved already then
1786 if (ic->regsSaved || (OP_SYMBOL(IC_LEFT(ic))->calleeSave))
1789 /* find the registers in use at this time
1790 and push them away to safety */
1791 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1795 if (options.useXstack) {
1796 if (bitVectBitValue(rsave,R0_IDX))
1797 pic14_emitcode("mov","b,r0");
1798 pic14_emitcode("mov","r0,%s",spname);
1799 for (i = 0 ; i < pic14_nRegs ; i++) {
1800 if (bitVectBitValue(rsave,i)) {
1802 pic14_emitcode("mov","a,b");
1804 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1805 pic14_emitcode("movx","@r0,a");
1806 pic14_emitcode("inc","r0");
1809 pic14_emitcode("mov","%s,r0",spname);
1810 if (bitVectBitValue(rsave,R0_IDX))
1811 pic14_emitcode("mov","r0,b");
1813 for (i = 0 ; i < pic14_nRegs ; i++) {
1814 if (bitVectBitValue(rsave,i))
1815 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1818 detype = getSpec(operandType(IC_LEFT(ic)));
1820 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
1821 IS_ISR(currFunc->etype) &&
1824 saverbank(SPEC_BANK(detype),ic,TRUE);
1827 /*-----------------------------------------------------------------*/
1828 /* unsaveRegisters - pop the pushed registers */
1829 /*-----------------------------------------------------------------*/
1830 static void unsaveRegisters (iCode *ic)
1835 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1836 /* find the registers in use at this time
1837 and push them away to safety */
1838 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1841 if (options.useXstack) {
1842 pic14_emitcode("mov","r0,%s",spname);
1843 for (i = pic14_nRegs ; i >= 0 ; i--) {
1844 if (bitVectBitValue(rsave,i)) {
1845 pic14_emitcode("dec","r0");
1846 pic14_emitcode("movx","a,@r0");
1848 pic14_emitcode("mov","b,a");
1850 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1854 pic14_emitcode("mov","%s,r0",spname);
1855 if (bitVectBitValue(rsave,R0_IDX))
1856 pic14_emitcode("mov","r0,b");
1858 for (i = pic14_nRegs ; i >= 0 ; i--) {
1859 if (bitVectBitValue(rsave,i))
1860 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1866 /*-----------------------------------------------------------------*/
1868 /*-----------------------------------------------------------------*/
1869 static void pushSide(operand * oper, int size)
1872 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1874 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1875 if (AOP_TYPE(oper) != AOP_REG &&
1876 AOP_TYPE(oper) != AOP_DIR &&
1878 pic14_emitcode("mov","a,%s",l);
1879 pic14_emitcode("push","acc");
1881 pic14_emitcode("push","%s",l);
1885 /*-----------------------------------------------------------------*/
1886 /* assignResultValue - */
1887 /*-----------------------------------------------------------------*/
1888 static void assignResultValue(operand * oper)
1891 int size = AOP_SIZE(oper);
1893 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1895 // The last byte in the assignment is in W
1896 aopPut(AOP(oper),"W",size-1);
1900 aopPut(AOP(oper),fReturn[offset],offset);
1908 /*-----------------------------------------------------------------*/
1909 /* genXpush - pushes onto the external stack */
1910 /*-----------------------------------------------------------------*/
1911 static void genXpush (iCode *ic)
1913 asmop *aop = newAsmop(0);
1915 int size,offset = 0;
1917 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1918 aopOp(IC_LEFT(ic),ic,FALSE);
1919 r = getFreePtr(ic,&aop,FALSE);
1922 pic14_emitcode("mov","%s,_spx",r->name);
1924 size = AOP_SIZE(IC_LEFT(ic));
1927 char *l = aopGet(AOP(IC_LEFT(ic)),
1928 offset++,FALSE,FALSE);
1930 pic14_emitcode("movx","@%s,a",r->name);
1931 pic14_emitcode("inc","%s",r->name);
1936 pic14_emitcode("mov","_spx,%s",r->name);
1938 freeAsmop(NULL,aop,ic,TRUE);
1939 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
1942 /*-----------------------------------------------------------------*/
1943 /* genIpush - genrate code for pushing this gets a little complex */
1944 /*-----------------------------------------------------------------*/
1945 static void genIpush (iCode *ic)
1947 int size, offset = 0 ;
1951 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1952 /* if this is not a parm push : ie. it is spill push
1953 and spill push is always done on the local stack */
1954 if (!ic->parmPush) {
1956 /* and the item is spilt then do nothing */
1957 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
1960 aopOp(IC_LEFT(ic),ic,FALSE);
1961 size = AOP_SIZE(IC_LEFT(ic));
1962 /* push it on the stack */
1964 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1969 pic14_emitcode("push","%s",l);
1974 /* this is a paramter push: in this case we call
1975 the routine to find the call and save those
1976 registers that need to be saved */
1979 /* if use external stack then call the external
1980 stack pushing routine */
1981 if (options.useXstack) {
1986 /* then do the push */
1987 aopOp(IC_LEFT(ic),ic,FALSE);
1990 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
1991 size = AOP_SIZE(IC_LEFT(ic));
1994 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1995 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
1996 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
1998 pic14_emitcode("mov","a,%s",l);
1999 pic14_emitcode("push","acc");
2001 pic14_emitcode("push","%s",l);
2004 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2007 /*-----------------------------------------------------------------*/
2008 /* genIpop - recover the registers: can happen only for spilling */
2009 /*-----------------------------------------------------------------*/
2010 static void genIpop (iCode *ic)
2015 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2016 /* if the temp was not pushed then */
2017 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2020 aopOp(IC_LEFT(ic),ic,FALSE);
2021 size = AOP_SIZE(IC_LEFT(ic));
2024 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2027 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2030 /*-----------------------------------------------------------------*/
2031 /* unsaverbank - restores the resgister bank from stack */
2032 /*-----------------------------------------------------------------*/
2033 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2039 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2041 if (options.useXstack) {
2043 r = getFreePtr(ic,&aop,FALSE);
2046 pic14_emitcode("mov","%s,_spx",r->name);
2047 pic14_emitcode("movx","a,@%s",r->name);
2048 pic14_emitcode("mov","psw,a");
2049 pic14_emitcode("dec","%s",r->name);
2052 pic14_emitcode ("pop","psw");
2055 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2056 if (options.useXstack) {
2057 pic14_emitcode("movx","a,@%s",r->name);
2058 //pic14_emitcode("mov","(%s+%d),a",
2059 // regspic14[i].base,8*bank+regspic14[i].offset);
2060 pic14_emitcode("dec","%s",r->name);
2063 pic14_emitcode("pop",""); //"(%s+%d)",
2064 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2067 if (options.useXstack) {
2069 pic14_emitcode("mov","_spx,%s",r->name);
2070 freeAsmop(NULL,aop,ic,TRUE);
2075 /*-----------------------------------------------------------------*/
2076 /* saverbank - saves an entire register bank on the stack */
2077 /*-----------------------------------------------------------------*/
2078 static void saverbank (int bank, iCode *ic, bool pushPsw)
2084 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2085 if (options.useXstack) {
2088 r = getFreePtr(ic,&aop,FALSE);
2089 pic14_emitcode("mov","%s,_spx",r->name);
2093 for (i = 0 ; i < pic14_nRegs ;i++) {
2094 if (options.useXstack) {
2095 pic14_emitcode("inc","%s",r->name);
2096 //pic14_emitcode("mov","a,(%s+%d)",
2097 // regspic14[i].base,8*bank+regspic14[i].offset);
2098 pic14_emitcode("movx","@%s,a",r->name);
2100 pic14_emitcode("push","");// "(%s+%d)",
2101 //regspic14[i].base,8*bank+regspic14[i].offset);
2105 if (options.useXstack) {
2106 pic14_emitcode("mov","a,psw");
2107 pic14_emitcode("movx","@%s,a",r->name);
2108 pic14_emitcode("inc","%s",r->name);
2109 pic14_emitcode("mov","_spx,%s",r->name);
2110 freeAsmop (NULL,aop,ic,TRUE);
2113 pic14_emitcode("push","psw");
2115 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2121 /*-----------------------------------------------------------------*/
2122 /* genCall - generates a call statement */
2123 /*-----------------------------------------------------------------*/
2124 static void genCall (iCode *ic)
2128 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2130 /* if caller saves & we have not saved then */
2134 /* if we are calling a function that is not using
2135 the same register bank then we need to save the
2136 destination registers on the stack */
2137 detype = getSpec(operandType(IC_LEFT(ic)));
2139 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
2140 IS_ISR(currFunc->etype) &&
2143 saverbank(SPEC_BANK(detype),ic,TRUE);
2145 /* if send set is not empty the assign */
2149 for (sic = setFirstItem(_G.sendSet) ; sic ;
2150 sic = setNextItem(_G.sendSet)) {
2151 int size, offset = 0;
2153 aopOp(IC_LEFT(sic),sic,FALSE);
2154 size = AOP_SIZE(IC_LEFT(sic));
2156 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2158 DEBUGpic14_emitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
2160 if (strcmp(l,fReturn[offset])) {
2162 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2163 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2164 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2165 //pic14_emitcode("movlw","%s",l);
2167 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2168 //pic14_emitcode("movf","%s,w",l);
2170 // The last one is passed in W
2172 pic14_emitcode("movwf","%s",fReturn[offset]);
2176 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2181 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2182 OP_SYMBOL(IC_LEFT(ic))->rname :
2183 OP_SYMBOL(IC_LEFT(ic))->name));
2185 pic14_emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2186 OP_SYMBOL(IC_LEFT(ic))->rname :
2187 OP_SYMBOL(IC_LEFT(ic))->name));
2189 /* if we need assign a result value */
2190 if ((IS_ITEMP(IC_RESULT(ic)) &&
2191 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2192 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2193 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2196 aopOp(IC_RESULT(ic),ic,FALSE);
2199 assignResultValue(IC_RESULT(ic));
2201 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2204 /* adjust the stack for parameters if
2206 if (ic->parmBytes) {
2208 if (ic->parmBytes > 3) {
2209 pic14_emitcode("mov","a,%s",spname);
2210 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2211 pic14_emitcode("mov","%s,a",spname);
2213 for ( i = 0 ; i < ic->parmBytes ;i++)
2214 pic14_emitcode("dec","%s",spname);
2218 /* if register bank was saved then pop them */
2220 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2222 /* if we hade saved some registers then unsave them */
2223 if (ic->regsSaved && !(OP_SYMBOL(IC_LEFT(ic))->calleeSave))
2224 unsaveRegisters (ic);
2229 /*-----------------------------------------------------------------*/
2230 /* genPcall - generates a call by pointer statement */
2231 /*-----------------------------------------------------------------*/
2232 static void genPcall (iCode *ic)
2235 symbol *rlbl = newiTempLabel(NULL);
2238 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2239 /* if caller saves & we have not saved then */
2243 /* if we are calling a function that is not using
2244 the same register bank then we need to save the
2245 destination registers on the stack */
2246 detype = getSpec(operandType(IC_LEFT(ic)));
2248 IS_ISR(currFunc->etype) &&
2249 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)))
2250 saverbank(SPEC_BANK(detype),ic,TRUE);
2253 /* push the return address on to the stack */
2254 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2255 pic14_emitcode("push","acc");
2256 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2257 pic14_emitcode("push","acc");
2259 if (options.model == MODEL_FLAT24)
2261 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2262 pic14_emitcode("push","acc");
2265 /* now push the calling address */
2266 aopOp(IC_LEFT(ic),ic,FALSE);
2268 pushSide(IC_LEFT(ic), FPTRSIZE);
2270 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2272 /* if send set is not empty the assign */
2276 for (sic = setFirstItem(_G.sendSet) ; sic ;
2277 sic = setNextItem(_G.sendSet)) {
2278 int size, offset = 0;
2279 aopOp(IC_LEFT(sic),sic,FALSE);
2280 size = AOP_SIZE(IC_LEFT(sic));
2282 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2284 if (strcmp(l,fReturn[offset]))
2285 pic14_emitcode("mov","%s,%s",
2290 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2295 pic14_emitcode("ret","");
2296 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2299 /* if we need assign a result value */
2300 if ((IS_ITEMP(IC_RESULT(ic)) &&
2301 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2302 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2303 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2306 aopOp(IC_RESULT(ic),ic,FALSE);
2309 assignResultValue(IC_RESULT(ic));
2311 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2314 /* adjust the stack for parameters if
2316 if (ic->parmBytes) {
2318 if (ic->parmBytes > 3) {
2319 pic14_emitcode("mov","a,%s",spname);
2320 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2321 pic14_emitcode("mov","%s,a",spname);
2323 for ( i = 0 ; i < ic->parmBytes ;i++)
2324 pic14_emitcode("dec","%s",spname);
2328 /* if register bank was saved then unsave them */
2330 (SPEC_BANK(currFunc->etype) !=
2332 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2334 /* if we hade saved some registers then
2337 unsaveRegisters (ic);
2341 /*-----------------------------------------------------------------*/
2342 /* resultRemat - result is rematerializable */
2343 /*-----------------------------------------------------------------*/
2344 static int resultRemat (iCode *ic)
2346 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2347 if (SKIP_IC(ic) || ic->op == IFX)
2350 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2351 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2352 if (sym->remat && !POINTER_SET(ic))
2359 #if defined(__BORLANDC__) || defined(_MSC_VER)
2360 #define STRCASECMP stricmp
2362 #define STRCASECMP strcasecmp
2365 /*-----------------------------------------------------------------*/
2366 /* inExcludeList - return 1 if the string is in exclude Reg list */
2367 /*-----------------------------------------------------------------*/
2368 static bool inExcludeList(char *s)
2372 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2373 if (options.excludeRegs[i] &&
2374 STRCASECMP(options.excludeRegs[i],"none") == 0)
2377 for ( i = 0 ; options.excludeRegs[i]; i++) {
2378 if (options.excludeRegs[i] &&
2379 STRCASECMP(s,options.excludeRegs[i]) == 0)
2385 /*-----------------------------------------------------------------*/
2386 /* genFunction - generated code for function entry */
2387 /*-----------------------------------------------------------------*/
2388 static void genFunction (iCode *ic)
2393 DEBUGpic14_emitcode ("; ***","%s %d previous max_key=%d ",__FUNCTION__,__LINE__,max_key);
2395 labelOffset += (max_key+1);
2399 /* create the function header */
2400 pic14_emitcode(";","-----------------------------------------");
2401 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2402 pic14_emitcode(";","-----------------------------------------");
2404 pic14_emitcode("","%s:",sym->rname);
2405 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2407 fetype = getSpec(operandType(IC_LEFT(ic)));
2409 /* if critical function then turn interrupts off */
2410 if (SPEC_CRTCL(fetype))
2411 pic14_emitcode("clr","ea");
2413 /* here we need to generate the equates for the
2414 register bank if required */
2416 if (SPEC_BANK(fetype) != rbank) {
2419 rbank = SPEC_BANK(fetype);
2420 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2421 if (strcmp(regspic14[i].base,"0") == 0)
2422 pic14_emitcode("","%s = 0x%02x",
2424 8*rbank+regspic14[i].offset);
2426 pic14_emitcode ("","%s = %s + 0x%02x",
2429 8*rbank+regspic14[i].offset);
2434 /* if this is an interrupt service routine then
2435 save acc, b, dpl, dph */
2436 if (IS_ISR(sym->etype)) {
2438 if (!inExcludeList("acc"))
2439 pic14_emitcode ("push","acc");
2440 if (!inExcludeList("b"))
2441 pic14_emitcode ("push","b");
2442 if (!inExcludeList("dpl"))
2443 pic14_emitcode ("push","dpl");
2444 if (!inExcludeList("dph"))
2445 pic14_emitcode ("push","dph");
2446 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2448 pic14_emitcode ("push", "dpx");
2449 /* Make sure we're using standard DPTR */
2450 pic14_emitcode ("push", "dps");
2451 pic14_emitcode ("mov", "dps, #0x00");
2452 if (options.stack10bit)
2454 /* This ISR could conceivably use DPTR2. Better save it. */
2455 pic14_emitcode ("push", "dpl1");
2456 pic14_emitcode ("push", "dph1");
2457 pic14_emitcode ("push", "dpx1");
2460 /* if this isr has no bank i.e. is going to
2461 run with bank 0 , then we need to save more
2463 if (!SPEC_BANK(sym->etype)) {
2465 /* if this function does not call any other
2466 function then we can be economical and
2467 save only those registers that are used */
2468 if (! sym->hasFcall) {
2471 /* if any registers used */
2472 if (sym->regsUsed) {
2473 /* save the registers used */
2474 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2475 if (bitVectBitValue(sym->regsUsed,i) ||
2476 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2477 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2482 /* this function has a function call cannot
2483 determines register usage so we will have the
2485 saverbank(0,ic,FALSE);
2489 /* if callee-save to be used for this function
2490 then save the registers being used in this function */
2491 if (sym->calleeSave) {
2494 /* if any registers used */
2495 if (sym->regsUsed) {
2496 /* save the registers used */
2497 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2498 if (bitVectBitValue(sym->regsUsed,i) ||
2499 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2500 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2508 /* set the register bank to the desired value */
2509 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) {
2510 pic14_emitcode("push","psw");
2511 pic14_emitcode("mov","psw,#0x%02x",(SPEC_BANK(sym->etype) << 3)&0x00ff);
2514 if (IS_RENT(sym->etype) || options.stackAuto) {
2516 if (options.useXstack) {
2517 pic14_emitcode("mov","r0,%s",spname);
2518 pic14_emitcode("mov","a,_bp");
2519 pic14_emitcode("movx","@r0,a");
2520 pic14_emitcode("inc","%s",spname);
2524 /* set up the stack */
2525 pic14_emitcode ("push","_bp"); /* save the callers stack */
2527 pic14_emitcode ("mov","_bp,%s",spname);
2530 /* adjust the stack for the function */
2535 werror(W_STACK_OVERFLOW,sym->name);
2537 if (i > 3 && sym->recvSize < 4) {
2539 pic14_emitcode ("mov","a,sp");
2540 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2541 pic14_emitcode ("mov","sp,a");
2546 pic14_emitcode("inc","sp");
2551 pic14_emitcode ("mov","a,_spx");
2552 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2553 pic14_emitcode ("mov","_spx,a");
2558 /*-----------------------------------------------------------------*/
2559 /* genEndFunction - generates epilogue for functions */
2560 /*-----------------------------------------------------------------*/
2561 static void genEndFunction (iCode *ic)
2563 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2565 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2567 if (IS_RENT(sym->etype) || options.stackAuto)
2569 pic14_emitcode ("mov","%s,_bp",spname);
2572 /* if use external stack but some variables were
2573 added to the local stack then decrement the
2575 if (options.useXstack && sym->stack) {
2576 pic14_emitcode("mov","a,sp");
2577 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2578 pic14_emitcode("mov","sp,a");
2582 if ((IS_RENT(sym->etype) || options.stackAuto)) {
2583 if (options.useXstack) {
2584 pic14_emitcode("mov","r0,%s",spname);
2585 pic14_emitcode("movx","a,@r0");
2586 pic14_emitcode("mov","_bp,a");
2587 pic14_emitcode("dec","%s",spname);
2591 pic14_emitcode ("pop","_bp");
2595 /* restore the register bank */
2596 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype))
2597 pic14_emitcode ("pop","psw");
2599 if (IS_ISR(sym->etype)) {
2601 /* now we need to restore the registers */
2602 /* if this isr has no bank i.e. is going to
2603 run with bank 0 , then we need to save more
2605 if (!SPEC_BANK(sym->etype)) {
2607 /* if this function does not call any other
2608 function then we can be economical and
2609 save only those registers that are used */
2610 if (! sym->hasFcall) {
2613 /* if any registers used */
2614 if (sym->regsUsed) {
2615 /* save the registers used */
2616 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2617 if (bitVectBitValue(sym->regsUsed,i) ||
2618 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2619 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2624 /* this function has a function call cannot
2625 determines register usage so we will have the
2627 unsaverbank(0,ic,FALSE);
2631 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2633 if (options.stack10bit)
2635 pic14_emitcode ("pop", "dpx1");
2636 pic14_emitcode ("pop", "dph1");
2637 pic14_emitcode ("pop", "dpl1");
2639 pic14_emitcode ("pop", "dps");
2640 pic14_emitcode ("pop", "dpx");
2642 if (!inExcludeList("dph"))
2643 pic14_emitcode ("pop","dph");
2644 if (!inExcludeList("dpl"))
2645 pic14_emitcode ("pop","dpl");
2646 if (!inExcludeList("b"))
2647 pic14_emitcode ("pop","b");
2648 if (!inExcludeList("acc"))
2649 pic14_emitcode ("pop","acc");
2651 if (SPEC_CRTCL(sym->etype))
2652 pic14_emitcode("setb","ea");
2654 /* if debug then send end of function */
2655 /* if (options.debug && currFunc) { */
2658 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2659 FileBaseName(ic->filename),currFunc->lastLine,
2660 ic->level,ic->block);
2661 if (IS_STATIC(currFunc->etype))
2662 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2664 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2668 pic14_emitcode ("reti","");
2671 if (SPEC_CRTCL(sym->etype))
2672 pic14_emitcode("setb","ea");
2674 if (sym->calleeSave) {
2677 /* if any registers used */
2678 if (sym->regsUsed) {
2679 /* save the registers used */
2680 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2681 if (bitVectBitValue(sym->regsUsed,i) ||
2682 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2683 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2689 /* if debug then send end of function */
2692 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2693 FileBaseName(ic->filename),currFunc->lastLine,
2694 ic->level,ic->block);
2695 if (IS_STATIC(currFunc->etype))
2696 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2698 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2702 pic14_emitcode ("return","");
2703 emitpcodeNULLop(POC_RETURN);
2705 /* Mark the end of a function */
2706 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2711 /*-----------------------------------------------------------------*/
2712 /* genRet - generate code for return statement */
2713 /*-----------------------------------------------------------------*/
2714 static void genRet (iCode *ic)
2716 int size,offset = 0 , pushed = 0;
2718 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2719 /* if we have no return value then
2720 just generate the "ret" */
2724 /* we have something to return then
2725 move the return value into place */
2726 aopOp(IC_LEFT(ic),ic,FALSE);
2727 size = AOP_SIZE(IC_LEFT(ic));
2731 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2733 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2735 pic14_emitcode("push","%s",l);
2738 l = aopGet(AOP(IC_LEFT(ic)),offset,
2740 if (strcmp(fReturn[offset],l)) {
2741 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2742 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
2743 pic14_emitcode("movlw","%s",l);
2745 pic14_emitcode("movf","%s,w",l);
2747 pic14_emitcode("movwf","%s",fReturn[offset]);
2756 if (strcmp(fReturn[pushed],"a"))
2757 pic14_emitcode("pop",fReturn[pushed]);
2759 pic14_emitcode("pop","acc");
2762 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2765 /* generate a jump to the return label
2766 if the next is not the return statement */
2767 if (!(ic->next && ic->next->op == LABEL &&
2768 IC_LABEL(ic->next) == returnLabel)) {
2770 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2771 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2776 /*-----------------------------------------------------------------*/
2777 /* genLabel - generates a label */
2778 /*-----------------------------------------------------------------*/
2779 static void genLabel (iCode *ic)
2781 /* special case never generate */
2782 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2783 if (IC_LABEL(ic) == entryLabel)
2786 emitpLabel(IC_LABEL(ic)->key+100 + labelOffset);
2787 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2790 /*-----------------------------------------------------------------*/
2791 /* genGoto - generates a goto */
2792 /*-----------------------------------------------------------------*/
2794 static void genGoto (iCode *ic)
2796 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2797 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2800 /*-----------------------------------------------------------------*/
2801 /* findLabelBackwards: walks back through the iCode chain looking */
2802 /* for the given label. Returns number of iCode instructions */
2803 /* between that label and given ic. */
2804 /* Returns zero if label not found. */
2805 /*-----------------------------------------------------------------*/
2807 static int findLabelBackwards(iCode *ic, int key)
2811 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2817 if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2819 /* printf("findLabelBackwards = %d\n", count); */
2828 /*-----------------------------------------------------------------*/
2829 /* genMultbits :- multiplication of bits */
2830 /*-----------------------------------------------------------------*/
2831 static void genMultbits (operand *left,
2835 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2837 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2838 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2839 pic14_outBitC(result);
2843 /*-----------------------------------------------------------------*/
2844 /* genMultOneByte : 8 bit multiplication & division */
2845 /*-----------------------------------------------------------------*/
2846 static void genMultOneByte (operand *left,
2850 sym_link *opetype = operandType(result);
2855 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2856 /* (if two literals, the value is computed before) */
2857 /* if one literal, literal on the right */
2858 if (AOP_TYPE(left) == AOP_LIT){
2864 size = AOP_SIZE(result);
2865 /* signed or unsigned */
2866 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2867 l = aopGet(AOP(left),0,FALSE,FALSE);
2869 pic14_emitcode("mul","ab");
2870 /* if result size = 1, mul signed = mul unsigned */
2871 aopPut(AOP(result),"a",0);
2873 if (SPEC_USIGN(opetype)){
2874 aopPut(AOP(result),"b",1);
2876 /* for filling the MSBs */
2877 pic14_emitcode("clr","a");
2880 pic14_emitcode("mov","a,b");
2882 /* adjust the MSB if left or right neg */
2884 /* if one literal */
2885 if (AOP_TYPE(right) == AOP_LIT){
2886 /* AND literal negative */
2887 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2888 /* adjust MSB (c==0 after mul) */
2889 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2893 lbl = newiTempLabel(NULL);
2894 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2895 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2896 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2897 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2898 lbl = newiTempLabel(NULL);
2899 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2900 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2901 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2904 lbl = newiTempLabel(NULL);
2905 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2906 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2907 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2908 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2909 lbl = newiTempLabel(NULL);
2910 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2911 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2912 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2914 aopPut(AOP(result),"a",1);
2917 pic14_emitcode("rlc","a");
2918 pic14_emitcode("subb","a,acc");
2925 aopPut(AOP(result),"a",offset++);
2929 /*-----------------------------------------------------------------*/
2930 /* genMult - generates code for multiplication */
2931 /*-----------------------------------------------------------------*/
2932 static void genMult (iCode *ic)
2934 operand *left = IC_LEFT(ic);
2935 operand *right = IC_RIGHT(ic);
2936 operand *result= IC_RESULT(ic);
2938 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2939 /* assign the amsops */
2940 aopOp (left,ic,FALSE);
2941 aopOp (right,ic,FALSE);
2942 aopOp (result,ic,TRUE);
2944 /* special cases first */
2946 if (AOP_TYPE(left) == AOP_CRY &&
2947 AOP_TYPE(right)== AOP_CRY) {
2948 genMultbits(left,right,result);
2952 /* if both are of size == 1 */
2953 if (AOP_SIZE(left) == 1 &&
2954 AOP_SIZE(right) == 1 ) {
2955 genMultOneByte(left,right,result);
2959 /* should have been converted to function call */
2963 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2964 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2965 freeAsmop(result,NULL,ic,TRUE);
2968 /*-----------------------------------------------------------------*/
2969 /* genDivbits :- division of bits */
2970 /*-----------------------------------------------------------------*/
2971 static void genDivbits (operand *left,
2978 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2979 /* the result must be bit */
2980 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
2981 l = aopGet(AOP(left),0,FALSE,FALSE);
2985 pic14_emitcode("div","ab");
2986 pic14_emitcode("rrc","a");
2987 aopPut(AOP(result),"c",0);
2990 /*-----------------------------------------------------------------*/
2991 /* genDivOneByte : 8 bit division */
2992 /*-----------------------------------------------------------------*/
2993 static void genDivOneByte (operand *left,
2997 sym_link *opetype = operandType(result);
3002 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3003 size = AOP_SIZE(result) - 1;
3005 /* signed or unsigned */
3006 if (SPEC_USIGN(opetype)) {
3007 /* unsigned is easy */
3008 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3009 l = aopGet(AOP(left),0,FALSE,FALSE);
3011 pic14_emitcode("div","ab");
3012 aopPut(AOP(result),"a",0);
3014 aopPut(AOP(result),zero,offset++);
3018 /* signed is a little bit more difficult */
3020 /* save the signs of the operands */
3021 l = aopGet(AOP(left),0,FALSE,FALSE);
3023 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3024 pic14_emitcode("push","acc"); /* save it on the stack */
3026 /* now sign adjust for both left & right */
3027 l = aopGet(AOP(right),0,FALSE,FALSE);
3029 lbl = newiTempLabel(NULL);
3030 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3031 pic14_emitcode("cpl","a");
3032 pic14_emitcode("inc","a");
3033 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3034 pic14_emitcode("mov","b,a");
3036 /* sign adjust left side */
3037 l = aopGet(AOP(left),0,FALSE,FALSE);
3040 lbl = newiTempLabel(NULL);
3041 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3042 pic14_emitcode("cpl","a");
3043 pic14_emitcode("inc","a");
3044 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3046 /* now the division */
3047 pic14_emitcode("div","ab");
3048 /* we are interested in the lower order
3050 pic14_emitcode("mov","b,a");
3051 lbl = newiTempLabel(NULL);
3052 pic14_emitcode("pop","acc");
3053 /* if there was an over flow we don't
3054 adjust the sign of the result */
3055 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3056 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3058 pic14_emitcode("clr","a");
3059 pic14_emitcode("subb","a,b");
3060 pic14_emitcode("mov","b,a");
3061 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3063 /* now we are done */
3064 aopPut(AOP(result),"b",0);
3066 pic14_emitcode("mov","c,b.7");
3067 pic14_emitcode("subb","a,acc");
3070 aopPut(AOP(result),"a",offset++);
3074 /*-----------------------------------------------------------------*/
3075 /* genDiv - generates code for division */
3076 /*-----------------------------------------------------------------*/
3077 static void genDiv (iCode *ic)
3079 operand *left = IC_LEFT(ic);
3080 operand *right = IC_RIGHT(ic);
3081 operand *result= IC_RESULT(ic);
3083 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3084 /* assign the amsops */
3085 aopOp (left,ic,FALSE);
3086 aopOp (right,ic,FALSE);
3087 aopOp (result,ic,TRUE);
3089 /* special cases first */
3091 if (AOP_TYPE(left) == AOP_CRY &&
3092 AOP_TYPE(right)== AOP_CRY) {
3093 genDivbits(left,right,result);
3097 /* if both are of size == 1 */
3098 if (AOP_SIZE(left) == 1 &&
3099 AOP_SIZE(right) == 1 ) {
3100 genDivOneByte(left,right,result);
3104 /* should have been converted to function call */
3107 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3108 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3109 freeAsmop(result,NULL,ic,TRUE);
3112 /*-----------------------------------------------------------------*/
3113 /* genModbits :- modulus of bits */
3114 /*-----------------------------------------------------------------*/
3115 static void genModbits (operand *left,
3122 /* the result must be bit */
3123 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3124 l = aopGet(AOP(left),0,FALSE,FALSE);
3128 pic14_emitcode("div","ab");
3129 pic14_emitcode("mov","a,b");
3130 pic14_emitcode("rrc","a");
3131 aopPut(AOP(result),"c",0);
3134 /*-----------------------------------------------------------------*/
3135 /* genModOneByte : 8 bit modulus */
3136 /*-----------------------------------------------------------------*/
3137 static void genModOneByte (operand *left,
3141 sym_link *opetype = operandType(result);
3145 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3146 /* signed or unsigned */
3147 if (SPEC_USIGN(opetype)) {
3148 /* unsigned is easy */
3149 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3150 l = aopGet(AOP(left),0,FALSE,FALSE);
3152 pic14_emitcode("div","ab");
3153 aopPut(AOP(result),"b",0);
3157 /* signed is a little bit more difficult */
3159 /* save the signs of the operands */
3160 l = aopGet(AOP(left),0,FALSE,FALSE);
3163 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3164 pic14_emitcode("push","acc"); /* save it on the stack */
3166 /* now sign adjust for both left & right */
3167 l = aopGet(AOP(right),0,FALSE,FALSE);
3170 lbl = newiTempLabel(NULL);
3171 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3172 pic14_emitcode("cpl","a");
3173 pic14_emitcode("inc","a");
3174 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3175 pic14_emitcode("mov","b,a");
3177 /* sign adjust left side */
3178 l = aopGet(AOP(left),0,FALSE,FALSE);
3181 lbl = newiTempLabel(NULL);
3182 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3183 pic14_emitcode("cpl","a");
3184 pic14_emitcode("inc","a");
3185 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3187 /* now the multiplication */
3188 pic14_emitcode("div","ab");
3189 /* we are interested in the lower order
3191 lbl = newiTempLabel(NULL);
3192 pic14_emitcode("pop","acc");
3193 /* if there was an over flow we don't
3194 adjust the sign of the result */
3195 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3196 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3198 pic14_emitcode("clr","a");
3199 pic14_emitcode("subb","a,b");
3200 pic14_emitcode("mov","b,a");
3201 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3203 /* now we are done */
3204 aopPut(AOP(result),"b",0);
3208 /*-----------------------------------------------------------------*/
3209 /* genMod - generates code for division */
3210 /*-----------------------------------------------------------------*/
3211 static void genMod (iCode *ic)
3213 operand *left = IC_LEFT(ic);
3214 operand *right = IC_RIGHT(ic);
3215 operand *result= IC_RESULT(ic);
3217 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3218 /* assign the amsops */
3219 aopOp (left,ic,FALSE);
3220 aopOp (right,ic,FALSE);
3221 aopOp (result,ic,TRUE);
3223 /* special cases first */
3225 if (AOP_TYPE(left) == AOP_CRY &&
3226 AOP_TYPE(right)== AOP_CRY) {
3227 genModbits(left,right,result);
3231 /* if both are of size == 1 */
3232 if (AOP_SIZE(left) == 1 &&
3233 AOP_SIZE(right) == 1 ) {
3234 genModOneByte(left,right,result);
3238 /* should have been converted to function call */
3242 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3243 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3244 freeAsmop(result,NULL,ic,TRUE);
3247 /*-----------------------------------------------------------------*/
3248 /* genIfxJump :- will create a jump depending on the ifx */
3249 /*-----------------------------------------------------------------*/
3251 note: May need to add parameter to indicate when a variable is in bit space.
3253 static void genIfxJump (iCode *ic, char *jval)
3256 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3257 /* if true label then we jump if condition
3259 if ( IC_TRUE(ic) ) {
3261 if(strcmp(jval,"a") == 0)
3263 else if (strcmp(jval,"c") == 0)
3266 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3267 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3270 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3271 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3275 /* false label is present */
3276 if(strcmp(jval,"a") == 0)
3278 else if (strcmp(jval,"c") == 0)
3281 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3282 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3285 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3286 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3291 /* mark the icode as generated */
3295 /*-----------------------------------------------------------------*/
3297 /*-----------------------------------------------------------------*/
3298 static void genSkip(iCode *ifx,int status_bit)
3303 if ( IC_TRUE(ifx) ) {
3304 switch(status_bit) {
3319 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3320 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3324 switch(status_bit) {
3338 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3339 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3345 /*-----------------------------------------------------------------*/
3347 /*-----------------------------------------------------------------*/
3348 static void genSkipc(iCode *ifx, int condition)
3359 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3361 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3364 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3366 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3370 /*-----------------------------------------------------------------*/
3372 /*-----------------------------------------------------------------*/
3373 static void genSkipz(iCode *ifx, int condition)
3384 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3386 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3389 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3391 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3394 /*-----------------------------------------------------------------*/
3395 /* genCmp :- greater or less than comparison */
3396 /*-----------------------------------------------------------------*/
3397 static void genCmp (operand *left,operand *right,
3398 operand *result, iCode *ifx, int sign)
3400 int size, offset = 0 ;
3401 unsigned long lit = 0L,i = 0;
3403 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3404 /* if left & right are bit variables */
3405 if (AOP_TYPE(left) == AOP_CRY &&
3406 AOP_TYPE(right) == AOP_CRY ) {
3407 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3408 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3410 /* subtract right from left if at the
3411 end the carry flag is set then we know that
3412 left is greater than right */
3413 size = max(AOP_SIZE(left),AOP_SIZE(right));
3415 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3416 if((size == 1) && !sign &&
3417 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3418 symbol *lbl = newiTempLabel(NULL);
3419 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3420 aopGet(AOP(left),offset,FALSE,FALSE),
3421 aopGet(AOP(right),offset,FALSE,FALSE),
3423 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3426 if(AOP_TYPE(right) == AOP_LIT) {
3428 DEBUGpic14_emitcode(";right lit","%d",sign);
3430 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3433 i = (lit >> (size*8)) & 0xff;
3435 emitpcode(POC_MOVFW, popGet(AOP(left),size,FALSE,FALSE));
3436 pic14_emitcode("movf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
3437 genSkipz(ifx,IC_TRUE(ifx) == NULL);
3439 emitpcode(POC_MOVLW, popGetLit(i));
3440 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3442 pic14_emitcode("movlw","0x%x",i);
3443 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
3444 genSkipc(ifx,IC_TRUE(ifx) == NULL);
3451 if(AOP_TYPE(left) == AOP_LIT) {
3453 DEBUGpic14_emitcode(";left lit","%d",sign);
3455 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit))+1;
3459 i = (lit >> (size*8)) & 0xff;
3461 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3462 pic14_emitcode("movf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3463 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3464 } else if( i == 1 ) {
3465 emitpcode(POC_DECFW, popGet(AOP(right),size,FALSE,FALSE));
3466 pic14_emitcode("decf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3467 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3470 emitpcode(POC_MOVLW, popGetLit(i));
3471 emitpcode(POC_SUBFW, popGet(AOP(right),size,FALSE,FALSE));
3473 pic14_emitcode("movlw","0x%x",i);
3474 pic14_emitcode("subwf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3475 genSkipc(ifx,IC_TRUE(ifx) != NULL);
3484 DEBUGpic14_emitcode(";sign","%d",sign);
3486 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3487 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3489 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3490 emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3495 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3497 emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3498 emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE));
3501 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3503 pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3504 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3512 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3513 pic14_outBitC(result);
3515 /* if the result is used in the next
3516 ifx conditional branch then generate
3517 code a little differently */
3519 genIfxJump (ifx,"c");
3521 pic14_outBitC(result);
3522 /* leave the result in acc */
3527 /*-----------------------------------------------------------------*/
3528 /* genCmpGt :- greater than comparison */
3529 /*-----------------------------------------------------------------*/
3530 static void genCmpGt (iCode *ic, iCode *ifx)
3532 operand *left, *right, *result;
3533 sym_link *letype , *retype;
3536 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3538 right= IC_RIGHT(ic);
3539 result = IC_RESULT(ic);
3541 letype = getSpec(operandType(left));
3542 retype =getSpec(operandType(right));
3543 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3544 /* assign the amsops */
3545 aopOp (left,ic,FALSE);
3546 aopOp (right,ic,FALSE);
3547 aopOp (result,ic,TRUE);
3549 genCmp(right, left, result, ifx, sign);
3551 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3552 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3553 freeAsmop(result,NULL,ic,TRUE);
3556 /*-----------------------------------------------------------------*/
3557 /* genCmpLt - less than comparisons */
3558 /*-----------------------------------------------------------------*/
3559 static void genCmpLt (iCode *ic, iCode *ifx)
3561 operand *left, *right, *result;
3562 sym_link *letype , *retype;
3565 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3567 right= IC_RIGHT(ic);
3568 result = IC_RESULT(ic);
3570 letype = getSpec(operandType(left));
3571 retype =getSpec(operandType(right));
3572 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3574 /* assign the amsops */
3575 aopOp (left,ic,FALSE);
3576 aopOp (right,ic,FALSE);
3577 aopOp (result,ic,TRUE);
3579 genCmp(left, right, result, ifx, sign);
3581 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3582 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3583 freeAsmop(result,NULL,ic,TRUE);
3586 /*-----------------------------------------------------------------*/
3587 /* gencjneshort - compare and jump if not equal */
3588 /*-----------------------------------------------------------------*/
3589 static void gencjneshort(operand *left, operand *right, symbol *lbl)
3591 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3593 unsigned long lit = 0L;
3595 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3596 /* if the left side is a literal or
3597 if the right is in a pointer register and left
3599 if ((AOP_TYPE(left) == AOP_LIT) ||
3600 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3605 if(AOP_TYPE(right) == AOP_LIT)
3606 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3608 /* if the right side is a literal then anything goes */
3609 if (AOP_TYPE(right) == AOP_LIT &&
3610 AOP_TYPE(left) != AOP_DIR ) {
3613 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3614 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3616 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3619 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3625 /* if the right side is in a register or in direct space or
3626 if the left is a pointer register & right is not */
3627 else if (AOP_TYPE(right) == AOP_REG ||
3628 AOP_TYPE(right) == AOP_DIR ||
3629 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3630 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3632 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3633 ( (lit & 0xff) != 0)) {
3634 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3635 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3638 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3641 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3644 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
3645 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3646 ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0))
3647 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
3649 pic14_emitcode("cjne","a,%s,%05d_DS_",
3650 aopGet(AOP(right),offset,FALSE,TRUE),
3656 /* right is a pointer reg need both a & b */
3658 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3660 pic14_emitcode("mov","b,%s",l);
3661 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3662 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
3668 /*-----------------------------------------------------------------*/
3669 /* gencjne - compare and jump if not equal */
3670 /*-----------------------------------------------------------------*/
3671 static void gencjne(operand *left, operand *right, symbol *lbl)
3673 symbol *tlbl = newiTempLabel(NULL);
3675 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3676 gencjneshort(left, right, lbl);
3678 pic14_emitcode("mov","a,%s",one);
3679 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3680 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3681 pic14_emitcode("clr","a");
3682 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
3686 /*-----------------------------------------------------------------*/
3687 /* genCmpEq - generates code for equal to */
3688 /*-----------------------------------------------------------------*/
3689 static void genCmpEq (iCode *ic, iCode *ifx)
3691 operand *left, *right, *result;
3692 unsigned long lit = 0L;
3695 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3697 DEBUGpic14_emitcode ("; ifx is non-null","");
3699 DEBUGpic14_emitcode ("; ifx is null","");
3701 aopOp((left=IC_LEFT(ic)),ic,FALSE);
3702 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
3703 aopOp((result=IC_RESULT(ic)),ic,TRUE);
3705 size = max(AOP_SIZE(left),AOP_SIZE(right));
3707 /* if literal, literal on the right or
3708 if the right is in a pointer register and left
3710 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
3711 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3712 operand *t = IC_RIGHT(ic);
3713 IC_RIGHT(ic) = IC_LEFT(ic);
3717 if(ifx && !AOP_SIZE(result)){
3719 /* if they are both bit variables */
3720 if (AOP_TYPE(left) == AOP_CRY &&
3721 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3722 if(AOP_TYPE(right) == AOP_LIT){
3723 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3725 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3726 pic14_emitcode("cpl","c");
3727 } else if(lit == 1L) {
3728 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3730 pic14_emitcode("clr","c");
3732 /* AOP_TYPE(right) == AOP_CRY */
3734 symbol *lbl = newiTempLabel(NULL);
3735 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3736 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3737 pic14_emitcode("cpl","c");
3738 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3740 /* if true label then we jump if condition
3742 tlbl = newiTempLabel(NULL);
3743 if ( IC_TRUE(ifx) ) {
3744 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
3745 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
3747 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
3748 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
3750 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
3753 /* They're not both bit variables. Is the right a literal? */
3754 if(AOP_TYPE(right) == AOP_LIT) {
3756 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3761 int h = (lit>>8) & 0xff;
3764 /* Check special cases for integers */
3765 switch(lit & 0xffff) {
3767 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3768 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3769 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3770 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3775 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3776 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3777 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3778 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3783 emitpcode(POC_DECFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3784 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3785 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3786 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3791 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3792 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3793 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3794 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3799 emitpcode(POC_INCFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3800 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3801 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3802 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3808 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3809 emitpcode(POC_XORLW,popGetLit(l));
3810 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3812 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3813 pic14_emitcode("xorlw","0x%x",l);
3814 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3817 } else if (l == 0) {
3818 emitpcode(POC_MOVFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3819 emitpcode(POC_XORLW,popGetLit(h));
3820 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3822 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3823 pic14_emitcode("xorlw","0x%x",h);
3824 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3828 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3829 emitpcode(POC_XORLW,popGetLit(l));
3830 emitpcode(POC_MOVLW,popGetLit(h));
3832 emitpcode(POC_XORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3834 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3835 pic14_emitcode("xorlw","0x%x",l);
3836 pic14_emitcode("movlw","0x%x",h);
3838 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3855 switch(lit & 0xff) {
3857 if ( IC_TRUE(ifx) ) {
3859 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3861 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3863 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3865 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3867 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3868 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3870 pic14_emitcode("decfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3871 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3875 if ( IC_TRUE(ifx) ) {
3876 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3878 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3880 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3882 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3884 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3885 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3887 pic14_emitcode("incfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3888 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3892 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3893 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3895 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3896 //pic14_emitcode("xorlw","0x%x",lit & 0xff);
3901 // pic14_emitcode("goto","_%05d_DS_",tlbl->key+100+labelOffset);
3902 //pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
3907 } else if(AOP_TYPE(right) == AOP_CRY ) {
3908 /* we know the left is not a bit, but that the right is */
3909 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3910 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
3911 popGet(AOP(right),offset,FALSE,FALSE));
3912 emitpcode(POC_XORLW,popGetLit(1));
3914 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3916 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
3917 AOP(right)->aopu.aop_dir,
3918 AOP(right)->aopu.aop_dir);
3920 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
3921 AOP(right)->aopu.aop_dir,
3922 AOP(right)->aopu.aop_dir);
3924 pic14_emitcode("xorlw","1");
3926 /* if the two are equal, then W will be 0 and the Z bit is set
3927 * we could test Z now, or go ahead and check the high order bytes if
3928 * the variable we're comparing is larger than a byte. */
3931 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3932 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3934 if ( IC_TRUE(ifx) ) {
3936 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3937 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3940 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3941 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3945 /* They're both variables that are larger than bits */
3948 tlbl = newiTempLabel(NULL);
3951 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3952 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3954 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3955 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3957 if ( IC_TRUE(ifx) ) {
3960 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
3961 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
3964 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3965 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3969 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3970 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3974 if(s>1 && IC_TRUE(ifx)) {
3975 emitpLabel(tlbl->key+100+labelOffset);
3976 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
3980 /* mark the icode as generated */
3985 /* if they are both bit variables */
3986 if (AOP_TYPE(left) == AOP_CRY &&
3987 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3988 if(AOP_TYPE(right) == AOP_LIT){
3989 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3991 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3992 pic14_emitcode("cpl","c");
3993 } else if(lit == 1L) {
3994 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3996 pic14_emitcode("clr","c");
3998 /* AOP_TYPE(right) == AOP_CRY */
4000 symbol *lbl = newiTempLabel(NULL);
4001 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4002 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4003 pic14_emitcode("cpl","c");
4004 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4007 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4008 pic14_outBitC(result);
4012 genIfxJump (ifx,"c");
4015 /* if the result is used in an arithmetic operation
4016 then put the result in place */
4017 pic14_outBitC(result);
4019 gencjne(left,right,newiTempLabel(NULL));
4020 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4021 aopPut(AOP(result),"a",0);
4025 genIfxJump (ifx,"a");
4028 /* if the result is used in an arithmetic operation
4029 then put the result in place */
4030 if (AOP_TYPE(result) != AOP_CRY)
4031 pic14_outAcc(result);
4032 /* leave the result in acc */
4036 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4037 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4038 freeAsmop(result,NULL,ic,TRUE);
4041 /*-----------------------------------------------------------------*/
4042 /* ifxForOp - returns the icode containing the ifx for operand */
4043 /*-----------------------------------------------------------------*/
4044 static iCode *ifxForOp ( operand *op, iCode *ic )
4046 /* if true symbol then needs to be assigned */
4047 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4048 if (IS_TRUE_SYMOP(op))
4051 /* if this has register type condition and
4052 the next instruction is ifx with the same operand
4053 and live to of the operand is upto the ifx only then */
4055 ic->next->op == IFX &&
4056 IC_COND(ic->next)->key == op->key &&
4057 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4062 /*-----------------------------------------------------------------*/
4063 /* genAndOp - for && operation */
4064 /*-----------------------------------------------------------------*/
4065 static void genAndOp (iCode *ic)
4067 operand *left,*right, *result;
4070 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4071 /* note here that && operations that are in an
4072 if statement are taken away by backPatchLabels
4073 only those used in arthmetic operations remain */
4074 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4075 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4076 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4078 /* if both are bit variables */
4079 if (AOP_TYPE(left) == AOP_CRY &&
4080 AOP_TYPE(right) == AOP_CRY ) {
4081 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4082 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4083 pic14_outBitC(result);
4085 tlbl = newiTempLabel(NULL);
4086 pic14_toBoolean(left);
4087 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4088 pic14_toBoolean(right);
4089 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4090 pic14_outBitAcc(result);
4093 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4094 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4095 freeAsmop(result,NULL,ic,TRUE);
4099 /*-----------------------------------------------------------------*/
4100 /* genOrOp - for || operation */
4101 /*-----------------------------------------------------------------*/
4104 modified this code, but it doesn't appear to ever get called
4107 static void genOrOp (iCode *ic)
4109 operand *left,*right, *result;
4112 /* note here that || operations that are in an
4113 if statement are taken away by backPatchLabels
4114 only those used in arthmetic operations remain */
4115 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4116 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4117 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4118 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4120 /* if both are bit variables */
4121 if (AOP_TYPE(left) == AOP_CRY &&
4122 AOP_TYPE(right) == AOP_CRY ) {
4123 pic14_emitcode("clrc","");
4124 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4125 AOP(left)->aopu.aop_dir,
4126 AOP(left)->aopu.aop_dir);
4127 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4128 AOP(right)->aopu.aop_dir,
4129 AOP(right)->aopu.aop_dir);
4130 pic14_emitcode("setc","");
4133 tlbl = newiTempLabel(NULL);
4134 pic14_toBoolean(left);
4136 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4137 pic14_toBoolean(right);
4138 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4140 pic14_outBitAcc(result);
4143 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4144 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4145 freeAsmop(result,NULL,ic,TRUE);
4148 /*-----------------------------------------------------------------*/
4149 /* isLiteralBit - test if lit == 2^n */
4150 /*-----------------------------------------------------------------*/
4151 static int isLiteralBit(unsigned long lit)
4153 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4154 0x100L,0x200L,0x400L,0x800L,
4155 0x1000L,0x2000L,0x4000L,0x8000L,
4156 0x10000L,0x20000L,0x40000L,0x80000L,
4157 0x100000L,0x200000L,0x400000L,0x800000L,
4158 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4159 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4162 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4163 for(idx = 0; idx < 32; idx++)
4169 /*-----------------------------------------------------------------*/
4170 /* continueIfTrue - */
4171 /*-----------------------------------------------------------------*/
4172 static void continueIfTrue (iCode *ic)
4174 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4176 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4180 /*-----------------------------------------------------------------*/
4182 /*-----------------------------------------------------------------*/
4183 static void jumpIfTrue (iCode *ic)
4185 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4187 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4191 /*-----------------------------------------------------------------*/
4192 /* jmpTrueOrFalse - */
4193 /*-----------------------------------------------------------------*/
4194 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4196 // ugly but optimized by peephole
4197 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4199 symbol *nlbl = newiTempLabel(NULL);
4200 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4201 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4202 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4203 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4206 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4207 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4212 /*-----------------------------------------------------------------*/
4213 /* genAnd - code for and */
4214 /*-----------------------------------------------------------------*/
4215 static void genAnd (iCode *ic, iCode *ifx)
4217 operand *left, *right, *result;
4219 unsigned long lit = 0L;
4223 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4224 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4225 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4226 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4229 pic14_emitcode("","; Type res[%d] = l[%d]&r[%d]",
4231 AOP_TYPE(left), AOP_TYPE(right));
4232 pic14_emitcode("","; Size res[%d] = l[%d]&r[%d]",
4234 AOP_SIZE(left), AOP_SIZE(right));
4237 /* if left is a literal & right is not then exchange them */
4238 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4239 AOP_NEEDSACC(left)) {
4240 operand *tmp = right ;
4245 /* if result = right then exchange them */
4246 if(pic14_sameRegs(AOP(result),AOP(right))){
4247 operand *tmp = right ;
4252 /* if right is bit then exchange them */
4253 if (AOP_TYPE(right) == AOP_CRY &&
4254 AOP_TYPE(left) != AOP_CRY){
4255 operand *tmp = right ;
4259 if(AOP_TYPE(right) == AOP_LIT)
4260 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4262 size = AOP_SIZE(result);
4265 // result = bit & yy;
4266 if (AOP_TYPE(left) == AOP_CRY){
4267 // c = bit & literal;
4268 if(AOP_TYPE(right) == AOP_LIT){
4270 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4273 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4276 if(size && (AOP_TYPE(result) == AOP_CRY)){
4277 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4280 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4284 pic14_emitcode("clr","c");
4287 if (AOP_TYPE(right) == AOP_CRY){
4289 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4290 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4293 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4295 pic14_emitcode("rrc","a");
4296 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4302 pic14_outBitC(result);
4304 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4305 genIfxJump(ifx, "c");
4309 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4310 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4311 if((AOP_TYPE(right) == AOP_LIT) &&
4312 (AOP_TYPE(result) == AOP_CRY) &&
4313 (AOP_TYPE(left) != AOP_CRY)){
4314 int posbit = isLiteralBit(lit);
4318 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4321 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4325 pCodeOp *pcorb = popGet(AOP(left),0,TRUE,FALSE);
4326 PCORB(pcorb)->subtype = PCOP(pcorb)->type;
4327 PCOP(pcorb)->type = PO_GPR_BIT;
4328 PCORB(pcorb)->bit = posbit;
4330 emitpcode(POC_BTFSC, pcorb);
4331 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4333 emitpcode(POC_BTFSS, pcorb);
4334 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4341 symbol *tlbl = newiTempLabel(NULL);
4342 int sizel = AOP_SIZE(left);
4344 pic14_emitcode("setb","c");
4346 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4347 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4349 if((posbit = isLiteralBit(bytelit)) != 0)
4350 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4352 if(bytelit != 0x0FFL)
4353 pic14_emitcode("anl","a,%s",
4354 aopGet(AOP(right),offset,FALSE,TRUE));
4355 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4360 // bit = left & literal
4362 pic14_emitcode("clr","c");
4363 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4365 // if(left & literal)
4368 jmpTrueOrFalse(ifx, tlbl);
4372 pic14_outBitC(result);
4376 /* if left is same as result */
4377 if(pic14_sameRegs(AOP(result),AOP(left))){
4378 for(;size--; offset++,lit>>=8) {
4379 if(AOP_TYPE(right) == AOP_LIT){
4380 switch(lit & 0xff) {
4382 /* and'ing with 0 has clears the result */
4383 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4384 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4387 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4388 emitpcode(POC_MOVWF,popGet(AOP(right),offset,FALSE,FALSE));
4393 int p = my_powof2( (~lit) & 0xff );
4395 /* only one bit is set in the literal, so use a bcf instruction */
4396 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4397 emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
4399 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4400 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4401 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4402 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
4407 if (AOP_TYPE(left) == AOP_ACC) {
4408 pic14_emitcode("?iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4409 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4412 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4413 pic14_emitcode("?iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4414 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4415 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4422 // left & result in different registers
4423 if(AOP_TYPE(result) == AOP_CRY){
4425 // if(size), result in bit
4426 // if(!size && ifx), conditional oper: if(left & right)
4427 symbol *tlbl = newiTempLabel(NULL);
4428 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4430 pic14_emitcode("setb","c");
4432 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4433 pic14_emitcode("anl","a,%s",
4434 aopGet(AOP(left),offset,FALSE,FALSE));
4435 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4440 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4441 pic14_outBitC(result);
4443 jmpTrueOrFalse(ifx, tlbl);
4445 for(;(size--);offset++) {
4447 // result = left & right
4448 if(AOP_TYPE(right) == AOP_LIT){
4449 int t = (lit >> (offset*8)) & 0x0FFL;
4452 pic14_emitcode("clrf","%s",
4453 aopGet(AOP(result),offset,FALSE,FALSE));
4454 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4457 pic14_emitcode("movf","%s,w",
4458 aopGet(AOP(left),offset,FALSE,FALSE));
4459 pic14_emitcode("movwf","%s",
4460 aopGet(AOP(result),offset,FALSE,FALSE));
4461 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4462 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4465 pic14_emitcode("movlw","0x%x",t);
4466 pic14_emitcode("andwf","%s,w",
4467 aopGet(AOP(left),offset,FALSE,FALSE));
4468 pic14_emitcode("movwf","%s",
4469 aopGet(AOP(result),offset,FALSE,FALSE));
4471 emitpcode(POC_MOVLW, popGetLit(t));
4472 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4473 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4478 if (AOP_TYPE(left) == AOP_ACC) {
4479 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4480 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4482 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4483 pic14_emitcode("andwf","%s,w",
4484 aopGet(AOP(left),offset,FALSE,FALSE));
4485 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4486 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4488 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4489 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4495 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4496 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4497 freeAsmop(result,NULL,ic,TRUE);
4500 /*-----------------------------------------------------------------*/
4501 /* genOr - code for or */
4502 /*-----------------------------------------------------------------*/
4503 static void genOr (iCode *ic, iCode *ifx)
4505 operand *left, *right, *result;
4507 unsigned long lit = 0L;
4509 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4511 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4512 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4513 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4516 /* if left is a literal & right is not then exchange them */
4517 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4518 AOP_NEEDSACC(left)) {
4519 operand *tmp = right ;
4524 /* if result = right then exchange them */
4525 if(pic14_sameRegs(AOP(result),AOP(right))){
4526 operand *tmp = right ;
4531 /* if right is bit then exchange them */
4532 if (AOP_TYPE(right) == AOP_CRY &&
4533 AOP_TYPE(left) != AOP_CRY){
4534 operand *tmp = right ;
4539 if(AOP_TYPE(right) == AOP_LIT)
4540 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4542 size = AOP_SIZE(result);
4546 if (AOP_TYPE(left) == AOP_CRY){
4547 if(AOP_TYPE(right) == AOP_LIT){
4548 // c = bit & literal;
4550 // lit != 0 => result = 1
4551 if(AOP_TYPE(result) == AOP_CRY){
4553 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4554 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4555 // AOP(result)->aopu.aop_dir,
4556 // AOP(result)->aopu.aop_dir);
4558 continueIfTrue(ifx);
4562 // lit == 0 => result = left
4563 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4565 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4568 if (AOP_TYPE(right) == AOP_CRY){
4569 if(pic14_sameRegs(AOP(result),AOP(left))){
4571 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4572 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4573 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4575 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4576 AOP(result)->aopu.aop_dir,
4577 AOP(result)->aopu.aop_dir);
4578 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4579 AOP(right)->aopu.aop_dir,
4580 AOP(right)->aopu.aop_dir);
4581 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4582 AOP(result)->aopu.aop_dir,
4583 AOP(result)->aopu.aop_dir);
4586 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4587 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4588 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4589 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4591 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4592 AOP(result)->aopu.aop_dir,
4593 AOP(result)->aopu.aop_dir);
4594 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4595 AOP(right)->aopu.aop_dir,
4596 AOP(right)->aopu.aop_dir);
4597 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4598 AOP(left)->aopu.aop_dir,
4599 AOP(left)->aopu.aop_dir);
4600 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4601 AOP(result)->aopu.aop_dir,
4602 AOP(result)->aopu.aop_dir);
4607 symbol *tlbl = newiTempLabel(NULL);
4608 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4609 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4610 pic14_emitcode(";XXX setb","c");
4611 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4612 AOP(left)->aopu.aop_dir,tlbl->key+100);
4613 pic14_toBoolean(right);
4614 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4615 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4616 jmpTrueOrFalse(ifx, tlbl);
4620 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4627 pic14_outBitC(result);
4629 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4630 genIfxJump(ifx, "c");
4634 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4635 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4636 if((AOP_TYPE(right) == AOP_LIT) &&
4637 (AOP_TYPE(result) == AOP_CRY) &&
4638 (AOP_TYPE(left) != AOP_CRY)){
4640 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4643 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4645 continueIfTrue(ifx);
4648 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4649 // lit = 0, result = boolean(left)
4651 pic14_emitcode(";XXX setb","c");
4652 pic14_toBoolean(right);
4654 symbol *tlbl = newiTempLabel(NULL);
4655 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4657 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4659 genIfxJump (ifx,"a");
4663 pic14_outBitC(result);
4667 /* if left is same as result */
4668 if(pic14_sameRegs(AOP(result),AOP(left))){
4669 for(;size--; offset++,lit>>=8) {
4670 if(AOP_TYPE(right) == AOP_LIT){
4671 if((lit & 0xff) == 0)
4672 /* or'ing with 0 has no effect */
4675 int p = my_powof2(lit & 0xff);
4677 /* only one bit is set in the literal, so use a bsf instruction */
4678 emitpcode(POC_BSF, popGet(AOP(left),offset,FALSE,FALSE));
4679 pic14_emitcode("bsf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4681 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4682 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4684 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4685 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
4690 if (AOP_TYPE(left) == AOP_ACC) {
4691 emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE));
4692 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4694 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4695 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4697 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4698 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4704 // left & result in different registers
4705 if(AOP_TYPE(result) == AOP_CRY){
4707 // if(size), result in bit
4708 // if(!size && ifx), conditional oper: if(left | right)
4709 symbol *tlbl = newiTempLabel(NULL);
4710 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4711 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4714 pic14_emitcode(";XXX setb","c");
4716 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4717 pic14_emitcode(";XXX orl","a,%s",
4718 aopGet(AOP(left),offset,FALSE,FALSE));
4719 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4724 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4725 pic14_outBitC(result);
4727 jmpTrueOrFalse(ifx, tlbl);
4728 } else for(;(size--);offset++){
4730 // result = left & right
4731 if(AOP_TYPE(right) == AOP_LIT){
4732 int t = (lit >> (offset*8)) & 0x0FFL;
4735 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
4736 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4738 pic14_emitcode("movf","%s,w",
4739 aopGet(AOP(left),offset,FALSE,FALSE));
4740 pic14_emitcode("movwf","%s",
4741 aopGet(AOP(result),offset,FALSE,FALSE));
4744 emitpcode(POC_MOVLW, popGetLit(t));
4745 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4746 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4748 pic14_emitcode("movlw","0x%x",t);
4749 pic14_emitcode("iorwf","%s,w",
4750 aopGet(AOP(left),offset,FALSE,FALSE));
4751 pic14_emitcode("movwf","%s",
4752 aopGet(AOP(result),offset,FALSE,FALSE));
4758 // faster than result <- left, anl result,right
4759 // and better if result is SFR
4760 if (AOP_TYPE(left) == AOP_ACC) {
4761 emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE));
4762 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4764 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4765 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4767 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4768 pic14_emitcode("iorwf","%s,w",
4769 aopGet(AOP(left),offset,FALSE,FALSE));
4771 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4772 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4777 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4778 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4779 freeAsmop(result,NULL,ic,TRUE);
4782 /*-----------------------------------------------------------------*/
4783 /* genXor - code for xclusive or */
4784 /*-----------------------------------------------------------------*/
4785 static void genXor (iCode *ic, iCode *ifx)
4787 operand *left, *right, *result;
4789 unsigned long lit = 0L;
4791 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4793 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4794 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4795 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4797 /* if left is a literal & right is not ||
4798 if left needs acc & right does not */
4799 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4800 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
4801 operand *tmp = right ;
4806 /* if result = right then exchange them */
4807 if(pic14_sameRegs(AOP(result),AOP(right))){
4808 operand *tmp = right ;
4813 /* if right is bit then exchange them */
4814 if (AOP_TYPE(right) == AOP_CRY &&
4815 AOP_TYPE(left) != AOP_CRY){
4816 operand *tmp = right ;
4820 if(AOP_TYPE(right) == AOP_LIT)
4821 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4823 size = AOP_SIZE(result);
4827 if (AOP_TYPE(left) == AOP_CRY){
4828 if(AOP_TYPE(right) == AOP_LIT){
4829 // c = bit & literal;
4831 // lit>>1 != 0 => result = 1
4832 if(AOP_TYPE(result) == AOP_CRY){
4834 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
4836 continueIfTrue(ifx);
4839 pic14_emitcode("setb","c");
4843 // lit == 0, result = left
4844 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4846 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4848 // lit == 1, result = not(left)
4849 if(size && pic14_sameRegs(AOP(result),AOP(left))){
4850 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
4853 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4854 pic14_emitcode("cpl","c");
4861 symbol *tlbl = newiTempLabel(NULL);
4862 if (AOP_TYPE(right) == AOP_CRY){
4864 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4867 int sizer = AOP_SIZE(right);
4869 // if val>>1 != 0, result = 1
4870 pic14_emitcode("setb","c");
4872 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
4874 // test the msb of the lsb
4875 pic14_emitcode("anl","a,#0xfe");
4876 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4880 pic14_emitcode("rrc","a");
4882 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
4883 pic14_emitcode("cpl","c");
4884 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
4889 pic14_outBitC(result);
4891 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4892 genIfxJump(ifx, "c");
4896 if(pic14_sameRegs(AOP(result),AOP(left))){
4897 /* if left is same as result */
4898 for(;size--; offset++) {
4899 if(AOP_TYPE(right) == AOP_LIT){
4900 int t = (lit >> (offset*8)) & 0x0FFL;
4904 if (IS_AOP_PREG(left)) {
4905 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4906 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4907 aopPut(AOP(result),"a",offset);
4909 emitpcode(POC_MOVLW, popGetLit(t));
4910 emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
4911 pic14_emitcode("xrl","%s,%s",
4912 aopGet(AOP(left),offset,FALSE,TRUE),
4913 aopGet(AOP(right),offset,FALSE,FALSE));
4916 if (AOP_TYPE(left) == AOP_ACC)
4917 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
4919 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4920 if (IS_AOP_PREG(left)) {
4921 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4922 aopPut(AOP(result),"a",offset);
4924 pic14_emitcode("xrl","%s,a",
4925 aopGet(AOP(left),offset,FALSE,TRUE));
4930 // left & result in different registers
4931 if(AOP_TYPE(result) == AOP_CRY){
4933 // if(size), result in bit
4934 // if(!size && ifx), conditional oper: if(left ^ right)
4935 symbol *tlbl = newiTempLabel(NULL);
4936 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4938 pic14_emitcode("setb","c");
4940 if((AOP_TYPE(right) == AOP_LIT) &&
4941 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
4942 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
4944 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4945 pic14_emitcode("xrl","a,%s",
4946 aopGet(AOP(left),offset,FALSE,FALSE));
4948 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4953 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4954 pic14_outBitC(result);
4956 jmpTrueOrFalse(ifx, tlbl);
4957 } else for(;(size--);offset++){
4959 // result = left & right
4960 if(AOP_TYPE(right) == AOP_LIT){
4961 int t = (lit >> (offset*8)) & 0x0FFL;
4964 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4965 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4966 pic14_emitcode("movf","%s,w",
4967 aopGet(AOP(left),offset,FALSE,FALSE));
4968 pic14_emitcode("movwf","%s",
4969 aopGet(AOP(result),offset,FALSE,FALSE));
4972 emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
4973 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4974 pic14_emitcode("comf","%s,w",
4975 aopGet(AOP(left),offset,FALSE,FALSE));
4976 pic14_emitcode("movwf","%s",
4977 aopGet(AOP(result),offset,FALSE,FALSE));
4980 emitpcode(POC_MOVLW, popGetLit(t));
4981 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
4982 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4983 pic14_emitcode("movlw","0x%x",t);
4984 pic14_emitcode("xorwf","%s,w",
4985 aopGet(AOP(left),offset,FALSE,FALSE));
4986 pic14_emitcode("movwf","%s",
4987 aopGet(AOP(result),offset,FALSE,FALSE));
4993 // faster than result <- left, anl result,right
4994 // and better if result is SFR
4995 if (AOP_TYPE(left) == AOP_ACC) {
4996 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
4997 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4999 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
5000 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5001 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5002 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5004 if ( AOP_TYPE(result) != AOP_ACC){
5005 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5006 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5012 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5013 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5014 freeAsmop(result,NULL,ic,TRUE);
5017 /*-----------------------------------------------------------------*/
5018 /* genInline - write the inline code out */
5019 /*-----------------------------------------------------------------*/
5020 static void genInline (iCode *ic)
5022 char *buffer, *bp, *bp1;
5024 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5026 _G.inLine += (!options.asmpeep);
5028 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5029 strcpy(buffer,IC_INLINE(ic));
5031 /* emit each line as a code */
5035 pic14_emitcode(bp1,"");
5042 pic14_emitcode(bp1,"");
5049 pic14_emitcode(bp1,"");
5050 /* pic14_emitcode("",buffer); */
5051 _G.inLine -= (!options.asmpeep);
5054 /*-----------------------------------------------------------------*/
5055 /* genRRC - rotate right with carry */
5056 /*-----------------------------------------------------------------*/
5057 static void genRRC (iCode *ic)
5059 operand *left , *result ;
5060 int size, offset = 0;
5063 /* rotate right with carry */
5065 result=IC_RESULT(ic);
5066 aopOp (left,ic,FALSE);
5067 aopOp (result,ic,FALSE);
5069 /* move it to the result */
5070 size = AOP_SIZE(result);
5074 l = aopGet(AOP(left),offset,FALSE,FALSE);
5076 pic14_emitcode("rrc","a");
5077 if (AOP_SIZE(result) > 1)
5078 aopPut(AOP(result),"a",offset--);
5080 /* now we need to put the carry into the
5081 highest order byte of the result */
5082 if (AOP_SIZE(result) > 1) {
5083 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5086 pic14_emitcode("mov","acc.7,c");
5087 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5088 freeAsmop(left,NULL,ic,TRUE);
5089 freeAsmop(result,NULL,ic,TRUE);
5092 /*-----------------------------------------------------------------*/
5093 /* genRLC - generate code for rotate left with carry */
5094 /*-----------------------------------------------------------------*/
5095 static void genRLC (iCode *ic)
5097 operand *left , *result ;
5098 int size, offset = 0;
5101 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5102 /* rotate right with carry */
5104 result=IC_RESULT(ic);
5105 aopOp (left,ic,FALSE);
5106 aopOp (result,ic,FALSE);
5108 /* move it to the result */
5109 size = AOP_SIZE(result);
5112 l = aopGet(AOP(left),offset,FALSE,FALSE);
5114 pic14_emitcode("add","a,acc");
5115 if (AOP_SIZE(result) > 1)
5116 aopPut(AOP(result),"a",offset++);
5118 l = aopGet(AOP(left),offset,FALSE,FALSE);
5120 pic14_emitcode("rlc","a");
5121 if (AOP_SIZE(result) > 1)
5122 aopPut(AOP(result),"a",offset++);
5125 /* now we need to put the carry into the
5126 highest order byte of the result */
5127 if (AOP_SIZE(result) > 1) {
5128 l = aopGet(AOP(result),0,FALSE,FALSE);
5131 pic14_emitcode("mov","acc.0,c");
5132 aopPut(AOP(result),"a",0);
5133 freeAsmop(left,NULL,ic,TRUE);
5134 freeAsmop(result,NULL,ic,TRUE);
5137 /*-----------------------------------------------------------------*/
5138 /* genGetHbit - generates code get highest order bit */
5139 /*-----------------------------------------------------------------*/
5140 static void genGetHbit (iCode *ic)
5142 operand *left, *result;
5144 result=IC_RESULT(ic);
5145 aopOp (left,ic,FALSE);
5146 aopOp (result,ic,FALSE);
5148 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5149 /* get the highest order byte into a */
5150 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5151 if(AOP_TYPE(result) == AOP_CRY){
5152 pic14_emitcode("rlc","a");
5153 pic14_outBitC(result);
5156 pic14_emitcode("rl","a");
5157 pic14_emitcode("anl","a,#0x01");
5158 pic14_outAcc(result);
5162 freeAsmop(left,NULL,ic,TRUE);
5163 freeAsmop(result,NULL,ic,TRUE);
5166 /*-----------------------------------------------------------------*/
5167 /* AccRol - rotate left accumulator by known count */
5168 /*-----------------------------------------------------------------*/
5169 static void AccRol (int shCount)
5171 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5172 shCount &= 0x0007; // shCount : 0..7
5177 pic14_emitcode("rl","a");
5180 pic14_emitcode("rl","a");
5181 pic14_emitcode("rl","a");
5184 pic14_emitcode("swap","a");
5185 pic14_emitcode("rr","a");
5188 pic14_emitcode("swap","a");
5191 pic14_emitcode("swap","a");
5192 pic14_emitcode("rl","a");
5195 pic14_emitcode("rr","a");
5196 pic14_emitcode("rr","a");
5199 pic14_emitcode("rr","a");
5204 /*-----------------------------------------------------------------*/
5205 /* AccLsh - left shift accumulator by known count */
5206 /*-----------------------------------------------------------------*/
5207 static void AccLsh (int shCount)
5209 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5212 pic14_emitcode("add","a,acc");
5215 pic14_emitcode("add","a,acc");
5216 pic14_emitcode("add","a,acc");
5218 /* rotate left accumulator */
5220 /* and kill the lower order bits */
5221 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5226 /*-----------------------------------------------------------------*/
5227 /* AccRsh - right shift accumulator by known count */
5228 /*-----------------------------------------------------------------*/
5229 static void AccRsh (int shCount)
5231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5235 pic14_emitcode("rrc","a");
5237 /* rotate right accumulator */
5238 AccRol(8 - shCount);
5239 /* and kill the higher order bits */
5240 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5246 /*-----------------------------------------------------------------*/
5247 /* AccSRsh - signed right shift accumulator by known count */
5248 /*-----------------------------------------------------------------*/
5249 static void AccSRsh (int shCount)
5252 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5255 pic14_emitcode("mov","c,acc.7");
5256 pic14_emitcode("rrc","a");
5257 } else if(shCount == 2){
5258 pic14_emitcode("mov","c,acc.7");
5259 pic14_emitcode("rrc","a");
5260 pic14_emitcode("mov","c,acc.7");
5261 pic14_emitcode("rrc","a");
5263 tlbl = newiTempLabel(NULL);
5264 /* rotate right accumulator */
5265 AccRol(8 - shCount);
5266 /* and kill the higher order bits */
5267 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5268 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5269 pic14_emitcode("orl","a,#0x%02x",
5270 (unsigned char)~SRMask[shCount]);
5271 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5276 /*-----------------------------------------------------------------*/
5277 /* shiftR1Left2Result - shift right one byte from left to result */
5278 /*-----------------------------------------------------------------*/
5279 static void shiftR1Left2ResultSigned (operand *left, int offl,
5280 operand *result, int offr,
5285 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5287 same = (left == result) || (AOP(left) == AOP(result));
5291 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5293 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5295 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5296 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5306 /*-----------------------------------------------------------------*/
5307 /* shiftR1Left2Result - shift right one byte from left to result */
5308 /*-----------------------------------------------------------------*/
5309 static void shiftR1Left2Result (operand *left, int offl,
5310 operand *result, int offr,
5311 int shCount, int sign)
5315 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5317 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5319 /* Copy the msb into the carry if signed. */
5321 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5331 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5333 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5334 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5340 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5342 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5343 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5346 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5351 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5353 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5354 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5357 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5358 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5359 emitpcode(POC_ANDLW, popGetLit(0x1f));
5360 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5364 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5365 emitpcode(POC_ANDLW, popGetLit(0x0f));
5366 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5370 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5371 emitpcode(POC_ANDLW, popGetLit(0x0f));
5372 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5374 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5379 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5380 emitpcode(POC_ANDLW, popGetLit(0x80));
5381 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5382 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5383 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5388 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5389 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5390 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5401 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5403 /* shift right accumulator */
5408 aopPut(AOP(result),"a",offr);
5412 /*-----------------------------------------------------------------*/
5413 /* shiftL1Left2Result - shift left one byte from left to result */
5414 /*-----------------------------------------------------------------*/
5415 static void shiftL1Left2Result (operand *left, int offl,
5416 operand *result, int offr, int shCount)
5421 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5423 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5424 DEBUGpic14_emitcode ("; ***","same = %d",same);
5425 // l = aopGet(AOP(left),offl,FALSE,FALSE);
5427 /* shift left accumulator */
5428 //AccLsh(shCount); // don't comment out just yet...
5429 // aopPut(AOP(result),"a",offr);
5433 /* Shift left 1 bit position */
5434 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5436 emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
5438 emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
5439 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5443 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5444 emitpcode(POC_ANDLW,popGetLit(0x7e));
5445 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5446 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5449 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5450 emitpcode(POC_ANDLW,popGetLit(0x3e));
5451 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5452 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5453 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5456 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5457 emitpcode(POC_ANDLW, popGetLit(0xf0));
5458 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5461 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5462 emitpcode(POC_ANDLW, popGetLit(0xf0));
5463 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5464 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5467 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5468 emitpcode(POC_ANDLW, popGetLit(0x30));
5469 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5470 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5471 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5474 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5475 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5476 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5480 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5485 /*-----------------------------------------------------------------*/
5486 /* movLeft2Result - move byte from left to result */
5487 /*-----------------------------------------------------------------*/
5488 static void movLeft2Result (operand *left, int offl,
5489 operand *result, int offr, int sign)
5492 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5493 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5494 l = aopGet(AOP(left),offl,FALSE,FALSE);
5496 if (*l == '@' && (IS_AOP_PREG(result))) {
5497 pic14_emitcode("mov","a,%s",l);
5498 aopPut(AOP(result),"a",offr);
5501 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5502 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5504 //aopPut(AOP(result),l,offr);
5506 /* MSB sign in acc.7 ! */
5507 if(pic14_getDataSize(left) == offl+1){
5508 pic14_emitcode("mov","a,%s",l);
5509 aopPut(AOP(result),"a",offr);
5516 /*-----------------------------------------------------------------*/
5517 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5518 /*-----------------------------------------------------------------*/
5519 static void AccAXRrl1 (char *x)
5521 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5522 pic14_emitcode("rrc","a");
5523 pic14_emitcode("xch","a,%s", x);
5524 pic14_emitcode("rrc","a");
5525 pic14_emitcode("xch","a,%s", x);
5528 /*-----------------------------------------------------------------*/
5529 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5530 /*-----------------------------------------------------------------*/
5531 static void AccAXLrl1 (char *x)
5533 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5534 pic14_emitcode("xch","a,%s",x);
5535 pic14_emitcode("rlc","a");
5536 pic14_emitcode("xch","a,%s",x);
5537 pic14_emitcode("rlc","a");
5540 /*-----------------------------------------------------------------*/
5541 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5542 /*-----------------------------------------------------------------*/
5543 static void AccAXLsh1 (char *x)
5545 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5546 pic14_emitcode("xch","a,%s",x);
5547 pic14_emitcode("add","a,acc");
5548 pic14_emitcode("xch","a,%s",x);
5549 pic14_emitcode("rlc","a");
5553 /*-----------------------------------------------------------------*/
5554 /* AccAXLsh - left shift a:x by known count (0..7) */
5555 /*-----------------------------------------------------------------*/
5556 static void AccAXLsh (char *x, int shCount)
5558 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5571 case 5 : // AAAAABBB:CCCCCDDD
5572 AccRol(shCount); // BBBAAAAA:CCCCCDDD
5573 pic14_emitcode("anl","a,#0x%02x",
5574 SLMask[shCount]); // BBB00000:CCCCCDDD
5575 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
5576 AccRol(shCount); // DDDCCCCC:BBB00000
5577 pic14_emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
5578 pic14_emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
5579 pic14_emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
5580 pic14_emitcode("anl","a,#0x%02x",
5581 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5582 pic14_emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
5583 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
5585 case 6 : // AAAAAABB:CCCCCCDD
5586 pic14_emitcode("anl","a,#0x%02x",
5587 SRMask[shCount]); // 000000BB:CCCCCCDD
5588 pic14_emitcode("mov","c,acc.0"); // c = B
5589 pic14_emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
5590 AccAXRrl1(x); // BCCCCCCD:D000000B
5591 AccAXRrl1(x); // BBCCCCCC:DD000000
5593 case 7 : // a:x <<= 7
5594 pic14_emitcode("anl","a,#0x%02x",
5595 SRMask[shCount]); // 0000000B:CCCCCCCD
5596 pic14_emitcode("mov","c,acc.0"); // c = B
5597 pic14_emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
5598 AccAXRrl1(x); // BCCCCCCC:D0000000
5606 /*-----------------------------------------------------------------*/
5607 /* AccAXRsh - right shift a:x known count (0..7) */
5608 /*-----------------------------------------------------------------*/
5609 static void AccAXRsh (char *x, int shCount)
5611 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5617 AccAXRrl1(x); // 0->a:x
5621 AccAXRrl1(x); // 0->a:x
5623 AccAXRrl1(x); // 0->a:x
5627 case 5 : // AAAAABBB:CCCCCDDD = a:x
5628 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5629 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5630 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5631 pic14_emitcode("anl","a,#0x%02x",
5632 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5633 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5634 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5635 pic14_emitcode("anl","a,#0x%02x",
5636 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5637 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5638 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5639 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5641 case 6 : // AABBBBBB:CCDDDDDD
5642 pic14_emitcode("mov","c,acc.7");
5643 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5644 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5645 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5646 pic14_emitcode("anl","a,#0x%02x",
5647 SRMask[shCount]); // 000000AA:BBBBBBCC
5649 case 7 : // ABBBBBBB:CDDDDDDD
5650 pic14_emitcode("mov","c,acc.7"); // c = A
5651 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5652 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5653 pic14_emitcode("anl","a,#0x%02x",
5654 SRMask[shCount]); // 0000000A:BBBBBBBC
5661 /*-----------------------------------------------------------------*/
5662 /* AccAXRshS - right shift signed a:x known count (0..7) */
5663 /*-----------------------------------------------------------------*/
5664 static void AccAXRshS (char *x, int shCount)
5667 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5672 pic14_emitcode("mov","c,acc.7");
5673 AccAXRrl1(x); // s->a:x
5676 pic14_emitcode("mov","c,acc.7");
5677 AccAXRrl1(x); // s->a:x
5678 pic14_emitcode("mov","c,acc.7");
5679 AccAXRrl1(x); // s->a:x
5683 case 5 : // AAAAABBB:CCCCCDDD = a:x
5684 tlbl = newiTempLabel(NULL);
5685 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
5686 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5687 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5688 pic14_emitcode("anl","a,#0x%02x",
5689 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5690 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5691 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5692 pic14_emitcode("anl","a,#0x%02x",
5693 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5694 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5695 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5696 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
5697 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5698 pic14_emitcode("orl","a,#0x%02x",
5699 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5700 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5701 break; // SSSSAAAA:BBBCCCCC
5702 case 6 : // AABBBBBB:CCDDDDDD
5703 tlbl = newiTempLabel(NULL);
5704 pic14_emitcode("mov","c,acc.7");
5705 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5706 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5707 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5708 pic14_emitcode("anl","a,#0x%02x",
5709 SRMask[shCount]); // 000000AA:BBBBBBCC
5710 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5711 pic14_emitcode("orl","a,#0x%02x",
5712 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
5713 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5715 case 7 : // ABBBBBBB:CDDDDDDD
5716 tlbl = newiTempLabel(NULL);
5717 pic14_emitcode("mov","c,acc.7"); // c = A
5718 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5719 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5720 pic14_emitcode("anl","a,#0x%02x",
5721 SRMask[shCount]); // 0000000A:BBBBBBBC
5722 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5723 pic14_emitcode("orl","a,#0x%02x",
5724 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
5725 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5732 /*-----------------------------------------------------------------*/
5733 /* shiftL2Left2Result - shift left two bytes from left to result */
5734 /*-----------------------------------------------------------------*/
5735 static void shiftL2Left2Result (operand *left, int offl,
5736 operand *result, int offr, int shCount)
5740 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5742 if(pic14_sameRegs(AOP(result), AOP(left))) {
5750 emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
5751 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5752 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5756 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5757 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5763 emitpcode(POC_MOVLW, popGetLit(0x0f));
5764 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5765 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5766 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5767 emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
5768 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5769 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5771 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5772 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5776 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5777 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5778 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5779 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5780 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5781 emitpcode(POC_ANDLW,popGetLit(0xc0));
5782 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5783 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5784 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5785 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5788 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5789 emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
5790 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5791 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5792 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5802 /* note, use a mov/add for the shift since the mov has a
5803 chance of getting optimized out */
5804 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5805 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5806 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5807 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5808 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5812 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5813 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5819 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5820 emitpcode(POC_ANDLW, popGetLit(0xF0));
5821 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5822 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5823 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5824 emitpcode(POC_ANDLW, popGetLit(0xF0));
5825 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5826 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5830 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5831 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5835 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5836 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5837 emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
5838 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5840 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5841 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5842 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5843 emitpcode(POC_ANDLW,popGetLit(0xc0));
5844 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5845 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5846 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5847 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5850 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5851 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5852 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5853 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5854 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5859 /*-----------------------------------------------------------------*/
5860 /* shiftR2Left2Result - shift right two bytes from left to result */
5861 /*-----------------------------------------------------------------*/
5862 static void shiftR2Left2Result (operand *left, int offl,
5863 operand *result, int offr,
5864 int shCount, int sign)
5868 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5869 same = pic14_sameRegs(AOP(result), AOP(left));
5871 if(same && ((offl + MSB16) == offr)){
5873 /* don't crash result[offr] */
5874 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5875 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5877 movLeft2Result(left,offl, result, offr, 0);
5878 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5880 /* a:x >> shCount (x = lsb(result))*/
5882 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5884 //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5894 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5895 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5898 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5899 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5900 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5901 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5906 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5907 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5914 emitpcode(POC_MOVLW, popGetLit(0xf0));
5915 emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
5916 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5918 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5919 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5920 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5921 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5923 emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
5924 emitpcode(POC_ANDLW, popGetLit(0x0f));
5925 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5927 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5928 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5929 emitpcode(POC_ANDLW, popGetLit(0xf0));
5930 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5931 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5935 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5936 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5944 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5945 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5947 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5948 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5949 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5950 emitpcode(POC_ANDLW,popGetLit(0x03));
5951 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5952 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5953 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5954 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5956 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5957 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5958 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
5959 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5960 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5961 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5962 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5963 emitpcode(POC_ANDLW,popGetLit(0x03));
5964 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5969 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5970 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5971 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5972 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5973 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5978 /*-----------------------------------------------------------------*/
5979 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
5980 /*-----------------------------------------------------------------*/
5981 static void shiftLLeftOrResult (operand *left, int offl,
5982 operand *result, int offr, int shCount)
5984 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5985 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5986 /* shift left accumulator */
5988 /* or with result */
5989 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5990 /* back to result */
5991 aopPut(AOP(result),"a",offr);
5994 /*-----------------------------------------------------------------*/
5995 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
5996 /*-----------------------------------------------------------------*/
5997 static void shiftRLeftOrResult (operand *left, int offl,
5998 operand *result, int offr, int shCount)
6000 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6001 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6002 /* shift right accumulator */
6004 /* or with result */
6005 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6006 /* back to result */
6007 aopPut(AOP(result),"a",offr);
6010 /*-----------------------------------------------------------------*/
6011 /* genlshOne - left shift a one byte quantity by known count */
6012 /*-----------------------------------------------------------------*/
6013 static void genlshOne (operand *result, operand *left, int shCount)
6015 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6016 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6019 /*-----------------------------------------------------------------*/
6020 /* genlshTwo - left shift two bytes by known amount != 0 */
6021 /*-----------------------------------------------------------------*/
6022 static void genlshTwo (operand *result,operand *left, int shCount)
6026 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6027 size = pic14_getDataSize(result);
6029 /* if shCount >= 8 */
6035 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6037 movLeft2Result(left, LSB, result, MSB16, 0);
6039 emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6042 /* 1 <= shCount <= 7 */
6045 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6047 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6051 /*-----------------------------------------------------------------*/
6052 /* shiftLLong - shift left one long from left to result */
6053 /* offl = LSB or MSB16 */
6054 /*-----------------------------------------------------------------*/
6055 static void shiftLLong (operand *left, operand *result, int offr )
6058 int size = AOP_SIZE(result);
6060 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6061 if(size >= LSB+offr){
6062 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6064 pic14_emitcode("add","a,acc");
6065 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6066 size >= MSB16+offr && offr != LSB )
6067 pic14_emitcode("xch","a,%s",
6068 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6070 aopPut(AOP(result),"a",LSB+offr);
6073 if(size >= MSB16+offr){
6074 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6075 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6078 pic14_emitcode("rlc","a");
6079 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6080 size >= MSB24+offr && offr != LSB)
6081 pic14_emitcode("xch","a,%s",
6082 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6084 aopPut(AOP(result),"a",MSB16+offr);
6087 if(size >= MSB24+offr){
6088 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6089 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6092 pic14_emitcode("rlc","a");
6093 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6094 size >= MSB32+offr && offr != LSB )
6095 pic14_emitcode("xch","a,%s",
6096 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6098 aopPut(AOP(result),"a",MSB24+offr);
6101 if(size > MSB32+offr){
6102 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6103 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6106 pic14_emitcode("rlc","a");
6107 aopPut(AOP(result),"a",MSB32+offr);
6110 aopPut(AOP(result),zero,LSB);
6113 /*-----------------------------------------------------------------*/
6114 /* genlshFour - shift four byte by a known amount != 0 */
6115 /*-----------------------------------------------------------------*/
6116 static void genlshFour (operand *result, operand *left, int shCount)
6120 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6121 size = AOP_SIZE(result);
6123 /* if shifting more that 3 bytes */
6124 if (shCount >= 24 ) {
6127 /* lowest order of left goes to the highest
6128 order of the destination */
6129 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6131 movLeft2Result(left, LSB, result, MSB32, 0);
6132 aopPut(AOP(result),zero,LSB);
6133 aopPut(AOP(result),zero,MSB16);
6134 aopPut(AOP(result),zero,MSB32);
6138 /* more than two bytes */
6139 else if ( shCount >= 16 ) {
6140 /* lower order two bytes goes to higher order two bytes */
6142 /* if some more remaining */
6144 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6146 movLeft2Result(left, MSB16, result, MSB32, 0);
6147 movLeft2Result(left, LSB, result, MSB24, 0);
6149 aopPut(AOP(result),zero,MSB16);
6150 aopPut(AOP(result),zero,LSB);
6154 /* if more than 1 byte */
6155 else if ( shCount >= 8 ) {
6156 /* lower order three bytes goes to higher order three bytes */
6160 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6162 movLeft2Result(left, LSB, result, MSB16, 0);
6164 else{ /* size = 4 */
6166 movLeft2Result(left, MSB24, result, MSB32, 0);
6167 movLeft2Result(left, MSB16, result, MSB24, 0);
6168 movLeft2Result(left, LSB, result, MSB16, 0);
6169 aopPut(AOP(result),zero,LSB);
6171 else if(shCount == 1)
6172 shiftLLong(left, result, MSB16);
6174 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6175 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6176 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6177 aopPut(AOP(result),zero,LSB);
6182 /* 1 <= shCount <= 7 */
6183 else if(shCount <= 2){
6184 shiftLLong(left, result, LSB);
6186 shiftLLong(result, result, LSB);
6188 /* 3 <= shCount <= 7, optimize */
6190 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6191 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6192 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6196 /*-----------------------------------------------------------------*/
6197 /* genLeftShiftLiteral - left shifting by known count */
6198 /*-----------------------------------------------------------------*/
6199 static void genLeftShiftLiteral (operand *left,
6204 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6207 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6208 freeAsmop(right,NULL,ic,TRUE);
6210 aopOp(left,ic,FALSE);
6211 aopOp(result,ic,FALSE);
6213 size = getSize(operandType(result));
6216 pic14_emitcode("; shift left ","result %d, left %d",size,
6220 /* I suppose that the left size >= result size */
6223 movLeft2Result(left, size, result, size, 0);
6227 else if(shCount >= (size * 8))
6229 aopPut(AOP(result),zero,size);
6233 genlshOne (result,left,shCount);
6238 genlshTwo (result,left,shCount);
6242 genlshFour (result,left,shCount);
6246 freeAsmop(left,NULL,ic,TRUE);
6247 freeAsmop(result,NULL,ic,TRUE);
6250 /*-----------------------------------------------------------------*/
6251 /* genLeftShift - generates code for left shifting */
6252 /*-----------------------------------------------------------------*/
6253 static void genLeftShift (iCode *ic)
6255 operand *left,*right, *result;
6258 symbol *tlbl , *tlbl1;
6260 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6262 right = IC_RIGHT(ic);
6264 result = IC_RESULT(ic);
6266 aopOp(right,ic,FALSE);
6268 /* if the shift count is known then do it
6269 as efficiently as possible */
6270 if (AOP_TYPE(right) == AOP_LIT) {
6271 genLeftShiftLiteral (left,right,result,ic);
6275 /* shift count is unknown then we have to form
6276 a loop get the loop count in B : Note: we take
6277 only the lower order byte since shifting
6278 more that 32 bits make no sense anyway, ( the
6279 largest size of an object can be only 32 bits ) */
6282 aopOp(left,ic,FALSE);
6283 aopOp(result,ic,FALSE);
6285 /* now move the left to the result if they are not the
6287 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6288 AOP_SIZE(result) > 1) {
6290 size = AOP_SIZE(result);
6293 l = aopGet(AOP(left),offset,FALSE,TRUE);
6294 if (*l == '@' && (IS_AOP_PREG(result))) {
6296 pic14_emitcode("mov","a,%s",l);
6297 aopPut(AOP(result),"a",offset);
6299 aopPut(AOP(result),l,offset);
6304 size = AOP_SIZE(result);
6306 /* if it is only one byte then */
6308 if(optimized_for_speed) {
6309 emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6310 emitpcode(POC_ANDLW, popGetLit(0xf0));
6311 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6312 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6313 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6314 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6315 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6316 emitpcode(POC_RLFW, popGet(AOP(result),0,FALSE,FALSE));
6317 emitpcode(POC_ANDLW, popGetLit(0xfe));
6318 emitpcode(POC_ADDFW, popGet(AOP(result),0,FALSE,FALSE));
6319 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6320 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6323 tlbl = newiTempLabel(NULL);
6324 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6325 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6326 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6329 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6330 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6331 emitpLabel(tlbl->key+100+labelOffset);
6332 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6333 emitpcode(POC_ADDLW, popGetLit(1));
6335 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6341 tlbl = newiTempLabel(NULL);
6343 tlbl1 = newiTempLabel(NULL);
6345 reAdjustPreg(AOP(result));
6347 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6348 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6349 l = aopGet(AOP(result),offset,FALSE,FALSE);
6351 pic14_emitcode("add","a,acc");
6352 aopPut(AOP(result),"a",offset++);
6354 l = aopGet(AOP(result),offset,FALSE,FALSE);
6356 pic14_emitcode("rlc","a");
6357 aopPut(AOP(result),"a",offset++);
6359 reAdjustPreg(AOP(result));
6361 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6362 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6364 freeAsmop (right,NULL,ic,TRUE);
6365 freeAsmop(left,NULL,ic,TRUE);
6366 freeAsmop(result,NULL,ic,TRUE);
6369 /*-----------------------------------------------------------------*/
6370 /* genrshOne - right shift a one byte quantity by known count */
6371 /*-----------------------------------------------------------------*/
6372 static void genrshOne (operand *result, operand *left,
6373 int shCount, int sign)
6375 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6376 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6379 /*-----------------------------------------------------------------*/
6380 /* genrshTwo - right shift two bytes by known amount != 0 */
6381 /*-----------------------------------------------------------------*/
6382 static void genrshTwo (operand *result,operand *left,
6383 int shCount, int sign)
6385 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6386 /* if shCount >= 8 */
6390 shiftR1Left2Result(left, MSB16, result, LSB,
6393 movLeft2Result(left, MSB16, result, LSB, sign);
6395 addSign(result, MSB16, sign);
6397 emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6401 /* 1 <= shCount <= 7 */
6403 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6406 /*-----------------------------------------------------------------*/
6407 /* shiftRLong - shift right one long from left to result */
6408 /* offl = LSB or MSB16 */
6409 /*-----------------------------------------------------------------*/
6410 static void shiftRLong (operand *left, int offl,
6411 operand *result, int sign)
6413 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6415 pic14_emitcode("clr","c");
6416 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6418 pic14_emitcode("mov","c,acc.7");
6419 pic14_emitcode("rrc","a");
6420 aopPut(AOP(result),"a",MSB32-offl);
6422 /* add sign of "a" */
6423 addSign(result, MSB32, sign);
6425 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6426 pic14_emitcode("rrc","a");
6427 aopPut(AOP(result),"a",MSB24-offl);
6429 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6430 pic14_emitcode("rrc","a");
6431 aopPut(AOP(result),"a",MSB16-offl);
6434 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6435 pic14_emitcode("rrc","a");
6436 aopPut(AOP(result),"a",LSB);
6440 /*-----------------------------------------------------------------*/
6441 /* genrshFour - shift four byte by a known amount != 0 */
6442 /*-----------------------------------------------------------------*/
6443 static void genrshFour (operand *result, operand *left,
6444 int shCount, int sign)
6446 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6447 /* if shifting more that 3 bytes */
6448 if(shCount >= 24 ) {
6451 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6453 movLeft2Result(left, MSB32, result, LSB, sign);
6454 addSign(result, MSB16, sign);
6456 else if(shCount >= 16){
6459 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6461 movLeft2Result(left, MSB24, result, LSB, 0);
6462 movLeft2Result(left, MSB32, result, MSB16, sign);
6464 addSign(result, MSB24, sign);
6466 else if(shCount >= 8){
6469 shiftRLong(left, MSB16, result, sign);
6470 else if(shCount == 0){
6471 movLeft2Result(left, MSB16, result, LSB, 0);
6472 movLeft2Result(left, MSB24, result, MSB16, 0);
6473 movLeft2Result(left, MSB32, result, MSB24, sign);
6474 addSign(result, MSB32, sign);
6477 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6478 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6479 /* the last shift is signed */
6480 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6481 addSign(result, MSB32, sign);
6484 else{ /* 1 <= shCount <= 7 */
6486 shiftRLong(left, LSB, result, sign);
6488 shiftRLong(result, LSB, result, sign);
6491 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6492 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6493 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6498 /*-----------------------------------------------------------------*/
6499 /* genRightShiftLiteral - right shifting by known count */
6500 /*-----------------------------------------------------------------*/
6501 static void genRightShiftLiteral (operand *left,
6507 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6510 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6511 freeAsmop(right,NULL,ic,TRUE);
6513 aopOp(left,ic,FALSE);
6514 aopOp(result,ic,FALSE);
6517 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6521 size = pic14_getDataSize(left);
6522 /* test the LEFT size !!! */
6524 /* I suppose that the left size >= result size */
6526 size = pic14_getDataSize(result);
6528 movLeft2Result(left, size, result, size, 0);
6531 else if(shCount >= (size * 8)){
6533 /* get sign in acc.7 */
6534 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6535 addSign(result, LSB, sign);
6539 genrshOne (result,left,shCount,sign);
6543 genrshTwo (result,left,shCount,sign);
6547 genrshFour (result,left,shCount,sign);
6553 freeAsmop(left,NULL,ic,TRUE);
6554 freeAsmop(result,NULL,ic,TRUE);
6558 /*-----------------------------------------------------------------*/
6559 /* genSignedRightShift - right shift of signed number */
6560 /*-----------------------------------------------------------------*/
6561 static void genSignedRightShift (iCode *ic)
6563 operand *right, *left, *result;
6566 symbol *tlbl, *tlbl1 ;
6568 /* we do it the hard way put the shift count in b
6569 and loop thru preserving the sign */
6570 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6572 right = IC_RIGHT(ic);
6574 result = IC_RESULT(ic);
6576 aopOp(right,ic,FALSE);
6579 if ( AOP_TYPE(right) == AOP_LIT) {
6580 genRightShiftLiteral (left,right,result,ic,1);
6583 /* shift count is unknown then we have to form
6584 a loop get the loop count in B : Note: we take
6585 only the lower order byte since shifting
6586 more that 32 bits make no sense anyway, ( the
6587 largest size of an object can be only 32 bits ) */
6589 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6590 pic14_emitcode("inc","b");
6591 freeAsmop (right,NULL,ic,TRUE);
6592 aopOp(left,ic,FALSE);
6593 aopOp(result,ic,FALSE);
6595 /* now move the left to the result if they are not the
6597 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6598 AOP_SIZE(result) > 1) {
6600 size = AOP_SIZE(result);
6603 l = aopGet(AOP(left),offset,FALSE,TRUE);
6604 if (*l == '@' && IS_AOP_PREG(result)) {
6606 pic14_emitcode("mov","a,%s",l);
6607 aopPut(AOP(result),"a",offset);
6609 aopPut(AOP(result),l,offset);
6614 /* mov the highest order bit to OVR */
6615 tlbl = newiTempLabel(NULL);
6616 tlbl1= newiTempLabel(NULL);
6618 size = AOP_SIZE(result);
6620 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6621 pic14_emitcode("rlc","a");
6622 pic14_emitcode("mov","ov,c");
6623 /* if it is only one byte then */
6625 l = aopGet(AOP(left),0,FALSE,FALSE);
6627 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6628 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6629 pic14_emitcode("mov","c,ov");
6630 pic14_emitcode("rrc","a");
6631 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6632 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6633 aopPut(AOP(result),"a",0);
6637 reAdjustPreg(AOP(result));
6638 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6639 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6640 pic14_emitcode("mov","c,ov");
6642 l = aopGet(AOP(result),offset,FALSE,FALSE);
6644 pic14_emitcode("rrc","a");
6645 aopPut(AOP(result),"a",offset--);
6647 reAdjustPreg(AOP(result));
6648 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6649 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6652 freeAsmop(left,NULL,ic,TRUE);
6653 freeAsmop(result,NULL,ic,TRUE);
6656 /*-----------------------------------------------------------------*/
6657 /* genRightShift - generate code for right shifting */
6658 /*-----------------------------------------------------------------*/
6659 static void genRightShift (iCode *ic)
6661 operand *right, *left, *result;
6665 symbol *tlbl, *tlbl1 ;
6667 /* if signed then we do it the hard way preserve the
6668 sign bit moving it inwards */
6669 retype = getSpec(operandType(IC_RESULT(ic)));
6670 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6672 if (!SPEC_USIGN(retype)) {
6673 genSignedRightShift (ic);
6677 /* signed & unsigned types are treated the same : i.e. the
6678 signed is NOT propagated inwards : quoting from the
6679 ANSI - standard : "for E1 >> E2, is equivalent to division
6680 by 2**E2 if unsigned or if it has a non-negative value,
6681 otherwise the result is implementation defined ", MY definition
6682 is that the sign does not get propagated */
6684 right = IC_RIGHT(ic);
6686 result = IC_RESULT(ic);
6688 aopOp(right,ic,FALSE);
6690 /* if the shift count is known then do it
6691 as efficiently as possible */
6692 if (AOP_TYPE(right) == AOP_LIT) {
6693 genRightShiftLiteral (left,right,result,ic, 0);
6697 /* shift count is unknown then we have to form
6698 a loop get the loop count in B : Note: we take
6699 only the lower order byte since shifting
6700 more that 32 bits make no sense anyway, ( the
6701 largest size of an object can be only 32 bits ) */
6703 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6704 pic14_emitcode("inc","b");
6705 aopOp(left,ic,FALSE);
6706 aopOp(result,ic,FALSE);
6708 /* now move the left to the result if they are not the
6710 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6711 AOP_SIZE(result) > 1) {
6713 size = AOP_SIZE(result);
6716 l = aopGet(AOP(left),offset,FALSE,TRUE);
6717 if (*l == '@' && IS_AOP_PREG(result)) {
6719 pic14_emitcode("mov","a,%s",l);
6720 aopPut(AOP(result),"a",offset);
6722 aopPut(AOP(result),l,offset);
6727 tlbl = newiTempLabel(NULL);
6728 tlbl1= newiTempLabel(NULL);
6729 size = AOP_SIZE(result);
6732 /* if it is only one byte then */
6735 l = aopGet(AOP(left),0,FALSE,FALSE);
6737 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6738 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6740 pic14_emitcode("rrc","a");
6741 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6742 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6743 aopPut(AOP(result),"a",0);
6745 tlbl = newiTempLabel(NULL);
6746 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6747 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6748 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6751 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6752 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6753 emitpLabel(tlbl->key+100+labelOffset);
6754 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6755 emitpcode(POC_ADDLW, popGetLit(1));
6757 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6762 reAdjustPreg(AOP(result));
6763 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6764 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6767 l = aopGet(AOP(result),offset,FALSE,FALSE);
6769 pic14_emitcode("rrc","a");
6770 aopPut(AOP(result),"a",offset--);
6772 reAdjustPreg(AOP(result));
6774 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6775 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6778 freeAsmop(left,NULL,ic,TRUE);
6779 freeAsmop (right,NULL,ic,TRUE);
6780 freeAsmop(result,NULL,ic,TRUE);
6783 /*-----------------------------------------------------------------*/
6784 /* genUnpackBits - generates code for unpacking bits */
6785 /*-----------------------------------------------------------------*/
6786 static void genUnpackBits (operand *result, char *rname, int ptype)
6793 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6794 etype = getSpec(operandType(result));
6796 /* read the first byte */
6801 pic14_emitcode("mov","a,@%s",rname);
6805 pic14_emitcode("movx","a,@%s",rname);
6809 pic14_emitcode("movx","a,@dptr");
6813 pic14_emitcode("clr","a");
6814 pic14_emitcode("movc","a","@a+dptr");
6818 pic14_emitcode("lcall","__gptrget");
6822 /* if we have bitdisplacement then it fits */
6823 /* into this byte completely or if length is */
6824 /* less than a byte */
6825 if ((shCnt = SPEC_BSTR(etype)) ||
6826 (SPEC_BLEN(etype) <= 8)) {
6828 /* shift right acc */
6831 pic14_emitcode("anl","a,#0x%02x",
6832 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6833 aopPut(AOP(result),"a",offset);
6837 /* bit field did not fit in a byte */
6838 rlen = SPEC_BLEN(etype) - 8;
6839 aopPut(AOP(result),"a",offset++);
6846 pic14_emitcode("inc","%s",rname);
6847 pic14_emitcode("mov","a,@%s",rname);
6851 pic14_emitcode("inc","%s",rname);
6852 pic14_emitcode("movx","a,@%s",rname);
6856 pic14_emitcode("inc","dptr");
6857 pic14_emitcode("movx","a,@dptr");
6861 pic14_emitcode("clr","a");
6862 pic14_emitcode("inc","dptr");
6863 pic14_emitcode("movc","a","@a+dptr");
6867 pic14_emitcode("inc","dptr");
6868 pic14_emitcode("lcall","__gptrget");
6873 /* if we are done */
6877 aopPut(AOP(result),"a",offset++);
6882 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
6883 aopPut(AOP(result),"a",offset);
6890 /*-----------------------------------------------------------------*/
6891 /* genDataPointerGet - generates code when ptr offset is known */
6892 /*-----------------------------------------------------------------*/
6893 static void genDataPointerGet (operand *left,
6897 int size , offset = 0;
6900 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6903 /* optimization - most of the time, left and result are the same
6904 * address, but different types. for the pic code, we could omit
6908 aopOp(result,ic,TRUE);
6910 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
6912 size = AOP_SIZE(result);
6915 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
6919 freeAsmop(left,NULL,ic,TRUE);
6920 freeAsmop(result,NULL,ic,TRUE);
6923 /*-----------------------------------------------------------------*/
6924 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
6925 /*-----------------------------------------------------------------*/
6926 static void genNearPointerGet (operand *left,
6933 sym_link *rtype, *retype;
6934 sym_link *ltype = operandType(left);
6937 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6939 rtype = operandType(result);
6940 retype= getSpec(rtype);
6942 aopOp(left,ic,FALSE);
6944 /* if left is rematerialisable and
6945 result is not bit variable type and
6946 the left is pointer to data space i.e
6947 lower 128 bytes of space */
6948 if (AOP_TYPE(left) == AOP_IMMD &&
6949 !IS_BITVAR(retype) &&
6950 DCL_TYPE(ltype) == POINTER) {
6951 genDataPointerGet (left,result,ic);
6955 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6957 /* if the value is already in a pointer register
6958 then don't need anything more */
6959 if (!AOP_INPREG(AOP(left))) {
6960 /* otherwise get a free pointer register */
6961 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6963 preg = getFreePtr(ic,&aop,FALSE);
6964 pic14_emitcode("mov","%s,%s",
6966 aopGet(AOP(left),0,FALSE,TRUE));
6967 rname = preg->name ;
6969 rname = aopGet(AOP(left),0,FALSE,FALSE);
6971 freeAsmop(left,NULL,ic,TRUE);
6972 aopOp (result,ic,FALSE);
6974 /* if bitfield then unpack the bits */
6975 if (IS_BITVAR(retype))
6976 genUnpackBits (result,rname,POINTER);
6978 /* we have can just get the values */
6979 int size = AOP_SIZE(result);
6982 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6984 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
6986 pic14_emitcode("mov","a,@%s",rname);
6987 aopPut(AOP(result),"a",offset);
6989 sprintf(buffer,"@%s",rname);
6990 aopPut(AOP(result),buffer,offset);
6994 pic14_emitcode("inc","%s",rname);
6998 /* now some housekeeping stuff */
7000 /* we had to allocate for this iCode */
7001 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7002 freeAsmop(NULL,aop,ic,TRUE);
7004 /* we did not allocate which means left
7005 already in a pointer register, then
7006 if size > 0 && this could be used again
7007 we have to point it back to where it
7009 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7010 if (AOP_SIZE(result) > 1 &&
7011 !OP_SYMBOL(left)->remat &&
7012 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7014 int size = AOP_SIZE(result) - 1;
7016 pic14_emitcode("dec","%s",rname);
7021 freeAsmop(result,NULL,ic,TRUE);
7025 /*-----------------------------------------------------------------*/
7026 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7027 /*-----------------------------------------------------------------*/
7028 static void genPagedPointerGet (operand *left,
7035 sym_link *rtype, *retype;
7037 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7039 rtype = operandType(result);
7040 retype= getSpec(rtype);
7042 aopOp(left,ic,FALSE);
7044 /* if the value is already in a pointer register
7045 then don't need anything more */
7046 if (!AOP_INPREG(AOP(left))) {
7047 /* otherwise get a free pointer register */
7049 preg = getFreePtr(ic,&aop,FALSE);
7050 pic14_emitcode("mov","%s,%s",
7052 aopGet(AOP(left),0,FALSE,TRUE));
7053 rname = preg->name ;
7055 rname = aopGet(AOP(left),0,FALSE,FALSE);
7057 freeAsmop(left,NULL,ic,TRUE);
7058 aopOp (result,ic,FALSE);
7060 /* if bitfield then unpack the bits */
7061 if (IS_BITVAR(retype))
7062 genUnpackBits (result,rname,PPOINTER);
7064 /* we have can just get the values */
7065 int size = AOP_SIZE(result);
7070 pic14_emitcode("movx","a,@%s",rname);
7071 aopPut(AOP(result),"a",offset);
7076 pic14_emitcode("inc","%s",rname);
7080 /* now some housekeeping stuff */
7082 /* we had to allocate for this iCode */
7083 freeAsmop(NULL,aop,ic,TRUE);
7085 /* we did not allocate which means left
7086 already in a pointer register, then
7087 if size > 0 && this could be used again
7088 we have to point it back to where it
7090 if (AOP_SIZE(result) > 1 &&
7091 !OP_SYMBOL(left)->remat &&
7092 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7094 int size = AOP_SIZE(result) - 1;
7096 pic14_emitcode("dec","%s",rname);
7101 freeAsmop(result,NULL,ic,TRUE);
7106 /*-----------------------------------------------------------------*/
7107 /* genFarPointerGet - gget value from far space */
7108 /*-----------------------------------------------------------------*/
7109 static void genFarPointerGet (operand *left,
7110 operand *result, iCode *ic)
7113 sym_link *retype = getSpec(operandType(result));
7115 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7117 aopOp(left,ic,FALSE);
7119 /* if the operand is already in dptr
7120 then we do nothing else we move the value to dptr */
7121 if (AOP_TYPE(left) != AOP_STR) {
7122 /* if this is remateriazable */
7123 if (AOP_TYPE(left) == AOP_IMMD)
7124 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7125 else { /* we need to get it byte by byte */
7126 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7127 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7128 if (options.model == MODEL_FLAT24)
7130 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7134 /* so dptr know contains the address */
7135 freeAsmop(left,NULL,ic,TRUE);
7136 aopOp(result,ic,FALSE);
7138 /* if bit then unpack */
7139 if (IS_BITVAR(retype))
7140 genUnpackBits(result,"dptr",FPOINTER);
7142 size = AOP_SIZE(result);
7146 pic14_emitcode("movx","a,@dptr");
7147 aopPut(AOP(result),"a",offset++);
7149 pic14_emitcode("inc","dptr");
7153 freeAsmop(result,NULL,ic,TRUE);
7156 /*-----------------------------------------------------------------*/
7157 /* pic14_emitcodePointerGet - gget value from code space */
7158 /*-----------------------------------------------------------------*/
7159 static void pic14_emitcodePointerGet (operand *left,
7160 operand *result, iCode *ic)
7163 sym_link *retype = getSpec(operandType(result));
7165 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7167 aopOp(left,ic,FALSE);
7169 /* if the operand is already in dptr
7170 then we do nothing else we move the value to dptr */
7171 if (AOP_TYPE(left) != AOP_STR) {
7172 /* if this is remateriazable */
7173 if (AOP_TYPE(left) == AOP_IMMD)
7174 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7175 else { /* we need to get it byte by byte */
7176 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7177 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7178 if (options.model == MODEL_FLAT24)
7180 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7184 /* so dptr know contains the address */
7185 freeAsmop(left,NULL,ic,TRUE);
7186 aopOp(result,ic,FALSE);
7188 /* if bit then unpack */
7189 if (IS_BITVAR(retype))
7190 genUnpackBits(result,"dptr",CPOINTER);
7192 size = AOP_SIZE(result);
7196 pic14_emitcode("clr","a");
7197 pic14_emitcode("movc","a,@a+dptr");
7198 aopPut(AOP(result),"a",offset++);
7200 pic14_emitcode("inc","dptr");
7204 freeAsmop(result,NULL,ic,TRUE);
7207 /*-----------------------------------------------------------------*/
7208 /* genGenPointerGet - gget value from generic pointer space */
7209 /*-----------------------------------------------------------------*/
7210 static void genGenPointerGet (operand *left,
7211 operand *result, iCode *ic)
7214 sym_link *retype = getSpec(operandType(result));
7216 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7217 aopOp(left,ic,FALSE);
7219 /* if the operand is already in dptr
7220 then we do nothing else we move the value to dptr */
7221 if (AOP_TYPE(left) != AOP_STR) {
7222 /* if this is remateriazable */
7223 if (AOP_TYPE(left) == AOP_IMMD) {
7224 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7225 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7227 else { /* we need to get it byte by byte */
7228 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7229 //emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
7230 //emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7231 pic14_emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
7232 pic14_emitcode("movwf","FSR");
7234 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7235 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7236 if (options.model == MODEL_FLAT24)
7238 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7239 pic14_emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
7243 pic14_emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
7248 /* so dptr know contains the address */
7249 freeAsmop(left,NULL,ic,TRUE);
7250 aopOp(result,ic,FALSE);
7252 /* if bit then unpack */
7253 if (IS_BITVAR(retype))
7254 genUnpackBits(result,"dptr",GPOINTER);
7256 size = AOP_SIZE(result);
7260 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7262 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7264 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7266 pic14_emitcode("movf","indf,w");
7267 pic14_emitcode("movwf","%s",
7268 aopGet(AOP(result),offset++,FALSE,FALSE));
7270 pic14_emitcode("incf","fsr,f");
7275 freeAsmop(result,NULL,ic,TRUE);
7278 /*-----------------------------------------------------------------*/
7279 /* genPointerGet - generate code for pointer get */
7280 /*-----------------------------------------------------------------*/
7281 static void genPointerGet (iCode *ic)
7283 operand *left, *result ;
7284 sym_link *type, *etype;
7287 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7290 result = IC_RESULT(ic) ;
7292 /* depending on the type of pointer we need to
7293 move it to the correct pointer register */
7294 type = operandType(left);
7295 etype = getSpec(type);
7296 /* if left is of type of pointer then it is simple */
7297 if (IS_PTR(type) && !IS_FUNC(type->next))
7298 p_type = DCL_TYPE(type);
7300 /* we have to go by the storage class */
7301 p_type = PTR_TYPE(SPEC_OCLS(etype));
7303 /* if (SPEC_OCLS(etype)->codesp ) { */
7304 /* p_type = CPOINTER ; */
7307 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7308 /* p_type = FPOINTER ; */
7310 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7311 /* p_type = PPOINTER; */
7313 /* if (SPEC_OCLS(etype) == idata ) */
7314 /* p_type = IPOINTER; */
7316 /* p_type = POINTER ; */
7319 /* now that we have the pointer type we assign
7320 the pointer values */
7325 genNearPointerGet (left,result,ic);
7329 genPagedPointerGet(left,result,ic);
7333 genFarPointerGet (left,result,ic);
7337 pic14_emitcodePointerGet (left,result,ic);
7341 genGenPointerGet (left,result,ic);
7347 /*-----------------------------------------------------------------*/
7348 /* genPackBits - generates code for packed bit storage */
7349 /*-----------------------------------------------------------------*/
7350 static void genPackBits (sym_link *etype ,
7352 char *rname, int p_type)
7360 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7361 blen = SPEC_BLEN(etype);
7362 bstr = SPEC_BSTR(etype);
7364 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7367 /* if the bit lenth is less than or */
7368 /* it exactly fits a byte then */
7369 if (SPEC_BLEN(etype) <= 8 ) {
7370 shCount = SPEC_BSTR(etype) ;
7372 /* shift left acc */
7375 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7380 pic14_emitcode ("mov","b,a");
7381 pic14_emitcode("mov","a,@%s",rname);
7385 pic14_emitcode ("mov","b,a");
7386 pic14_emitcode("movx","a,@dptr");
7390 pic14_emitcode ("push","b");
7391 pic14_emitcode ("push","acc");
7392 pic14_emitcode ("lcall","__gptrget");
7393 pic14_emitcode ("pop","b");
7397 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7398 ((unsigned char)(0xFF << (blen+bstr)) |
7399 (unsigned char)(0xFF >> (8-bstr)) ) );
7400 pic14_emitcode ("orl","a,b");
7401 if (p_type == GPOINTER)
7402 pic14_emitcode("pop","b");
7408 pic14_emitcode("mov","@%s,a",rname);
7412 pic14_emitcode("movx","@dptr,a");
7416 DEBUGpic14_emitcode(";lcall","__gptrput");
7421 if ( SPEC_BLEN(etype) <= 8 )
7424 pic14_emitcode("inc","%s",rname);
7425 rLen = SPEC_BLEN(etype) ;
7427 /* now generate for lengths greater than one byte */
7430 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7440 pic14_emitcode("mov","@%s,a",rname);
7442 pic14_emitcode("mov","@%s,%s",rname,l);
7447 pic14_emitcode("movx","@dptr,a");
7452 DEBUGpic14_emitcode(";lcall","__gptrput");
7455 pic14_emitcode ("inc","%s",rname);
7460 /* last last was not complete */
7462 /* save the byte & read byte */
7465 pic14_emitcode ("mov","b,a");
7466 pic14_emitcode("mov","a,@%s",rname);
7470 pic14_emitcode ("mov","b,a");
7471 pic14_emitcode("movx","a,@dptr");
7475 pic14_emitcode ("push","b");
7476 pic14_emitcode ("push","acc");
7477 pic14_emitcode ("lcall","__gptrget");
7478 pic14_emitcode ("pop","b");
7482 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7483 pic14_emitcode ("orl","a,b");
7486 if (p_type == GPOINTER)
7487 pic14_emitcode("pop","b");
7492 pic14_emitcode("mov","@%s,a",rname);
7496 pic14_emitcode("movx","@dptr,a");
7500 DEBUGpic14_emitcode(";lcall","__gptrput");
7504 /*-----------------------------------------------------------------*/
7505 /* genDataPointerSet - remat pointer to data space */
7506 /*-----------------------------------------------------------------*/
7507 static void genDataPointerSet(operand *right,
7511 int size, offset = 0 ;
7512 char *l, buffer[256];
7514 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7515 aopOp(right,ic,FALSE);
7517 l = aopGet(AOP(result),0,FALSE,TRUE);
7518 size = AOP_SIZE(right);
7519 // tsd, was l+1 - the underline `_' prefix was being stripped
7522 sprintf(buffer,"(%s + %d)",l,offset);
7524 sprintf(buffer,"%s",l);
7526 if (AOP_TYPE(right) == AOP_LIT) {
7527 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7528 lit = lit >> (8*offset);
7530 pic14_emitcode("movlw","%d",lit);
7531 pic14_emitcode("movwf","%s",buffer);
7533 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7534 emitpcode(POC_MOVWF, popRegFromString(buffer));
7537 pic14_emitcode("clrf","%s",buffer);
7538 emitpcode(POC_CLRF, popRegFromString(buffer));
7541 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7542 pic14_emitcode("movwf","%s",buffer);
7544 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7545 emitpcode(POC_MOVWF, popRegFromString(buffer));
7552 freeAsmop(right,NULL,ic,TRUE);
7553 freeAsmop(result,NULL,ic,TRUE);
7556 /*-----------------------------------------------------------------*/
7557 /* genNearPointerSet - pic14_emitcode for near pointer put */
7558 /*-----------------------------------------------------------------*/
7559 static void genNearPointerSet (operand *right,
7566 sym_link *ptype = operandType(result);
7569 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7570 retype= getSpec(operandType(right));
7572 aopOp(result,ic,FALSE);
7574 /* if the result is rematerializable &
7575 in data space & not a bit variable */
7576 if (AOP_TYPE(result) == AOP_IMMD &&
7577 DCL_TYPE(ptype) == POINTER &&
7578 !IS_BITVAR(retype)) {
7579 genDataPointerSet (right,result,ic);
7583 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7585 /* if the value is already in a pointer register
7586 then don't need anything more */
7587 if (!AOP_INPREG(AOP(result))) {
7588 /* otherwise get a free pointer register */
7589 //aop = newAsmop(0);
7590 //preg = getFreePtr(ic,&aop,FALSE);
7591 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7592 //pic14_emitcode("mov","%s,%s",
7594 // aopGet(AOP(result),0,FALSE,TRUE));
7595 //rname = preg->name ;
7596 pic14_emitcode("movwf","fsr");
7598 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7600 freeAsmop(result,NULL,ic,TRUE);
7601 aopOp (right,ic,FALSE);
7602 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7604 /* if bitfield then unpack the bits */
7605 if (IS_BITVAR(retype)) {
7606 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7607 "The programmer is obviously confused");
7608 //genPackBits (retype,right,rname,POINTER);
7612 /* we have can just get the values */
7613 int size = AOP_SIZE(right);
7616 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7618 l = aopGet(AOP(right),offset,FALSE,TRUE);
7621 //pic14_emitcode("mov","@%s,a",rname);
7622 pic14_emitcode("movf","indf,w ;1");
7625 if (AOP_TYPE(right) == AOP_LIT) {
7626 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7628 pic14_emitcode("movlw","%s",l);
7629 pic14_emitcode("movwf","indf ;2");
7631 pic14_emitcode("clrf","indf");
7633 pic14_emitcode("movf","%s,w",l);
7634 pic14_emitcode("movwf","indf ;2");
7636 //pic14_emitcode("mov","@%s,%s",rname,l);
7639 pic14_emitcode("incf","fsr,f ;3");
7640 //pic14_emitcode("inc","%s",rname);
7645 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7646 /* now some housekeeping stuff */
7648 /* we had to allocate for this iCode */
7649 freeAsmop(NULL,aop,ic,TRUE);
7651 /* we did not allocate which means left
7652 already in a pointer register, then
7653 if size > 0 && this could be used again
7654 we have to point it back to where it
7656 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7657 if (AOP_SIZE(right) > 1 &&
7658 !OP_SYMBOL(result)->remat &&
7659 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7661 int size = AOP_SIZE(right) - 1;
7663 pic14_emitcode("decf","fsr,f");
7664 //pic14_emitcode("dec","%s",rname);
7668 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7670 freeAsmop(right,NULL,ic,TRUE);
7675 /*-----------------------------------------------------------------*/
7676 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7677 /*-----------------------------------------------------------------*/
7678 static void genPagedPointerSet (operand *right,
7687 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7689 retype= getSpec(operandType(right));
7691 aopOp(result,ic,FALSE);
7693 /* if the value is already in a pointer register
7694 then don't need anything more */
7695 if (!AOP_INPREG(AOP(result))) {
7696 /* otherwise get a free pointer register */
7698 preg = getFreePtr(ic,&aop,FALSE);
7699 pic14_emitcode("mov","%s,%s",
7701 aopGet(AOP(result),0,FALSE,TRUE));
7702 rname = preg->name ;
7704 rname = aopGet(AOP(result),0,FALSE,FALSE);
7706 freeAsmop(result,NULL,ic,TRUE);
7707 aopOp (right,ic,FALSE);
7709 /* if bitfield then unpack the bits */
7710 if (IS_BITVAR(retype))
7711 genPackBits (retype,right,rname,PPOINTER);
7713 /* we have can just get the values */
7714 int size = AOP_SIZE(right);
7718 l = aopGet(AOP(right),offset,FALSE,TRUE);
7721 pic14_emitcode("movx","@%s,a",rname);
7724 pic14_emitcode("inc","%s",rname);
7730 /* now some housekeeping stuff */
7732 /* we had to allocate for this iCode */
7733 freeAsmop(NULL,aop,ic,TRUE);
7735 /* we did not allocate which means left
7736 already in a pointer register, then
7737 if size > 0 && this could be used again
7738 we have to point it back to where it
7740 if (AOP_SIZE(right) > 1 &&
7741 !OP_SYMBOL(result)->remat &&
7742 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7744 int size = AOP_SIZE(right) - 1;
7746 pic14_emitcode("dec","%s",rname);
7751 freeAsmop(right,NULL,ic,TRUE);
7756 /*-----------------------------------------------------------------*/
7757 /* genFarPointerSet - set value from far space */
7758 /*-----------------------------------------------------------------*/
7759 static void genFarPointerSet (operand *right,
7760 operand *result, iCode *ic)
7763 sym_link *retype = getSpec(operandType(right));
7765 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7766 aopOp(result,ic,FALSE);
7768 /* if the operand is already in dptr
7769 then we do nothing else we move the value to dptr */
7770 if (AOP_TYPE(result) != AOP_STR) {
7771 /* if this is remateriazable */
7772 if (AOP_TYPE(result) == AOP_IMMD)
7773 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7774 else { /* we need to get it byte by byte */
7775 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7776 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7777 if (options.model == MODEL_FLAT24)
7779 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7783 /* so dptr know contains the address */
7784 freeAsmop(result,NULL,ic,TRUE);
7785 aopOp(right,ic,FALSE);
7787 /* if bit then unpack */
7788 if (IS_BITVAR(retype))
7789 genPackBits(retype,right,"dptr",FPOINTER);
7791 size = AOP_SIZE(right);
7795 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7797 pic14_emitcode("movx","@dptr,a");
7799 pic14_emitcode("inc","dptr");
7803 freeAsmop(right,NULL,ic,TRUE);
7806 /*-----------------------------------------------------------------*/
7807 /* genGenPointerSet - set value from generic pointer space */
7808 /*-----------------------------------------------------------------*/
7809 static void genGenPointerSet (operand *right,
7810 operand *result, iCode *ic)
7813 sym_link *retype = getSpec(operandType(right));
7815 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7817 aopOp(result,ic,FALSE);
7819 /* if the operand is already in dptr
7820 then we do nothing else we move the value to dptr */
7821 if (AOP_TYPE(result) != AOP_STR) {
7822 /* if this is remateriazable */
7823 if (AOP_TYPE(result) == AOP_IMMD) {
7824 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7825 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7827 else { /* we need to get it byte by byte */
7828 char *l = aopGet(AOP(result),0,FALSE,FALSE);
7831 emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
7832 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7835 pic14_emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
7837 pic14_emitcode("movwf","INDF");
7840 /* so dptr know contains the address */
7841 freeAsmop(result,NULL,ic,TRUE);
7842 aopOp(right,ic,FALSE);
7844 /* if bit then unpack */
7845 if (IS_BITVAR(retype))
7846 genPackBits(retype,right,"dptr",GPOINTER);
7848 size = AOP_SIZE(right);
7852 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7854 pic14_emitcode("incf","fsr,f");
7855 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
7856 pic14_emitcode("movwf","indf");
7858 //DEBUGpic14_emitcode(";lcall","__gptrput");
7860 // pic14_emitcode("inc","dptr");
7864 freeAsmop(right,NULL,ic,TRUE);
7867 /*-----------------------------------------------------------------*/
7868 /* genPointerSet - stores the value into a pointer location */
7869 /*-----------------------------------------------------------------*/
7870 static void genPointerSet (iCode *ic)
7872 operand *right, *result ;
7873 sym_link *type, *etype;
7876 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7878 right = IC_RIGHT(ic);
7879 result = IC_RESULT(ic) ;
7881 /* depending on the type of pointer we need to
7882 move it to the correct pointer register */
7883 type = operandType(result);
7884 etype = getSpec(type);
7885 /* if left is of type of pointer then it is simple */
7886 if (IS_PTR(type) && !IS_FUNC(type->next)) {
7887 p_type = DCL_TYPE(type);
7890 /* we have to go by the storage class */
7891 p_type = PTR_TYPE(SPEC_OCLS(etype));
7893 /* if (SPEC_OCLS(etype)->codesp ) { */
7894 /* p_type = CPOINTER ; */
7897 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7898 /* p_type = FPOINTER ; */
7900 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7901 /* p_type = PPOINTER ; */
7903 /* if (SPEC_OCLS(etype) == idata ) */
7904 /* p_type = IPOINTER ; */
7906 /* p_type = POINTER ; */
7909 /* now that we have the pointer type we assign
7910 the pointer values */
7915 genNearPointerSet (right,result,ic);
7919 genPagedPointerSet (right,result,ic);
7923 genFarPointerSet (right,result,ic);
7927 genGenPointerSet (right,result,ic);
7933 /*-----------------------------------------------------------------*/
7934 /* genIfx - generate code for Ifx statement */
7935 /*-----------------------------------------------------------------*/
7936 static void genIfx (iCode *ic, iCode *popIc)
7938 operand *cond = IC_COND(ic);
7941 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7942 aopOp(cond,ic,FALSE);
7944 /* get the value into acc */
7945 if (AOP_TYPE(cond) != AOP_CRY)
7946 pic14_toBoolean(cond);
7949 /* the result is now in the accumulator */
7950 freeAsmop(cond,NULL,ic,TRUE);
7952 /* if there was something to be popped then do it */
7956 /* if the condition is a bit variable */
7957 if (isbit && IS_ITEMP(cond) &&
7959 genIfxJump(ic,SPIL_LOC(cond)->rname);
7960 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
7964 if (isbit && !IS_ITEMP(cond))
7965 DEBUGpic14_emitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
7967 DEBUGpic14_emitcode ("; isbit","a");
7970 if (isbit && !IS_ITEMP(cond))
7971 genIfxJump(ic,OP_SYMBOL(cond)->rname);
7978 /*-----------------------------------------------------------------*/
7979 /* genAddrOf - generates code for address of */
7980 /*-----------------------------------------------------------------*/
7981 static void genAddrOf (iCode *ic)
7983 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
7986 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7988 aopOp(IC_RESULT(ic),ic,FALSE);
7990 /* if the operand is on the stack then we
7991 need to get the stack offset of this
7994 /* if it has an offset then we need to compute
7997 pic14_emitcode("mov","a,_bp");
7998 pic14_emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
7999 aopPut(AOP(IC_RESULT(ic)),"a",0);
8001 /* we can just move _bp */
8002 aopPut(AOP(IC_RESULT(ic)),"_bp",0);
8004 /* fill the result with zero */
8005 size = AOP_SIZE(IC_RESULT(ic)) - 1;
8008 if (options.stack10bit && size < (FPTRSIZE - 1))
8011 "*** warning: pointer to stack var truncated.\n");
8018 if (options.stack10bit && offset == 2)
8020 aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
8024 aopPut(AOP(IC_RESULT(ic)),zero,offset++);
8031 /* object not on stack then we need the name */
8032 size = AOP_SIZE(IC_RESULT(ic));
8036 char s[SDCC_NAME_MAX];
8038 sprintf(s,"#(%s >> %d)",
8042 sprintf(s,"#%s",sym->rname);
8043 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8047 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8052 /*-----------------------------------------------------------------*/
8053 /* genFarFarAssign - assignment when both are in far space */
8054 /*-----------------------------------------------------------------*/
8055 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8057 int size = AOP_SIZE(right);
8060 /* first push the right side on to the stack */
8062 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8064 pic14_emitcode ("push","acc");
8067 freeAsmop(right,NULL,ic,FALSE);
8068 /* now assign DPTR to result */
8069 aopOp(result,ic,FALSE);
8070 size = AOP_SIZE(result);
8072 pic14_emitcode ("pop","acc");
8073 aopPut(AOP(result),"a",--offset);
8075 freeAsmop(result,NULL,ic,FALSE);
8080 /*-----------------------------------------------------------------*/
8081 /* genAssign - generate code for assignment */
8082 /*-----------------------------------------------------------------*/
8083 static void genAssign (iCode *ic)
8085 operand *result, *right;
8087 unsigned long lit = 0L;
8089 result = IC_RESULT(ic);
8090 right = IC_RIGHT(ic) ;
8092 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8094 /* if they are the same */
8095 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8098 aopOp(right,ic,FALSE);
8099 aopOp(result,ic,TRUE);
8101 /* if they are the same registers */
8102 if (pic14_sameRegs(AOP(right),AOP(result)))
8105 /* if the result is a bit */
8106 if (AOP_TYPE(result) == AOP_CRY) {
8108 /* if the right size is a literal then
8109 we know what the value is */
8110 if (AOP_TYPE(right) == AOP_LIT) {
8112 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8113 popGet(AOP(result),0,FALSE,FALSE));
8115 if (((int) operandLitValue(right)))
8116 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8117 AOP(result)->aopu.aop_dir,
8118 AOP(result)->aopu.aop_dir);
8120 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8121 AOP(result)->aopu.aop_dir,
8122 AOP(result)->aopu.aop_dir);
8126 /* the right is also a bit variable */
8127 if (AOP_TYPE(right) == AOP_CRY) {
8128 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8129 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8130 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8132 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8133 AOP(result)->aopu.aop_dir,
8134 AOP(result)->aopu.aop_dir);
8135 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8136 AOP(right)->aopu.aop_dir,
8137 AOP(right)->aopu.aop_dir);
8138 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8139 AOP(result)->aopu.aop_dir,
8140 AOP(result)->aopu.aop_dir);
8145 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8146 pic14_toBoolean(right);
8148 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8149 //aopPut(AOP(result),"a",0);
8153 /* bit variables done */
8155 size = AOP_SIZE(result);
8157 if(AOP_TYPE(right) == AOP_LIT)
8158 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8159 if((AOP_TYPE(result) != AOP_REG) &&
8160 (AOP_TYPE(right) == AOP_LIT) &&
8161 !IS_FLOAT(operandType(right)) &&
8165 if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) {
8166 //pic14_emitcode("clrf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8167 emitpcode(POC_CLRF,popGet(AOP(result),size,FALSE,FALSE));
8169 emitpcode(POC_MOVLW,popGet(AOP(right),size,FALSE,FALSE));
8170 emitpcode(POC_MOVWF,popGet(AOP(result),size,FALSE,FALSE));
8171 //pic14_emitcode("movlw","%s", aopGet(AOP(right),size,FALSE,FALSE));
8172 //pic14_emitcode("movwf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8177 if(AOP_TYPE(right) == AOP_LIT) {
8178 emitpcode(POC_MOVLW, popGet(AOP(right),offset,FALSE,FALSE));
8179 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8181 } else if (AOP_TYPE(right) == AOP_CRY) {
8182 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8184 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8185 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8188 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8189 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8192 //pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE));
8198 freeAsmop (right,NULL,ic,FALSE);
8199 freeAsmop (result,NULL,ic,TRUE);
8202 /*-----------------------------------------------------------------*/
8203 /* genJumpTab - genrates code for jump table */
8204 /*-----------------------------------------------------------------*/
8205 static void genJumpTab (iCode *ic)
8210 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8212 aopOp(IC_JTCOND(ic),ic,FALSE);
8213 /* get the condition into accumulator */
8214 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8216 /* multiply by three */
8217 pic14_emitcode("add","a,acc");
8218 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8220 jtab = newiTempLabel(NULL);
8221 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8222 pic14_emitcode("jmp","@a+dptr");
8223 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8225 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8226 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8228 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8229 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8230 emitpLabel(jtab->key+100+labelOffset);
8232 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8234 /* now generate the jump labels */
8235 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8236 jtab = setNextItem(IC_JTLABELS(ic))) {
8237 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8238 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8244 /*-----------------------------------------------------------------*/
8245 /* genMixedOperation - gen code for operators between mixed types */
8246 /*-----------------------------------------------------------------*/
8248 TSD - Written for the PIC port - but this unfortunately is buggy.
8249 This routine is good in that it is able to efficiently promote
8250 types to different (larger) sizes. Unfortunately, the temporary
8251 variables that are optimized out by this routine are sometimes
8252 used in other places. So until I know how to really parse the
8253 iCode tree, I'm going to not be using this routine :(.
8255 static int genMixedOperation (iCode *ic)
8258 operand *result = IC_RESULT(ic);
8259 sym_link *ctype = operandType(IC_LEFT(ic));
8260 operand *right = IC_RIGHT(ic);
8266 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8268 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8274 nextright = IC_RIGHT(nextic);
8275 nextleft = IC_LEFT(nextic);
8276 nextresult = IC_RESULT(nextic);
8278 aopOp(right,ic,FALSE);
8279 aopOp(result,ic,FALSE);
8280 aopOp(nextright, nextic, FALSE);
8281 aopOp(nextleft, nextic, FALSE);
8282 aopOp(nextresult, nextic, FALSE);
8284 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8290 pic14_emitcode(";remove right +","");
8292 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8298 pic14_emitcode(";remove left +","");
8302 big = AOP_SIZE(nextleft);
8303 small = AOP_SIZE(nextright);
8305 switch(nextic->op) {
8308 pic14_emitcode(";optimize a +","");
8309 /* if unsigned or not an integral type */
8310 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8311 pic14_emitcode(";add a bit to something","");
8314 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8316 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8317 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8318 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8320 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8328 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8329 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8330 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8333 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8335 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8336 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8337 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8338 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8339 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8342 pic14_emitcode("rlf","known_zero,w");
8349 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8350 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8351 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8353 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8363 freeAsmop(right,NULL,ic,TRUE);
8364 freeAsmop(result,NULL,ic,TRUE);
8365 freeAsmop(nextright,NULL,ic,TRUE);
8366 freeAsmop(nextleft,NULL,ic,TRUE);
8368 nextic->generated = 1;
8375 /*-----------------------------------------------------------------*/
8376 /* genCast - gen code for casting */
8377 /*-----------------------------------------------------------------*/
8378 static void genCast (iCode *ic)
8380 operand *result = IC_RESULT(ic);
8381 sym_link *ctype = operandType(IC_LEFT(ic));
8382 operand *right = IC_RIGHT(ic);
8385 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8386 /* if they are equivalent then do nothing */
8387 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8390 aopOp(right,ic,FALSE) ;
8391 aopOp(result,ic,FALSE);
8393 /* if the result is a bit */
8394 if (AOP_TYPE(result) == AOP_CRY) {
8395 /* if the right size is a literal then
8396 we know what the value is */
8397 if (AOP_TYPE(right) == AOP_LIT) {
8399 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8400 popGet(AOP(result),0,FALSE,FALSE));
8402 if (((int) operandLitValue(right)))
8403 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8404 AOP(result)->aopu.aop_dir,
8405 AOP(result)->aopu.aop_dir);
8407 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8408 AOP(result)->aopu.aop_dir,
8409 AOP(result)->aopu.aop_dir);
8414 /* the right is also a bit variable */
8415 if (AOP_TYPE(right) == AOP_CRY) {
8418 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8420 pic14_emitcode("clrc","");
8421 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8422 AOP(right)->aopu.aop_dir,
8423 AOP(right)->aopu.aop_dir);
8424 aopPut(AOP(result),"c",0);
8429 pic14_toBoolean(right);
8430 aopPut(AOP(result),"a",0);
8434 /* if they are the same size : or less */
8435 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8437 /* if they are in the same place */
8438 if (pic14_sameRegs(AOP(right),AOP(result)))
8441 /* if they in different places then copy */
8442 size = AOP_SIZE(result);
8446 aopGet(AOP(right),offset,FALSE,FALSE),
8454 /* if the result is of type pointer */
8455 if (IS_PTR(ctype)) {
8458 sym_link *type = operandType(right);
8459 sym_link *etype = getSpec(type);
8461 /* pointer to generic pointer */
8462 if (IS_GENPTR(ctype)) {
8466 p_type = DCL_TYPE(type);
8468 /* we have to go by the storage class */
8469 p_type = PTR_TYPE(SPEC_OCLS(etype));
8471 /* if (SPEC_OCLS(etype)->codesp ) */
8472 /* p_type = CPOINTER ; */
8474 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8475 /* p_type = FPOINTER ; */
8477 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8478 /* p_type = PPOINTER; */
8480 /* if (SPEC_OCLS(etype) == idata ) */
8481 /* p_type = IPOINTER ; */
8483 /* p_type = POINTER ; */
8486 /* the first two bytes are known */
8487 size = GPTRSIZE - 1;
8491 aopGet(AOP(right),offset,FALSE,FALSE),
8495 /* the last byte depending on type */
8512 /* this should never happen */
8513 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8514 "got unknown pointer type");
8517 aopPut(AOP(result),l, GPTRSIZE - 1);
8521 /* just copy the pointers */
8522 size = AOP_SIZE(result);
8526 aopGet(AOP(right),offset,FALSE,FALSE),
8534 if (AOP_TYPE(right) == AOP_CRY) {
8536 size = AOP_SIZE(right);
8538 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8539 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8540 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8542 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8543 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8544 AOP(right)->aopu.aop_dir,
8545 AOP(right)->aopu.aop_dir);
8546 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8548 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8549 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8554 /* so we now know that the size of destination is greater
8555 than the size of the source.
8556 Now, if the next iCode is an operator then we might be
8557 able to optimize the operation without performing a cast.
8559 if(genMixedOperation(ic))
8563 /* we move to result for the size of source */
8564 size = AOP_SIZE(right);
8567 pic14_emitcode(";","%d",__LINE__);
8568 /* aopPut(AOP(result),
8569 aopGet(AOP(right),offset,FALSE,FALSE),
8571 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8572 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8576 /* now depending on the sign of the destination */
8577 size = AOP_SIZE(result) - AOP_SIZE(right);
8578 /* if unsigned or not an integral type */
8579 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8581 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8582 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8586 /* we need to extend the sign :{ */
8588 emitpcodeNULLop(POC_CLRW);
8591 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8593 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8595 emitpcode(POC_MOVLW, popGetLit(0xff));
8597 pic14_emitcode("clrw","");
8598 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8599 AOP(right)->aopu.aop_dir,
8600 AOP(right)->aopu.aop_dir);
8601 pic14_emitcode("movlw","0xff");
8603 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8604 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8606 // aopPut(AOP(result),"a",offset++);
8611 /* we are done hurray !!!! */
8614 freeAsmop(right,NULL,ic,TRUE);
8615 freeAsmop(result,NULL,ic,TRUE);
8619 /*-----------------------------------------------------------------*/
8620 /* genDjnz - generate decrement & jump if not zero instrucion */
8621 /*-----------------------------------------------------------------*/
8622 static int genDjnz (iCode *ic, iCode *ifx)
8625 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8630 /* if the if condition has a false label
8631 then we cannot save */
8635 /* if the minus is not of the form
8637 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8638 !IS_OP_LITERAL(IC_RIGHT(ic)))
8641 if (operandLitValue(IC_RIGHT(ic)) != 1)
8644 /* if the size of this greater than one then no
8646 if (getSize(operandType(IC_RESULT(ic))) > 1)
8649 /* otherwise we can save BIG */
8650 lbl = newiTempLabel(NULL);
8651 lbl1= newiTempLabel(NULL);
8653 aopOp(IC_RESULT(ic),ic,FALSE);
8655 if (IS_AOP_PREG(IC_RESULT(ic))) {
8656 pic14_emitcode("dec","%s",
8657 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8658 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8659 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8663 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8664 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8666 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8667 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8670 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8671 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8672 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8673 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8676 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8681 /*-----------------------------------------------------------------*/
8682 /* genReceive - generate code for a receive iCode */
8683 /*-----------------------------------------------------------------*/
8684 static void genReceive (iCode *ic)
8686 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8688 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8689 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8690 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8692 int size = getSize(operandType(IC_RESULT(ic)));
8693 int offset = fReturnSizePic - size;
8695 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8696 fReturn[fReturnSizePic - offset - 1] : "acc"));
8699 aopOp(IC_RESULT(ic),ic,FALSE);
8700 size = AOP_SIZE(IC_RESULT(ic));
8703 pic14_emitcode ("pop","acc");
8704 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8709 aopOp(IC_RESULT(ic),ic,FALSE);
8711 assignResultValue(IC_RESULT(ic));
8714 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8717 /*-----------------------------------------------------------------*/
8718 /* genpic14Code - generate code for pic14 based controllers */
8719 /*-----------------------------------------------------------------*/
8721 * At this point, ralloc.c has gone through the iCode and attempted
8722 * to optimize in a way suitable for a PIC. Now we've got to generate
8723 * PIC instructions that correspond to the iCode.
8725 * Once the instructions are generated, we'll pass through both the
8726 * peep hole optimizer and the pCode optimizer.
8727 *-----------------------------------------------------------------*/
8729 void genpic14Code (iCode *lic)
8734 lineHead = lineCurr = NULL;
8736 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8739 /* if debug information required */
8740 /* if (options.debug && currFunc) { */
8742 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8744 if (IS_STATIC(currFunc->etype)) {
8745 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8746 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8748 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8749 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8755 for (ic = lic ; ic ; ic = ic->next ) {
8757 DEBUGpic14_emitcode(";ic","");
8758 if ( cln != ic->lineno ) {
8759 if ( options.debug ) {
8761 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8762 FileBaseName(ic->filename),ic->lineno,
8763 ic->level,ic->block);
8766 pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
8769 /* if the result is marked as
8770 spilt and rematerializable or code for
8771 this has already been generated then
8773 if (resultRemat(ic) || ic->generated )
8776 /* depending on the operation */
8795 /* IPOP happens only when trying to restore a
8796 spilt live range, if there is an ifx statement
8797 following this pop then the if statement might
8798 be using some of the registers being popped which
8799 would destory the contents of the register so
8800 we need to check for this condition and handle it */
8802 ic->next->op == IFX &&
8803 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8804 genIfx (ic->next,ic);
8822 genEndFunction (ic);
8842 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
8859 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
8863 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
8870 /* note these two are xlated by algebraic equivalence
8871 during parsing SDCC.y */
8872 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8873 "got '>=' or '<=' shouldn't have come here");
8877 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
8889 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
8893 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
8897 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
8924 case GET_VALUE_AT_ADDRESS:
8929 if (POINTER_SET(ic))
8956 addSet(&_G.sendSet,ic);
8965 /* now we are ready to call the
8966 peep hole optimizer */
8967 if (!options.nopeep) {
8968 printf("peep hole optimizing\n");
8969 peepHole (&lineHead);
8971 /* now do the actual printing */
8972 printLine (lineHead,codeOutFile);
8974 printf("printing pBlock\n\n");
8975 printpBlock(stdout,pb);