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 unsigned int pic14aopLiteral (value *val, int offset);
68 /* this is the down and dirty file with all kinds of
69 kludgy & hacky stuff. This is what it is all about
70 CODE GENERATION for a specific MCU . some of the
71 routines may be reusable, will have to see */
73 static char *zero = "#0x00";
74 static char *one = "#0x01";
75 static char *spname = "sp";
77 char *fReturnpic14[] = {"FSR","dph","b","a" };
78 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
79 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
80 static char **fReturn = fReturnpic14;
82 static char *accUse[] = {"a","b"};
84 //static short rbank = -1;
96 extern int pic14_ptrRegReq ;
97 extern int pic14_nRegs;
98 extern FILE *codeOutFile;
99 static void saverbank (int, iCode *,bool);
101 static lineNode *lineHead = NULL;
102 static lineNode *lineCurr = NULL;
104 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
105 0xE0, 0xC0, 0x80, 0x00};
106 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
107 0x07, 0x03, 0x01, 0x00};
111 /*-----------------------------------------------------------------*/
112 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
113 /* exponent of 2 is returned, otherwise -1 is */
115 /* note that this is similar to the function `powof2' in SDCCsymt */
119 /*-----------------------------------------------------------------*/
120 static int my_powof2 (unsigned long num)
123 if( (num & (num-1)) == 0) {
136 static void emitpLabel(int key)
138 addpCode2pBlock(pb,newpCodeLabel(key));
141 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
144 addpCode2pBlock(pb,newpCode(poc,pcop));
147 /*-----------------------------------------------------------------*/
148 /* pic14_emitcode - writes the code into a file : for now it is simple */
149 /*-----------------------------------------------------------------*/
150 void pic14_emitcode (char *inst,char *fmt, ...)
153 char lb[INITIAL_INLINEASM];
160 sprintf(lb,"%s\t",inst);
162 sprintf(lb,"%s",inst);
163 vsprintf(lb+(strlen(lb)),fmt,ap);
167 while (isspace(*lbp)) lbp++;
170 lineCurr = (lineCurr ?
171 connectLine(lineCurr,newLineNode(lb)) :
172 (lineHead = newLineNode(lb)));
173 lineCurr->isInline = _G.inLine;
174 lineCurr->isDebug = _G.debugLine;
177 addpCode2pBlock(pb,newpCodeCharP(lb));
182 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
185 char lb[INITIAL_INLINEASM];
195 sprintf(lb,"%s\t",inst);
197 sprintf(lb,"%s",inst);
198 vsprintf(lb+(strlen(lb)),fmt,ap);
202 while (isspace(*lbp)) lbp++;
205 lineCurr = (lineCurr ?
206 connectLine(lineCurr,newLineNode(lb)) :
207 (lineHead = newLineNode(lb)));
208 lineCurr->isInline = _G.inLine;
209 lineCurr->isDebug = _G.debugLine;
211 addpCode2pBlock(pb,newpCodeCharP(lb));
217 /*-----------------------------------------------------------------*/
218 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
219 /*-----------------------------------------------------------------*/
220 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
222 bool r0iu = FALSE , r1iu = FALSE;
223 bool r0ou = FALSE , r1ou = FALSE;
225 /* the logic: if r0 & r1 used in the instruction
226 then we are in trouble otherwise */
228 /* first check if r0 & r1 are used by this
229 instruction, in which case we are in trouble */
230 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
231 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
236 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
237 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
239 /* if no usage of r0 then return it */
240 if (!r0iu && !r0ou) {
241 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
242 (*aopp)->type = AOP_R0;
244 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
247 /* if no usage of r1 then return it */
248 if (!r1iu && !r1ou) {
249 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
250 (*aopp)->type = AOP_R1;
252 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
255 /* now we know they both have usage */
256 /* if r0 not used in this instruction */
258 /* push it if not already pushed */
260 pic14_emitcode ("push","%s",
261 pic14_regWithIdx(R0_IDX)->dname);
265 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
266 (*aopp)->type = AOP_R0;
268 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
271 /* if r1 not used then */
274 /* push it if not already pushed */
276 pic14_emitcode ("push","%s",
277 pic14_regWithIdx(R1_IDX)->dname);
281 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
282 (*aopp)->type = AOP_R1;
283 return pic14_regWithIdx(R1_IDX);
287 /* I said end of world but not quite end of world yet */
288 /* if this is a result then we can push it on the stack*/
290 (*aopp)->type = AOP_STK;
294 /* other wise this is true end of the world */
295 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
296 "getFreePtr should never reach here");
300 /*-----------------------------------------------------------------*/
301 /* newAsmop - creates a new asmOp */
302 /*-----------------------------------------------------------------*/
303 asmop *newAsmop (short type)
307 aop = Safe_calloc(1,sizeof(asmop));
312 static void genSetDPTR(int n)
316 pic14_emitcode(";", "Select standard DPTR");
317 pic14_emitcode("mov", "dps, #0x00");
321 pic14_emitcode(";", "Select alternate DPTR");
322 pic14_emitcode("mov", "dps, #0x01");
326 /*-----------------------------------------------------------------*/
327 /* pointerCode - returns the code for a pointer type */
328 /*-----------------------------------------------------------------*/
329 static int pointerCode (sym_link *etype)
332 return PTR_TYPE(SPEC_OCLS(etype));
336 /*-----------------------------------------------------------------*/
337 /* aopForSym - for a true symbol */
338 /*-----------------------------------------------------------------*/
339 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
342 memmap *space= SPEC_OCLS(sym->etype);
344 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
345 /* if already has one */
349 /* assign depending on the storage class */
350 /* if it is on the stack or indirectly addressable */
351 /* space we need to assign either r0 or r1 to it */
352 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
353 sym->aop = aop = newAsmop(0);
354 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
355 aop->size = getSize(sym->type);
357 /* now assign the address of the variable to
358 the pointer register */
359 if (aop->type != AOP_STK) {
363 pic14_emitcode("push","acc");
365 pic14_emitcode("mov","a,_bp");
366 pic14_emitcode("add","a,#0x%02x",
368 ((char)(sym->stack - _G.nRegsSaved )) :
369 ((char)sym->stack)) & 0xff);
370 pic14_emitcode("mov","%s,a",
371 aop->aopu.aop_ptr->name);
374 pic14_emitcode("pop","acc");
376 pic14_emitcode("mov","%s,#%s",
377 aop->aopu.aop_ptr->name,
379 aop->paged = space->paged;
381 aop->aopu.aop_stk = sym->stack;
385 if (sym->onStack && options.stack10bit)
387 /* It's on the 10 bit stack, which is located in
391 //DEBUGpic14_emitcode(";","%d",__LINE__);
394 pic14_emitcode("push","acc");
396 pic14_emitcode("mov","a,_bp");
397 pic14_emitcode("add","a,#0x%02x",
399 ((char)(sym->stack - _G.nRegsSaved )) :
400 ((char)sym->stack)) & 0xff);
403 pic14_emitcode ("mov","dpx1,#0x40");
404 pic14_emitcode ("mov","dph1,#0x00");
405 pic14_emitcode ("mov","dpl1, a");
409 pic14_emitcode("pop","acc");
411 sym->aop = aop = newAsmop(AOP_DPTR2);
412 aop->size = getSize(sym->type);
416 //DEBUGpic14_emitcode(";","%d",__LINE__);
417 /* if in bit space */
418 if (IN_BITSPACE(space)) {
419 sym->aop = aop = newAsmop (AOP_CRY);
420 aop->aopu.aop_dir = sym->rname ;
421 aop->size = getSize(sym->type);
422 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
425 /* if it is in direct space */
426 if (IN_DIRSPACE(space)) {
427 sym->aop = aop = newAsmop (AOP_DIR);
428 aop->aopu.aop_dir = sym->rname ;
429 aop->size = getSize(sym->type);
430 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
434 /* special case for a function */
435 if (IS_FUNC(sym->type)) {
436 sym->aop = aop = newAsmop(AOP_IMMD);
437 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
438 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
439 strcpy(aop->aopu.aop_immd,sym->rname);
440 aop->size = FPTRSIZE;
445 /* only remaining is far space */
446 /* in which case DPTR gets the address */
447 sym->aop = aop = newAsmop(AOP_DPTR);
448 pic14_emitcode ("mov","dptr,#%s", sym->rname);
449 aop->size = getSize(sym->type);
451 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
452 /* if it is in code space */
453 if (IN_CODESPACE(space))
459 /*-----------------------------------------------------------------*/
460 /* aopForRemat - rematerialzes an object */
461 /*-----------------------------------------------------------------*/
462 static asmop *aopForRemat (symbol *sym)
464 iCode *ic = sym->rematiCode;
465 asmop *aop = newAsmop(AOP_IMMD);
467 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
470 val += (int) operandLitValue(IC_RIGHT(ic));
471 else if (ic->op == '-')
472 val -= (int) operandLitValue(IC_RIGHT(ic));
476 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
480 sprintf(buffer,"(%s %c 0x%04x)",
481 OP_SYMBOL(IC_LEFT(ic))->rname,
482 val >= 0 ? '+' : '-',
485 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
487 //DEBUGpic14_emitcode(";","%s",buffer);
488 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
489 strcpy(aop->aopu.aop_immd,buffer);
493 /*-----------------------------------------------------------------*/
494 /* regsInCommon - two operands have some registers in common */
495 /*-----------------------------------------------------------------*/
496 static bool regsInCommon (operand *op1, operand *op2)
501 /* if they have registers in common */
502 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
505 sym1 = OP_SYMBOL(op1);
506 sym2 = OP_SYMBOL(op2);
508 if (sym1->nRegs == 0 || sym2->nRegs == 0)
511 for (i = 0 ; i < sym1->nRegs ; i++) {
516 for (j = 0 ; j < sym2->nRegs ;j++ ) {
520 if (sym2->regs[j] == sym1->regs[i])
528 /*-----------------------------------------------------------------*/
529 /* operandsEqu - equivalent */
530 /*-----------------------------------------------------------------*/
531 static bool operandsEqu ( operand *op1, operand *op2)
535 /* if they not symbols */
536 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
539 sym1 = OP_SYMBOL(op1);
540 sym2 = OP_SYMBOL(op2);
542 /* if both are itemps & one is spilt
543 and the other is not then false */
544 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
545 sym1->isspilt != sym2->isspilt )
548 /* if they are the same */
552 if (strcmp(sym1->rname,sym2->rname) == 0)
556 /* if left is a tmp & right is not */
560 (sym1->usl.spillLoc == sym2))
567 (sym2->usl.spillLoc == sym1))
573 /*-----------------------------------------------------------------*/
574 /* pic14_sameRegs - two asmops have the same registers */
575 /*-----------------------------------------------------------------*/
576 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
583 if (aop1->type != AOP_REG ||
584 aop2->type != AOP_REG )
587 if (aop1->size != aop2->size )
590 for (i = 0 ; i < aop1->size ; i++ )
591 if (aop1->aopu.aop_reg[i] !=
592 aop2->aopu.aop_reg[i] )
598 /*-----------------------------------------------------------------*/
599 /* aopOp - allocates an asmop for an operand : */
600 /*-----------------------------------------------------------------*/
601 void aopOp (operand *op, iCode *ic, bool result)
610 DEBUGpic14_emitcode(";","%d",__LINE__);
611 /* if this a literal */
612 if (IS_OP_LITERAL(op)) {
613 op->aop = aop = newAsmop(AOP_LIT);
614 aop->aopu.aop_lit = op->operand.valOperand;
615 aop->size = getSize(operandType(op));
616 DEBUGpic14_emitcode(";","%d, lit = %d",__LINE__,aop->aopu.aop_lit);
620 /* if already has a asmop then continue */
624 /* if the underlying symbol has a aop */
625 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
626 DEBUGpic14_emitcode(";","%d",__LINE__);
627 op->aop = OP_SYMBOL(op)->aop;
631 /* if this is a true symbol */
632 if (IS_TRUE_SYMOP(op)) {
633 DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
634 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
638 /* this is a temporary : this has
644 e) can be a return use only */
649 /* if the type is a conditional */
650 if (sym->regType == REG_CND) {
651 DEBUGpic14_emitcode(";","%d",__LINE__);
652 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
657 /* if it is spilt then two situations
659 b) has a spill location */
660 if (sym->isspilt || sym->nRegs == 0) {
662 DEBUGpic14_emitcode(";","%d",__LINE__);
663 /* rematerialize it NOW */
665 sym->aop = op->aop = aop =
667 aop->size = getSize(sym->type);
668 DEBUGpic14_emitcode(";","%d",__LINE__);
674 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
675 aop->size = getSize(sym->type);
676 for ( i = 0 ; i < 2 ; i++ )
677 aop->aopu.aop_str[i] = accUse[i];
678 DEBUGpic14_emitcode(";","%d",__LINE__);
684 aop = op->aop = sym->aop = newAsmop(AOP_STR);
685 aop->size = getSize(sym->type);
686 for ( i = 0 ; i < fReturnSizePic ; i++ )
687 aop->aopu.aop_str[i] = fReturn[i];
688 DEBUGpic14_emitcode(";","%d",__LINE__);
692 /* else spill location */
693 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
694 sym->aop = op->aop = aop =
695 aopForSym(ic,sym->usl.spillLoc,result);
696 aop->size = getSize(sym->type);
700 /* must be in a register */
701 sym->aop = op->aop = aop = newAsmop(AOP_REG);
702 aop->size = sym->nRegs;
703 for ( i = 0 ; i < sym->nRegs ;i++)
704 aop->aopu.aop_reg[i] = sym->regs[i];
707 /*-----------------------------------------------------------------*/
708 /* freeAsmop - free up the asmop given to an operand */
709 /*----------------------------------------------------------------*/
710 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
727 /* depending on the asmop type only three cases need work AOP_RO
728 , AOP_R1 && AOP_STK */
733 pic14_emitcode ("pop","ar0");
737 bitVectUnSetBit(ic->rUsed,R0_IDX);
743 pic14_emitcode ("pop","ar1");
747 bitVectUnSetBit(ic->rUsed,R1_IDX);
753 int stk = aop->aopu.aop_stk + aop->size;
754 bitVectUnSetBit(ic->rUsed,R0_IDX);
755 bitVectUnSetBit(ic->rUsed,R1_IDX);
757 getFreePtr(ic,&aop,FALSE);
759 if (options.stack10bit)
761 /* I'm not sure what to do here yet... */
764 "*** Warning: probably generating bad code for "
765 "10 bit stack mode.\n");
769 pic14_emitcode ("mov","a,_bp");
770 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
771 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
773 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
777 pic14_emitcode("pop","acc");
778 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
780 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
783 freeAsmop(op,NULL,ic,TRUE);
785 pic14_emitcode("pop","ar0");
790 pic14_emitcode("pop","ar1");
797 /* all other cases just dealloc */
801 OP_SYMBOL(op)->aop = NULL;
802 /* if the symbol has a spill */
804 SPIL_LOC(op)->aop = NULL;
809 /*-----------------------------------------------------------------*/
810 /* aopGet - for fetching value of the aop */
811 /*-----------------------------------------------------------------*/
812 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
817 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
818 /* offset is greater than
820 if (offset > (aop->size - 1) &&
821 aop->type != AOP_LIT)
824 /* depending on type */
829 DEBUGpic14_emitcode(";","%d",__LINE__);
830 /* if we need to increment it */
831 while (offset > aop->coff) {
832 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
836 while (offset < aop->coff) {
837 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
843 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
844 return (dname ? "acc" : "a");
846 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
847 rs = Safe_calloc(1,strlen(s)+1);
853 DEBUGpic14_emitcode(";","%d",__LINE__);
854 if (aop->type == AOP_DPTR2)
859 while (offset > aop->coff) {
860 pic14_emitcode ("inc","dptr");
864 while (offset < aop->coff) {
865 pic14_emitcode("lcall","__decdptr");
871 pic14_emitcode("clr","a");
872 pic14_emitcode("movc","a,@a+dptr");
875 pic14_emitcode("movx","a,@dptr");
878 if (aop->type == AOP_DPTR2)
883 return (dname ? "acc" : "a");
887 DEBUGpic14_emitcode(";","%d",__LINE__);
889 sprintf (s,"%s",aop->aopu.aop_immd);
892 sprintf(s,"(%s >> %d)",
898 rs = Safe_calloc(1,strlen(s)+1);
904 sprintf(s,"(%s + %d)",
908 sprintf(s,"%s",aop->aopu.aop_dir);
909 rs = Safe_calloc(1,strlen(s)+1);
914 DEBUGpic14_emitcode(";","%d",__LINE__);
916 return aop->aopu.aop_reg[offset]->dname;
918 return aop->aopu.aop_reg[offset]->name;
921 pic14_emitcode(";","%d",__LINE__);
922 //pic14_emitcode("clr","a");
923 //pic14_emitcode("mov","c,%s",aop->aopu.aop_dir);
924 //pic14_emitcode("rlc","a") ;
925 //return (dname ? "acc" : "a");
926 return aop->aopu.aop_dir;
929 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
930 //if (!offset && dname)
932 //return aop->aopu.aop_str[offset];
933 return "AOP_accumulator_bug";
936 DEBUGpic14_emitcode(";","%d",__LINE__);
937 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
938 rs = Safe_calloc(1,strlen(s)+1);
943 DEBUGpic14_emitcode(";","%d",__LINE__);
945 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
949 return aop->aopu.aop_str[offset];
953 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
954 "aopget got unsupported aop->type");
958 /*-----------------------------------------------------------------*/
959 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
960 /*-----------------------------------------------------------------*/
961 pCodeOp *popGetLabel(unsigned int key)
963 return newpCodeOpLabel(key+100+labelOffset);
966 /*-----------------------------------------------------------------*/
967 /* popCopyReg - copy a pcode operator */
968 /*-----------------------------------------------------------------*/
969 pCodeOp *popCopyReg(pCodeOpReg *pc)
973 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
974 pcor->pcop.type = pc->pcop.type;
975 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
976 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
978 pcor->rIdx = pc->rIdx;
984 /*-----------------------------------------------------------------*/
985 /* popCopy - copy a pcode operator */
986 /*-----------------------------------------------------------------*/
987 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
991 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
993 if(!(pcop->name = Safe_strdup(pc->name)))
994 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
995 ((pCodeOpBit *)pcop)->bit = bitval;
997 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1002 /*-----------------------------------------------------------------*/
1003 /* popGet - asm operator to pcode operator conversion */
1004 /*-----------------------------------------------------------------*/
1005 pCodeOp *popGetLit(unsigned int lit)
1008 return newpCodeOpLit(lit);
1012 /*-----------------------------------------------------------------*/
1013 /* popGet - asm operator to pcode operator conversion */
1014 /*-----------------------------------------------------------------*/
1015 pCodeOp *popGetWithString(char *str)
1021 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1025 pcop = newpCodeOp(str,PO_STR);
1030 pCodeOp *popRegFromString(char *str)
1033 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1034 pcop->type = PO_GPR_REGISTER;
1036 PCOR(pcop)->rIdx = -1;
1037 PCOR(pcop)->r = NULL;
1039 DEBUGpic14_emitcode(";","%d",__LINE__);
1040 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1045 /*-----------------------------------------------------------------*/
1046 /* popGet - asm operator to pcode operator conversion */
1047 /*-----------------------------------------------------------------*/
1048 pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
1055 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1056 /* offset is greater than
1059 if (offset > (aop->size - 1) &&
1060 aop->type != AOP_LIT)
1061 return NULL; //zero;
1063 /* depending on type */
1064 switch (aop->type) {
1071 DEBUGpic14_emitcode(";8051 legacy","%d",__LINE__);
1072 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1073 pcop->type = PO_SFR_REGISTER;
1075 PCOR(pcop)->rIdx = -1;
1076 PCOR(pcop)->r = NULL;
1077 // Really nasty hack to check for temporary registers
1079 pcop->name = Safe_strdup("BAD_REGISTER");
1084 DEBUGpic14_emitcode(";","%d",__LINE__);
1085 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1086 pcop->type = PO_IMMEDIATE;
1088 sprintf (s,"%s",aop->aopu.aop_immd);
1091 sprintf(s,"(%s >> %d)",
1096 aop->aopu.aop_immd);
1097 pcop->name = Safe_calloc(1,strlen(s)+1);
1098 strcpy(pcop->name,s);
1102 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1103 pcop->type = PO_DIR;
1105 sprintf(s,"(%s + %d)",
1109 sprintf(s,"%s",aop->aopu.aop_dir);
1110 pcop->name = Safe_calloc(1,strlen(s)+1);
1111 strcpy(pcop->name,s);
1116 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1118 DEBUGpic14_emitcode(";","%d",__LINE__);
1120 pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1122 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1123 //pcop->type = PO_GPR_REGISTER;
1124 PCOR(pcop)->rIdx = rIdx;
1125 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1126 pcop->type = PCOR(pcop)->r->pc_type;
1129 rs = aop->aopu.aop_reg[offset]->dname;
1131 rs = aop->aopu.aop_reg[offset]->name;
1133 DEBUGpic14_emitcode(";","%d %s",__LINE__,rs);
1139 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1143 DEBUGpic14_emitcode(";","%d",__LINE__);
1144 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1147 DEBUGpic14_emitcode(";","%d",__LINE__);
1149 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1150 pcop->type = PO_STR;
1152 //aop->coff = offset ;
1153 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1154 sprintf(s,"%s","acc");
1156 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1157 pcop->name = Safe_calloc(1,strlen(s)+1);
1158 strcpy(pcop->name,s);
1163 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1164 "popGet got unsupported aop->type");
1167 /*-----------------------------------------------------------------*/
1168 /* aopPut - puts a string for a aop */
1169 /*-----------------------------------------------------------------*/
1170 void aopPut (asmop *aop, char *s, int offset)
1175 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1177 if (aop->size && offset > ( aop->size - 1)) {
1178 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1179 "aopPut got offset > aop->size");
1183 /* will assign value to value */
1184 /* depending on where it is ofcourse */
1185 switch (aop->type) {
1188 sprintf(d,"(%s + %d)",
1189 aop->aopu.aop_dir,offset);
1191 sprintf(d,"%s",aop->aopu.aop_dir);
1194 DEBUGpic14_emitcode(";","%d",__LINE__);
1196 pic14_emitcode("movf","%s,w",s);
1197 pic14_emitcode("movwf","%s",d);
1200 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1201 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1208 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1209 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1212 strcmp(s,"r0") == 0 ||
1213 strcmp(s,"r1") == 0 ||
1214 strcmp(s,"r2") == 0 ||
1215 strcmp(s,"r3") == 0 ||
1216 strcmp(s,"r4") == 0 ||
1217 strcmp(s,"r5") == 0 ||
1218 strcmp(s,"r6") == 0 ||
1219 strcmp(s,"r7") == 0 )
1220 pic14_emitcode("mov","%s,%s ; %d",
1221 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1226 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1228 pic14_emitcode("movwf","%s",
1229 aop->aopu.aop_reg[offset]->name);
1232 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1233 pcop->type = PO_GPR_REGISTER;
1235 PCOR(pcop)->rIdx = -1;
1236 PCOR(pcop)->r = NULL;
1238 DEBUGpic14_emitcode(";","%d",__LINE__);
1239 pcop->name = Safe_strdup(s);
1240 emitpcode(POC_MOVFW,pcop);
1242 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1250 if (aop->type == AOP_DPTR2)
1256 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1257 "aopPut writting to code space");
1261 while (offset > aop->coff) {
1263 pic14_emitcode ("inc","dptr");
1266 while (offset < aop->coff) {
1268 pic14_emitcode("lcall","__decdptr");
1273 /* if not in accumulater */
1276 pic14_emitcode ("movx","@dptr,a");
1278 if (aop->type == AOP_DPTR2)
1286 while (offset > aop->coff) {
1288 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1290 while (offset < aop->coff) {
1292 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1298 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1303 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1305 if (strcmp(s,"r0") == 0 ||
1306 strcmp(s,"r1") == 0 ||
1307 strcmp(s,"r2") == 0 ||
1308 strcmp(s,"r3") == 0 ||
1309 strcmp(s,"r4") == 0 ||
1310 strcmp(s,"r5") == 0 ||
1311 strcmp(s,"r6") == 0 ||
1312 strcmp(s,"r7") == 0 ) {
1314 sprintf(buffer,"a%s",s);
1315 pic14_emitcode("mov","@%s,%s",
1316 aop->aopu.aop_ptr->name,buffer);
1318 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1323 if (strcmp(s,"a") == 0)
1324 pic14_emitcode("push","acc");
1326 pic14_emitcode("push","%s",s);
1331 /* if bit variable */
1332 if (!aop->aopu.aop_dir) {
1333 pic14_emitcode("clr","a");
1334 pic14_emitcode("rlc","a");
1337 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1340 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1343 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1345 lbl = newiTempLabel(NULL);
1347 if (strcmp(s,"a")) {
1350 pic14_emitcode("clr","c");
1351 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1352 pic14_emitcode("cpl","c");
1353 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1354 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1361 if (strcmp(aop->aopu.aop_str[offset],s))
1362 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1367 if (!offset && (strcmp(s,"acc") == 0))
1370 if (strcmp(aop->aopu.aop_str[offset],s))
1371 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1375 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1376 "aopPut got unsupported aop->type");
1382 /*-----------------------------------------------------------------*/
1383 /* reAdjustPreg - points a register back to where it should */
1384 /*-----------------------------------------------------------------*/
1385 static void reAdjustPreg (asmop *aop)
1389 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1391 if ((size = aop->size) <= 1)
1394 switch (aop->type) {
1398 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1402 if (aop->type == AOP_DPTR2)
1408 pic14_emitcode("lcall","__decdptr");
1411 if (aop->type == AOP_DPTR2)
1421 /*-----------------------------------------------------------------*/
1422 /* genNotFloat - generates not for float operations */
1423 /*-----------------------------------------------------------------*/
1424 static void genNotFloat (operand *op, operand *res)
1430 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1431 /* we will put 127 in the first byte of
1433 aopPut(AOP(res),"#127",0);
1434 size = AOP_SIZE(op) - 1;
1437 l = aopGet(op->aop,offset++,FALSE,FALSE);
1441 pic14_emitcode("orl","a,%s",
1443 offset++,FALSE,FALSE));
1445 tlbl = newiTempLabel(NULL);
1447 tlbl = newiTempLabel(NULL);
1448 aopPut(res->aop,one,1);
1449 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1450 aopPut(res->aop,zero,1);
1451 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1453 size = res->aop->size - 2;
1455 /* put zeros in the rest */
1457 aopPut(res->aop,zero,offset++);
1461 /*-----------------------------------------------------------------*/
1462 /* opIsGptr: returns non-zero if the passed operand is */
1463 /* a generic pointer type. */
1464 /*-----------------------------------------------------------------*/
1465 static int opIsGptr(operand *op)
1467 sym_link *type = operandType(op);
1469 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1470 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1478 /*-----------------------------------------------------------------*/
1479 /* pic14_getDataSize - get the operand data size */
1480 /*-----------------------------------------------------------------*/
1481 int pic14_getDataSize(operand *op)
1483 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1486 return AOP_SIZE(op);
1488 // tsd- in the pic port, the genptr size is 1, so this code here
1489 // fails. ( in the 8051 port, the size was 4).
1492 size = AOP_SIZE(op);
1493 if (size == GPTRSIZE)
1495 sym_link *type = operandType(op);
1496 if (IS_GENPTR(type))
1498 /* generic pointer; arithmetic operations
1499 * should ignore the high byte (pointer type).
1502 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1509 /*-----------------------------------------------------------------*/
1510 /* pic14_outAcc - output Acc */
1511 /*-----------------------------------------------------------------*/
1512 void pic14_outAcc(operand *result)
1515 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1516 size = pic14_getDataSize(result);
1518 aopPut(AOP(result),"a",0);
1521 /* unsigned or positive */
1523 aopPut(AOP(result),zero,offset++);
1528 /*-----------------------------------------------------------------*/
1529 /* pic14_outBitC - output a bit C */
1530 /*-----------------------------------------------------------------*/
1531 void pic14_outBitC(operand *result)
1534 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1535 /* if the result is bit */
1536 if (AOP_TYPE(result) == AOP_CRY)
1537 aopPut(AOP(result),"c",0);
1539 pic14_emitcode("clr","a ; %d", __LINE__);
1540 pic14_emitcode("rlc","a");
1541 pic14_outAcc(result);
1545 /*-----------------------------------------------------------------*/
1546 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1547 /*-----------------------------------------------------------------*/
1548 void pic14_toBoolean(operand *oper)
1550 int size = AOP_SIZE(oper) - 1;
1553 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1555 if ( AOP_TYPE(oper) != AOP_ACC) {
1556 emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1557 pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1560 pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1561 emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1566 /*-----------------------------------------------------------------*/
1567 /* genNot - generate code for ! operation */
1568 /*-----------------------------------------------------------------*/
1569 static void genNot (iCode *ic)
1572 sym_link *optype = operandType(IC_LEFT(ic));
1574 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1575 /* assign asmOps to operand & result */
1576 aopOp (IC_LEFT(ic),ic,FALSE);
1577 aopOp (IC_RESULT(ic),ic,TRUE);
1579 /* if in bit space then a special case */
1580 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1581 pic14_emitcode("movlw","1<<%s");
1582 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1583 //pic14_emitcode("cpl","c");
1584 //pic14_outBitC(IC_RESULT(ic));
1588 /* if type float then do float */
1589 if (IS_FLOAT(optype)) {
1590 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1594 pic14_toBoolean(IC_LEFT(ic));
1596 tlbl = newiTempLabel(NULL);
1597 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1598 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1599 pic14_outBitC(IC_RESULT(ic));
1602 /* release the aops */
1603 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1604 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1608 /*-----------------------------------------------------------------*/
1609 /* genCpl - generate code for complement */
1610 /*-----------------------------------------------------------------*/
1611 static void genCpl (iCode *ic)
1617 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1618 /* assign asmOps to operand & result */
1619 aopOp (IC_LEFT(ic),ic,FALSE);
1620 aopOp (IC_RESULT(ic),ic,TRUE);
1622 /* if both are in bit space then
1624 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1625 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1627 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1628 pic14_emitcode("cpl","c");
1629 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1633 size = AOP_SIZE(IC_RESULT(ic));
1635 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1637 pic14_emitcode("cpl","a");
1638 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1643 /* release the aops */
1644 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1645 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1648 /*-----------------------------------------------------------------*/
1649 /* genUminusFloat - unary minus for floating points */
1650 /*-----------------------------------------------------------------*/
1651 static void genUminusFloat(operand *op,operand *result)
1653 int size ,offset =0 ;
1656 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1657 /* for this we just need to flip the
1658 first it then copy the rest in place */
1659 size = AOP_SIZE(op) - 1;
1660 l = aopGet(AOP(op),3,FALSE,FALSE);
1664 pic14_emitcode("cpl","acc.7");
1665 aopPut(AOP(result),"a",3);
1669 aopGet(AOP(op),offset,FALSE,FALSE),
1675 /*-----------------------------------------------------------------*/
1676 /* genUminus - unary minus code generation */
1677 /*-----------------------------------------------------------------*/
1678 static void genUminus (iCode *ic)
1681 sym_link *optype, *rtype;
1684 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1686 aopOp(IC_LEFT(ic),ic,FALSE);
1687 aopOp(IC_RESULT(ic),ic,TRUE);
1689 /* if both in bit space then special
1691 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1692 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1694 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1695 pic14_emitcode("cpl","c");
1696 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1700 optype = operandType(IC_LEFT(ic));
1701 rtype = operandType(IC_RESULT(ic));
1703 /* if float then do float stuff */
1704 if (IS_FLOAT(optype)) {
1705 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1709 /* otherwise subtract from zero */
1710 size = AOP_SIZE(IC_LEFT(ic));
1714 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1715 if (!strcmp(l,"a")) {
1716 pic14_emitcode("cpl","a");
1717 pic14_emitcode("inc","a");
1719 pic14_emitcode("clr","a");
1720 pic14_emitcode("subb","a,%s",l);
1722 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1725 /* if any remaining bytes in the result */
1726 /* we just need to propagate the sign */
1727 if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1728 pic14_emitcode("rlc","a");
1729 pic14_emitcode("subb","a,acc");
1731 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1735 /* release the aops */
1736 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1737 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1740 /*-----------------------------------------------------------------*/
1741 /* saveRegisters - will look for a call and save the registers */
1742 /*-----------------------------------------------------------------*/
1743 static void saveRegisters(iCode *lic)
1750 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1752 for (ic = lic ; ic ; ic = ic->next)
1753 if (ic->op == CALL || ic->op == PCALL)
1757 fprintf(stderr,"found parameter push with no function call\n");
1761 /* if the registers have been saved already then
1763 if (ic->regsSaved || (OP_SYMBOL(IC_LEFT(ic))->calleeSave))
1766 /* find the registers in use at this time
1767 and push them away to safety */
1768 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1772 if (options.useXstack) {
1773 if (bitVectBitValue(rsave,R0_IDX))
1774 pic14_emitcode("mov","b,r0");
1775 pic14_emitcode("mov","r0,%s",spname);
1776 for (i = 0 ; i < pic14_nRegs ; i++) {
1777 if (bitVectBitValue(rsave,i)) {
1779 pic14_emitcode("mov","a,b");
1781 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1782 pic14_emitcode("movx","@r0,a");
1783 pic14_emitcode("inc","r0");
1786 pic14_emitcode("mov","%s,r0",spname);
1787 if (bitVectBitValue(rsave,R0_IDX))
1788 pic14_emitcode("mov","r0,b");
1790 for (i = 0 ; i < pic14_nRegs ; i++) {
1791 if (bitVectBitValue(rsave,i))
1792 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1795 detype = getSpec(operandType(IC_LEFT(ic)));
1797 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
1798 IS_ISR(currFunc->etype) &&
1801 saverbank(SPEC_BANK(detype),ic,TRUE);
1804 /*-----------------------------------------------------------------*/
1805 /* unsaveRegisters - pop the pushed registers */
1806 /*-----------------------------------------------------------------*/
1807 static void unsaveRegisters (iCode *ic)
1812 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1813 /* find the registers in use at this time
1814 and push them away to safety */
1815 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1818 if (options.useXstack) {
1819 pic14_emitcode("mov","r0,%s",spname);
1820 for (i = pic14_nRegs ; i >= 0 ; i--) {
1821 if (bitVectBitValue(rsave,i)) {
1822 pic14_emitcode("dec","r0");
1823 pic14_emitcode("movx","a,@r0");
1825 pic14_emitcode("mov","b,a");
1827 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1831 pic14_emitcode("mov","%s,r0",spname);
1832 if (bitVectBitValue(rsave,R0_IDX))
1833 pic14_emitcode("mov","r0,b");
1835 for (i = pic14_nRegs ; i >= 0 ; i--) {
1836 if (bitVectBitValue(rsave,i))
1837 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1843 /*-----------------------------------------------------------------*/
1845 /*-----------------------------------------------------------------*/
1846 static void pushSide(operand * oper, int size)
1849 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1851 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1852 if (AOP_TYPE(oper) != AOP_REG &&
1853 AOP_TYPE(oper) != AOP_DIR &&
1855 pic14_emitcode("mov","a,%s",l);
1856 pic14_emitcode("push","acc");
1858 pic14_emitcode("push","%s",l);
1862 /*-----------------------------------------------------------------*/
1863 /* assignResultValue - */
1864 /*-----------------------------------------------------------------*/
1865 static void assignResultValue(operand * oper)
1868 int size = AOP_SIZE(oper);
1870 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1872 // The last byte in the assignment is in W
1873 aopPut(AOP(oper),"W",size-1);
1877 aopPut(AOP(oper),fReturn[offset],offset);
1885 /*-----------------------------------------------------------------*/
1886 /* genXpush - pushes onto the external stack */
1887 /*-----------------------------------------------------------------*/
1888 static void genXpush (iCode *ic)
1890 asmop *aop = newAsmop(0);
1892 int size,offset = 0;
1894 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1895 aopOp(IC_LEFT(ic),ic,FALSE);
1896 r = getFreePtr(ic,&aop,FALSE);
1899 pic14_emitcode("mov","%s,_spx",r->name);
1901 size = AOP_SIZE(IC_LEFT(ic));
1904 char *l = aopGet(AOP(IC_LEFT(ic)),
1905 offset++,FALSE,FALSE);
1907 pic14_emitcode("movx","@%s,a",r->name);
1908 pic14_emitcode("inc","%s",r->name);
1913 pic14_emitcode("mov","_spx,%s",r->name);
1915 freeAsmop(NULL,aop,ic,TRUE);
1916 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
1919 /*-----------------------------------------------------------------*/
1920 /* genIpush - genrate code for pushing this gets a little complex */
1921 /*-----------------------------------------------------------------*/
1922 static void genIpush (iCode *ic)
1924 int size, offset = 0 ;
1928 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1929 /* if this is not a parm push : ie. it is spill push
1930 and spill push is always done on the local stack */
1931 if (!ic->parmPush) {
1933 /* and the item is spilt then do nothing */
1934 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
1937 aopOp(IC_LEFT(ic),ic,FALSE);
1938 size = AOP_SIZE(IC_LEFT(ic));
1939 /* push it on the stack */
1941 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1946 pic14_emitcode("push","%s",l);
1951 /* this is a paramter push: in this case we call
1952 the routine to find the call and save those
1953 registers that need to be saved */
1956 /* if use external stack then call the external
1957 stack pushing routine */
1958 if (options.useXstack) {
1963 /* then do the push */
1964 aopOp(IC_LEFT(ic),ic,FALSE);
1967 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
1968 size = AOP_SIZE(IC_LEFT(ic));
1971 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1972 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
1973 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
1975 pic14_emitcode("mov","a,%s",l);
1976 pic14_emitcode("push","acc");
1978 pic14_emitcode("push","%s",l);
1981 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
1984 /*-----------------------------------------------------------------*/
1985 /* genIpop - recover the registers: can happen only for spilling */
1986 /*-----------------------------------------------------------------*/
1987 static void genIpop (iCode *ic)
1992 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1993 /* if the temp was not pushed then */
1994 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
1997 aopOp(IC_LEFT(ic),ic,FALSE);
1998 size = AOP_SIZE(IC_LEFT(ic));
2001 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2004 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2007 /*-----------------------------------------------------------------*/
2008 /* unsaverbank - restores the resgister bank from stack */
2009 /*-----------------------------------------------------------------*/
2010 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2016 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2018 if (options.useXstack) {
2020 r = getFreePtr(ic,&aop,FALSE);
2023 pic14_emitcode("mov","%s,_spx",r->name);
2024 pic14_emitcode("movx","a,@%s",r->name);
2025 pic14_emitcode("mov","psw,a");
2026 pic14_emitcode("dec","%s",r->name);
2029 pic14_emitcode ("pop","psw");
2032 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2033 if (options.useXstack) {
2034 pic14_emitcode("movx","a,@%s",r->name);
2035 //pic14_emitcode("mov","(%s+%d),a",
2036 // regspic14[i].base,8*bank+regspic14[i].offset);
2037 pic14_emitcode("dec","%s",r->name);
2040 pic14_emitcode("pop",""); //"(%s+%d)",
2041 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2044 if (options.useXstack) {
2046 pic14_emitcode("mov","_spx,%s",r->name);
2047 freeAsmop(NULL,aop,ic,TRUE);
2052 /*-----------------------------------------------------------------*/
2053 /* saverbank - saves an entire register bank on the stack */
2054 /*-----------------------------------------------------------------*/
2055 static void saverbank (int bank, iCode *ic, bool pushPsw)
2061 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2062 if (options.useXstack) {
2065 r = getFreePtr(ic,&aop,FALSE);
2066 pic14_emitcode("mov","%s,_spx",r->name);
2070 for (i = 0 ; i < pic14_nRegs ;i++) {
2071 if (options.useXstack) {
2072 pic14_emitcode("inc","%s",r->name);
2073 //pic14_emitcode("mov","a,(%s+%d)",
2074 // regspic14[i].base,8*bank+regspic14[i].offset);
2075 pic14_emitcode("movx","@%s,a",r->name);
2077 pic14_emitcode("push","");// "(%s+%d)",
2078 //regspic14[i].base,8*bank+regspic14[i].offset);
2082 if (options.useXstack) {
2083 pic14_emitcode("mov","a,psw");
2084 pic14_emitcode("movx","@%s,a",r->name);
2085 pic14_emitcode("inc","%s",r->name);
2086 pic14_emitcode("mov","_spx,%s",r->name);
2087 freeAsmop (NULL,aop,ic,TRUE);
2090 pic14_emitcode("push","psw");
2092 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2098 /*-----------------------------------------------------------------*/
2099 /* genCall - generates a call statement */
2100 /*-----------------------------------------------------------------*/
2101 static void genCall (iCode *ic)
2105 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2107 /* if caller saves & we have not saved then */
2111 /* if we are calling a function that is not using
2112 the same register bank then we need to save the
2113 destination registers on the stack */
2114 detype = getSpec(operandType(IC_LEFT(ic)));
2116 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
2117 IS_ISR(currFunc->etype) &&
2120 saverbank(SPEC_BANK(detype),ic,TRUE);
2122 /* if send set is not empty the assign */
2126 for (sic = setFirstItem(_G.sendSet) ; sic ;
2127 sic = setNextItem(_G.sendSet)) {
2128 int size, offset = 0;
2130 aopOp(IC_LEFT(sic),sic,FALSE);
2131 size = AOP_SIZE(IC_LEFT(sic));
2133 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2135 DEBUGpic14_emitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
2137 if (strcmp(l,fReturn[offset])) {
2139 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2140 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2141 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2142 //pic14_emitcode("movlw","%s",l);
2144 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2145 //pic14_emitcode("movf","%s,w",l);
2147 // The last one is passed in W
2149 pic14_emitcode("movwf","%s",fReturn[offset]);
2153 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2158 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2159 OP_SYMBOL(IC_LEFT(ic))->rname :
2160 OP_SYMBOL(IC_LEFT(ic))->name));
2162 pic14_emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2163 OP_SYMBOL(IC_LEFT(ic))->rname :
2164 OP_SYMBOL(IC_LEFT(ic))->name));
2166 /* if we need assign a result value */
2167 if ((IS_ITEMP(IC_RESULT(ic)) &&
2168 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2169 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2170 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2173 aopOp(IC_RESULT(ic),ic,FALSE);
2176 assignResultValue(IC_RESULT(ic));
2178 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2181 /* adjust the stack for parameters if
2183 if (ic->parmBytes) {
2185 if (ic->parmBytes > 3) {
2186 pic14_emitcode("mov","a,%s",spname);
2187 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2188 pic14_emitcode("mov","%s,a",spname);
2190 for ( i = 0 ; i < ic->parmBytes ;i++)
2191 pic14_emitcode("dec","%s",spname);
2195 /* if register bank was saved then pop them */
2197 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2199 /* if we hade saved some registers then unsave them */
2200 if (ic->regsSaved && !(OP_SYMBOL(IC_LEFT(ic))->calleeSave))
2201 unsaveRegisters (ic);
2206 /*-----------------------------------------------------------------*/
2207 /* genPcall - generates a call by pointer statement */
2208 /*-----------------------------------------------------------------*/
2209 static void genPcall (iCode *ic)
2212 symbol *rlbl = newiTempLabel(NULL);
2215 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2216 /* if caller saves & we have not saved then */
2220 /* if we are calling a function that is not using
2221 the same register bank then we need to save the
2222 destination registers on the stack */
2223 detype = getSpec(operandType(IC_LEFT(ic)));
2225 IS_ISR(currFunc->etype) &&
2226 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)))
2227 saverbank(SPEC_BANK(detype),ic,TRUE);
2230 /* push the return address on to the stack */
2231 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2232 pic14_emitcode("push","acc");
2233 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2234 pic14_emitcode("push","acc");
2236 if (options.model == MODEL_FLAT24)
2238 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2239 pic14_emitcode("push","acc");
2242 /* now push the calling address */
2243 aopOp(IC_LEFT(ic),ic,FALSE);
2245 pushSide(IC_LEFT(ic), FPTRSIZE);
2247 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2249 /* if send set is not empty the assign */
2253 for (sic = setFirstItem(_G.sendSet) ; sic ;
2254 sic = setNextItem(_G.sendSet)) {
2255 int size, offset = 0;
2256 aopOp(IC_LEFT(sic),sic,FALSE);
2257 size = AOP_SIZE(IC_LEFT(sic));
2259 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2261 if (strcmp(l,fReturn[offset]))
2262 pic14_emitcode("mov","%s,%s",
2267 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2272 pic14_emitcode("ret","");
2273 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2276 /* if we need assign a result value */
2277 if ((IS_ITEMP(IC_RESULT(ic)) &&
2278 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2279 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2280 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2283 aopOp(IC_RESULT(ic),ic,FALSE);
2286 assignResultValue(IC_RESULT(ic));
2288 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2291 /* adjust the stack for parameters if
2293 if (ic->parmBytes) {
2295 if (ic->parmBytes > 3) {
2296 pic14_emitcode("mov","a,%s",spname);
2297 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2298 pic14_emitcode("mov","%s,a",spname);
2300 for ( i = 0 ; i < ic->parmBytes ;i++)
2301 pic14_emitcode("dec","%s",spname);
2305 /* if register bank was saved then unsave them */
2307 (SPEC_BANK(currFunc->etype) !=
2309 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2311 /* if we hade saved some registers then
2314 unsaveRegisters (ic);
2318 /*-----------------------------------------------------------------*/
2319 /* resultRemat - result is rematerializable */
2320 /*-----------------------------------------------------------------*/
2321 static int resultRemat (iCode *ic)
2323 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2324 if (SKIP_IC(ic) || ic->op == IFX)
2327 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2328 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2329 if (sym->remat && !POINTER_SET(ic))
2336 #if defined(__BORLANDC__) || defined(_MSC_VER)
2337 #define STRCASECMP stricmp
2339 #define STRCASECMP strcasecmp
2342 /*-----------------------------------------------------------------*/
2343 /* inExcludeList - return 1 if the string is in exclude Reg list */
2344 /*-----------------------------------------------------------------*/
2345 static bool inExcludeList(char *s)
2349 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2350 if (options.excludeRegs[i] &&
2351 STRCASECMP(options.excludeRegs[i],"none") == 0)
2354 for ( i = 0 ; options.excludeRegs[i]; i++) {
2355 if (options.excludeRegs[i] &&
2356 STRCASECMP(s,options.excludeRegs[i]) == 0)
2362 /*-----------------------------------------------------------------*/
2363 /* genFunction - generated code for function entry */
2364 /*-----------------------------------------------------------------*/
2365 static void genFunction (iCode *ic)
2370 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2371 labelOffset += FUNCTION_LABEL_INC;
2374 /* create the function header */
2375 pic14_emitcode(";","-----------------------------------------");
2376 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2377 pic14_emitcode(";","-----------------------------------------");
2379 pic14_emitcode("","%s:",sym->rname);
2380 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2382 fetype = getSpec(operandType(IC_LEFT(ic)));
2384 /* if critical function then turn interrupts off */
2385 if (SPEC_CRTCL(fetype))
2386 pic14_emitcode("clr","ea");
2388 /* here we need to generate the equates for the
2389 register bank if required */
2391 if (SPEC_BANK(fetype) != rbank) {
2394 rbank = SPEC_BANK(fetype);
2395 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2396 if (strcmp(regspic14[i].base,"0") == 0)
2397 pic14_emitcode("","%s = 0x%02x",
2399 8*rbank+regspic14[i].offset);
2401 pic14_emitcode ("","%s = %s + 0x%02x",
2404 8*rbank+regspic14[i].offset);
2409 /* if this is an interrupt service routine then
2410 save acc, b, dpl, dph */
2411 if (IS_ISR(sym->etype)) {
2413 if (!inExcludeList("acc"))
2414 pic14_emitcode ("push","acc");
2415 if (!inExcludeList("b"))
2416 pic14_emitcode ("push","b");
2417 if (!inExcludeList("dpl"))
2418 pic14_emitcode ("push","dpl");
2419 if (!inExcludeList("dph"))
2420 pic14_emitcode ("push","dph");
2421 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2423 pic14_emitcode ("push", "dpx");
2424 /* Make sure we're using standard DPTR */
2425 pic14_emitcode ("push", "dps");
2426 pic14_emitcode ("mov", "dps, #0x00");
2427 if (options.stack10bit)
2429 /* This ISR could conceivably use DPTR2. Better save it. */
2430 pic14_emitcode ("push", "dpl1");
2431 pic14_emitcode ("push", "dph1");
2432 pic14_emitcode ("push", "dpx1");
2435 /* if this isr has no bank i.e. is going to
2436 run with bank 0 , then we need to save more
2438 if (!SPEC_BANK(sym->etype)) {
2440 /* if this function does not call any other
2441 function then we can be economical and
2442 save only those registers that are used */
2443 if (! sym->hasFcall) {
2446 /* if any registers used */
2447 if (sym->regsUsed) {
2448 /* save the registers used */
2449 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2450 if (bitVectBitValue(sym->regsUsed,i) ||
2451 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2452 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2457 /* this function has a function call cannot
2458 determines register usage so we will have the
2460 saverbank(0,ic,FALSE);
2464 /* if callee-save to be used for this function
2465 then save the registers being used in this function */
2466 if (sym->calleeSave) {
2469 /* if any registers used */
2470 if (sym->regsUsed) {
2471 /* save the registers used */
2472 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2473 if (bitVectBitValue(sym->regsUsed,i) ||
2474 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2475 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2483 /* set the register bank to the desired value */
2484 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) {
2485 pic14_emitcode("push","psw");
2486 pic14_emitcode("mov","psw,#0x%02x",(SPEC_BANK(sym->etype) << 3)&0x00ff);
2489 if (IS_RENT(sym->etype) || options.stackAuto) {
2491 if (options.useXstack) {
2492 pic14_emitcode("mov","r0,%s",spname);
2493 pic14_emitcode("mov","a,_bp");
2494 pic14_emitcode("movx","@r0,a");
2495 pic14_emitcode("inc","%s",spname);
2499 /* set up the stack */
2500 pic14_emitcode ("push","_bp"); /* save the callers stack */
2502 pic14_emitcode ("mov","_bp,%s",spname);
2505 /* adjust the stack for the function */
2510 werror(W_STACK_OVERFLOW,sym->name);
2512 if (i > 3 && sym->recvSize < 4) {
2514 pic14_emitcode ("mov","a,sp");
2515 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2516 pic14_emitcode ("mov","sp,a");
2521 pic14_emitcode("inc","sp");
2526 pic14_emitcode ("mov","a,_spx");
2527 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2528 pic14_emitcode ("mov","_spx,a");
2533 /*-----------------------------------------------------------------*/
2534 /* genEndFunction - generates epilogue for functions */
2535 /*-----------------------------------------------------------------*/
2536 static void genEndFunction (iCode *ic)
2538 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2540 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2542 if (IS_RENT(sym->etype) || options.stackAuto)
2544 pic14_emitcode ("mov","%s,_bp",spname);
2547 /* if use external stack but some variables were
2548 added to the local stack then decrement the
2550 if (options.useXstack && sym->stack) {
2551 pic14_emitcode("mov","a,sp");
2552 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2553 pic14_emitcode("mov","sp,a");
2557 if ((IS_RENT(sym->etype) || options.stackAuto)) {
2558 if (options.useXstack) {
2559 pic14_emitcode("mov","r0,%s",spname);
2560 pic14_emitcode("movx","a,@r0");
2561 pic14_emitcode("mov","_bp,a");
2562 pic14_emitcode("dec","%s",spname);
2566 pic14_emitcode ("pop","_bp");
2570 /* restore the register bank */
2571 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype))
2572 pic14_emitcode ("pop","psw");
2574 if (IS_ISR(sym->etype)) {
2576 /* now we need to restore the registers */
2577 /* if this isr has no bank i.e. is going to
2578 run with bank 0 , then we need to save more
2580 if (!SPEC_BANK(sym->etype)) {
2582 /* if this function does not call any other
2583 function then we can be economical and
2584 save only those registers that are used */
2585 if (! sym->hasFcall) {
2588 /* if any registers used */
2589 if (sym->regsUsed) {
2590 /* save the registers used */
2591 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2592 if (bitVectBitValue(sym->regsUsed,i) ||
2593 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2594 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2599 /* this function has a function call cannot
2600 determines register usage so we will have the
2602 unsaverbank(0,ic,FALSE);
2606 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2608 if (options.stack10bit)
2610 pic14_emitcode ("pop", "dpx1");
2611 pic14_emitcode ("pop", "dph1");
2612 pic14_emitcode ("pop", "dpl1");
2614 pic14_emitcode ("pop", "dps");
2615 pic14_emitcode ("pop", "dpx");
2617 if (!inExcludeList("dph"))
2618 pic14_emitcode ("pop","dph");
2619 if (!inExcludeList("dpl"))
2620 pic14_emitcode ("pop","dpl");
2621 if (!inExcludeList("b"))
2622 pic14_emitcode ("pop","b");
2623 if (!inExcludeList("acc"))
2624 pic14_emitcode ("pop","acc");
2626 if (SPEC_CRTCL(sym->etype))
2627 pic14_emitcode("setb","ea");
2629 /* if debug then send end of function */
2630 /* if (options.debug && currFunc) { */
2633 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2634 FileBaseName(ic->filename),currFunc->lastLine,
2635 ic->level,ic->block);
2636 if (IS_STATIC(currFunc->etype))
2637 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2639 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2643 pic14_emitcode ("reti","");
2646 if (SPEC_CRTCL(sym->etype))
2647 pic14_emitcode("setb","ea");
2649 if (sym->calleeSave) {
2652 /* if any registers used */
2653 if (sym->regsUsed) {
2654 /* save the registers used */
2655 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2656 if (bitVectBitValue(sym->regsUsed,i) ||
2657 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2658 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2664 /* if debug then send end of function */
2667 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2668 FileBaseName(ic->filename),currFunc->lastLine,
2669 ic->level,ic->block);
2670 if (IS_STATIC(currFunc->etype))
2671 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2673 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2677 pic14_emitcode ("return","");
2678 emitpcode(POC_RETURN,NULL);
2680 /* Mark the end of a function */
2681 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2686 /*-----------------------------------------------------------------*/
2687 /* genRet - generate code for return statement */
2688 /*-----------------------------------------------------------------*/
2689 static void genRet (iCode *ic)
2691 int size,offset = 0 , pushed = 0;
2693 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2694 /* if we have no return value then
2695 just generate the "ret" */
2699 /* we have something to return then
2700 move the return value into place */
2701 aopOp(IC_LEFT(ic),ic,FALSE);
2702 size = AOP_SIZE(IC_LEFT(ic));
2706 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2708 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2710 pic14_emitcode("push","%s",l);
2713 l = aopGet(AOP(IC_LEFT(ic)),offset,
2715 if (strcmp(fReturn[offset],l)) {
2716 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2717 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
2718 pic14_emitcode("movlw","%s",l);
2720 pic14_emitcode("movf","%s,w",l);
2722 pic14_emitcode("movwf","%s",fReturn[offset]);
2731 if (strcmp(fReturn[pushed],"a"))
2732 pic14_emitcode("pop",fReturn[pushed]);
2734 pic14_emitcode("pop","acc");
2737 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2740 /* generate a jump to the return label
2741 if the next is not the return statement */
2742 if (!(ic->next && ic->next->op == LABEL &&
2743 IC_LABEL(ic->next) == returnLabel)) {
2745 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2746 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2751 /*-----------------------------------------------------------------*/
2752 /* genLabel - generates a label */
2753 /*-----------------------------------------------------------------*/
2754 static void genLabel (iCode *ic)
2756 /* special case never generate */
2757 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2758 if (IC_LABEL(ic) == entryLabel)
2761 emitpLabel(IC_LABEL(ic)->key+100 + labelOffset);
2762 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2765 /*-----------------------------------------------------------------*/
2766 /* genGoto - generates a goto */
2767 /*-----------------------------------------------------------------*/
2769 static void genGoto (iCode *ic)
2771 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2772 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2775 /*-----------------------------------------------------------------*/
2776 /* findLabelBackwards: walks back through the iCode chain looking */
2777 /* for the given label. Returns number of iCode instructions */
2778 /* between that label and given ic. */
2779 /* Returns zero if label not found. */
2780 /*-----------------------------------------------------------------*/
2782 static int findLabelBackwards(iCode *ic, int key)
2786 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2792 if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2794 /* printf("findLabelBackwards = %d\n", count); */
2803 /*-----------------------------------------------------------------*/
2804 /* genMultbits :- multiplication of bits */
2805 /*-----------------------------------------------------------------*/
2806 static void genMultbits (operand *left,
2810 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2812 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2813 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2814 pic14_outBitC(result);
2818 /*-----------------------------------------------------------------*/
2819 /* genMultOneByte : 8 bit multiplication & division */
2820 /*-----------------------------------------------------------------*/
2821 static void genMultOneByte (operand *left,
2825 sym_link *opetype = operandType(result);
2830 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2831 /* (if two literals, the value is computed before) */
2832 /* if one literal, literal on the right */
2833 if (AOP_TYPE(left) == AOP_LIT){
2839 size = AOP_SIZE(result);
2840 /* signed or unsigned */
2841 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2842 l = aopGet(AOP(left),0,FALSE,FALSE);
2844 pic14_emitcode("mul","ab");
2845 /* if result size = 1, mul signed = mul unsigned */
2846 aopPut(AOP(result),"a",0);
2848 if (SPEC_USIGN(opetype)){
2849 aopPut(AOP(result),"b",1);
2851 /* for filling the MSBs */
2852 pic14_emitcode("clr","a");
2855 pic14_emitcode("mov","a,b");
2857 /* adjust the MSB if left or right neg */
2859 /* if one literal */
2860 if (AOP_TYPE(right) == AOP_LIT){
2861 /* AND literal negative */
2862 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2863 /* adjust MSB (c==0 after mul) */
2864 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2868 lbl = newiTempLabel(NULL);
2869 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2870 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2871 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2872 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2873 lbl = newiTempLabel(NULL);
2874 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2875 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2876 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2879 lbl = newiTempLabel(NULL);
2880 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2881 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2882 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2883 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2884 lbl = newiTempLabel(NULL);
2885 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2886 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2887 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2889 aopPut(AOP(result),"a",1);
2892 pic14_emitcode("rlc","a");
2893 pic14_emitcode("subb","a,acc");
2900 aopPut(AOP(result),"a",offset++);
2904 /*-----------------------------------------------------------------*/
2905 /* genMult - generates code for multiplication */
2906 /*-----------------------------------------------------------------*/
2907 static void genMult (iCode *ic)
2909 operand *left = IC_LEFT(ic);
2910 operand *right = IC_RIGHT(ic);
2911 operand *result= IC_RESULT(ic);
2913 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2914 /* assign the amsops */
2915 aopOp (left,ic,FALSE);
2916 aopOp (right,ic,FALSE);
2917 aopOp (result,ic,TRUE);
2919 /* special cases first */
2921 if (AOP_TYPE(left) == AOP_CRY &&
2922 AOP_TYPE(right)== AOP_CRY) {
2923 genMultbits(left,right,result);
2927 /* if both are of size == 1 */
2928 if (AOP_SIZE(left) == 1 &&
2929 AOP_SIZE(right) == 1 ) {
2930 genMultOneByte(left,right,result);
2934 /* should have been converted to function call */
2938 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2939 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2940 freeAsmop(result,NULL,ic,TRUE);
2943 /*-----------------------------------------------------------------*/
2944 /* genDivbits :- division of bits */
2945 /*-----------------------------------------------------------------*/
2946 static void genDivbits (operand *left,
2953 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2954 /* the result must be bit */
2955 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
2956 l = aopGet(AOP(left),0,FALSE,FALSE);
2960 pic14_emitcode("div","ab");
2961 pic14_emitcode("rrc","a");
2962 aopPut(AOP(result),"c",0);
2965 /*-----------------------------------------------------------------*/
2966 /* genDivOneByte : 8 bit division */
2967 /*-----------------------------------------------------------------*/
2968 static void genDivOneByte (operand *left,
2972 sym_link *opetype = operandType(result);
2977 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2978 size = AOP_SIZE(result) - 1;
2980 /* signed or unsigned */
2981 if (SPEC_USIGN(opetype)) {
2982 /* unsigned is easy */
2983 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2984 l = aopGet(AOP(left),0,FALSE,FALSE);
2986 pic14_emitcode("div","ab");
2987 aopPut(AOP(result),"a",0);
2989 aopPut(AOP(result),zero,offset++);
2993 /* signed is a little bit more difficult */
2995 /* save the signs of the operands */
2996 l = aopGet(AOP(left),0,FALSE,FALSE);
2998 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
2999 pic14_emitcode("push","acc"); /* save it on the stack */
3001 /* now sign adjust for both left & right */
3002 l = aopGet(AOP(right),0,FALSE,FALSE);
3004 lbl = newiTempLabel(NULL);
3005 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3006 pic14_emitcode("cpl","a");
3007 pic14_emitcode("inc","a");
3008 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3009 pic14_emitcode("mov","b,a");
3011 /* sign adjust left side */
3012 l = aopGet(AOP(left),0,FALSE,FALSE);
3015 lbl = newiTempLabel(NULL);
3016 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3017 pic14_emitcode("cpl","a");
3018 pic14_emitcode("inc","a");
3019 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3021 /* now the division */
3022 pic14_emitcode("div","ab");
3023 /* we are interested in the lower order
3025 pic14_emitcode("mov","b,a");
3026 lbl = newiTempLabel(NULL);
3027 pic14_emitcode("pop","acc");
3028 /* if there was an over flow we don't
3029 adjust the sign of the result */
3030 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3031 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3033 pic14_emitcode("clr","a");
3034 pic14_emitcode("subb","a,b");
3035 pic14_emitcode("mov","b,a");
3036 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3038 /* now we are done */
3039 aopPut(AOP(result),"b",0);
3041 pic14_emitcode("mov","c,b.7");
3042 pic14_emitcode("subb","a,acc");
3045 aopPut(AOP(result),"a",offset++);
3049 /*-----------------------------------------------------------------*/
3050 /* genDiv - generates code for division */
3051 /*-----------------------------------------------------------------*/
3052 static void genDiv (iCode *ic)
3054 operand *left = IC_LEFT(ic);
3055 operand *right = IC_RIGHT(ic);
3056 operand *result= IC_RESULT(ic);
3058 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3059 /* assign the amsops */
3060 aopOp (left,ic,FALSE);
3061 aopOp (right,ic,FALSE);
3062 aopOp (result,ic,TRUE);
3064 /* special cases first */
3066 if (AOP_TYPE(left) == AOP_CRY &&
3067 AOP_TYPE(right)== AOP_CRY) {
3068 genDivbits(left,right,result);
3072 /* if both are of size == 1 */
3073 if (AOP_SIZE(left) == 1 &&
3074 AOP_SIZE(right) == 1 ) {
3075 genDivOneByte(left,right,result);
3079 /* should have been converted to function call */
3082 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3083 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3084 freeAsmop(result,NULL,ic,TRUE);
3087 /*-----------------------------------------------------------------*/
3088 /* genModbits :- modulus of bits */
3089 /*-----------------------------------------------------------------*/
3090 static void genModbits (operand *left,
3097 /* the result must be bit */
3098 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3099 l = aopGet(AOP(left),0,FALSE,FALSE);
3103 pic14_emitcode("div","ab");
3104 pic14_emitcode("mov","a,b");
3105 pic14_emitcode("rrc","a");
3106 aopPut(AOP(result),"c",0);
3109 /*-----------------------------------------------------------------*/
3110 /* genModOneByte : 8 bit modulus */
3111 /*-----------------------------------------------------------------*/
3112 static void genModOneByte (operand *left,
3116 sym_link *opetype = operandType(result);
3120 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3121 /* signed or unsigned */
3122 if (SPEC_USIGN(opetype)) {
3123 /* unsigned is easy */
3124 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3125 l = aopGet(AOP(left),0,FALSE,FALSE);
3127 pic14_emitcode("div","ab");
3128 aopPut(AOP(result),"b",0);
3132 /* signed is a little bit more difficult */
3134 /* save the signs of the operands */
3135 l = aopGet(AOP(left),0,FALSE,FALSE);
3138 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3139 pic14_emitcode("push","acc"); /* save it on the stack */
3141 /* now sign adjust for both left & right */
3142 l = aopGet(AOP(right),0,FALSE,FALSE);
3145 lbl = newiTempLabel(NULL);
3146 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3147 pic14_emitcode("cpl","a");
3148 pic14_emitcode("inc","a");
3149 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3150 pic14_emitcode("mov","b,a");
3152 /* sign adjust left side */
3153 l = aopGet(AOP(left),0,FALSE,FALSE);
3156 lbl = newiTempLabel(NULL);
3157 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3158 pic14_emitcode("cpl","a");
3159 pic14_emitcode("inc","a");
3160 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3162 /* now the multiplication */
3163 pic14_emitcode("div","ab");
3164 /* we are interested in the lower order
3166 lbl = newiTempLabel(NULL);
3167 pic14_emitcode("pop","acc");
3168 /* if there was an over flow we don't
3169 adjust the sign of the result */
3170 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3171 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3173 pic14_emitcode("clr","a");
3174 pic14_emitcode("subb","a,b");
3175 pic14_emitcode("mov","b,a");
3176 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3178 /* now we are done */
3179 aopPut(AOP(result),"b",0);
3183 /*-----------------------------------------------------------------*/
3184 /* genMod - generates code for division */
3185 /*-----------------------------------------------------------------*/
3186 static void genMod (iCode *ic)
3188 operand *left = IC_LEFT(ic);
3189 operand *right = IC_RIGHT(ic);
3190 operand *result= IC_RESULT(ic);
3192 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3193 /* assign the amsops */
3194 aopOp (left,ic,FALSE);
3195 aopOp (right,ic,FALSE);
3196 aopOp (result,ic,TRUE);
3198 /* special cases first */
3200 if (AOP_TYPE(left) == AOP_CRY &&
3201 AOP_TYPE(right)== AOP_CRY) {
3202 genModbits(left,right,result);
3206 /* if both are of size == 1 */
3207 if (AOP_SIZE(left) == 1 &&
3208 AOP_SIZE(right) == 1 ) {
3209 genModOneByte(left,right,result);
3213 /* should have been converted to function call */
3217 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3218 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3219 freeAsmop(result,NULL,ic,TRUE);
3222 /*-----------------------------------------------------------------*/
3223 /* genIfxJump :- will create a jump depending on the ifx */
3224 /*-----------------------------------------------------------------*/
3226 note: May need to add parameter to indicate when a variable is in bit space.
3228 static void genIfxJump (iCode *ic, char *jval)
3231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3232 /* if true label then we jump if condition
3234 if ( IC_TRUE(ic) ) {
3236 if(strcmp(jval,"a") == 0)
3238 else if (strcmp(jval,"c") == 0)
3241 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3242 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3245 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3246 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3250 /* false label is present */
3251 if(strcmp(jval,"a") == 0)
3253 else if (strcmp(jval,"c") == 0)
3256 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3257 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3260 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3261 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3266 /* mark the icode as generated */
3270 /*-----------------------------------------------------------------*/
3272 /*-----------------------------------------------------------------*/
3273 static void genSkip(iCode *ifx,int status_bit)
3278 if ( IC_TRUE(ifx) ) {
3279 switch(status_bit) {
3294 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3295 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3299 switch(status_bit) {
3313 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3314 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3320 /*-----------------------------------------------------------------*/
3322 /*-----------------------------------------------------------------*/
3323 static void genSkipc(iCode *ifx, int condition)
3334 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3336 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3339 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3341 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3345 /*-----------------------------------------------------------------*/
3347 /*-----------------------------------------------------------------*/
3348 static void genSkipz(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);
3369 /*-----------------------------------------------------------------*/
3370 /* genCmp :- greater or less than comparison */
3371 /*-----------------------------------------------------------------*/
3372 static void genCmp (operand *left,operand *right,
3373 operand *result, iCode *ifx, int sign)
3375 int size, offset = 0 ;
3376 unsigned long lit = 0L,i = 0;
3378 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3379 /* if left & right are bit variables */
3380 if (AOP_TYPE(left) == AOP_CRY &&
3381 AOP_TYPE(right) == AOP_CRY ) {
3382 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3383 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3385 /* subtract right from left if at the
3386 end the carry flag is set then we know that
3387 left is greater than right */
3388 size = max(AOP_SIZE(left),AOP_SIZE(right));
3390 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3391 if((size == 1) && !sign &&
3392 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3393 symbol *lbl = newiTempLabel(NULL);
3394 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3395 aopGet(AOP(left),offset,FALSE,FALSE),
3396 aopGet(AOP(right),offset,FALSE,FALSE),
3398 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3401 if(AOP_TYPE(right) == AOP_LIT) {
3403 DEBUGpic14_emitcode(";right lit","%d",sign);
3405 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3408 i = (lit >> (size*8)) & 0xff;
3410 emitpcode(POC_MOVFW, popGet(AOP(left),size,FALSE,FALSE));
3411 pic14_emitcode("movf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
3412 genSkipz(ifx,IC_TRUE(ifx) == NULL);
3414 emitpcode(POC_MOVLW, popGetLit(i));
3415 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3417 pic14_emitcode("movlw","0x%x",i);
3418 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
3419 genSkipc(ifx,IC_TRUE(ifx) == NULL);
3426 if(AOP_TYPE(left) == AOP_LIT) {
3428 DEBUGpic14_emitcode(";left lit","%d",sign);
3430 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit))+1;
3434 i = (lit >> (size*8)) & 0xff;
3436 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3437 pic14_emitcode("movf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3438 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3439 } else if( i == 1 ) {
3440 emitpcode(POC_DECFW, popGet(AOP(right),size,FALSE,FALSE));
3441 pic14_emitcode("decf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3442 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3445 emitpcode(POC_MOVLW, popGetLit(i));
3446 emitpcode(POC_SUBFW, popGet(AOP(right),size,FALSE,FALSE));
3448 pic14_emitcode("movlw","0x%x",i);
3449 pic14_emitcode("subwf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3450 genSkipc(ifx,IC_TRUE(ifx) != NULL);
3459 DEBUGpic14_emitcode(";sign","%d",sign);
3461 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3462 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3464 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3465 emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3470 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3472 emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3473 emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE));
3476 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3478 pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3479 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3487 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3488 pic14_outBitC(result);
3490 /* if the result is used in the next
3491 ifx conditional branch then generate
3492 code a little differently */
3494 genIfxJump (ifx,"c");
3496 pic14_outBitC(result);
3497 /* leave the result in acc */
3502 /*-----------------------------------------------------------------*/
3503 /* genCmpGt :- greater than comparison */
3504 /*-----------------------------------------------------------------*/
3505 static void genCmpGt (iCode *ic, iCode *ifx)
3507 operand *left, *right, *result;
3508 sym_link *letype , *retype;
3511 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3513 right= IC_RIGHT(ic);
3514 result = IC_RESULT(ic);
3516 letype = getSpec(operandType(left));
3517 retype =getSpec(operandType(right));
3518 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3519 /* assign the amsops */
3520 aopOp (left,ic,FALSE);
3521 aopOp (right,ic,FALSE);
3522 aopOp (result,ic,TRUE);
3524 genCmp(right, left, result, ifx, sign);
3526 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3527 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3528 freeAsmop(result,NULL,ic,TRUE);
3531 /*-----------------------------------------------------------------*/
3532 /* genCmpLt - less than comparisons */
3533 /*-----------------------------------------------------------------*/
3534 static void genCmpLt (iCode *ic, iCode *ifx)
3536 operand *left, *right, *result;
3537 sym_link *letype , *retype;
3540 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3542 right= IC_RIGHT(ic);
3543 result = IC_RESULT(ic);
3545 letype = getSpec(operandType(left));
3546 retype =getSpec(operandType(right));
3547 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3549 /* assign the amsops */
3550 aopOp (left,ic,FALSE);
3551 aopOp (right,ic,FALSE);
3552 aopOp (result,ic,TRUE);
3554 genCmp(left, right, result, ifx, sign);
3556 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3557 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3558 freeAsmop(result,NULL,ic,TRUE);
3561 /*-----------------------------------------------------------------*/
3562 /* gencjneshort - compare and jump if not equal */
3563 /*-----------------------------------------------------------------*/
3564 static void gencjneshort(operand *left, operand *right, symbol *lbl)
3566 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3568 unsigned long lit = 0L;
3570 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3571 /* if the left side is a literal or
3572 if the right is in a pointer register and left
3574 if ((AOP_TYPE(left) == AOP_LIT) ||
3575 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3580 if(AOP_TYPE(right) == AOP_LIT)
3581 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3583 /* if the right side is a literal then anything goes */
3584 if (AOP_TYPE(right) == AOP_LIT &&
3585 AOP_TYPE(left) != AOP_DIR ) {
3588 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3589 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3591 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3594 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3600 /* if the right side is in a register or in direct space or
3601 if the left is a pointer register & right is not */
3602 else if (AOP_TYPE(right) == AOP_REG ||
3603 AOP_TYPE(right) == AOP_DIR ||
3604 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3605 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3607 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3608 ( (lit & 0xff) != 0)) {
3609 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3610 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3613 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3616 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3619 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
3620 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3621 ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0))
3622 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
3624 pic14_emitcode("cjne","a,%s,%05d_DS_",
3625 aopGet(AOP(right),offset,FALSE,TRUE),
3631 /* right is a pointer reg need both a & b */
3633 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3635 pic14_emitcode("mov","b,%s",l);
3636 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3637 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
3643 /*-----------------------------------------------------------------*/
3644 /* gencjne - compare and jump if not equal */
3645 /*-----------------------------------------------------------------*/
3646 static void gencjne(operand *left, operand *right, symbol *lbl)
3648 symbol *tlbl = newiTempLabel(NULL);
3650 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3651 gencjneshort(left, right, lbl);
3653 pic14_emitcode("mov","a,%s",one);
3654 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3655 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3656 pic14_emitcode("clr","a");
3657 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
3661 /*-----------------------------------------------------------------*/
3662 /* genCmpEq - generates code for equal to */
3663 /*-----------------------------------------------------------------*/
3664 static void genCmpEq (iCode *ic, iCode *ifx)
3666 operand *left, *right, *result;
3667 unsigned long lit = 0L;
3670 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3672 DEBUGpic14_emitcode ("; ifx is non-null","");
3674 DEBUGpic14_emitcode ("; ifx is null","");
3676 aopOp((left=IC_LEFT(ic)),ic,FALSE);
3677 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
3678 aopOp((result=IC_RESULT(ic)),ic,TRUE);
3680 size = max(AOP_SIZE(left),AOP_SIZE(right));
3682 /* if literal, literal on the right or
3683 if the right is in a pointer register and left
3685 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
3686 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3687 operand *t = IC_RIGHT(ic);
3688 IC_RIGHT(ic) = IC_LEFT(ic);
3692 if(ifx && !AOP_SIZE(result)){
3694 /* if they are both bit variables */
3695 if (AOP_TYPE(left) == AOP_CRY &&
3696 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3697 if(AOP_TYPE(right) == AOP_LIT){
3698 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3700 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3701 pic14_emitcode("cpl","c");
3702 } else if(lit == 1L) {
3703 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3705 pic14_emitcode("clr","c");
3707 /* AOP_TYPE(right) == AOP_CRY */
3709 symbol *lbl = newiTempLabel(NULL);
3710 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3711 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3712 pic14_emitcode("cpl","c");
3713 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3715 /* if true label then we jump if condition
3717 tlbl = newiTempLabel(NULL);
3718 if ( IC_TRUE(ifx) ) {
3719 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
3720 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
3722 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
3723 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
3725 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
3728 /* They're not both bit variables. Is the right a literal? */
3729 if(AOP_TYPE(right) == AOP_LIT) {
3731 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3736 int h = (lit>>8) & 0xff;
3739 /* Check special cases for integers */
3740 switch(lit & 0xffff) {
3742 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3743 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3744 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3745 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3750 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3751 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3752 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3753 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3758 emitpcode(POC_DECFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3759 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3760 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3761 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3766 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3767 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3768 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3769 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3774 emitpcode(POC_INCFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3775 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3776 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3777 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3783 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3784 emitpcode(POC_XORLW,popGetLit(l));
3785 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3787 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3788 pic14_emitcode("xorlw","0x%x",l);
3789 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3792 } else if (l == 0) {
3793 emitpcode(POC_MOVFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3794 emitpcode(POC_XORLW,popGetLit(h));
3795 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3797 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3798 pic14_emitcode("xorlw","0x%x",h);
3799 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3803 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3804 emitpcode(POC_XORLW,popGetLit(l));
3805 emitpcode(POC_MOVLW,popGetLit(h));
3807 emitpcode(POC_XORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3809 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3810 pic14_emitcode("xorlw","0x%x",l);
3811 pic14_emitcode("movlw","0x%x",h);
3813 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3830 switch(lit & 0xff) {
3832 if ( IC_TRUE(ifx) ) {
3834 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3836 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3838 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3840 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3842 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3843 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3845 pic14_emitcode("decfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3846 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3850 if ( IC_TRUE(ifx) ) {
3851 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3853 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3855 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3857 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3859 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3860 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3862 pic14_emitcode("incfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3863 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3867 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3868 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3870 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3871 //pic14_emitcode("xorlw","0x%x",lit & 0xff);
3876 // pic14_emitcode("goto","_%05d_DS_",tlbl->key+100+labelOffset);
3877 //pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
3882 } else if(AOP_TYPE(right) == AOP_CRY ) {
3883 /* we know the left is not a bit, but that the right is */
3884 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3885 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
3886 popGet(AOP(right),offset,FALSE,FALSE));
3887 emitpcode(POC_XORLW,popGetLit(1));
3889 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3891 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
3892 AOP(right)->aopu.aop_dir,
3893 AOP(right)->aopu.aop_dir);
3895 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
3896 AOP(right)->aopu.aop_dir,
3897 AOP(right)->aopu.aop_dir);
3899 pic14_emitcode("xorlw","1");
3901 /* if the two are equal, then W will be 0 and the Z bit is set
3902 * we could test Z now, or go ahead and check the high order bytes if
3903 * the variable we're comparing is larger than a byte. */
3906 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3907 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3909 if ( IC_TRUE(ifx) ) {
3911 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3912 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3915 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3916 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3920 /* They're both variables that are larger than bits */
3923 tlbl = newiTempLabel(NULL);
3926 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3927 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3929 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3930 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3932 if ( IC_TRUE(ifx) ) {
3935 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
3936 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
3939 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3940 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3944 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3945 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3949 if(s>1 && IC_TRUE(ifx)) {
3950 emitpLabel(tlbl->key+100+labelOffset);
3951 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
3955 /* mark the icode as generated */
3960 /* if they are both bit variables */
3961 if (AOP_TYPE(left) == AOP_CRY &&
3962 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3963 if(AOP_TYPE(right) == AOP_LIT){
3964 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3966 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3967 pic14_emitcode("cpl","c");
3968 } else if(lit == 1L) {
3969 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3971 pic14_emitcode("clr","c");
3973 /* AOP_TYPE(right) == AOP_CRY */
3975 symbol *lbl = newiTempLabel(NULL);
3976 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3977 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3978 pic14_emitcode("cpl","c");
3979 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3982 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
3983 pic14_outBitC(result);
3987 genIfxJump (ifx,"c");
3990 /* if the result is used in an arithmetic operation
3991 then put the result in place */
3992 pic14_outBitC(result);
3994 gencjne(left,right,newiTempLabel(NULL));
3995 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3996 aopPut(AOP(result),"a",0);
4000 genIfxJump (ifx,"a");
4003 /* if the result is used in an arithmetic operation
4004 then put the result in place */
4005 if (AOP_TYPE(result) != AOP_CRY)
4006 pic14_outAcc(result);
4007 /* leave the result in acc */
4011 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4012 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4013 freeAsmop(result,NULL,ic,TRUE);
4016 /*-----------------------------------------------------------------*/
4017 /* ifxForOp - returns the icode containing the ifx for operand */
4018 /*-----------------------------------------------------------------*/
4019 static iCode *ifxForOp ( operand *op, iCode *ic )
4021 /* if true symbol then needs to be assigned */
4022 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4023 if (IS_TRUE_SYMOP(op))
4026 /* if this has register type condition and
4027 the next instruction is ifx with the same operand
4028 and live to of the operand is upto the ifx only then */
4030 ic->next->op == IFX &&
4031 IC_COND(ic->next)->key == op->key &&
4032 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4037 /*-----------------------------------------------------------------*/
4038 /* genAndOp - for && operation */
4039 /*-----------------------------------------------------------------*/
4040 static void genAndOp (iCode *ic)
4042 operand *left,*right, *result;
4045 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4046 /* note here that && operations that are in an
4047 if statement are taken away by backPatchLabels
4048 only those used in arthmetic operations remain */
4049 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4050 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4051 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4053 /* if both are bit variables */
4054 if (AOP_TYPE(left) == AOP_CRY &&
4055 AOP_TYPE(right) == AOP_CRY ) {
4056 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4057 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4058 pic14_outBitC(result);
4060 tlbl = newiTempLabel(NULL);
4061 pic14_toBoolean(left);
4062 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4063 pic14_toBoolean(right);
4064 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4065 pic14_outBitAcc(result);
4068 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4069 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4070 freeAsmop(result,NULL,ic,TRUE);
4074 /*-----------------------------------------------------------------*/
4075 /* genOrOp - for || operation */
4076 /*-----------------------------------------------------------------*/
4079 modified this code, but it doesn't appear to ever get called
4082 static void genOrOp (iCode *ic)
4084 operand *left,*right, *result;
4087 /* note here that || operations that are in an
4088 if statement are taken away by backPatchLabels
4089 only those used in arthmetic operations remain */
4090 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4091 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4092 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4093 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4095 /* if both are bit variables */
4096 if (AOP_TYPE(left) == AOP_CRY &&
4097 AOP_TYPE(right) == AOP_CRY ) {
4098 pic14_emitcode("clrc","");
4099 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4100 AOP(left)->aopu.aop_dir,
4101 AOP(left)->aopu.aop_dir);
4102 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4103 AOP(right)->aopu.aop_dir,
4104 AOP(right)->aopu.aop_dir);
4105 pic14_emitcode("setc","");
4108 tlbl = newiTempLabel(NULL);
4109 pic14_toBoolean(left);
4111 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4112 pic14_toBoolean(right);
4113 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4115 pic14_outBitAcc(result);
4118 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4119 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4120 freeAsmop(result,NULL,ic,TRUE);
4123 /*-----------------------------------------------------------------*/
4124 /* isLiteralBit - test if lit == 2^n */
4125 /*-----------------------------------------------------------------*/
4126 static int isLiteralBit(unsigned long lit)
4128 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4129 0x100L,0x200L,0x400L,0x800L,
4130 0x1000L,0x2000L,0x4000L,0x8000L,
4131 0x10000L,0x20000L,0x40000L,0x80000L,
4132 0x100000L,0x200000L,0x400000L,0x800000L,
4133 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4134 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4137 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4138 for(idx = 0; idx < 32; idx++)
4144 /*-----------------------------------------------------------------*/
4145 /* continueIfTrue - */
4146 /*-----------------------------------------------------------------*/
4147 static void continueIfTrue (iCode *ic)
4149 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4151 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4155 /*-----------------------------------------------------------------*/
4157 /*-----------------------------------------------------------------*/
4158 static void jumpIfTrue (iCode *ic)
4160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4162 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4166 /*-----------------------------------------------------------------*/
4167 /* jmpTrueOrFalse - */
4168 /*-----------------------------------------------------------------*/
4169 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4171 // ugly but optimized by peephole
4172 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4174 symbol *nlbl = newiTempLabel(NULL);
4175 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4176 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4177 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4178 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4181 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4182 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4187 /*-----------------------------------------------------------------*/
4188 /* genAnd - code for and */
4189 /*-----------------------------------------------------------------*/
4190 static void genAnd (iCode *ic, iCode *ifx)
4192 operand *left, *right, *result;
4194 unsigned long lit = 0L;
4198 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4199 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4200 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4201 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4204 pic14_emitcode("","; Type res[%d] = l[%d]&r[%d]",
4206 AOP_TYPE(left), AOP_TYPE(right));
4207 pic14_emitcode("","; Size res[%d] = l[%d]&r[%d]",
4209 AOP_SIZE(left), AOP_SIZE(right));
4212 /* if left is a literal & right is not then exchange them */
4213 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4214 AOP_NEEDSACC(left)) {
4215 operand *tmp = right ;
4220 /* if result = right then exchange them */
4221 if(pic14_sameRegs(AOP(result),AOP(right))){
4222 operand *tmp = right ;
4227 /* if right is bit then exchange them */
4228 if (AOP_TYPE(right) == AOP_CRY &&
4229 AOP_TYPE(left) != AOP_CRY){
4230 operand *tmp = right ;
4234 if(AOP_TYPE(right) == AOP_LIT)
4235 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4237 size = AOP_SIZE(result);
4240 // result = bit & yy;
4241 if (AOP_TYPE(left) == AOP_CRY){
4242 // c = bit & literal;
4243 if(AOP_TYPE(right) == AOP_LIT){
4245 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4248 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4251 if(size && (AOP_TYPE(result) == AOP_CRY)){
4252 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4255 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4259 pic14_emitcode("clr","c");
4262 if (AOP_TYPE(right) == AOP_CRY){
4264 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4265 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4268 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4270 pic14_emitcode("rrc","a");
4271 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4277 pic14_outBitC(result);
4279 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4280 genIfxJump(ifx, "c");
4284 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4285 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4286 if((AOP_TYPE(right) == AOP_LIT) &&
4287 (AOP_TYPE(result) == AOP_CRY) &&
4288 (AOP_TYPE(left) != AOP_CRY)){
4289 int posbit = isLiteralBit(lit);
4293 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4296 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4300 pCodeOp *pcorb = popGet(AOP(left),0,TRUE,FALSE);
4301 PCORB(pcorb)->subtype = PCOP(pcorb)->type;
4302 PCOP(pcorb)->type = PO_GPR_BIT;
4303 PCORB(pcorb)->bit = posbit;
4305 emitpcode(POC_BTFSC, pcorb);
4306 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4308 emitpcode(POC_BTFSS, pcorb);
4309 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4316 symbol *tlbl = newiTempLabel(NULL);
4317 int sizel = AOP_SIZE(left);
4319 pic14_emitcode("setb","c");
4321 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4322 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4324 if((posbit = isLiteralBit(bytelit)) != 0)
4325 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4327 if(bytelit != 0x0FFL)
4328 pic14_emitcode("anl","a,%s",
4329 aopGet(AOP(right),offset,FALSE,TRUE));
4330 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4335 // bit = left & literal
4337 pic14_emitcode("clr","c");
4338 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4340 // if(left & literal)
4343 jmpTrueOrFalse(ifx, tlbl);
4347 pic14_outBitC(result);
4351 /* if left is same as result */
4352 if(pic14_sameRegs(AOP(result),AOP(left))){
4353 for(;size--; offset++,lit>>=8) {
4354 if(AOP_TYPE(right) == AOP_LIT){
4355 switch(lit & 0xff) {
4357 /* and'ing with 0 has clears the result */
4358 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4359 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4362 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4363 emitpcode(POC_MOVWF,popGet(AOP(right),offset,FALSE,FALSE));
4368 int p = my_powof2( (~lit) & 0xff );
4370 /* only one bit is set in the literal, so use a bcf instruction */
4371 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4372 emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
4374 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4375 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4376 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4377 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
4382 if (AOP_TYPE(left) == AOP_ACC) {
4383 pic14_emitcode("?iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4384 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4387 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4388 pic14_emitcode("?iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4389 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4390 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4397 // left & result in different registers
4398 if(AOP_TYPE(result) == AOP_CRY){
4400 // if(size), result in bit
4401 // if(!size && ifx), conditional oper: if(left & right)
4402 symbol *tlbl = newiTempLabel(NULL);
4403 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4405 pic14_emitcode("setb","c");
4407 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4408 pic14_emitcode("anl","a,%s",
4409 aopGet(AOP(left),offset,FALSE,FALSE));
4410 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4415 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4416 pic14_outBitC(result);
4418 jmpTrueOrFalse(ifx, tlbl);
4420 for(;(size--);offset++) {
4422 // result = left & right
4423 if(AOP_TYPE(right) == AOP_LIT){
4424 int t = (lit >> (offset*8)) & 0x0FFL;
4427 pic14_emitcode("clrf","%s",
4428 aopGet(AOP(result),offset,FALSE,FALSE));
4429 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4432 pic14_emitcode("movf","%s,w",
4433 aopGet(AOP(left),offset,FALSE,FALSE));
4434 pic14_emitcode("movwf","%s",
4435 aopGet(AOP(result),offset,FALSE,FALSE));
4436 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4437 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4440 pic14_emitcode("movlw","0x%x",t);
4441 pic14_emitcode("andwf","%s,w",
4442 aopGet(AOP(left),offset,FALSE,FALSE));
4443 pic14_emitcode("movwf","%s",
4444 aopGet(AOP(result),offset,FALSE,FALSE));
4446 emitpcode(POC_MOVLW, popGetLit(t));
4447 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4448 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4453 if (AOP_TYPE(left) == AOP_ACC) {
4454 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4455 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4457 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4458 pic14_emitcode("andwf","%s,w",
4459 aopGet(AOP(left),offset,FALSE,FALSE));
4460 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4461 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4463 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4464 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4470 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4471 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4472 freeAsmop(result,NULL,ic,TRUE);
4475 /*-----------------------------------------------------------------*/
4476 /* genOr - code for or */
4477 /*-----------------------------------------------------------------*/
4478 static void genOr (iCode *ic, iCode *ifx)
4480 operand *left, *right, *result;
4482 unsigned long lit = 0L;
4484 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4486 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4487 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4488 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4491 /* if left is a literal & right is not then exchange them */
4492 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4493 AOP_NEEDSACC(left)) {
4494 operand *tmp = right ;
4499 /* if result = right then exchange them */
4500 if(pic14_sameRegs(AOP(result),AOP(right))){
4501 operand *tmp = right ;
4506 /* if right is bit then exchange them */
4507 if (AOP_TYPE(right) == AOP_CRY &&
4508 AOP_TYPE(left) != AOP_CRY){
4509 operand *tmp = right ;
4514 if(AOP_TYPE(right) == AOP_LIT)
4515 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4517 size = AOP_SIZE(result);
4521 if (AOP_TYPE(left) == AOP_CRY){
4522 if(AOP_TYPE(right) == AOP_LIT){
4523 // c = bit & literal;
4525 // lit != 0 => result = 1
4526 if(AOP_TYPE(result) == AOP_CRY){
4528 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4529 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4530 // AOP(result)->aopu.aop_dir,
4531 // AOP(result)->aopu.aop_dir);
4533 continueIfTrue(ifx);
4537 // lit == 0 => result = left
4538 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4540 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4543 if (AOP_TYPE(right) == AOP_CRY){
4544 if(pic14_sameRegs(AOP(result),AOP(left))){
4546 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4547 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4548 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4550 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4551 AOP(result)->aopu.aop_dir,
4552 AOP(result)->aopu.aop_dir);
4553 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4554 AOP(right)->aopu.aop_dir,
4555 AOP(right)->aopu.aop_dir);
4556 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4557 AOP(result)->aopu.aop_dir,
4558 AOP(result)->aopu.aop_dir);
4561 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4562 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4563 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4564 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4566 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4567 AOP(result)->aopu.aop_dir,
4568 AOP(result)->aopu.aop_dir);
4569 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4570 AOP(right)->aopu.aop_dir,
4571 AOP(right)->aopu.aop_dir);
4572 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4573 AOP(left)->aopu.aop_dir,
4574 AOP(left)->aopu.aop_dir);
4575 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4576 AOP(result)->aopu.aop_dir,
4577 AOP(result)->aopu.aop_dir);
4582 symbol *tlbl = newiTempLabel(NULL);
4583 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4584 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4585 pic14_emitcode(";XXX setb","c");
4586 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4587 AOP(left)->aopu.aop_dir,tlbl->key+100);
4588 pic14_toBoolean(right);
4589 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4590 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4591 jmpTrueOrFalse(ifx, tlbl);
4595 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4602 pic14_outBitC(result);
4604 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4605 genIfxJump(ifx, "c");
4609 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4610 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4611 if((AOP_TYPE(right) == AOP_LIT) &&
4612 (AOP_TYPE(result) == AOP_CRY) &&
4613 (AOP_TYPE(left) != AOP_CRY)){
4615 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4618 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4620 continueIfTrue(ifx);
4623 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4624 // lit = 0, result = boolean(left)
4626 pic14_emitcode(";XXX setb","c");
4627 pic14_toBoolean(right);
4629 symbol *tlbl = newiTempLabel(NULL);
4630 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4632 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4634 genIfxJump (ifx,"a");
4638 pic14_outBitC(result);
4642 /* if left is same as result */
4643 if(pic14_sameRegs(AOP(result),AOP(left))){
4644 for(;size--; offset++,lit>>=8) {
4645 if(AOP_TYPE(right) == AOP_LIT){
4646 if((lit & 0xff) == 0)
4647 /* or'ing with 0 has no effect */
4650 int p = my_powof2(lit & 0xff);
4652 /* only one bit is set in the literal, so use a bsf instruction */
4653 emitpcode(POC_BSF, popGet(AOP(left),offset,FALSE,FALSE));
4654 pic14_emitcode("bsf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4656 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4657 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4659 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4660 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
4665 if (AOP_TYPE(left) == AOP_ACC) {
4666 emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE));
4667 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4669 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4670 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4672 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4673 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4679 // left & result in different registers
4680 if(AOP_TYPE(result) == AOP_CRY){
4682 // if(size), result in bit
4683 // if(!size && ifx), conditional oper: if(left | right)
4684 symbol *tlbl = newiTempLabel(NULL);
4685 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4686 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4689 pic14_emitcode(";XXX setb","c");
4691 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4692 pic14_emitcode(";XXX orl","a,%s",
4693 aopGet(AOP(left),offset,FALSE,FALSE));
4694 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4699 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4700 pic14_outBitC(result);
4702 jmpTrueOrFalse(ifx, tlbl);
4703 } else for(;(size--);offset++){
4705 // result = left & right
4706 if(AOP_TYPE(right) == AOP_LIT){
4707 int t = (lit >> (offset*8)) & 0x0FFL;
4710 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
4711 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4713 pic14_emitcode("movf","%s,w",
4714 aopGet(AOP(left),offset,FALSE,FALSE));
4715 pic14_emitcode("movwf","%s",
4716 aopGet(AOP(result),offset,FALSE,FALSE));
4719 emitpcode(POC_MOVLW, popGetLit(t));
4720 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4721 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4723 pic14_emitcode("movlw","0x%x",t);
4724 pic14_emitcode("iorwf","%s,w",
4725 aopGet(AOP(left),offset,FALSE,FALSE));
4726 pic14_emitcode("movwf","%s",
4727 aopGet(AOP(result),offset,FALSE,FALSE));
4733 // faster than result <- left, anl result,right
4734 // and better if result is SFR
4735 if (AOP_TYPE(left) == AOP_ACC) {
4736 emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE));
4737 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4739 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4740 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4742 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4743 pic14_emitcode("iorwf","%s,w",
4744 aopGet(AOP(left),offset,FALSE,FALSE));
4746 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4747 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4752 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4753 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4754 freeAsmop(result,NULL,ic,TRUE);
4757 /*-----------------------------------------------------------------*/
4758 /* genXor - code for xclusive or */
4759 /*-----------------------------------------------------------------*/
4760 static void genXor (iCode *ic, iCode *ifx)
4762 operand *left, *right, *result;
4764 unsigned long lit = 0L;
4766 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4768 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4769 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4770 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4772 /* if left is a literal & right is not ||
4773 if left needs acc & right does not */
4774 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4775 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
4776 operand *tmp = right ;
4781 /* if result = right then exchange them */
4782 if(pic14_sameRegs(AOP(result),AOP(right))){
4783 operand *tmp = right ;
4788 /* if right is bit then exchange them */
4789 if (AOP_TYPE(right) == AOP_CRY &&
4790 AOP_TYPE(left) != AOP_CRY){
4791 operand *tmp = right ;
4795 if(AOP_TYPE(right) == AOP_LIT)
4796 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4798 size = AOP_SIZE(result);
4802 if (AOP_TYPE(left) == AOP_CRY){
4803 if(AOP_TYPE(right) == AOP_LIT){
4804 // c = bit & literal;
4806 // lit>>1 != 0 => result = 1
4807 if(AOP_TYPE(result) == AOP_CRY){
4809 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
4811 continueIfTrue(ifx);
4814 pic14_emitcode("setb","c");
4818 // lit == 0, result = left
4819 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4821 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4823 // lit == 1, result = not(left)
4824 if(size && pic14_sameRegs(AOP(result),AOP(left))){
4825 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
4828 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4829 pic14_emitcode("cpl","c");
4836 symbol *tlbl = newiTempLabel(NULL);
4837 if (AOP_TYPE(right) == AOP_CRY){
4839 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4842 int sizer = AOP_SIZE(right);
4844 // if val>>1 != 0, result = 1
4845 pic14_emitcode("setb","c");
4847 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
4849 // test the msb of the lsb
4850 pic14_emitcode("anl","a,#0xfe");
4851 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4855 pic14_emitcode("rrc","a");
4857 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
4858 pic14_emitcode("cpl","c");
4859 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
4864 pic14_outBitC(result);
4866 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4867 genIfxJump(ifx, "c");
4871 if(pic14_sameRegs(AOP(result),AOP(left))){
4872 /* if left is same as result */
4873 for(;size--; offset++) {
4874 if(AOP_TYPE(right) == AOP_LIT){
4875 int t = (lit >> (offset*8)) & 0x0FFL;
4879 if (IS_AOP_PREG(left)) {
4880 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4881 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4882 aopPut(AOP(result),"a",offset);
4884 emitpcode(POC_MOVLW, popGetLit(t));
4885 emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
4886 pic14_emitcode("xrl","%s,%s",
4887 aopGet(AOP(left),offset,FALSE,TRUE),
4888 aopGet(AOP(right),offset,FALSE,FALSE));
4891 if (AOP_TYPE(left) == AOP_ACC)
4892 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
4894 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4895 if (IS_AOP_PREG(left)) {
4896 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4897 aopPut(AOP(result),"a",offset);
4899 pic14_emitcode("xrl","%s,a",
4900 aopGet(AOP(left),offset,FALSE,TRUE));
4905 // left & result in different registers
4906 if(AOP_TYPE(result) == AOP_CRY){
4908 // if(size), result in bit
4909 // if(!size && ifx), conditional oper: if(left ^ right)
4910 symbol *tlbl = newiTempLabel(NULL);
4911 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4913 pic14_emitcode("setb","c");
4915 if((AOP_TYPE(right) == AOP_LIT) &&
4916 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
4917 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
4919 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4920 pic14_emitcode("xrl","a,%s",
4921 aopGet(AOP(left),offset,FALSE,FALSE));
4923 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4928 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4929 pic14_outBitC(result);
4931 jmpTrueOrFalse(ifx, tlbl);
4932 } else for(;(size--);offset++){
4934 // result = left & right
4935 if(AOP_TYPE(right) == AOP_LIT){
4936 int t = (lit >> (offset*8)) & 0x0FFL;
4939 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4940 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4941 pic14_emitcode("movf","%s,w",
4942 aopGet(AOP(left),offset,FALSE,FALSE));
4943 pic14_emitcode("movwf","%s",
4944 aopGet(AOP(result),offset,FALSE,FALSE));
4947 emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
4948 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4949 pic14_emitcode("comf","%s,w",
4950 aopGet(AOP(left),offset,FALSE,FALSE));
4951 pic14_emitcode("movwf","%s",
4952 aopGet(AOP(result),offset,FALSE,FALSE));
4955 emitpcode(POC_MOVLW, popGetLit(t));
4956 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
4957 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4958 pic14_emitcode("movlw","0x%x",t);
4959 pic14_emitcode("xorwf","%s,w",
4960 aopGet(AOP(left),offset,FALSE,FALSE));
4961 pic14_emitcode("movwf","%s",
4962 aopGet(AOP(result),offset,FALSE,FALSE));
4968 // faster than result <- left, anl result,right
4969 // and better if result is SFR
4970 if (AOP_TYPE(left) == AOP_ACC) {
4971 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
4972 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4974 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4975 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
4976 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4977 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4979 if ( AOP_TYPE(result) != AOP_ACC){
4980 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4981 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4987 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4988 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4989 freeAsmop(result,NULL,ic,TRUE);
4992 /*-----------------------------------------------------------------*/
4993 /* genInline - write the inline code out */
4994 /*-----------------------------------------------------------------*/
4995 static void genInline (iCode *ic)
4997 char *buffer, *bp, *bp1;
4999 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5001 _G.inLine += (!options.asmpeep);
5003 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5004 strcpy(buffer,IC_INLINE(ic));
5006 /* emit each line as a code */
5010 pic14_emitcode(bp1,"");
5017 pic14_emitcode(bp1,"");
5024 pic14_emitcode(bp1,"");
5025 /* pic14_emitcode("",buffer); */
5026 _G.inLine -= (!options.asmpeep);
5029 /*-----------------------------------------------------------------*/
5030 /* genRRC - rotate right with carry */
5031 /*-----------------------------------------------------------------*/
5032 static void genRRC (iCode *ic)
5034 operand *left , *result ;
5035 int size, offset = 0;
5038 /* rotate right with carry */
5040 result=IC_RESULT(ic);
5041 aopOp (left,ic,FALSE);
5042 aopOp (result,ic,FALSE);
5044 /* move it to the result */
5045 size = AOP_SIZE(result);
5049 l = aopGet(AOP(left),offset,FALSE,FALSE);
5051 pic14_emitcode("rrc","a");
5052 if (AOP_SIZE(result) > 1)
5053 aopPut(AOP(result),"a",offset--);
5055 /* now we need to put the carry into the
5056 highest order byte of the result */
5057 if (AOP_SIZE(result) > 1) {
5058 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5061 pic14_emitcode("mov","acc.7,c");
5062 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5063 freeAsmop(left,NULL,ic,TRUE);
5064 freeAsmop(result,NULL,ic,TRUE);
5067 /*-----------------------------------------------------------------*/
5068 /* genRLC - generate code for rotate left with carry */
5069 /*-----------------------------------------------------------------*/
5070 static void genRLC (iCode *ic)
5072 operand *left , *result ;
5073 int size, offset = 0;
5076 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5077 /* rotate right with carry */
5079 result=IC_RESULT(ic);
5080 aopOp (left,ic,FALSE);
5081 aopOp (result,ic,FALSE);
5083 /* move it to the result */
5084 size = AOP_SIZE(result);
5087 l = aopGet(AOP(left),offset,FALSE,FALSE);
5089 pic14_emitcode("add","a,acc");
5090 if (AOP_SIZE(result) > 1)
5091 aopPut(AOP(result),"a",offset++);
5093 l = aopGet(AOP(left),offset,FALSE,FALSE);
5095 pic14_emitcode("rlc","a");
5096 if (AOP_SIZE(result) > 1)
5097 aopPut(AOP(result),"a",offset++);
5100 /* now we need to put the carry into the
5101 highest order byte of the result */
5102 if (AOP_SIZE(result) > 1) {
5103 l = aopGet(AOP(result),0,FALSE,FALSE);
5106 pic14_emitcode("mov","acc.0,c");
5107 aopPut(AOP(result),"a",0);
5108 freeAsmop(left,NULL,ic,TRUE);
5109 freeAsmop(result,NULL,ic,TRUE);
5112 /*-----------------------------------------------------------------*/
5113 /* genGetHbit - generates code get highest order bit */
5114 /*-----------------------------------------------------------------*/
5115 static void genGetHbit (iCode *ic)
5117 operand *left, *result;
5119 result=IC_RESULT(ic);
5120 aopOp (left,ic,FALSE);
5121 aopOp (result,ic,FALSE);
5123 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5124 /* get the highest order byte into a */
5125 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5126 if(AOP_TYPE(result) == AOP_CRY){
5127 pic14_emitcode("rlc","a");
5128 pic14_outBitC(result);
5131 pic14_emitcode("rl","a");
5132 pic14_emitcode("anl","a,#0x01");
5133 pic14_outAcc(result);
5137 freeAsmop(left,NULL,ic,TRUE);
5138 freeAsmop(result,NULL,ic,TRUE);
5141 /*-----------------------------------------------------------------*/
5142 /* AccRol - rotate left accumulator by known count */
5143 /*-----------------------------------------------------------------*/
5144 static void AccRol (int shCount)
5146 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5147 shCount &= 0x0007; // shCount : 0..7
5152 pic14_emitcode("rl","a");
5155 pic14_emitcode("rl","a");
5156 pic14_emitcode("rl","a");
5159 pic14_emitcode("swap","a");
5160 pic14_emitcode("rr","a");
5163 pic14_emitcode("swap","a");
5166 pic14_emitcode("swap","a");
5167 pic14_emitcode("rl","a");
5170 pic14_emitcode("rr","a");
5171 pic14_emitcode("rr","a");
5174 pic14_emitcode("rr","a");
5179 /*-----------------------------------------------------------------*/
5180 /* AccLsh - left shift accumulator by known count */
5181 /*-----------------------------------------------------------------*/
5182 static void AccLsh (int shCount)
5184 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5187 pic14_emitcode("add","a,acc");
5190 pic14_emitcode("add","a,acc");
5191 pic14_emitcode("add","a,acc");
5193 /* rotate left accumulator */
5195 /* and kill the lower order bits */
5196 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5201 /*-----------------------------------------------------------------*/
5202 /* AccRsh - right shift accumulator by known count */
5203 /*-----------------------------------------------------------------*/
5204 static void AccRsh (int shCount)
5206 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5210 pic14_emitcode("rrc","a");
5212 /* rotate right accumulator */
5213 AccRol(8 - shCount);
5214 /* and kill the higher order bits */
5215 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5221 /*-----------------------------------------------------------------*/
5222 /* AccSRsh - signed right shift accumulator by known count */
5223 /*-----------------------------------------------------------------*/
5224 static void AccSRsh (int shCount)
5227 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5230 pic14_emitcode("mov","c,acc.7");
5231 pic14_emitcode("rrc","a");
5232 } else if(shCount == 2){
5233 pic14_emitcode("mov","c,acc.7");
5234 pic14_emitcode("rrc","a");
5235 pic14_emitcode("mov","c,acc.7");
5236 pic14_emitcode("rrc","a");
5238 tlbl = newiTempLabel(NULL);
5239 /* rotate right accumulator */
5240 AccRol(8 - shCount);
5241 /* and kill the higher order bits */
5242 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5243 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5244 pic14_emitcode("orl","a,#0x%02x",
5245 (unsigned char)~SRMask[shCount]);
5246 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5251 /*-----------------------------------------------------------------*/
5252 /* shiftR1Left2Result - shift right one byte from left to result */
5253 /*-----------------------------------------------------------------*/
5254 static void shiftR1Left2ResultSigned (operand *left, int offl,
5255 operand *result, int offr,
5260 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5262 same = (left == result) || (AOP(left) == AOP(result));
5266 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5268 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5270 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5271 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5281 /*-----------------------------------------------------------------*/
5282 /* shiftR1Left2Result - shift right one byte from left to result */
5283 /*-----------------------------------------------------------------*/
5284 static void shiftR1Left2Result (operand *left, int offl,
5285 operand *result, int offr,
5286 int shCount, int sign)
5290 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5292 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5294 /* Copy the msb into the carry if signed. */
5296 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5306 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5308 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5309 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5315 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5317 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5318 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5321 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5326 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5328 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5329 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5332 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5333 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5334 emitpcode(POC_ANDLW, popGetLit(0x1f));
5335 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5339 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5340 emitpcode(POC_ANDLW, popGetLit(0x0f));
5341 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5345 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5346 emitpcode(POC_ANDLW, popGetLit(0x0f));
5347 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5349 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5354 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5355 emitpcode(POC_ANDLW, popGetLit(0x80));
5356 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5357 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5358 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5363 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5364 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5365 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5376 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5378 /* shift right accumulator */
5383 aopPut(AOP(result),"a",offr);
5387 /*-----------------------------------------------------------------*/
5388 /* shiftL1Left2Result - shift left one byte from left to result */
5389 /*-----------------------------------------------------------------*/
5390 static void shiftL1Left2Result (operand *left, int offl,
5391 operand *result, int offr, int shCount)
5396 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5398 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5399 DEBUGpic14_emitcode ("; ***","same = %d",same);
5400 // l = aopGet(AOP(left),offl,FALSE,FALSE);
5402 /* shift left accumulator */
5403 //AccLsh(shCount); // don't comment out just yet...
5404 // aopPut(AOP(result),"a",offr);
5408 /* Shift left 1 bit position */
5409 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5411 emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
5413 emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
5414 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5418 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5419 emitpcode(POC_ANDLW,popGetLit(0x7e));
5420 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5421 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5424 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5425 emitpcode(POC_ANDLW,popGetLit(0x3e));
5426 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5427 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5428 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5431 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5432 emitpcode(POC_ANDLW, popGetLit(0xf0));
5433 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5436 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5437 emitpcode(POC_ANDLW, popGetLit(0xf0));
5438 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5439 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5442 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5443 emitpcode(POC_ANDLW, popGetLit(0x30));
5444 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5445 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5446 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5449 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5450 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5451 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5455 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5460 /*-----------------------------------------------------------------*/
5461 /* movLeft2Result - move byte from left to result */
5462 /*-----------------------------------------------------------------*/
5463 static void movLeft2Result (operand *left, int offl,
5464 operand *result, int offr, int sign)
5467 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5468 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5469 l = aopGet(AOP(left),offl,FALSE,FALSE);
5471 if (*l == '@' && (IS_AOP_PREG(result))) {
5472 pic14_emitcode("mov","a,%s",l);
5473 aopPut(AOP(result),"a",offr);
5476 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5477 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5479 //aopPut(AOP(result),l,offr);
5481 /* MSB sign in acc.7 ! */
5482 if(pic14_getDataSize(left) == offl+1){
5483 pic14_emitcode("mov","a,%s",l);
5484 aopPut(AOP(result),"a",offr);
5491 /*-----------------------------------------------------------------*/
5492 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5493 /*-----------------------------------------------------------------*/
5494 static void AccAXRrl1 (char *x)
5496 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5497 pic14_emitcode("rrc","a");
5498 pic14_emitcode("xch","a,%s", x);
5499 pic14_emitcode("rrc","a");
5500 pic14_emitcode("xch","a,%s", x);
5503 /*-----------------------------------------------------------------*/
5504 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5505 /*-----------------------------------------------------------------*/
5506 static void AccAXLrl1 (char *x)
5508 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5509 pic14_emitcode("xch","a,%s",x);
5510 pic14_emitcode("rlc","a");
5511 pic14_emitcode("xch","a,%s",x);
5512 pic14_emitcode("rlc","a");
5515 /*-----------------------------------------------------------------*/
5516 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5517 /*-----------------------------------------------------------------*/
5518 static void AccAXLsh1 (char *x)
5520 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5521 pic14_emitcode("xch","a,%s",x);
5522 pic14_emitcode("add","a,acc");
5523 pic14_emitcode("xch","a,%s",x);
5524 pic14_emitcode("rlc","a");
5528 /*-----------------------------------------------------------------*/
5529 /* AccAXLsh - left shift a:x by known count (0..7) */
5530 /*-----------------------------------------------------------------*/
5531 static void AccAXLsh (char *x, int shCount)
5533 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5546 case 5 : // AAAAABBB:CCCCCDDD
5547 AccRol(shCount); // BBBAAAAA:CCCCCDDD
5548 pic14_emitcode("anl","a,#0x%02x",
5549 SLMask[shCount]); // BBB00000:CCCCCDDD
5550 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
5551 AccRol(shCount); // DDDCCCCC:BBB00000
5552 pic14_emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
5553 pic14_emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
5554 pic14_emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
5555 pic14_emitcode("anl","a,#0x%02x",
5556 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5557 pic14_emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
5558 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
5560 case 6 : // AAAAAABB:CCCCCCDD
5561 pic14_emitcode("anl","a,#0x%02x",
5562 SRMask[shCount]); // 000000BB:CCCCCCDD
5563 pic14_emitcode("mov","c,acc.0"); // c = B
5564 pic14_emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
5565 AccAXRrl1(x); // BCCCCCCD:D000000B
5566 AccAXRrl1(x); // BBCCCCCC:DD000000
5568 case 7 : // a:x <<= 7
5569 pic14_emitcode("anl","a,#0x%02x",
5570 SRMask[shCount]); // 0000000B:CCCCCCCD
5571 pic14_emitcode("mov","c,acc.0"); // c = B
5572 pic14_emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
5573 AccAXRrl1(x); // BCCCCCCC:D0000000
5581 /*-----------------------------------------------------------------*/
5582 /* AccAXRsh - right shift a:x known count (0..7) */
5583 /*-----------------------------------------------------------------*/
5584 static void AccAXRsh (char *x, int shCount)
5586 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5592 AccAXRrl1(x); // 0->a:x
5596 AccAXRrl1(x); // 0->a:x
5598 AccAXRrl1(x); // 0->a:x
5602 case 5 : // AAAAABBB:CCCCCDDD = a:x
5603 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5604 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5605 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5606 pic14_emitcode("anl","a,#0x%02x",
5607 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5608 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5609 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5610 pic14_emitcode("anl","a,#0x%02x",
5611 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5612 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5613 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5614 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5616 case 6 : // AABBBBBB:CCDDDDDD
5617 pic14_emitcode("mov","c,acc.7");
5618 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5619 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5620 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5621 pic14_emitcode("anl","a,#0x%02x",
5622 SRMask[shCount]); // 000000AA:BBBBBBCC
5624 case 7 : // ABBBBBBB:CDDDDDDD
5625 pic14_emitcode("mov","c,acc.7"); // c = A
5626 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5627 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5628 pic14_emitcode("anl","a,#0x%02x",
5629 SRMask[shCount]); // 0000000A:BBBBBBBC
5636 /*-----------------------------------------------------------------*/
5637 /* AccAXRshS - right shift signed a:x known count (0..7) */
5638 /*-----------------------------------------------------------------*/
5639 static void AccAXRshS (char *x, int shCount)
5642 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5647 pic14_emitcode("mov","c,acc.7");
5648 AccAXRrl1(x); // s->a:x
5651 pic14_emitcode("mov","c,acc.7");
5652 AccAXRrl1(x); // s->a:x
5653 pic14_emitcode("mov","c,acc.7");
5654 AccAXRrl1(x); // s->a:x
5658 case 5 : // AAAAABBB:CCCCCDDD = a:x
5659 tlbl = newiTempLabel(NULL);
5660 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
5661 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5662 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5663 pic14_emitcode("anl","a,#0x%02x",
5664 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5665 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5666 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5667 pic14_emitcode("anl","a,#0x%02x",
5668 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5669 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5670 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5671 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
5672 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5673 pic14_emitcode("orl","a,#0x%02x",
5674 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5675 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5676 break; // SSSSAAAA:BBBCCCCC
5677 case 6 : // AABBBBBB:CCDDDDDD
5678 tlbl = newiTempLabel(NULL);
5679 pic14_emitcode("mov","c,acc.7");
5680 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5681 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5682 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5683 pic14_emitcode("anl","a,#0x%02x",
5684 SRMask[shCount]); // 000000AA:BBBBBBCC
5685 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5686 pic14_emitcode("orl","a,#0x%02x",
5687 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
5688 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5690 case 7 : // ABBBBBBB:CDDDDDDD
5691 tlbl = newiTempLabel(NULL);
5692 pic14_emitcode("mov","c,acc.7"); // c = A
5693 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5694 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5695 pic14_emitcode("anl","a,#0x%02x",
5696 SRMask[shCount]); // 0000000A:BBBBBBBC
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]); // 1111111A:BBBBBBBC
5700 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5707 /*-----------------------------------------------------------------*/
5708 /* shiftL2Left2Result - shift left two bytes from left to result */
5709 /*-----------------------------------------------------------------*/
5710 static void shiftL2Left2Result (operand *left, int offl,
5711 operand *result, int offr, int shCount)
5715 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5717 if(pic14_sameRegs(AOP(result), AOP(left))) {
5725 emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
5726 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5727 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5731 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5732 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5738 emitpcode(POC_MOVLW, popGetLit(0x0f));
5739 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5740 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5741 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5742 emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
5743 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5744 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5746 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5747 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5751 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5752 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5753 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5754 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5755 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5756 emitpcode(POC_ANDLW,popGetLit(0xc0));
5757 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5758 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5759 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5760 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5763 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5764 emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
5765 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5766 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5767 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5777 /* note, use a mov/add for the shift since the mov has a
5778 chance of getting optimized out */
5779 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5780 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5781 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5782 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5783 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5787 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5788 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5794 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5795 emitpcode(POC_ANDLW, popGetLit(0xF0));
5796 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5797 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5798 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5799 emitpcode(POC_ANDLW, popGetLit(0xF0));
5800 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5801 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5805 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5806 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5810 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5811 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5812 emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
5813 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5815 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5816 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5817 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5818 emitpcode(POC_ANDLW,popGetLit(0xc0));
5819 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5820 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5821 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5822 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5825 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5826 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5827 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5828 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5829 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5834 /*-----------------------------------------------------------------*/
5835 /* shiftR2Left2Result - shift right two bytes from left to result */
5836 /*-----------------------------------------------------------------*/
5837 static void shiftR2Left2Result (operand *left, int offl,
5838 operand *result, int offr,
5839 int shCount, int sign)
5843 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5844 same = pic14_sameRegs(AOP(result), AOP(left));
5846 if(same && ((offl + MSB16) == offr)){
5848 /* don't crash result[offr] */
5849 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5850 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5852 movLeft2Result(left,offl, result, offr, 0);
5853 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5855 /* a:x >> shCount (x = lsb(result))*/
5857 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5859 //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5869 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5870 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5873 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5874 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5875 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5876 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5881 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5882 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5889 emitpcode(POC_MOVLW, popGetLit(0xf0));
5890 emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
5891 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5893 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5894 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5895 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5896 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5898 emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
5899 emitpcode(POC_ANDLW, popGetLit(0x0f));
5900 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5902 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5903 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5904 emitpcode(POC_ANDLW, popGetLit(0xf0));
5905 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5906 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5910 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5911 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5919 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5920 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5922 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5923 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5924 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5925 emitpcode(POC_ANDLW,popGetLit(0x03));
5926 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5927 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5928 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5929 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5931 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5932 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5933 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
5934 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5935 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5936 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5937 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5938 emitpcode(POC_ANDLW,popGetLit(0x03));
5939 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5944 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5945 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5946 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5947 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5948 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5953 /*-----------------------------------------------------------------*/
5954 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
5955 /*-----------------------------------------------------------------*/
5956 static void shiftLLeftOrResult (operand *left, int offl,
5957 operand *result, int offr, int shCount)
5959 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5960 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5961 /* shift left accumulator */
5963 /* or with result */
5964 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5965 /* back to result */
5966 aopPut(AOP(result),"a",offr);
5969 /*-----------------------------------------------------------------*/
5970 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
5971 /*-----------------------------------------------------------------*/
5972 static void shiftRLeftOrResult (operand *left, int offl,
5973 operand *result, int offr, int shCount)
5975 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5976 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5977 /* shift right accumulator */
5979 /* or with result */
5980 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5981 /* back to result */
5982 aopPut(AOP(result),"a",offr);
5985 /*-----------------------------------------------------------------*/
5986 /* genlshOne - left shift a one byte quantity by known count */
5987 /*-----------------------------------------------------------------*/
5988 static void genlshOne (operand *result, operand *left, int shCount)
5990 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5991 shiftL1Left2Result(left, LSB, result, LSB, shCount);
5994 /*-----------------------------------------------------------------*/
5995 /* genlshTwo - left shift two bytes by known amount != 0 */
5996 /*-----------------------------------------------------------------*/
5997 static void genlshTwo (operand *result,operand *left, int shCount)
6001 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6002 size = pic14_getDataSize(result);
6004 /* if shCount >= 8 */
6010 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6012 movLeft2Result(left, LSB, result, MSB16, 0);
6014 emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6017 /* 1 <= shCount <= 7 */
6020 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6022 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6026 /*-----------------------------------------------------------------*/
6027 /* shiftLLong - shift left one long from left to result */
6028 /* offl = LSB or MSB16 */
6029 /*-----------------------------------------------------------------*/
6030 static void shiftLLong (operand *left, operand *result, int offr )
6033 int size = AOP_SIZE(result);
6035 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6036 if(size >= LSB+offr){
6037 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6039 pic14_emitcode("add","a,acc");
6040 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6041 size >= MSB16+offr && offr != LSB )
6042 pic14_emitcode("xch","a,%s",
6043 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6045 aopPut(AOP(result),"a",LSB+offr);
6048 if(size >= MSB16+offr){
6049 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6050 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6053 pic14_emitcode("rlc","a");
6054 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6055 size >= MSB24+offr && offr != LSB)
6056 pic14_emitcode("xch","a,%s",
6057 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6059 aopPut(AOP(result),"a",MSB16+offr);
6062 if(size >= MSB24+offr){
6063 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6064 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6067 pic14_emitcode("rlc","a");
6068 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6069 size >= MSB32+offr && offr != LSB )
6070 pic14_emitcode("xch","a,%s",
6071 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6073 aopPut(AOP(result),"a",MSB24+offr);
6076 if(size > MSB32+offr){
6077 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6078 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6081 pic14_emitcode("rlc","a");
6082 aopPut(AOP(result),"a",MSB32+offr);
6085 aopPut(AOP(result),zero,LSB);
6088 /*-----------------------------------------------------------------*/
6089 /* genlshFour - shift four byte by a known amount != 0 */
6090 /*-----------------------------------------------------------------*/
6091 static void genlshFour (operand *result, operand *left, int shCount)
6095 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6096 size = AOP_SIZE(result);
6098 /* if shifting more that 3 bytes */
6099 if (shCount >= 24 ) {
6102 /* lowest order of left goes to the highest
6103 order of the destination */
6104 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6106 movLeft2Result(left, LSB, result, MSB32, 0);
6107 aopPut(AOP(result),zero,LSB);
6108 aopPut(AOP(result),zero,MSB16);
6109 aopPut(AOP(result),zero,MSB32);
6113 /* more than two bytes */
6114 else if ( shCount >= 16 ) {
6115 /* lower order two bytes goes to higher order two bytes */
6117 /* if some more remaining */
6119 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6121 movLeft2Result(left, MSB16, result, MSB32, 0);
6122 movLeft2Result(left, LSB, result, MSB24, 0);
6124 aopPut(AOP(result),zero,MSB16);
6125 aopPut(AOP(result),zero,LSB);
6129 /* if more than 1 byte */
6130 else if ( shCount >= 8 ) {
6131 /* lower order three bytes goes to higher order three bytes */
6135 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6137 movLeft2Result(left, LSB, result, MSB16, 0);
6139 else{ /* size = 4 */
6141 movLeft2Result(left, MSB24, result, MSB32, 0);
6142 movLeft2Result(left, MSB16, result, MSB24, 0);
6143 movLeft2Result(left, LSB, result, MSB16, 0);
6144 aopPut(AOP(result),zero,LSB);
6146 else if(shCount == 1)
6147 shiftLLong(left, result, MSB16);
6149 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6150 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6151 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6152 aopPut(AOP(result),zero,LSB);
6157 /* 1 <= shCount <= 7 */
6158 else if(shCount <= 2){
6159 shiftLLong(left, result, LSB);
6161 shiftLLong(result, result, LSB);
6163 /* 3 <= shCount <= 7, optimize */
6165 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6166 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6167 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6171 /*-----------------------------------------------------------------*/
6172 /* genLeftShiftLiteral - left shifting by known count */
6173 /*-----------------------------------------------------------------*/
6174 static void genLeftShiftLiteral (operand *left,
6179 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6182 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6183 freeAsmop(right,NULL,ic,TRUE);
6185 aopOp(left,ic,FALSE);
6186 aopOp(result,ic,FALSE);
6188 size = getSize(operandType(result));
6191 pic14_emitcode("; shift left ","result %d, left %d",size,
6195 /* I suppose that the left size >= result size */
6198 movLeft2Result(left, size, result, size, 0);
6202 else if(shCount >= (size * 8))
6204 aopPut(AOP(result),zero,size);
6208 genlshOne (result,left,shCount);
6213 genlshTwo (result,left,shCount);
6217 genlshFour (result,left,shCount);
6221 freeAsmop(left,NULL,ic,TRUE);
6222 freeAsmop(result,NULL,ic,TRUE);
6225 /*-----------------------------------------------------------------*/
6226 /* genLeftShift - generates code for left shifting */
6227 /*-----------------------------------------------------------------*/
6228 static void genLeftShift (iCode *ic)
6230 operand *left,*right, *result;
6233 symbol *tlbl , *tlbl1;
6235 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6237 right = IC_RIGHT(ic);
6239 result = IC_RESULT(ic);
6241 aopOp(right,ic,FALSE);
6243 /* if the shift count is known then do it
6244 as efficiently as possible */
6245 if (AOP_TYPE(right) == AOP_LIT) {
6246 genLeftShiftLiteral (left,right,result,ic);
6250 /* shift count is unknown then we have to form
6251 a loop get the loop count in B : Note: we take
6252 only the lower order byte since shifting
6253 more that 32 bits make no sense anyway, ( the
6254 largest size of an object can be only 32 bits ) */
6257 aopOp(left,ic,FALSE);
6258 aopOp(result,ic,FALSE);
6260 /* now move the left to the result if they are not the
6262 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6263 AOP_SIZE(result) > 1) {
6265 size = AOP_SIZE(result);
6268 l = aopGet(AOP(left),offset,FALSE,TRUE);
6269 if (*l == '@' && (IS_AOP_PREG(result))) {
6271 pic14_emitcode("mov","a,%s",l);
6272 aopPut(AOP(result),"a",offset);
6274 aopPut(AOP(result),l,offset);
6279 size = AOP_SIZE(result);
6281 /* if it is only one byte then */
6283 if(optimized_for_speed) {
6284 emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6285 emitpcode(POC_ANDLW, popGetLit(0xf0));
6286 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6287 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6288 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6289 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6290 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6291 emitpcode(POC_RLFW, popGet(AOP(result),0,FALSE,FALSE));
6292 emitpcode(POC_ANDLW, popGetLit(0xfe));
6293 emitpcode(POC_ADDFW, popGet(AOP(result),0,FALSE,FALSE));
6294 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6295 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6298 tlbl = newiTempLabel(NULL);
6299 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6300 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6301 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6304 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6305 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6306 emitpLabel(tlbl->key+100+labelOffset);
6307 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6308 emitpcode(POC_ADDLW, popGetLit(1));
6310 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6316 tlbl = newiTempLabel(NULL);
6318 tlbl1 = newiTempLabel(NULL);
6320 reAdjustPreg(AOP(result));
6322 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6323 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6324 l = aopGet(AOP(result),offset,FALSE,FALSE);
6326 pic14_emitcode("add","a,acc");
6327 aopPut(AOP(result),"a",offset++);
6329 l = aopGet(AOP(result),offset,FALSE,FALSE);
6331 pic14_emitcode("rlc","a");
6332 aopPut(AOP(result),"a",offset++);
6334 reAdjustPreg(AOP(result));
6336 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6337 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6339 freeAsmop (right,NULL,ic,TRUE);
6340 freeAsmop(left,NULL,ic,TRUE);
6341 freeAsmop(result,NULL,ic,TRUE);
6344 /*-----------------------------------------------------------------*/
6345 /* genrshOne - right shift a one byte quantity by known count */
6346 /*-----------------------------------------------------------------*/
6347 static void genrshOne (operand *result, operand *left,
6348 int shCount, int sign)
6350 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6351 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6354 /*-----------------------------------------------------------------*/
6355 /* genrshTwo - right shift two bytes by known amount != 0 */
6356 /*-----------------------------------------------------------------*/
6357 static void genrshTwo (operand *result,operand *left,
6358 int shCount, int sign)
6360 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6361 /* if shCount >= 8 */
6365 shiftR1Left2Result(left, MSB16, result, LSB,
6368 movLeft2Result(left, MSB16, result, LSB, sign);
6370 addSign(result, MSB16, sign);
6372 emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6376 /* 1 <= shCount <= 7 */
6378 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6381 /*-----------------------------------------------------------------*/
6382 /* shiftRLong - shift right one long from left to result */
6383 /* offl = LSB or MSB16 */
6384 /*-----------------------------------------------------------------*/
6385 static void shiftRLong (operand *left, int offl,
6386 operand *result, int sign)
6388 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6390 pic14_emitcode("clr","c");
6391 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6393 pic14_emitcode("mov","c,acc.7");
6394 pic14_emitcode("rrc","a");
6395 aopPut(AOP(result),"a",MSB32-offl);
6397 /* add sign of "a" */
6398 addSign(result, MSB32, sign);
6400 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6401 pic14_emitcode("rrc","a");
6402 aopPut(AOP(result),"a",MSB24-offl);
6404 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6405 pic14_emitcode("rrc","a");
6406 aopPut(AOP(result),"a",MSB16-offl);
6409 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6410 pic14_emitcode("rrc","a");
6411 aopPut(AOP(result),"a",LSB);
6415 /*-----------------------------------------------------------------*/
6416 /* genrshFour - shift four byte by a known amount != 0 */
6417 /*-----------------------------------------------------------------*/
6418 static void genrshFour (operand *result, operand *left,
6419 int shCount, int sign)
6421 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6422 /* if shifting more that 3 bytes */
6423 if(shCount >= 24 ) {
6426 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6428 movLeft2Result(left, MSB32, result, LSB, sign);
6429 addSign(result, MSB16, sign);
6431 else if(shCount >= 16){
6434 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6436 movLeft2Result(left, MSB24, result, LSB, 0);
6437 movLeft2Result(left, MSB32, result, MSB16, sign);
6439 addSign(result, MSB24, sign);
6441 else if(shCount >= 8){
6444 shiftRLong(left, MSB16, result, sign);
6445 else if(shCount == 0){
6446 movLeft2Result(left, MSB16, result, LSB, 0);
6447 movLeft2Result(left, MSB24, result, MSB16, 0);
6448 movLeft2Result(left, MSB32, result, MSB24, sign);
6449 addSign(result, MSB32, sign);
6452 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6453 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6454 /* the last shift is signed */
6455 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6456 addSign(result, MSB32, sign);
6459 else{ /* 1 <= shCount <= 7 */
6461 shiftRLong(left, LSB, result, sign);
6463 shiftRLong(result, LSB, result, sign);
6466 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6467 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6468 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6473 /*-----------------------------------------------------------------*/
6474 /* genRightShiftLiteral - right shifting by known count */
6475 /*-----------------------------------------------------------------*/
6476 static void genRightShiftLiteral (operand *left,
6482 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6485 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6486 freeAsmop(right,NULL,ic,TRUE);
6488 aopOp(left,ic,FALSE);
6489 aopOp(result,ic,FALSE);
6492 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6496 size = pic14_getDataSize(left);
6497 /* test the LEFT size !!! */
6499 /* I suppose that the left size >= result size */
6501 size = pic14_getDataSize(result);
6503 movLeft2Result(left, size, result, size, 0);
6506 else if(shCount >= (size * 8)){
6508 /* get sign in acc.7 */
6509 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6510 addSign(result, LSB, sign);
6514 genrshOne (result,left,shCount,sign);
6518 genrshTwo (result,left,shCount,sign);
6522 genrshFour (result,left,shCount,sign);
6528 freeAsmop(left,NULL,ic,TRUE);
6529 freeAsmop(result,NULL,ic,TRUE);
6533 /*-----------------------------------------------------------------*/
6534 /* genSignedRightShift - right shift of signed number */
6535 /*-----------------------------------------------------------------*/
6536 static void genSignedRightShift (iCode *ic)
6538 operand *right, *left, *result;
6541 symbol *tlbl, *tlbl1 ;
6543 /* we do it the hard way put the shift count in b
6544 and loop thru preserving the sign */
6545 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6547 right = IC_RIGHT(ic);
6549 result = IC_RESULT(ic);
6551 aopOp(right,ic,FALSE);
6554 if ( AOP_TYPE(right) == AOP_LIT) {
6555 genRightShiftLiteral (left,right,result,ic,1);
6558 /* shift count is unknown then we have to form
6559 a loop get the loop count in B : Note: we take
6560 only the lower order byte since shifting
6561 more that 32 bits make no sense anyway, ( the
6562 largest size of an object can be only 32 bits ) */
6564 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6565 pic14_emitcode("inc","b");
6566 freeAsmop (right,NULL,ic,TRUE);
6567 aopOp(left,ic,FALSE);
6568 aopOp(result,ic,FALSE);
6570 /* now move the left to the result if they are not the
6572 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6573 AOP_SIZE(result) > 1) {
6575 size = AOP_SIZE(result);
6578 l = aopGet(AOP(left),offset,FALSE,TRUE);
6579 if (*l == '@' && IS_AOP_PREG(result)) {
6581 pic14_emitcode("mov","a,%s",l);
6582 aopPut(AOP(result),"a",offset);
6584 aopPut(AOP(result),l,offset);
6589 /* mov the highest order bit to OVR */
6590 tlbl = newiTempLabel(NULL);
6591 tlbl1= newiTempLabel(NULL);
6593 size = AOP_SIZE(result);
6595 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6596 pic14_emitcode("rlc","a");
6597 pic14_emitcode("mov","ov,c");
6598 /* if it is only one byte then */
6600 l = aopGet(AOP(left),0,FALSE,FALSE);
6602 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6603 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6604 pic14_emitcode("mov","c,ov");
6605 pic14_emitcode("rrc","a");
6606 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6607 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6608 aopPut(AOP(result),"a",0);
6612 reAdjustPreg(AOP(result));
6613 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6614 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6615 pic14_emitcode("mov","c,ov");
6617 l = aopGet(AOP(result),offset,FALSE,FALSE);
6619 pic14_emitcode("rrc","a");
6620 aopPut(AOP(result),"a",offset--);
6622 reAdjustPreg(AOP(result));
6623 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6624 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6627 freeAsmop(left,NULL,ic,TRUE);
6628 freeAsmop(result,NULL,ic,TRUE);
6631 /*-----------------------------------------------------------------*/
6632 /* genRightShift - generate code for right shifting */
6633 /*-----------------------------------------------------------------*/
6634 static void genRightShift (iCode *ic)
6636 operand *right, *left, *result;
6640 symbol *tlbl, *tlbl1 ;
6642 /* if signed then we do it the hard way preserve the
6643 sign bit moving it inwards */
6644 retype = getSpec(operandType(IC_RESULT(ic)));
6645 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6647 if (!SPEC_USIGN(retype)) {
6648 genSignedRightShift (ic);
6652 /* signed & unsigned types are treated the same : i.e. the
6653 signed is NOT propagated inwards : quoting from the
6654 ANSI - standard : "for E1 >> E2, is equivalent to division
6655 by 2**E2 if unsigned or if it has a non-negative value,
6656 otherwise the result is implementation defined ", MY definition
6657 is that the sign does not get propagated */
6659 right = IC_RIGHT(ic);
6661 result = IC_RESULT(ic);
6663 aopOp(right,ic,FALSE);
6665 /* if the shift count is known then do it
6666 as efficiently as possible */
6667 if (AOP_TYPE(right) == AOP_LIT) {
6668 genRightShiftLiteral (left,right,result,ic, 0);
6672 /* shift count is unknown then we have to form
6673 a loop get the loop count in B : Note: we take
6674 only the lower order byte since shifting
6675 more that 32 bits make no sense anyway, ( the
6676 largest size of an object can be only 32 bits ) */
6678 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6679 pic14_emitcode("inc","b");
6680 aopOp(left,ic,FALSE);
6681 aopOp(result,ic,FALSE);
6683 /* now move the left to the result if they are not the
6685 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6686 AOP_SIZE(result) > 1) {
6688 size = AOP_SIZE(result);
6691 l = aopGet(AOP(left),offset,FALSE,TRUE);
6692 if (*l == '@' && IS_AOP_PREG(result)) {
6694 pic14_emitcode("mov","a,%s",l);
6695 aopPut(AOP(result),"a",offset);
6697 aopPut(AOP(result),l,offset);
6702 tlbl = newiTempLabel(NULL);
6703 tlbl1= newiTempLabel(NULL);
6704 size = AOP_SIZE(result);
6707 /* if it is only one byte then */
6710 l = aopGet(AOP(left),0,FALSE,FALSE);
6712 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6713 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6715 pic14_emitcode("rrc","a");
6716 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6717 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6718 aopPut(AOP(result),"a",0);
6720 tlbl = newiTempLabel(NULL);
6721 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6722 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6723 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6726 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6727 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6728 emitpLabel(tlbl->key+100+labelOffset);
6729 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6730 emitpcode(POC_ADDLW, popGetLit(1));
6732 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6737 reAdjustPreg(AOP(result));
6738 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6739 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6742 l = aopGet(AOP(result),offset,FALSE,FALSE);
6744 pic14_emitcode("rrc","a");
6745 aopPut(AOP(result),"a",offset--);
6747 reAdjustPreg(AOP(result));
6749 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6750 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6753 freeAsmop(left,NULL,ic,TRUE);
6754 freeAsmop (right,NULL,ic,TRUE);
6755 freeAsmop(result,NULL,ic,TRUE);
6758 /*-----------------------------------------------------------------*/
6759 /* genUnpackBits - generates code for unpacking bits */
6760 /*-----------------------------------------------------------------*/
6761 static void genUnpackBits (operand *result, char *rname, int ptype)
6768 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6769 etype = getSpec(operandType(result));
6771 /* read the first byte */
6776 pic14_emitcode("mov","a,@%s",rname);
6780 pic14_emitcode("movx","a,@%s",rname);
6784 pic14_emitcode("movx","a,@dptr");
6788 pic14_emitcode("clr","a");
6789 pic14_emitcode("movc","a","@a+dptr");
6793 pic14_emitcode("lcall","__gptrget");
6797 /* if we have bitdisplacement then it fits */
6798 /* into this byte completely or if length is */
6799 /* less than a byte */
6800 if ((shCnt = SPEC_BSTR(etype)) ||
6801 (SPEC_BLEN(etype) <= 8)) {
6803 /* shift right acc */
6806 pic14_emitcode("anl","a,#0x%02x",
6807 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6808 aopPut(AOP(result),"a",offset);
6812 /* bit field did not fit in a byte */
6813 rlen = SPEC_BLEN(etype) - 8;
6814 aopPut(AOP(result),"a",offset++);
6821 pic14_emitcode("inc","%s",rname);
6822 pic14_emitcode("mov","a,@%s",rname);
6826 pic14_emitcode("inc","%s",rname);
6827 pic14_emitcode("movx","a,@%s",rname);
6831 pic14_emitcode("inc","dptr");
6832 pic14_emitcode("movx","a,@dptr");
6836 pic14_emitcode("clr","a");
6837 pic14_emitcode("inc","dptr");
6838 pic14_emitcode("movc","a","@a+dptr");
6842 pic14_emitcode("inc","dptr");
6843 pic14_emitcode("lcall","__gptrget");
6848 /* if we are done */
6852 aopPut(AOP(result),"a",offset++);
6857 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
6858 aopPut(AOP(result),"a",offset);
6865 /*-----------------------------------------------------------------*/
6866 /* genDataPointerGet - generates code when ptr offset is known */
6867 /*-----------------------------------------------------------------*/
6868 static void genDataPointerGet (operand *left,
6872 int size , offset = 0;
6875 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6878 /* optimization - most of the time, left and result are the same
6879 * address, but different types. for the pic code, we could omit
6883 aopOp(result,ic,TRUE);
6885 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
6887 size = AOP_SIZE(result);
6890 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
6894 freeAsmop(left,NULL,ic,TRUE);
6895 freeAsmop(result,NULL,ic,TRUE);
6898 /*-----------------------------------------------------------------*/
6899 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
6900 /*-----------------------------------------------------------------*/
6901 static void genNearPointerGet (operand *left,
6908 sym_link *rtype, *retype;
6909 sym_link *ltype = operandType(left);
6912 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6914 rtype = operandType(result);
6915 retype= getSpec(rtype);
6917 aopOp(left,ic,FALSE);
6919 /* if left is rematerialisable and
6920 result is not bit variable type and
6921 the left is pointer to data space i.e
6922 lower 128 bytes of space */
6923 if (AOP_TYPE(left) == AOP_IMMD &&
6924 !IS_BITVAR(retype) &&
6925 DCL_TYPE(ltype) == POINTER) {
6926 genDataPointerGet (left,result,ic);
6930 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6932 /* if the value is already in a pointer register
6933 then don't need anything more */
6934 if (!AOP_INPREG(AOP(left))) {
6935 /* otherwise get a free pointer register */
6936 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6938 preg = getFreePtr(ic,&aop,FALSE);
6939 pic14_emitcode("mov","%s,%s",
6941 aopGet(AOP(left),0,FALSE,TRUE));
6942 rname = preg->name ;
6944 rname = aopGet(AOP(left),0,FALSE,FALSE);
6946 freeAsmop(left,NULL,ic,TRUE);
6947 aopOp (result,ic,FALSE);
6949 /* if bitfield then unpack the bits */
6950 if (IS_BITVAR(retype))
6951 genUnpackBits (result,rname,POINTER);
6953 /* we have can just get the values */
6954 int size = AOP_SIZE(result);
6957 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6959 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
6961 pic14_emitcode("mov","a,@%s",rname);
6962 aopPut(AOP(result),"a",offset);
6964 sprintf(buffer,"@%s",rname);
6965 aopPut(AOP(result),buffer,offset);
6969 pic14_emitcode("inc","%s",rname);
6973 /* now some housekeeping stuff */
6975 /* we had to allocate for this iCode */
6976 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6977 freeAsmop(NULL,aop,ic,TRUE);
6979 /* we did not allocate which means left
6980 already in a pointer register, then
6981 if size > 0 && this could be used again
6982 we have to point it back to where it
6984 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6985 if (AOP_SIZE(result) > 1 &&
6986 !OP_SYMBOL(left)->remat &&
6987 ( OP_SYMBOL(left)->liveTo > ic->seq ||
6989 int size = AOP_SIZE(result) - 1;
6991 pic14_emitcode("dec","%s",rname);
6996 freeAsmop(result,NULL,ic,TRUE);
7000 /*-----------------------------------------------------------------*/
7001 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7002 /*-----------------------------------------------------------------*/
7003 static void genPagedPointerGet (operand *left,
7010 sym_link *rtype, *retype;
7012 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7014 rtype = operandType(result);
7015 retype= getSpec(rtype);
7017 aopOp(left,ic,FALSE);
7019 /* if the value is already in a pointer register
7020 then don't need anything more */
7021 if (!AOP_INPREG(AOP(left))) {
7022 /* otherwise get a free pointer register */
7024 preg = getFreePtr(ic,&aop,FALSE);
7025 pic14_emitcode("mov","%s,%s",
7027 aopGet(AOP(left),0,FALSE,TRUE));
7028 rname = preg->name ;
7030 rname = aopGet(AOP(left),0,FALSE,FALSE);
7032 freeAsmop(left,NULL,ic,TRUE);
7033 aopOp (result,ic,FALSE);
7035 /* if bitfield then unpack the bits */
7036 if (IS_BITVAR(retype))
7037 genUnpackBits (result,rname,PPOINTER);
7039 /* we have can just get the values */
7040 int size = AOP_SIZE(result);
7045 pic14_emitcode("movx","a,@%s",rname);
7046 aopPut(AOP(result),"a",offset);
7051 pic14_emitcode("inc","%s",rname);
7055 /* now some housekeeping stuff */
7057 /* we had to allocate for this iCode */
7058 freeAsmop(NULL,aop,ic,TRUE);
7060 /* we did not allocate which means left
7061 already in a pointer register, then
7062 if size > 0 && this could be used again
7063 we have to point it back to where it
7065 if (AOP_SIZE(result) > 1 &&
7066 !OP_SYMBOL(left)->remat &&
7067 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7069 int size = AOP_SIZE(result) - 1;
7071 pic14_emitcode("dec","%s",rname);
7076 freeAsmop(result,NULL,ic,TRUE);
7081 /*-----------------------------------------------------------------*/
7082 /* genFarPointerGet - gget value from far space */
7083 /*-----------------------------------------------------------------*/
7084 static void genFarPointerGet (operand *left,
7085 operand *result, iCode *ic)
7088 sym_link *retype = getSpec(operandType(result));
7090 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7092 aopOp(left,ic,FALSE);
7094 /* if the operand is already in dptr
7095 then we do nothing else we move the value to dptr */
7096 if (AOP_TYPE(left) != AOP_STR) {
7097 /* if this is remateriazable */
7098 if (AOP_TYPE(left) == AOP_IMMD)
7099 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7100 else { /* we need to get it byte by byte */
7101 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7102 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7103 if (options.model == MODEL_FLAT24)
7105 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7109 /* so dptr know contains the address */
7110 freeAsmop(left,NULL,ic,TRUE);
7111 aopOp(result,ic,FALSE);
7113 /* if bit then unpack */
7114 if (IS_BITVAR(retype))
7115 genUnpackBits(result,"dptr",FPOINTER);
7117 size = AOP_SIZE(result);
7121 pic14_emitcode("movx","a,@dptr");
7122 aopPut(AOP(result),"a",offset++);
7124 pic14_emitcode("inc","dptr");
7128 freeAsmop(result,NULL,ic,TRUE);
7131 /*-----------------------------------------------------------------*/
7132 /* pic14_emitcodePointerGet - gget value from code space */
7133 /*-----------------------------------------------------------------*/
7134 static void pic14_emitcodePointerGet (operand *left,
7135 operand *result, iCode *ic)
7138 sym_link *retype = getSpec(operandType(result));
7140 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7142 aopOp(left,ic,FALSE);
7144 /* if the operand is already in dptr
7145 then we do nothing else we move the value to dptr */
7146 if (AOP_TYPE(left) != AOP_STR) {
7147 /* if this is remateriazable */
7148 if (AOP_TYPE(left) == AOP_IMMD)
7149 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7150 else { /* we need to get it byte by byte */
7151 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7152 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7153 if (options.model == MODEL_FLAT24)
7155 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7159 /* so dptr know contains the address */
7160 freeAsmop(left,NULL,ic,TRUE);
7161 aopOp(result,ic,FALSE);
7163 /* if bit then unpack */
7164 if (IS_BITVAR(retype))
7165 genUnpackBits(result,"dptr",CPOINTER);
7167 size = AOP_SIZE(result);
7171 pic14_emitcode("clr","a");
7172 pic14_emitcode("movc","a,@a+dptr");
7173 aopPut(AOP(result),"a",offset++);
7175 pic14_emitcode("inc","dptr");
7179 freeAsmop(result,NULL,ic,TRUE);
7182 /*-----------------------------------------------------------------*/
7183 /* genGenPointerGet - gget value from generic pointer space */
7184 /*-----------------------------------------------------------------*/
7185 static void genGenPointerGet (operand *left,
7186 operand *result, iCode *ic)
7189 sym_link *retype = getSpec(operandType(result));
7191 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7192 aopOp(left,ic,FALSE);
7194 /* if the operand is already in dptr
7195 then we do nothing else we move the value to dptr */
7196 if (AOP_TYPE(left) != AOP_STR) {
7197 /* if this is remateriazable */
7198 if (AOP_TYPE(left) == AOP_IMMD) {
7199 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7200 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7202 else { /* we need to get it byte by byte */
7203 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7204 //emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
7205 //emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7206 pic14_emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
7207 pic14_emitcode("movwf","FSR");
7209 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7210 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7211 if (options.model == MODEL_FLAT24)
7213 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7214 pic14_emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
7218 pic14_emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
7223 /* so dptr know contains the address */
7224 freeAsmop(left,NULL,ic,TRUE);
7225 aopOp(result,ic,FALSE);
7227 /* if bit then unpack */
7228 if (IS_BITVAR(retype))
7229 genUnpackBits(result,"dptr",GPOINTER);
7231 size = AOP_SIZE(result);
7235 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7237 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7239 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7241 pic14_emitcode("movf","indf,w");
7242 pic14_emitcode("movwf","%s",
7243 aopGet(AOP(result),offset++,FALSE,FALSE));
7245 pic14_emitcode("incf","fsr,f");
7250 freeAsmop(result,NULL,ic,TRUE);
7253 /*-----------------------------------------------------------------*/
7254 /* genPointerGet - generate code for pointer get */
7255 /*-----------------------------------------------------------------*/
7256 static void genPointerGet (iCode *ic)
7258 operand *left, *result ;
7259 sym_link *type, *etype;
7262 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7265 result = IC_RESULT(ic) ;
7267 /* depending on the type of pointer we need to
7268 move it to the correct pointer register */
7269 type = operandType(left);
7270 etype = getSpec(type);
7271 /* if left is of type of pointer then it is simple */
7272 if (IS_PTR(type) && !IS_FUNC(type->next))
7273 p_type = DCL_TYPE(type);
7275 /* we have to go by the storage class */
7276 p_type = PTR_TYPE(SPEC_OCLS(etype));
7278 /* if (SPEC_OCLS(etype)->codesp ) { */
7279 /* p_type = CPOINTER ; */
7282 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7283 /* p_type = FPOINTER ; */
7285 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7286 /* p_type = PPOINTER; */
7288 /* if (SPEC_OCLS(etype) == idata ) */
7289 /* p_type = IPOINTER; */
7291 /* p_type = POINTER ; */
7294 /* now that we have the pointer type we assign
7295 the pointer values */
7300 genNearPointerGet (left,result,ic);
7304 genPagedPointerGet(left,result,ic);
7308 genFarPointerGet (left,result,ic);
7312 pic14_emitcodePointerGet (left,result,ic);
7316 genGenPointerGet (left,result,ic);
7322 /*-----------------------------------------------------------------*/
7323 /* genPackBits - generates code for packed bit storage */
7324 /*-----------------------------------------------------------------*/
7325 static void genPackBits (sym_link *etype ,
7327 char *rname, int p_type)
7335 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7336 blen = SPEC_BLEN(etype);
7337 bstr = SPEC_BSTR(etype);
7339 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7342 /* if the bit lenth is less than or */
7343 /* it exactly fits a byte then */
7344 if (SPEC_BLEN(etype) <= 8 ) {
7345 shCount = SPEC_BSTR(etype) ;
7347 /* shift left acc */
7350 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7355 pic14_emitcode ("mov","b,a");
7356 pic14_emitcode("mov","a,@%s",rname);
7360 pic14_emitcode ("mov","b,a");
7361 pic14_emitcode("movx","a,@dptr");
7365 pic14_emitcode ("push","b");
7366 pic14_emitcode ("push","acc");
7367 pic14_emitcode ("lcall","__gptrget");
7368 pic14_emitcode ("pop","b");
7372 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7373 ((unsigned char)(0xFF << (blen+bstr)) |
7374 (unsigned char)(0xFF >> (8-bstr)) ) );
7375 pic14_emitcode ("orl","a,b");
7376 if (p_type == GPOINTER)
7377 pic14_emitcode("pop","b");
7383 pic14_emitcode("mov","@%s,a",rname);
7387 pic14_emitcode("movx","@dptr,a");
7391 DEBUGpic14_emitcode(";lcall","__gptrput");
7396 if ( SPEC_BLEN(etype) <= 8 )
7399 pic14_emitcode("inc","%s",rname);
7400 rLen = SPEC_BLEN(etype) ;
7402 /* now generate for lengths greater than one byte */
7405 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7415 pic14_emitcode("mov","@%s,a",rname);
7417 pic14_emitcode("mov","@%s,%s",rname,l);
7422 pic14_emitcode("movx","@dptr,a");
7427 DEBUGpic14_emitcode(";lcall","__gptrput");
7430 pic14_emitcode ("inc","%s",rname);
7435 /* last last was not complete */
7437 /* save the byte & read byte */
7440 pic14_emitcode ("mov","b,a");
7441 pic14_emitcode("mov","a,@%s",rname);
7445 pic14_emitcode ("mov","b,a");
7446 pic14_emitcode("movx","a,@dptr");
7450 pic14_emitcode ("push","b");
7451 pic14_emitcode ("push","acc");
7452 pic14_emitcode ("lcall","__gptrget");
7453 pic14_emitcode ("pop","b");
7457 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7458 pic14_emitcode ("orl","a,b");
7461 if (p_type == GPOINTER)
7462 pic14_emitcode("pop","b");
7467 pic14_emitcode("mov","@%s,a",rname);
7471 pic14_emitcode("movx","@dptr,a");
7475 DEBUGpic14_emitcode(";lcall","__gptrput");
7479 /*-----------------------------------------------------------------*/
7480 /* genDataPointerSet - remat pointer to data space */
7481 /*-----------------------------------------------------------------*/
7482 static void genDataPointerSet(operand *right,
7486 int size, offset = 0 ;
7487 char *l, buffer[256];
7489 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7490 aopOp(right,ic,FALSE);
7492 l = aopGet(AOP(result),0,FALSE,TRUE);
7493 size = AOP_SIZE(right);
7494 // tsd, was l+1 - the underline `_' prefix was being stripped
7497 sprintf(buffer,"(%s + %d)",l,offset);
7499 sprintf(buffer,"%s",l);
7501 if (AOP_TYPE(right) == AOP_LIT) {
7502 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7503 lit = lit >> (8*offset);
7505 pic14_emitcode("movlw","%d",lit);
7506 pic14_emitcode("movwf","%s",buffer);
7508 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7509 emitpcode(POC_MOVWF, popRegFromString(buffer));
7512 pic14_emitcode("clrf","%s",buffer);
7513 emitpcode(POC_CLRF, popRegFromString(buffer));
7516 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7517 pic14_emitcode("movwf","%s",buffer);
7519 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7520 emitpcode(POC_MOVWF, popRegFromString(buffer));
7527 freeAsmop(right,NULL,ic,TRUE);
7528 freeAsmop(result,NULL,ic,TRUE);
7531 /*-----------------------------------------------------------------*/
7532 /* genNearPointerSet - pic14_emitcode for near pointer put */
7533 /*-----------------------------------------------------------------*/
7534 static void genNearPointerSet (operand *right,
7541 sym_link *ptype = operandType(result);
7544 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7545 retype= getSpec(operandType(right));
7547 aopOp(result,ic,FALSE);
7549 /* if the result is rematerializable &
7550 in data space & not a bit variable */
7551 if (AOP_TYPE(result) == AOP_IMMD &&
7552 DCL_TYPE(ptype) == POINTER &&
7553 !IS_BITVAR(retype)) {
7554 genDataPointerSet (right,result,ic);
7558 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7560 /* if the value is already in a pointer register
7561 then don't need anything more */
7562 if (!AOP_INPREG(AOP(result))) {
7563 /* otherwise get a free pointer register */
7564 //aop = newAsmop(0);
7565 //preg = getFreePtr(ic,&aop,FALSE);
7566 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7567 //pic14_emitcode("mov","%s,%s",
7569 // aopGet(AOP(result),0,FALSE,TRUE));
7570 //rname = preg->name ;
7571 pic14_emitcode("movwf","fsr");
7573 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7575 freeAsmop(result,NULL,ic,TRUE);
7576 aopOp (right,ic,FALSE);
7577 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7579 /* if bitfield then unpack the bits */
7580 if (IS_BITVAR(retype)) {
7581 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7582 "The programmer is obviously confused");
7583 //genPackBits (retype,right,rname,POINTER);
7587 /* we have can just get the values */
7588 int size = AOP_SIZE(right);
7591 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7593 l = aopGet(AOP(right),offset,FALSE,TRUE);
7596 //pic14_emitcode("mov","@%s,a",rname);
7597 pic14_emitcode("movf","indf,w ;1");
7600 if (AOP_TYPE(right) == AOP_LIT) {
7601 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7603 pic14_emitcode("movlw","%s",l);
7604 pic14_emitcode("movwf","indf ;2");
7606 pic14_emitcode("clrf","indf");
7608 pic14_emitcode("movf","%s,w",l);
7609 pic14_emitcode("movwf","indf ;2");
7611 //pic14_emitcode("mov","@%s,%s",rname,l);
7614 pic14_emitcode("incf","fsr,f ;3");
7615 //pic14_emitcode("inc","%s",rname);
7620 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7621 /* now some housekeeping stuff */
7623 /* we had to allocate for this iCode */
7624 freeAsmop(NULL,aop,ic,TRUE);
7626 /* we did not allocate which means left
7627 already in a pointer register, then
7628 if size > 0 && this could be used again
7629 we have to point it back to where it
7631 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7632 if (AOP_SIZE(right) > 1 &&
7633 !OP_SYMBOL(result)->remat &&
7634 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7636 int size = AOP_SIZE(right) - 1;
7638 pic14_emitcode("decf","fsr,f");
7639 //pic14_emitcode("dec","%s",rname);
7643 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7645 freeAsmop(right,NULL,ic,TRUE);
7650 /*-----------------------------------------------------------------*/
7651 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7652 /*-----------------------------------------------------------------*/
7653 static void genPagedPointerSet (operand *right,
7662 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7664 retype= getSpec(operandType(right));
7666 aopOp(result,ic,FALSE);
7668 /* if the value is already in a pointer register
7669 then don't need anything more */
7670 if (!AOP_INPREG(AOP(result))) {
7671 /* otherwise get a free pointer register */
7673 preg = getFreePtr(ic,&aop,FALSE);
7674 pic14_emitcode("mov","%s,%s",
7676 aopGet(AOP(result),0,FALSE,TRUE));
7677 rname = preg->name ;
7679 rname = aopGet(AOP(result),0,FALSE,FALSE);
7681 freeAsmop(result,NULL,ic,TRUE);
7682 aopOp (right,ic,FALSE);
7684 /* if bitfield then unpack the bits */
7685 if (IS_BITVAR(retype))
7686 genPackBits (retype,right,rname,PPOINTER);
7688 /* we have can just get the values */
7689 int size = AOP_SIZE(right);
7693 l = aopGet(AOP(right),offset,FALSE,TRUE);
7696 pic14_emitcode("movx","@%s,a",rname);
7699 pic14_emitcode("inc","%s",rname);
7705 /* now some housekeeping stuff */
7707 /* we had to allocate for this iCode */
7708 freeAsmop(NULL,aop,ic,TRUE);
7710 /* we did not allocate which means left
7711 already in a pointer register, then
7712 if size > 0 && this could be used again
7713 we have to point it back to where it
7715 if (AOP_SIZE(right) > 1 &&
7716 !OP_SYMBOL(result)->remat &&
7717 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7719 int size = AOP_SIZE(right) - 1;
7721 pic14_emitcode("dec","%s",rname);
7726 freeAsmop(right,NULL,ic,TRUE);
7731 /*-----------------------------------------------------------------*/
7732 /* genFarPointerSet - set value from far space */
7733 /*-----------------------------------------------------------------*/
7734 static void genFarPointerSet (operand *right,
7735 operand *result, iCode *ic)
7738 sym_link *retype = getSpec(operandType(right));
7740 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7741 aopOp(result,ic,FALSE);
7743 /* if the operand is already in dptr
7744 then we do nothing else we move the value to dptr */
7745 if (AOP_TYPE(result) != AOP_STR) {
7746 /* if this is remateriazable */
7747 if (AOP_TYPE(result) == AOP_IMMD)
7748 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7749 else { /* we need to get it byte by byte */
7750 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7751 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7752 if (options.model == MODEL_FLAT24)
7754 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7758 /* so dptr know contains the address */
7759 freeAsmop(result,NULL,ic,TRUE);
7760 aopOp(right,ic,FALSE);
7762 /* if bit then unpack */
7763 if (IS_BITVAR(retype))
7764 genPackBits(retype,right,"dptr",FPOINTER);
7766 size = AOP_SIZE(right);
7770 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7772 pic14_emitcode("movx","@dptr,a");
7774 pic14_emitcode("inc","dptr");
7778 freeAsmop(right,NULL,ic,TRUE);
7781 /*-----------------------------------------------------------------*/
7782 /* genGenPointerSet - set value from generic pointer space */
7783 /*-----------------------------------------------------------------*/
7784 static void genGenPointerSet (operand *right,
7785 operand *result, iCode *ic)
7788 sym_link *retype = getSpec(operandType(right));
7790 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7792 aopOp(result,ic,FALSE);
7794 /* if the operand is already in dptr
7795 then we do nothing else we move the value to dptr */
7796 if (AOP_TYPE(result) != AOP_STR) {
7797 /* if this is remateriazable */
7798 if (AOP_TYPE(result) == AOP_IMMD) {
7799 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7800 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7802 else { /* we need to get it byte by byte */
7803 char *l = aopGet(AOP(result),0,FALSE,FALSE);
7806 emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
7807 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7810 pic14_emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
7812 pic14_emitcode("movwf","INDF");
7815 /* so dptr know contains the address */
7816 freeAsmop(result,NULL,ic,TRUE);
7817 aopOp(right,ic,FALSE);
7819 /* if bit then unpack */
7820 if (IS_BITVAR(retype))
7821 genPackBits(retype,right,"dptr",GPOINTER);
7823 size = AOP_SIZE(right);
7827 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7829 pic14_emitcode("incf","fsr,f");
7830 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
7831 pic14_emitcode("movwf","indf");
7833 //DEBUGpic14_emitcode(";lcall","__gptrput");
7835 // pic14_emitcode("inc","dptr");
7839 freeAsmop(right,NULL,ic,TRUE);
7842 /*-----------------------------------------------------------------*/
7843 /* genPointerSet - stores the value into a pointer location */
7844 /*-----------------------------------------------------------------*/
7845 static void genPointerSet (iCode *ic)
7847 operand *right, *result ;
7848 sym_link *type, *etype;
7851 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7853 right = IC_RIGHT(ic);
7854 result = IC_RESULT(ic) ;
7856 /* depending on the type of pointer we need to
7857 move it to the correct pointer register */
7858 type = operandType(result);
7859 etype = getSpec(type);
7860 /* if left is of type of pointer then it is simple */
7861 if (IS_PTR(type) && !IS_FUNC(type->next)) {
7862 p_type = DCL_TYPE(type);
7865 /* we have to go by the storage class */
7866 p_type = PTR_TYPE(SPEC_OCLS(etype));
7868 /* if (SPEC_OCLS(etype)->codesp ) { */
7869 /* p_type = CPOINTER ; */
7872 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7873 /* p_type = FPOINTER ; */
7875 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7876 /* p_type = PPOINTER ; */
7878 /* if (SPEC_OCLS(etype) == idata ) */
7879 /* p_type = IPOINTER ; */
7881 /* p_type = POINTER ; */
7884 /* now that we have the pointer type we assign
7885 the pointer values */
7890 genNearPointerSet (right,result,ic);
7894 genPagedPointerSet (right,result,ic);
7898 genFarPointerSet (right,result,ic);
7902 genGenPointerSet (right,result,ic);
7908 /*-----------------------------------------------------------------*/
7909 /* genIfx - generate code for Ifx statement */
7910 /*-----------------------------------------------------------------*/
7911 static void genIfx (iCode *ic, iCode *popIc)
7913 operand *cond = IC_COND(ic);
7916 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7917 aopOp(cond,ic,FALSE);
7919 /* get the value into acc */
7920 if (AOP_TYPE(cond) != AOP_CRY)
7921 pic14_toBoolean(cond);
7924 /* the result is now in the accumulator */
7925 freeAsmop(cond,NULL,ic,TRUE);
7927 /* if there was something to be popped then do it */
7931 /* if the condition is a bit variable */
7932 if (isbit && IS_ITEMP(cond) &&
7934 genIfxJump(ic,SPIL_LOC(cond)->rname);
7935 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
7939 if (isbit && !IS_ITEMP(cond))
7940 DEBUGpic14_emitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
7942 DEBUGpic14_emitcode ("; isbit","a");
7945 if (isbit && !IS_ITEMP(cond))
7946 genIfxJump(ic,OP_SYMBOL(cond)->rname);
7953 /*-----------------------------------------------------------------*/
7954 /* genAddrOf - generates code for address of */
7955 /*-----------------------------------------------------------------*/
7956 static void genAddrOf (iCode *ic)
7958 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
7961 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7963 aopOp(IC_RESULT(ic),ic,FALSE);
7965 /* if the operand is on the stack then we
7966 need to get the stack offset of this
7969 /* if it has an offset then we need to compute
7972 pic14_emitcode("mov","a,_bp");
7973 pic14_emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
7974 aopPut(AOP(IC_RESULT(ic)),"a",0);
7976 /* we can just move _bp */
7977 aopPut(AOP(IC_RESULT(ic)),"_bp",0);
7979 /* fill the result with zero */
7980 size = AOP_SIZE(IC_RESULT(ic)) - 1;
7983 if (options.stack10bit && size < (FPTRSIZE - 1))
7986 "*** warning: pointer to stack var truncated.\n");
7993 if (options.stack10bit && offset == 2)
7995 aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
7999 aopPut(AOP(IC_RESULT(ic)),zero,offset++);
8006 /* object not on stack then we need the name */
8007 size = AOP_SIZE(IC_RESULT(ic));
8011 char s[SDCC_NAME_MAX];
8013 sprintf(s,"#(%s >> %d)",
8017 sprintf(s,"#%s",sym->rname);
8018 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8022 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8027 /*-----------------------------------------------------------------*/
8028 /* genFarFarAssign - assignment when both are in far space */
8029 /*-----------------------------------------------------------------*/
8030 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8032 int size = AOP_SIZE(right);
8035 /* first push the right side on to the stack */
8037 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8039 pic14_emitcode ("push","acc");
8042 freeAsmop(right,NULL,ic,FALSE);
8043 /* now assign DPTR to result */
8044 aopOp(result,ic,FALSE);
8045 size = AOP_SIZE(result);
8047 pic14_emitcode ("pop","acc");
8048 aopPut(AOP(result),"a",--offset);
8050 freeAsmop(result,NULL,ic,FALSE);
8055 /*-----------------------------------------------------------------*/
8056 /* genAssign - generate code for assignment */
8057 /*-----------------------------------------------------------------*/
8058 static void genAssign (iCode *ic)
8060 operand *result, *right;
8062 unsigned long lit = 0L;
8064 result = IC_RESULT(ic);
8065 right = IC_RIGHT(ic) ;
8067 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8069 /* if they are the same */
8070 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8073 aopOp(right,ic,FALSE);
8074 aopOp(result,ic,TRUE);
8076 /* if they are the same registers */
8077 if (pic14_sameRegs(AOP(right),AOP(result)))
8080 /* if the result is a bit */
8081 if (AOP_TYPE(result) == AOP_CRY) {
8083 /* if the right size is a literal then
8084 we know what the value is */
8085 if (AOP_TYPE(right) == AOP_LIT) {
8087 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8088 popGet(AOP(result),0,FALSE,FALSE));
8090 if (((int) operandLitValue(right)))
8091 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8092 AOP(result)->aopu.aop_dir,
8093 AOP(result)->aopu.aop_dir);
8095 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8096 AOP(result)->aopu.aop_dir,
8097 AOP(result)->aopu.aop_dir);
8101 /* the right is also a bit variable */
8102 if (AOP_TYPE(right) == AOP_CRY) {
8103 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8104 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8105 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8107 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8108 AOP(result)->aopu.aop_dir,
8109 AOP(result)->aopu.aop_dir);
8110 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8111 AOP(right)->aopu.aop_dir,
8112 AOP(right)->aopu.aop_dir);
8113 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8114 AOP(result)->aopu.aop_dir,
8115 AOP(result)->aopu.aop_dir);
8120 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8121 pic14_toBoolean(right);
8123 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8124 //aopPut(AOP(result),"a",0);
8128 /* bit variables done */
8130 size = AOP_SIZE(result);
8132 if(AOP_TYPE(right) == AOP_LIT)
8133 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8134 if((AOP_TYPE(result) != AOP_REG) &&
8135 (AOP_TYPE(right) == AOP_LIT) &&
8136 !IS_FLOAT(operandType(right)) &&
8140 if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) {
8141 //pic14_emitcode("clrf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8142 emitpcode(POC_CLRF,popGet(AOP(result),size,FALSE,FALSE));
8144 emitpcode(POC_MOVLW,popGet(AOP(right),size,FALSE,FALSE));
8145 emitpcode(POC_MOVWF,popGet(AOP(result),size,FALSE,FALSE));
8146 //pic14_emitcode("movlw","%s", aopGet(AOP(right),size,FALSE,FALSE));
8147 //pic14_emitcode("movwf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8152 if(AOP_TYPE(right) == AOP_LIT) {
8153 emitpcode(POC_MOVLW, popGet(AOP(right),offset,FALSE,FALSE));
8154 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8156 } else if (AOP_TYPE(right) == AOP_CRY) {
8157 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8159 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8160 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8163 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8164 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8167 //pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE));
8173 freeAsmop (right,NULL,ic,FALSE);
8174 freeAsmop (result,NULL,ic,TRUE);
8177 /*-----------------------------------------------------------------*/
8178 /* genJumpTab - genrates code for jump table */
8179 /*-----------------------------------------------------------------*/
8180 static void genJumpTab (iCode *ic)
8185 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8187 aopOp(IC_JTCOND(ic),ic,FALSE);
8188 /* get the condition into accumulator */
8189 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8191 /* multiply by three */
8192 pic14_emitcode("add","a,acc");
8193 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8195 jtab = newiTempLabel(NULL);
8196 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8197 pic14_emitcode("jmp","@a+dptr");
8198 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8200 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8201 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8203 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8204 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8205 emitpLabel(jtab->key+100+labelOffset);
8207 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8209 /* now generate the jump labels */
8210 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8211 jtab = setNextItem(IC_JTLABELS(ic))) {
8212 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8213 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8219 /*-----------------------------------------------------------------*/
8220 /* genMixedOperation - gen code for operators between mixed types */
8221 /*-----------------------------------------------------------------*/
8223 TSD - Written for the PIC port - but this unfortunately is buggy.
8224 This routine is good in that it is able to efficiently promote
8225 types to different (larger) sizes. Unfortunately, the temporary
8226 variables that are optimized out by this routine are sometimes
8227 used in other places. So until I know how to really parse the
8228 iCode tree, I'm going to not be using this routine :(.
8230 static int genMixedOperation (iCode *ic)
8233 operand *result = IC_RESULT(ic);
8234 sym_link *ctype = operandType(IC_LEFT(ic));
8235 operand *right = IC_RIGHT(ic);
8241 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8243 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8249 nextright = IC_RIGHT(nextic);
8250 nextleft = IC_LEFT(nextic);
8251 nextresult = IC_RESULT(nextic);
8253 aopOp(right,ic,FALSE);
8254 aopOp(result,ic,FALSE);
8255 aopOp(nextright, nextic, FALSE);
8256 aopOp(nextleft, nextic, FALSE);
8257 aopOp(nextresult, nextic, FALSE);
8259 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8265 pic14_emitcode(";remove right +","");
8267 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8273 pic14_emitcode(";remove left +","");
8277 big = AOP_SIZE(nextleft);
8278 small = AOP_SIZE(nextright);
8280 switch(nextic->op) {
8283 pic14_emitcode(";optimize a +","");
8284 /* if unsigned or not an integral type */
8285 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8286 pic14_emitcode(";add a bit to something","");
8289 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8291 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8292 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8293 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8295 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8303 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8304 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8305 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8308 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8310 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8311 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8312 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8313 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8314 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8317 pic14_emitcode("rlf","known_zero,w");
8324 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8325 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8326 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8328 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8338 freeAsmop(right,NULL,ic,TRUE);
8339 freeAsmop(result,NULL,ic,TRUE);
8340 freeAsmop(nextright,NULL,ic,TRUE);
8341 freeAsmop(nextleft,NULL,ic,TRUE);
8343 nextic->generated = 1;
8350 /*-----------------------------------------------------------------*/
8351 /* genCast - gen code for casting */
8352 /*-----------------------------------------------------------------*/
8353 static void genCast (iCode *ic)
8355 operand *result = IC_RESULT(ic);
8356 sym_link *ctype = operandType(IC_LEFT(ic));
8357 operand *right = IC_RIGHT(ic);
8360 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8361 /* if they are equivalent then do nothing */
8362 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8365 aopOp(right,ic,FALSE) ;
8366 aopOp(result,ic,FALSE);
8368 /* if the result is a bit */
8369 if (AOP_TYPE(result) == AOP_CRY) {
8370 /* if the right size is a literal then
8371 we know what the value is */
8372 if (AOP_TYPE(right) == AOP_LIT) {
8374 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8375 popGet(AOP(result),0,FALSE,FALSE));
8377 if (((int) operandLitValue(right)))
8378 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8379 AOP(result)->aopu.aop_dir,
8380 AOP(result)->aopu.aop_dir);
8382 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8383 AOP(result)->aopu.aop_dir,
8384 AOP(result)->aopu.aop_dir);
8389 /* the right is also a bit variable */
8390 if (AOP_TYPE(right) == AOP_CRY) {
8393 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8395 pic14_emitcode("clrc","");
8396 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8397 AOP(right)->aopu.aop_dir,
8398 AOP(right)->aopu.aop_dir);
8399 aopPut(AOP(result),"c",0);
8404 pic14_toBoolean(right);
8405 aopPut(AOP(result),"a",0);
8409 /* if they are the same size : or less */
8410 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8412 /* if they are in the same place */
8413 if (pic14_sameRegs(AOP(right),AOP(result)))
8416 /* if they in different places then copy */
8417 size = AOP_SIZE(result);
8421 aopGet(AOP(right),offset,FALSE,FALSE),
8429 /* if the result is of type pointer */
8430 if (IS_PTR(ctype)) {
8433 sym_link *type = operandType(right);
8434 sym_link *etype = getSpec(type);
8436 /* pointer to generic pointer */
8437 if (IS_GENPTR(ctype)) {
8441 p_type = DCL_TYPE(type);
8443 /* we have to go by the storage class */
8444 p_type = PTR_TYPE(SPEC_OCLS(etype));
8446 /* if (SPEC_OCLS(etype)->codesp ) */
8447 /* p_type = CPOINTER ; */
8449 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8450 /* p_type = FPOINTER ; */
8452 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8453 /* p_type = PPOINTER; */
8455 /* if (SPEC_OCLS(etype) == idata ) */
8456 /* p_type = IPOINTER ; */
8458 /* p_type = POINTER ; */
8461 /* the first two bytes are known */
8462 size = GPTRSIZE - 1;
8466 aopGet(AOP(right),offset,FALSE,FALSE),
8470 /* the last byte depending on type */
8487 /* this should never happen */
8488 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8489 "got unknown pointer type");
8492 aopPut(AOP(result),l, GPTRSIZE - 1);
8496 /* just copy the pointers */
8497 size = AOP_SIZE(result);
8501 aopGet(AOP(right),offset,FALSE,FALSE),
8509 if (AOP_TYPE(right) == AOP_CRY) {
8511 size = AOP_SIZE(right);
8513 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8514 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8515 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8517 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8518 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8519 AOP(right)->aopu.aop_dir,
8520 AOP(right)->aopu.aop_dir);
8521 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8523 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8524 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8529 /* so we now know that the size of destination is greater
8530 than the size of the source.
8531 Now, if the next iCode is an operator then we might be
8532 able to optimize the operation without performing a cast.
8534 if(genMixedOperation(ic))
8538 /* we move to result for the size of source */
8539 size = AOP_SIZE(right);
8542 pic14_emitcode(";","%d",__LINE__);
8544 aopGet(AOP(right),offset,FALSE,FALSE),
8549 /* now depending on the sign of the destination */
8550 size = AOP_SIZE(result) - AOP_SIZE(right);
8551 /* if unsigned or not an integral type */
8552 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8554 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8555 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8559 /* we need to extend the sign :{ */
8560 //char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,FALSE,FALSE);
8563 emitpcode(POC_CLRW, NULL);
8564 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8565 emitpcode(POC_MOVLW, popGetLit(0xff));
8567 pic14_emitcode("clrw","");
8568 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8569 AOP(right)->aopu.aop_dir,
8570 AOP(right)->aopu.aop_dir);
8571 pic14_emitcode("movlw","0xff");
8573 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8574 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8576 // aopPut(AOP(result),"a",offset++);
8581 /* we are done hurray !!!! */
8584 freeAsmop(right,NULL,ic,TRUE);
8585 freeAsmop(result,NULL,ic,TRUE);
8589 /*-----------------------------------------------------------------*/
8590 /* genDjnz - generate decrement & jump if not zero instrucion */
8591 /*-----------------------------------------------------------------*/
8592 static int genDjnz (iCode *ic, iCode *ifx)
8595 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8600 /* if the if condition has a false label
8601 then we cannot save */
8605 /* if the minus is not of the form
8607 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8608 !IS_OP_LITERAL(IC_RIGHT(ic)))
8611 if (operandLitValue(IC_RIGHT(ic)) != 1)
8614 /* if the size of this greater than one then no
8616 if (getSize(operandType(IC_RESULT(ic))) > 1)
8619 /* otherwise we can save BIG */
8620 lbl = newiTempLabel(NULL);
8621 lbl1= newiTempLabel(NULL);
8623 aopOp(IC_RESULT(ic),ic,FALSE);
8625 if (IS_AOP_PREG(IC_RESULT(ic))) {
8626 pic14_emitcode("dec","%s",
8627 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8628 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8629 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8633 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8634 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8636 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8637 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8640 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8641 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8642 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8643 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8646 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8651 /*-----------------------------------------------------------------*/
8652 /* genReceive - generate code for a receive iCode */
8653 /*-----------------------------------------------------------------*/
8654 static void genReceive (iCode *ic)
8656 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8658 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8659 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8660 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8662 int size = getSize(operandType(IC_RESULT(ic)));
8663 int offset = fReturnSizePic - size;
8665 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8666 fReturn[fReturnSizePic - offset - 1] : "acc"));
8669 aopOp(IC_RESULT(ic),ic,FALSE);
8670 size = AOP_SIZE(IC_RESULT(ic));
8673 pic14_emitcode ("pop","acc");
8674 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8679 aopOp(IC_RESULT(ic),ic,FALSE);
8681 assignResultValue(IC_RESULT(ic));
8684 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8687 /*-----------------------------------------------------------------*/
8688 /* genpic14Code - generate code for pic14 based controllers */
8689 /*-----------------------------------------------------------------*/
8691 * At this point, ralloc.c has gone through the iCode and attempted
8692 * to optimize in a way suitable for a PIC. Now we've got to generate
8693 * PIC instructions that correspond to the iCode.
8695 * Once the instructions are generated, we'll pass through both the
8696 * peep hole optimizer and the pCode optimizer.
8697 *-----------------------------------------------------------------*/
8699 void genpic14Code (iCode *lic)
8704 lineHead = lineCurr = NULL;
8706 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8709 /* if debug information required */
8710 /* if (options.debug && currFunc) { */
8712 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8714 if (IS_STATIC(currFunc->etype)) {
8715 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8716 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8718 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8719 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8725 for (ic = lic ; ic ; ic = ic->next ) {
8727 DEBUGpic14_emitcode(";ic","");
8728 if ( cln != ic->lineno ) {
8729 if ( options.debug ) {
8731 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8732 FileBaseName(ic->filename),ic->lineno,
8733 ic->level,ic->block);
8736 pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
8739 /* if the result is marked as
8740 spilt and rematerializable or code for
8741 this has already been generated then
8743 if (resultRemat(ic) || ic->generated )
8746 /* depending on the operation */
8765 /* IPOP happens only when trying to restore a
8766 spilt live range, if there is an ifx statement
8767 following this pop then the if statement might
8768 be using some of the registers being popped which
8769 would destory the contents of the register so
8770 we need to check for this condition and handle it */
8772 ic->next->op == IFX &&
8773 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8774 genIfx (ic->next,ic);
8792 genEndFunction (ic);
8812 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
8829 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
8833 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
8840 /* note these two are xlated by algebraic equivalence
8841 during parsing SDCC.y */
8842 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8843 "got '>=' or '<=' shouldn't have come here");
8847 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
8859 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
8863 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
8867 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
8894 case GET_VALUE_AT_ADDRESS:
8899 if (POINTER_SET(ic))
8926 addSet(&_G.sendSet,ic);
8935 /* now we are ready to call the
8936 peep hole optimizer */
8937 if (!options.nopeep) {
8938 printf("peep hole optimizing\n");
8939 peepHole (&lineHead);
8941 /* now do the actual printing */
8942 printLine (lineHead,codeOutFile);
8944 printf("printing pBlock\n\n");
8945 printpBlock(stdout,pb);