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"
63 if(IC_RESULT(ic) && AOP(IC_RESULT(ic)))
64 DEBUGpic14_emitcode ("; ","result %s",
65 AopType(AOP_TYPE(IC_RESULT(ic))));
67 if(IC_LEFT(ic) && AOP(IC_LEFT(ic)))
68 DEBUGpic14_emitcode ("; ","left %s",
69 AopType(AOP_TYPE(IC_LEFT(ic))));
71 if(IC_RIGHT(ic) && AOP(IC_RIGHT(ic)))
72 DEBUGpic14_emitcode ("; ","right %s",
73 AopType(AOP_TYPE(IC_RIGHT(ic))));
77 static int labelOffset=0;
78 static int debug_verbose=1;
79 static int optimized_for_speed = 0;
81 /* max_key keeps track of the largest label number used in
82 a function. This is then used to adjust the label offset
83 for the next function.
86 unsigned int pic14aopLiteral (value *val, int offset);
87 const char *AopType(short type);
89 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
91 /* this is the down and dirty file with all kinds of
92 kludgy & hacky stuff. This is what it is all about
93 CODE GENERATION for a specific MCU . some of the
94 routines may be reusable, will have to see */
96 static char *zero = "#0x00";
97 static char *one = "#0x01";
98 static char *spname = "sp";
100 char *fReturnpic14[] = {"FSR","dph","b","a" };
101 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
102 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
103 static char **fReturn = fReturnpic14;
105 static char *accUse[] = {"a","b"};
107 //static short rbank = -1;
119 /* Resolved ifx structure. This structure stores information
120 about an iCode ifx that makes it easier to generate code.
122 typedef struct resolvedIfx {
123 symbol *lbl; /* pointer to a label */
124 int condition; /* true or false ifx */
125 int generated; /* set true when the code associated with the ifx
129 extern int pic14_ptrRegReq ;
130 extern int pic14_nRegs;
131 extern FILE *codeOutFile;
132 static void saverbank (int, iCode *,bool);
134 static lineNode *lineHead = NULL;
135 static lineNode *lineCurr = NULL;
137 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
138 0xE0, 0xC0, 0x80, 0x00};
139 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
140 0x07, 0x03, 0x01, 0x00};
144 /*-----------------------------------------------------------------*/
145 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
146 /* exponent of 2 is returned, otherwise -1 is */
148 /* note that this is similar to the function `powof2' in SDCCsymt */
152 /*-----------------------------------------------------------------*/
153 static int my_powof2 (unsigned long num)
156 if( (num & (num-1)) == 0) {
169 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
172 char lb[INITIAL_INLINEASM];
182 sprintf(lb,"%s\t",inst);
184 sprintf(lb,"%s",inst);
185 vsprintf(lb+(strlen(lb)),fmt,ap);
189 while (isspace(*lbp)) lbp++;
192 lineCurr = (lineCurr ?
193 connectLine(lineCurr,newLineNode(lb)) :
194 (lineHead = newLineNode(lb)));
195 lineCurr->isInline = _G.inLine;
196 lineCurr->isDebug = _G.debugLine;
198 addpCode2pBlock(pb,newpCodeCharP(lb));
204 static void emitpLabel(int key)
206 addpCode2pBlock(pb,newpCodeLabel(key+100+labelOffset));
209 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
213 addpCode2pBlock(pb,newpCode(poc,pcop));
215 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
218 void emitpcodeNULLop(PIC_OPCODE poc)
221 addpCode2pBlock(pb,newpCode(poc,NULL));
225 /*-----------------------------------------------------------------*/
226 /* pic14_emitcode - writes the code into a file : for now it is simple */
227 /*-----------------------------------------------------------------*/
228 void pic14_emitcode (char *inst,char *fmt, ...)
231 char lb[INITIAL_INLINEASM];
238 sprintf(lb,"%s\t",inst);
240 sprintf(lb,"%s",inst);
241 vsprintf(lb+(strlen(lb)),fmt,ap);
245 while (isspace(*lbp)) lbp++;
248 lineCurr = (lineCurr ?
249 connectLine(lineCurr,newLineNode(lb)) :
250 (lineHead = newLineNode(lb)));
251 lineCurr->isInline = _G.inLine;
252 lineCurr->isDebug = _G.debugLine;
255 addpCode2pBlock(pb,newpCodeCharP(lb));
261 /*-----------------------------------------------------------------*/
262 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
263 /*-----------------------------------------------------------------*/
264 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
266 bool r0iu = FALSE , r1iu = FALSE;
267 bool r0ou = FALSE , r1ou = FALSE;
269 /* the logic: if r0 & r1 used in the instruction
270 then we are in trouble otherwise */
272 /* first check if r0 & r1 are used by this
273 instruction, in which case we are in trouble */
274 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
275 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
280 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
281 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
283 /* if no usage of r0 then return it */
284 if (!r0iu && !r0ou) {
285 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
286 (*aopp)->type = AOP_R0;
288 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
291 /* if no usage of r1 then return it */
292 if (!r1iu && !r1ou) {
293 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
294 (*aopp)->type = AOP_R1;
296 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
299 /* now we know they both have usage */
300 /* if r0 not used in this instruction */
302 /* push it if not already pushed */
304 pic14_emitcode ("push","%s",
305 pic14_regWithIdx(R0_IDX)->dname);
309 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
310 (*aopp)->type = AOP_R0;
312 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
315 /* if r1 not used then */
318 /* push it if not already pushed */
320 pic14_emitcode ("push","%s",
321 pic14_regWithIdx(R1_IDX)->dname);
325 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
326 (*aopp)->type = AOP_R1;
327 return pic14_regWithIdx(R1_IDX);
331 /* I said end of world but not quite end of world yet */
332 /* if this is a result then we can push it on the stack*/
334 (*aopp)->type = AOP_STK;
338 /* other wise this is true end of the world */
339 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
340 "getFreePtr should never reach here");
344 /*-----------------------------------------------------------------*/
345 /* newAsmop - creates a new asmOp */
346 /*-----------------------------------------------------------------*/
347 asmop *newAsmop (short type)
351 aop = Safe_calloc(1,sizeof(asmop));
356 static void genSetDPTR(int n)
360 pic14_emitcode(";", "Select standard DPTR");
361 pic14_emitcode("mov", "dps, #0x00");
365 pic14_emitcode(";", "Select alternate DPTR");
366 pic14_emitcode("mov", "dps, #0x01");
370 /*-----------------------------------------------------------------*/
371 /* resolveIfx - converts an iCode ifx into a form more useful for */
372 /* generating code */
373 /*-----------------------------------------------------------------*/
374 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
379 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
381 resIfx->condition = 1; /* assume that the ifx is true */
382 resIfx->generated = 0; /* indicate that the ifx has not been used */
385 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
386 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
387 __FUNCTION__,__LINE__,resIfx->lbl->key);
390 resIfx->lbl = IC_TRUE(ifx);
392 resIfx->lbl = IC_FALSE(ifx);
393 resIfx->condition = 0;
397 DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
400 /*-----------------------------------------------------------------*/
401 /* pointerCode - returns the code for a pointer type */
402 /*-----------------------------------------------------------------*/
403 static int pointerCode (sym_link *etype)
406 return PTR_TYPE(SPEC_OCLS(etype));
410 /*-----------------------------------------------------------------*/
411 /* aopForSym - for a true symbol */
412 /*-----------------------------------------------------------------*/
413 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
416 memmap *space= SPEC_OCLS(sym->etype);
418 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
419 /* if already has one */
423 /* assign depending on the storage class */
424 /* if it is on the stack or indirectly addressable */
425 /* space we need to assign either r0 or r1 to it */
426 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
427 sym->aop = aop = newAsmop(0);
428 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
429 aop->size = getSize(sym->type);
431 /* now assign the address of the variable to
432 the pointer register */
433 if (aop->type != AOP_STK) {
437 pic14_emitcode("push","acc");
439 pic14_emitcode("mov","a,_bp");
440 pic14_emitcode("add","a,#0x%02x",
442 ((char)(sym->stack - _G.nRegsSaved )) :
443 ((char)sym->stack)) & 0xff);
444 pic14_emitcode("mov","%s,a",
445 aop->aopu.aop_ptr->name);
448 pic14_emitcode("pop","acc");
450 pic14_emitcode("mov","%s,#%s",
451 aop->aopu.aop_ptr->name,
453 aop->paged = space->paged;
455 aop->aopu.aop_stk = sym->stack;
459 if (sym->onStack && options.stack10bit)
461 /* It's on the 10 bit stack, which is located in
465 //DEBUGpic14_emitcode(";","%d",__LINE__);
468 pic14_emitcode("push","acc");
470 pic14_emitcode("mov","a,_bp");
471 pic14_emitcode("add","a,#0x%02x",
473 ((char)(sym->stack - _G.nRegsSaved )) :
474 ((char)sym->stack)) & 0xff);
477 pic14_emitcode ("mov","dpx1,#0x40");
478 pic14_emitcode ("mov","dph1,#0x00");
479 pic14_emitcode ("mov","dpl1, a");
483 pic14_emitcode("pop","acc");
485 sym->aop = aop = newAsmop(AOP_DPTR2);
486 aop->size = getSize(sym->type);
490 //DEBUGpic14_emitcode(";","%d",__LINE__);
491 /* if in bit space */
492 if (IN_BITSPACE(space)) {
493 sym->aop = aop = newAsmop (AOP_CRY);
494 aop->aopu.aop_dir = sym->rname ;
495 aop->size = getSize(sym->type);
496 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
499 /* if it is in direct space */
500 if (IN_DIRSPACE(space)) {
501 sym->aop = aop = newAsmop (AOP_DIR);
502 aop->aopu.aop_dir = sym->rname ;
503 aop->size = getSize(sym->type);
504 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
508 /* special case for a function */
509 if (IS_FUNC(sym->type)) {
510 sym->aop = aop = newAsmop(AOP_IMMD);
511 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
512 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
513 strcpy(aop->aopu.aop_immd,sym->rname);
514 aop->size = FPTRSIZE;
519 /* only remaining is far space */
520 /* in which case DPTR gets the address */
521 sym->aop = aop = newAsmop(AOP_DPTR);
522 pic14_emitcode ("mov","dptr,#%s", sym->rname);
523 aop->size = getSize(sym->type);
525 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
526 /* if it is in code space */
527 if (IN_CODESPACE(space))
533 /*-----------------------------------------------------------------*/
534 /* aopForRemat - rematerialzes an object */
535 /*-----------------------------------------------------------------*/
536 static asmop *aopForRemat (symbol *sym)
538 iCode *ic = sym->rematiCode;
539 asmop *aop = newAsmop(AOP_IMMD);
541 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
544 val += (int) operandLitValue(IC_RIGHT(ic));
545 else if (ic->op == '-')
546 val -= (int) operandLitValue(IC_RIGHT(ic));
550 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
554 sprintf(buffer,"(%s %c 0x%04x)",
555 OP_SYMBOL(IC_LEFT(ic))->rname,
556 val >= 0 ? '+' : '-',
559 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
561 //DEBUGpic14_emitcode(";","%s",buffer);
562 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
563 strcpy(aop->aopu.aop_immd,buffer);
567 int aopIdx (asmop *aop, int offset)
572 if(aop->type != AOP_REG)
575 return aop->aopu.aop_reg[offset]->rIdx;
578 /*-----------------------------------------------------------------*/
579 /* regsInCommon - two operands have some registers in common */
580 /*-----------------------------------------------------------------*/
581 static bool regsInCommon (operand *op1, operand *op2)
586 /* if they have registers in common */
587 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
590 sym1 = OP_SYMBOL(op1);
591 sym2 = OP_SYMBOL(op2);
593 if (sym1->nRegs == 0 || sym2->nRegs == 0)
596 for (i = 0 ; i < sym1->nRegs ; i++) {
601 for (j = 0 ; j < sym2->nRegs ;j++ ) {
605 if (sym2->regs[j] == sym1->regs[i])
613 /*-----------------------------------------------------------------*/
614 /* operandsEqu - equivalent */
615 /*-----------------------------------------------------------------*/
616 static bool operandsEqu ( operand *op1, operand *op2)
620 /* if they not symbols */
621 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
624 sym1 = OP_SYMBOL(op1);
625 sym2 = OP_SYMBOL(op2);
627 /* if both are itemps & one is spilt
628 and the other is not then false */
629 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
630 sym1->isspilt != sym2->isspilt )
633 /* if they are the same */
637 if (strcmp(sym1->rname,sym2->rname) == 0)
641 /* if left is a tmp & right is not */
645 (sym1->usl.spillLoc == sym2))
652 (sym2->usl.spillLoc == sym1))
658 /*-----------------------------------------------------------------*/
659 /* pic14_sameRegs - two asmops have the same registers */
660 /*-----------------------------------------------------------------*/
661 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
668 if (aop1->type != AOP_REG ||
669 aop2->type != AOP_REG )
672 if (aop1->size != aop2->size )
675 for (i = 0 ; i < aop1->size ; i++ )
676 if (aop1->aopu.aop_reg[i] !=
677 aop2->aopu.aop_reg[i] )
683 /*-----------------------------------------------------------------*/
684 /* aopOp - allocates an asmop for an operand : */
685 /*-----------------------------------------------------------------*/
686 void aopOp (operand *op, iCode *ic, bool result)
695 DEBUGpic14_emitcode(";","%d",__LINE__);
696 /* if this a literal */
697 if (IS_OP_LITERAL(op)) {
698 op->aop = aop = newAsmop(AOP_LIT);
699 aop->aopu.aop_lit = op->operand.valOperand;
700 aop->size = getSize(operandType(op));
701 DEBUGpic14_emitcode(";","%d, lit = %d",__LINE__,aop->aopu.aop_lit);
705 /* if already has a asmop then continue */
709 /* if the underlying symbol has a aop */
710 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
711 DEBUGpic14_emitcode(";","%d",__LINE__);
712 op->aop = OP_SYMBOL(op)->aop;
716 /* if this is a true symbol */
717 if (IS_TRUE_SYMOP(op)) {
718 DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
719 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
723 /* this is a temporary : this has
729 e) can be a return use only */
734 /* if the type is a conditional */
735 if (sym->regType == REG_CND) {
736 DEBUGpic14_emitcode(";","%d",__LINE__);
737 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
742 /* if it is spilt then two situations
744 b) has a spill location */
745 if (sym->isspilt || sym->nRegs == 0) {
747 DEBUGpic14_emitcode(";","%d",__LINE__);
748 /* rematerialize it NOW */
750 sym->aop = op->aop = aop =
752 aop->size = getSize(sym->type);
753 DEBUGpic14_emitcode(";","%d",__LINE__);
759 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
760 aop->size = getSize(sym->type);
761 for ( i = 0 ; i < 2 ; i++ )
762 aop->aopu.aop_str[i] = accUse[i];
763 DEBUGpic14_emitcode(";","%d",__LINE__);
769 aop = op->aop = sym->aop = newAsmop(AOP_STR);
770 aop->size = getSize(sym->type);
771 for ( i = 0 ; i < fReturnSizePic ; i++ )
772 aop->aopu.aop_str[i] = fReturn[i];
773 DEBUGpic14_emitcode(";","%d",__LINE__);
777 /* else spill location */
778 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
779 sym->aop = op->aop = aop =
780 aopForSym(ic,sym->usl.spillLoc,result);
781 aop->size = getSize(sym->type);
785 /* must be in a register */
786 sym->aop = op->aop = aop = newAsmop(AOP_REG);
787 aop->size = sym->nRegs;
788 for ( i = 0 ; i < sym->nRegs ;i++)
789 aop->aopu.aop_reg[i] = sym->regs[i];
792 /*-----------------------------------------------------------------*/
793 /* freeAsmop - free up the asmop given to an operand */
794 /*----------------------------------------------------------------*/
795 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
812 /* depending on the asmop type only three cases need work AOP_RO
813 , AOP_R1 && AOP_STK */
818 pic14_emitcode ("pop","ar0");
822 bitVectUnSetBit(ic->rUsed,R0_IDX);
828 pic14_emitcode ("pop","ar1");
832 bitVectUnSetBit(ic->rUsed,R1_IDX);
838 int stk = aop->aopu.aop_stk + aop->size;
839 bitVectUnSetBit(ic->rUsed,R0_IDX);
840 bitVectUnSetBit(ic->rUsed,R1_IDX);
842 getFreePtr(ic,&aop,FALSE);
844 if (options.stack10bit)
846 /* I'm not sure what to do here yet... */
849 "*** Warning: probably generating bad code for "
850 "10 bit stack mode.\n");
854 pic14_emitcode ("mov","a,_bp");
855 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
856 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
858 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
862 pic14_emitcode("pop","acc");
863 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
865 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
868 freeAsmop(op,NULL,ic,TRUE);
870 pic14_emitcode("pop","ar0");
875 pic14_emitcode("pop","ar1");
882 /* all other cases just dealloc */
886 OP_SYMBOL(op)->aop = NULL;
887 /* if the symbol has a spill */
889 SPIL_LOC(op)->aop = NULL;
894 /*-----------------------------------------------------------------*/
895 /* aopGet - for fetching value of the aop */
896 /*-----------------------------------------------------------------*/
897 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
902 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
903 /* offset is greater than
905 if (offset > (aop->size - 1) &&
906 aop->type != AOP_LIT)
909 /* depending on type */
914 DEBUGpic14_emitcode(";","%d",__LINE__);
915 /* if we need to increment it */
916 while (offset > aop->coff) {
917 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
921 while (offset < aop->coff) {
922 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
928 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
929 return (dname ? "acc" : "a");
931 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
932 rs = Safe_calloc(1,strlen(s)+1);
938 DEBUGpic14_emitcode(";","%d",__LINE__);
939 if (aop->type == AOP_DPTR2)
944 while (offset > aop->coff) {
945 pic14_emitcode ("inc","dptr");
949 while (offset < aop->coff) {
950 pic14_emitcode("lcall","__decdptr");
956 pic14_emitcode("clr","a");
957 pic14_emitcode("movc","a,@a+dptr");
960 pic14_emitcode("movx","a,@dptr");
963 if (aop->type == AOP_DPTR2)
968 return (dname ? "acc" : "a");
972 DEBUGpic14_emitcode(";","%d",__LINE__);
974 sprintf (s,"%s",aop->aopu.aop_immd);
977 sprintf(s,"(%s >> %d)",
983 rs = Safe_calloc(1,strlen(s)+1);
989 sprintf(s,"(%s + %d)",
993 sprintf(s,"%s",aop->aopu.aop_dir);
994 rs = Safe_calloc(1,strlen(s)+1);
999 DEBUGpic14_emitcode(";","%d",__LINE__);
1001 return aop->aopu.aop_reg[offset]->dname;
1003 return aop->aopu.aop_reg[offset]->name;
1006 pic14_emitcode(";","%d",__LINE__);
1007 //pic14_emitcode("clr","a");
1008 //pic14_emitcode("mov","c,%s",aop->aopu.aop_dir);
1009 //pic14_emitcode("rlc","a") ;
1010 //return (dname ? "acc" : "a");
1011 return aop->aopu.aop_dir;
1014 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1015 //if (!offset && dname)
1017 //return aop->aopu.aop_str[offset];
1018 return "AOP_accumulator_bug";
1021 DEBUGpic14_emitcode(";","%d",__LINE__);
1022 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1023 rs = Safe_calloc(1,strlen(s)+1);
1028 DEBUGpic14_emitcode(";","%d",__LINE__);
1029 aop->coff = offset ;
1030 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1034 return aop->aopu.aop_str[offset];
1038 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1039 "aopget got unsupported aop->type");
1043 /*-----------------------------------------------------------------*/
1044 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1045 /*-----------------------------------------------------------------*/
1046 pCodeOp *popGetLabel(unsigned int key)
1049 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1054 return newpCodeOpLabel(key+100+labelOffset);
1057 /*-----------------------------------------------------------------*/
1058 /* popCopyReg - copy a pcode operator */
1059 /*-----------------------------------------------------------------*/
1060 pCodeOp *popCopyReg(pCodeOpReg *pc)
1064 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1065 pcor->pcop.type = pc->pcop.type;
1066 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1067 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1069 pcor->rIdx = pc->rIdx;
1075 /*-----------------------------------------------------------------*/
1076 /* popCopy - copy a pcode operator */
1077 /*-----------------------------------------------------------------*/
1078 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1082 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1083 pcop->type = PO_BIT;
1084 if(!(pcop->name = Safe_strdup(pc->name)))
1085 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1086 ((pCodeOpBit *)pcop)->bit = bitval;
1088 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1093 /*-----------------------------------------------------------------*/
1094 /* popGet - asm operator to pcode operator conversion */
1095 /*-----------------------------------------------------------------*/
1096 pCodeOp *popGetLit(unsigned int lit)
1099 return newpCodeOpLit(lit);
1103 /*-----------------------------------------------------------------*/
1104 /* popGet - asm operator to pcode operator conversion */
1105 /*-----------------------------------------------------------------*/
1106 pCodeOp *popGetWithString(char *str)
1112 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1116 pcop = newpCodeOp(str,PO_STR);
1121 pCodeOp *popRegFromString(char *str)
1124 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1125 pcop->type = PO_GPR_REGISTER;
1127 PCOR(pcop)->rIdx = -1;
1128 PCOR(pcop)->r = NULL;
1130 DEBUGpic14_emitcode(";","%d",__LINE__);
1131 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1136 /*-----------------------------------------------------------------*/
1137 /* popGet - asm operator to pcode operator conversion */
1138 /*-----------------------------------------------------------------*/
1139 pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
1146 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1147 /* offset is greater than
1150 if (offset > (aop->size - 1) &&
1151 aop->type != AOP_LIT)
1152 return NULL; //zero;
1154 /* depending on type */
1155 switch (aop->type) {
1162 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1163 //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1164 //pcop->type = PO_SFR_REGISTER;
1166 //PCOR(pcop)->rIdx = -1;
1167 //PCOR(pcop)->r = NULL;
1168 // Really nasty hack to check for temporary registers
1170 //pcop->name = Safe_strdup("BAD_REGISTER");
1175 DEBUGpic14_emitcode(";","%d",__LINE__);
1176 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1177 pcop->type = PO_IMMEDIATE;
1179 sprintf (s,"%s",aop->aopu.aop_immd);
1182 sprintf(s,"(%s >> %d)",
1187 aop->aopu.aop_immd);
1188 pcop->name = Safe_calloc(1,strlen(s)+1);
1189 strcpy(pcop->name,s);
1193 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1194 pcop->type = PO_DIR;
1196 sprintf(s,"(%s + %d)",
1200 sprintf(s,"%s",aop->aopu.aop_dir);
1201 pcop->name = Safe_calloc(1,strlen(s)+1);
1202 strcpy(pcop->name,s);
1207 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1209 DEBUGpic14_emitcode(";","%d, rIdx=0x%x",__LINE__,rIdx);
1211 pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1213 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1214 //pcop->type = PO_GPR_REGISTER;
1215 PCOR(pcop)->rIdx = rIdx;
1216 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1217 pcop->type = PCOR(pcop)->r->pc_type;
1220 rs = aop->aopu.aop_reg[offset]->dname;
1222 rs = aop->aopu.aop_reg[offset]->name;
1224 DEBUGpic14_emitcode(";","%d %s",__LINE__,rs);
1230 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1234 DEBUGpic14_emitcode(";","%d",__LINE__);
1235 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1238 DEBUGpic14_emitcode(";","%d",__LINE__);
1240 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1241 pcop->type = PO_STR;
1243 //aop->coff = offset ;
1244 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1245 sprintf(s,"%s","acc");
1247 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1248 pcop->name = Safe_calloc(1,strlen(s)+1);
1249 strcpy(pcop->name,s);
1254 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1255 "popGet got unsupported aop->type");
1258 /*-----------------------------------------------------------------*/
1259 /* aopPut - puts a string for a aop */
1260 /*-----------------------------------------------------------------*/
1261 void aopPut (asmop *aop, char *s, int offset)
1266 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1268 if (aop->size && offset > ( aop->size - 1)) {
1269 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1270 "aopPut got offset > aop->size");
1274 /* will assign value to value */
1275 /* depending on where it is ofcourse */
1276 switch (aop->type) {
1279 sprintf(d,"(%s + %d)",
1280 aop->aopu.aop_dir,offset);
1282 sprintf(d,"%s",aop->aopu.aop_dir);
1285 DEBUGpic14_emitcode(";","%d",__LINE__);
1287 pic14_emitcode("movf","%s,w",s);
1288 pic14_emitcode("movwf","%s",d);
1291 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1292 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1299 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1300 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1303 strcmp(s,"r0") == 0 ||
1304 strcmp(s,"r1") == 0 ||
1305 strcmp(s,"r2") == 0 ||
1306 strcmp(s,"r3") == 0 ||
1307 strcmp(s,"r4") == 0 ||
1308 strcmp(s,"r5") == 0 ||
1309 strcmp(s,"r6") == 0 ||
1310 strcmp(s,"r7") == 0 )
1311 pic14_emitcode("mov","%s,%s ; %d",
1312 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1317 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1319 pic14_emitcode("movwf","%s",
1320 aop->aopu.aop_reg[offset]->name);
1323 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1324 pcop->type = PO_GPR_REGISTER;
1326 PCOR(pcop)->rIdx = -1;
1327 PCOR(pcop)->r = NULL;
1329 DEBUGpic14_emitcode(";","%d",__LINE__);
1330 pcop->name = Safe_strdup(s);
1331 emitpcode(POC_MOVFW,pcop);
1333 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1341 if (aop->type == AOP_DPTR2)
1347 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1348 "aopPut writting to code space");
1352 while (offset > aop->coff) {
1354 pic14_emitcode ("inc","dptr");
1357 while (offset < aop->coff) {
1359 pic14_emitcode("lcall","__decdptr");
1364 /* if not in accumulater */
1367 pic14_emitcode ("movx","@dptr,a");
1369 if (aop->type == AOP_DPTR2)
1377 while (offset > aop->coff) {
1379 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1381 while (offset < aop->coff) {
1383 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1389 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1394 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1396 if (strcmp(s,"r0") == 0 ||
1397 strcmp(s,"r1") == 0 ||
1398 strcmp(s,"r2") == 0 ||
1399 strcmp(s,"r3") == 0 ||
1400 strcmp(s,"r4") == 0 ||
1401 strcmp(s,"r5") == 0 ||
1402 strcmp(s,"r6") == 0 ||
1403 strcmp(s,"r7") == 0 ) {
1405 sprintf(buffer,"a%s",s);
1406 pic14_emitcode("mov","@%s,%s",
1407 aop->aopu.aop_ptr->name,buffer);
1409 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1414 if (strcmp(s,"a") == 0)
1415 pic14_emitcode("push","acc");
1417 pic14_emitcode("push","%s",s);
1422 /* if bit variable */
1423 if (!aop->aopu.aop_dir) {
1424 pic14_emitcode("clr","a");
1425 pic14_emitcode("rlc","a");
1428 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1431 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1434 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1436 lbl = newiTempLabel(NULL);
1438 if (strcmp(s,"a")) {
1441 pic14_emitcode("clr","c");
1442 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1443 pic14_emitcode("cpl","c");
1444 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1445 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1452 if (strcmp(aop->aopu.aop_str[offset],s))
1453 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1458 if (!offset && (strcmp(s,"acc") == 0))
1461 if (strcmp(aop->aopu.aop_str[offset],s))
1462 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1466 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1467 "aopPut got unsupported aop->type");
1473 /*-----------------------------------------------------------------*/
1474 /* reAdjustPreg - points a register back to where it should */
1475 /*-----------------------------------------------------------------*/
1476 static void reAdjustPreg (asmop *aop)
1480 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1482 if ((size = aop->size) <= 1)
1485 switch (aop->type) {
1489 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1493 if (aop->type == AOP_DPTR2)
1499 pic14_emitcode("lcall","__decdptr");
1502 if (aop->type == AOP_DPTR2)
1512 /*-----------------------------------------------------------------*/
1513 /* genNotFloat - generates not for float operations */
1514 /*-----------------------------------------------------------------*/
1515 static void genNotFloat (operand *op, operand *res)
1521 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1522 /* we will put 127 in the first byte of
1524 aopPut(AOP(res),"#127",0);
1525 size = AOP_SIZE(op) - 1;
1528 l = aopGet(op->aop,offset++,FALSE,FALSE);
1532 pic14_emitcode("orl","a,%s",
1534 offset++,FALSE,FALSE));
1536 tlbl = newiTempLabel(NULL);
1538 tlbl = newiTempLabel(NULL);
1539 aopPut(res->aop,one,1);
1540 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1541 aopPut(res->aop,zero,1);
1542 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1544 size = res->aop->size - 2;
1546 /* put zeros in the rest */
1548 aopPut(res->aop,zero,offset++);
1552 /*-----------------------------------------------------------------*/
1553 /* opIsGptr: returns non-zero if the passed operand is */
1554 /* a generic pointer type. */
1555 /*-----------------------------------------------------------------*/
1556 static int opIsGptr(operand *op)
1558 sym_link *type = operandType(op);
1560 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1561 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1569 /*-----------------------------------------------------------------*/
1570 /* pic14_getDataSize - get the operand data size */
1571 /*-----------------------------------------------------------------*/
1572 int pic14_getDataSize(operand *op)
1574 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1577 return AOP_SIZE(op);
1579 // tsd- in the pic port, the genptr size is 1, so this code here
1580 // fails. ( in the 8051 port, the size was 4).
1583 size = AOP_SIZE(op);
1584 if (size == GPTRSIZE)
1586 sym_link *type = operandType(op);
1587 if (IS_GENPTR(type))
1589 /* generic pointer; arithmetic operations
1590 * should ignore the high byte (pointer type).
1593 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1600 /*-----------------------------------------------------------------*/
1601 /* pic14_outAcc - output Acc */
1602 /*-----------------------------------------------------------------*/
1603 void pic14_outAcc(operand *result)
1606 DEBUGpic14_emitcode ("; ***","%s %d - Warning no code will be generated here",__FUNCTION__,__LINE__);
1609 size = pic14_getDataSize(result);
1611 aopPut(AOP(result),"a",0);
1614 /* unsigned or positive */
1616 aopPut(AOP(result),zero,offset++);
1622 /*-----------------------------------------------------------------*/
1623 /* pic14_outBitC - output a bit C */
1624 /*-----------------------------------------------------------------*/
1625 void pic14_outBitC(operand *result)
1628 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1629 /* if the result is bit */
1630 if (AOP_TYPE(result) == AOP_CRY)
1631 aopPut(AOP(result),"c",0);
1633 pic14_emitcode("clr","a ; %d", __LINE__);
1634 pic14_emitcode("rlc","a");
1635 pic14_outAcc(result);
1639 /*-----------------------------------------------------------------*/
1640 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1641 /*-----------------------------------------------------------------*/
1642 void pic14_toBoolean(operand *oper)
1644 int size = AOP_SIZE(oper) - 1;
1647 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1649 if ( AOP_TYPE(oper) != AOP_ACC) {
1650 emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1651 pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1654 pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1655 emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1660 /*-----------------------------------------------------------------*/
1661 /* genNot - generate code for ! operation */
1662 /*-----------------------------------------------------------------*/
1663 static void genNot (iCode *ic)
1666 sym_link *optype = operandType(IC_LEFT(ic));
1668 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1669 /* assign asmOps to operand & result */
1670 aopOp (IC_LEFT(ic),ic,FALSE);
1671 aopOp (IC_RESULT(ic),ic,TRUE);
1673 /* if in bit space then a special case */
1674 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1675 pic14_emitcode("movlw","1<<%s");
1676 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1677 //pic14_emitcode("cpl","c");
1678 //pic14_outBitC(IC_RESULT(ic));
1682 /* if type float then do float */
1683 if (IS_FLOAT(optype)) {
1684 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1688 pic14_toBoolean(IC_LEFT(ic));
1690 tlbl = newiTempLabel(NULL);
1691 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1692 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1693 pic14_outBitC(IC_RESULT(ic));
1696 /* release the aops */
1697 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1698 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1702 /*-----------------------------------------------------------------*/
1703 /* genCpl - generate code for complement */
1704 /*-----------------------------------------------------------------*/
1705 static void genCpl (iCode *ic)
1711 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1712 /* assign asmOps to operand & result */
1713 aopOp (IC_LEFT(ic),ic,FALSE);
1714 aopOp (IC_RESULT(ic),ic,TRUE);
1716 /* if both are in bit space then
1718 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1719 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1721 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1722 pic14_emitcode("cpl","c");
1723 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1727 size = AOP_SIZE(IC_RESULT(ic));
1729 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1731 pic14_emitcode("cpl","a");
1732 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1737 /* release the aops */
1738 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1739 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1742 /*-----------------------------------------------------------------*/
1743 /* genUminusFloat - unary minus for floating points */
1744 /*-----------------------------------------------------------------*/
1745 static void genUminusFloat(operand *op,operand *result)
1747 int size ,offset =0 ;
1750 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1751 /* for this we just need to flip the
1752 first it then copy the rest in place */
1753 size = AOP_SIZE(op) - 1;
1754 l = aopGet(AOP(op),3,FALSE,FALSE);
1758 pic14_emitcode("cpl","acc.7");
1759 aopPut(AOP(result),"a",3);
1763 aopGet(AOP(op),offset,FALSE,FALSE),
1769 /*-----------------------------------------------------------------*/
1770 /* genUminus - unary minus code generation */
1771 /*-----------------------------------------------------------------*/
1772 static void genUminus (iCode *ic)
1775 sym_link *optype, *rtype;
1778 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1780 aopOp(IC_LEFT(ic),ic,FALSE);
1781 aopOp(IC_RESULT(ic),ic,TRUE);
1783 /* if both in bit space then special
1785 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1786 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1788 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1789 pic14_emitcode("cpl","c");
1790 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1794 optype = operandType(IC_LEFT(ic));
1795 rtype = operandType(IC_RESULT(ic));
1797 /* if float then do float stuff */
1798 if (IS_FLOAT(optype)) {
1799 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1803 /* otherwise subtract from zero */
1804 size = AOP_SIZE(IC_LEFT(ic));
1808 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1809 if (!strcmp(l,"a")) {
1810 pic14_emitcode("cpl","a");
1811 pic14_emitcode("inc","a");
1813 pic14_emitcode("clr","a");
1814 pic14_emitcode("subb","a,%s",l);
1816 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1819 /* if any remaining bytes in the result */
1820 /* we just need to propagate the sign */
1821 if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1822 pic14_emitcode("rlc","a");
1823 pic14_emitcode("subb","a,acc");
1825 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1829 /* release the aops */
1830 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1831 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1834 /*-----------------------------------------------------------------*/
1835 /* saveRegisters - will look for a call and save the registers */
1836 /*-----------------------------------------------------------------*/
1837 static void saveRegisters(iCode *lic)
1844 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1846 for (ic = lic ; ic ; ic = ic->next)
1847 if (ic->op == CALL || ic->op == PCALL)
1851 fprintf(stderr,"found parameter push with no function call\n");
1855 /* if the registers have been saved already then
1857 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1860 /* find the registers in use at this time
1861 and push them away to safety */
1862 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1866 if (options.useXstack) {
1867 if (bitVectBitValue(rsave,R0_IDX))
1868 pic14_emitcode("mov","b,r0");
1869 pic14_emitcode("mov","r0,%s",spname);
1870 for (i = 0 ; i < pic14_nRegs ; i++) {
1871 if (bitVectBitValue(rsave,i)) {
1873 pic14_emitcode("mov","a,b");
1875 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1876 pic14_emitcode("movx","@r0,a");
1877 pic14_emitcode("inc","r0");
1880 pic14_emitcode("mov","%s,r0",spname);
1881 if (bitVectBitValue(rsave,R0_IDX))
1882 pic14_emitcode("mov","r0,b");
1884 for (i = 0 ; i < pic14_nRegs ; i++) {
1885 if (bitVectBitValue(rsave,i))
1886 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1889 dtype = operandType(IC_LEFT(ic));
1891 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1892 IFFUNC_ISISR(currFunc->type) &&
1895 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1898 /*-----------------------------------------------------------------*/
1899 /* unsaveRegisters - pop the pushed registers */
1900 /*-----------------------------------------------------------------*/
1901 static void unsaveRegisters (iCode *ic)
1906 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1907 /* find the registers in use at this time
1908 and push them away to safety */
1909 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1912 if (options.useXstack) {
1913 pic14_emitcode("mov","r0,%s",spname);
1914 for (i = pic14_nRegs ; i >= 0 ; i--) {
1915 if (bitVectBitValue(rsave,i)) {
1916 pic14_emitcode("dec","r0");
1917 pic14_emitcode("movx","a,@r0");
1919 pic14_emitcode("mov","b,a");
1921 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1925 pic14_emitcode("mov","%s,r0",spname);
1926 if (bitVectBitValue(rsave,R0_IDX))
1927 pic14_emitcode("mov","r0,b");
1929 for (i = pic14_nRegs ; i >= 0 ; i--) {
1930 if (bitVectBitValue(rsave,i))
1931 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1937 /*-----------------------------------------------------------------*/
1939 /*-----------------------------------------------------------------*/
1940 static void pushSide(operand * oper, int size)
1943 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1945 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1946 if (AOP_TYPE(oper) != AOP_REG &&
1947 AOP_TYPE(oper) != AOP_DIR &&
1949 pic14_emitcode("mov","a,%s",l);
1950 pic14_emitcode("push","acc");
1952 pic14_emitcode("push","%s",l);
1956 /*-----------------------------------------------------------------*/
1957 /* assignResultValue - */
1958 /*-----------------------------------------------------------------*/
1959 static void assignResultValue(operand * oper)
1962 int size = AOP_SIZE(oper);
1964 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1966 // The last byte in the assignment is in W
1967 aopPut(AOP(oper),"W",size-1);
1971 aopPut(AOP(oper),fReturn[offset],offset);
1979 /*-----------------------------------------------------------------*/
1980 /* genXpush - pushes onto the external stack */
1981 /*-----------------------------------------------------------------*/
1982 static void genXpush (iCode *ic)
1984 asmop *aop = newAsmop(0);
1986 int size,offset = 0;
1988 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1989 aopOp(IC_LEFT(ic),ic,FALSE);
1990 r = getFreePtr(ic,&aop,FALSE);
1993 pic14_emitcode("mov","%s,_spx",r->name);
1995 size = AOP_SIZE(IC_LEFT(ic));
1998 char *l = aopGet(AOP(IC_LEFT(ic)),
1999 offset++,FALSE,FALSE);
2001 pic14_emitcode("movx","@%s,a",r->name);
2002 pic14_emitcode("inc","%s",r->name);
2007 pic14_emitcode("mov","_spx,%s",r->name);
2009 freeAsmop(NULL,aop,ic,TRUE);
2010 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2013 /*-----------------------------------------------------------------*/
2014 /* genIpush - genrate code for pushing this gets a little complex */
2015 /*-----------------------------------------------------------------*/
2016 static void genIpush (iCode *ic)
2018 int size, offset = 0 ;
2022 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2023 /* if this is not a parm push : ie. it is spill push
2024 and spill push is always done on the local stack */
2025 if (!ic->parmPush) {
2027 /* and the item is spilt then do nothing */
2028 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2031 aopOp(IC_LEFT(ic),ic,FALSE);
2032 size = AOP_SIZE(IC_LEFT(ic));
2033 /* push it on the stack */
2035 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2040 pic14_emitcode("push","%s",l);
2045 /* this is a paramter push: in this case we call
2046 the routine to find the call and save those
2047 registers that need to be saved */
2050 /* if use external stack then call the external
2051 stack pushing routine */
2052 if (options.useXstack) {
2057 /* then do the push */
2058 aopOp(IC_LEFT(ic),ic,FALSE);
2061 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2062 size = AOP_SIZE(IC_LEFT(ic));
2065 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2066 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2067 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2069 pic14_emitcode("mov","a,%s",l);
2070 pic14_emitcode("push","acc");
2072 pic14_emitcode("push","%s",l);
2075 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2078 /*-----------------------------------------------------------------*/
2079 /* genIpop - recover the registers: can happen only for spilling */
2080 /*-----------------------------------------------------------------*/
2081 static void genIpop (iCode *ic)
2086 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2087 /* if the temp was not pushed then */
2088 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2091 aopOp(IC_LEFT(ic),ic,FALSE);
2092 size = AOP_SIZE(IC_LEFT(ic));
2095 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2098 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2101 /*-----------------------------------------------------------------*/
2102 /* unsaverbank - restores the resgister bank from stack */
2103 /*-----------------------------------------------------------------*/
2104 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2110 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2112 if (options.useXstack) {
2114 r = getFreePtr(ic,&aop,FALSE);
2117 pic14_emitcode("mov","%s,_spx",r->name);
2118 pic14_emitcode("movx","a,@%s",r->name);
2119 pic14_emitcode("mov","psw,a");
2120 pic14_emitcode("dec","%s",r->name);
2123 pic14_emitcode ("pop","psw");
2126 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2127 if (options.useXstack) {
2128 pic14_emitcode("movx","a,@%s",r->name);
2129 //pic14_emitcode("mov","(%s+%d),a",
2130 // regspic14[i].base,8*bank+regspic14[i].offset);
2131 pic14_emitcode("dec","%s",r->name);
2134 pic14_emitcode("pop",""); //"(%s+%d)",
2135 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2138 if (options.useXstack) {
2140 pic14_emitcode("mov","_spx,%s",r->name);
2141 freeAsmop(NULL,aop,ic,TRUE);
2146 /*-----------------------------------------------------------------*/
2147 /* saverbank - saves an entire register bank on the stack */
2148 /*-----------------------------------------------------------------*/
2149 static void saverbank (int bank, iCode *ic, bool pushPsw)
2155 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2156 if (options.useXstack) {
2159 r = getFreePtr(ic,&aop,FALSE);
2160 pic14_emitcode("mov","%s,_spx",r->name);
2164 for (i = 0 ; i < pic14_nRegs ;i++) {
2165 if (options.useXstack) {
2166 pic14_emitcode("inc","%s",r->name);
2167 //pic14_emitcode("mov","a,(%s+%d)",
2168 // regspic14[i].base,8*bank+regspic14[i].offset);
2169 pic14_emitcode("movx","@%s,a",r->name);
2171 pic14_emitcode("push","");// "(%s+%d)",
2172 //regspic14[i].base,8*bank+regspic14[i].offset);
2176 if (options.useXstack) {
2177 pic14_emitcode("mov","a,psw");
2178 pic14_emitcode("movx","@%s,a",r->name);
2179 pic14_emitcode("inc","%s",r->name);
2180 pic14_emitcode("mov","_spx,%s",r->name);
2181 freeAsmop (NULL,aop,ic,TRUE);
2184 pic14_emitcode("push","psw");
2186 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2192 /*-----------------------------------------------------------------*/
2193 /* genCall - generates a call statement */
2194 /*-----------------------------------------------------------------*/
2195 static void genCall (iCode *ic)
2199 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2201 /* if caller saves & we have not saved then */
2205 /* if we are calling a function that is not using
2206 the same register bank then we need to save the
2207 destination registers on the stack */
2208 dtype = operandType(IC_LEFT(ic));
2210 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2211 IFFUNC_ISISR(currFunc->type) &&
2214 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2216 /* if send set is not empty the assign */
2220 for (sic = setFirstItem(_G.sendSet) ; sic ;
2221 sic = setNextItem(_G.sendSet)) {
2222 int size, offset = 0;
2224 aopOp(IC_LEFT(sic),sic,FALSE);
2225 size = AOP_SIZE(IC_LEFT(sic));
2227 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2229 DEBUGpic14_emitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
2231 if (strcmp(l,fReturn[offset])) {
2233 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2234 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2235 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2236 //pic14_emitcode("movlw","%s",l);
2238 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2239 //pic14_emitcode("movf","%s,w",l);
2241 // The last one is passed in W
2243 pic14_emitcode("movwf","%s",fReturn[offset]);
2247 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2252 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2253 OP_SYMBOL(IC_LEFT(ic))->rname :
2254 OP_SYMBOL(IC_LEFT(ic))->name));
2256 pic14_emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2257 OP_SYMBOL(IC_LEFT(ic))->rname :
2258 OP_SYMBOL(IC_LEFT(ic))->name));
2260 /* if we need assign a result value */
2261 if ((IS_ITEMP(IC_RESULT(ic)) &&
2262 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2263 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2264 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2267 aopOp(IC_RESULT(ic),ic,FALSE);
2270 assignResultValue(IC_RESULT(ic));
2272 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2275 /* adjust the stack for parameters if
2277 if (ic->parmBytes) {
2279 if (ic->parmBytes > 3) {
2280 pic14_emitcode("mov","a,%s",spname);
2281 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2282 pic14_emitcode("mov","%s,a",spname);
2284 for ( i = 0 ; i < ic->parmBytes ;i++)
2285 pic14_emitcode("dec","%s",spname);
2289 /* if register bank was saved then pop them */
2291 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2293 /* if we hade saved some registers then unsave them */
2294 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2295 unsaveRegisters (ic);
2300 /*-----------------------------------------------------------------*/
2301 /* genPcall - generates a call by pointer statement */
2302 /*-----------------------------------------------------------------*/
2303 static void genPcall (iCode *ic)
2306 symbol *rlbl = newiTempLabel(NULL);
2309 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2310 /* if caller saves & we have not saved then */
2314 /* if we are calling a function that is not using
2315 the same register bank then we need to save the
2316 destination registers on the stack */
2317 dtype = operandType(IC_LEFT(ic));
2319 IFFUNC_ISISR(currFunc->type) &&
2320 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2321 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2324 /* push the return address on to the stack */
2325 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2326 pic14_emitcode("push","acc");
2327 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2328 pic14_emitcode("push","acc");
2330 if (options.model == MODEL_FLAT24)
2332 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2333 pic14_emitcode("push","acc");
2336 /* now push the calling address */
2337 aopOp(IC_LEFT(ic),ic,FALSE);
2339 pushSide(IC_LEFT(ic), FPTRSIZE);
2341 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2343 /* if send set is not empty the assign */
2347 for (sic = setFirstItem(_G.sendSet) ; sic ;
2348 sic = setNextItem(_G.sendSet)) {
2349 int size, offset = 0;
2350 aopOp(IC_LEFT(sic),sic,FALSE);
2351 size = AOP_SIZE(IC_LEFT(sic));
2353 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2355 if (strcmp(l,fReturn[offset]))
2356 pic14_emitcode("mov","%s,%s",
2361 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2366 pic14_emitcode("ret","");
2367 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2370 /* if we need assign a result value */
2371 if ((IS_ITEMP(IC_RESULT(ic)) &&
2372 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2373 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2374 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2377 aopOp(IC_RESULT(ic),ic,FALSE);
2380 assignResultValue(IC_RESULT(ic));
2382 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2385 /* adjust the stack for parameters if
2387 if (ic->parmBytes) {
2389 if (ic->parmBytes > 3) {
2390 pic14_emitcode("mov","a,%s",spname);
2391 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2392 pic14_emitcode("mov","%s,a",spname);
2394 for ( i = 0 ; i < ic->parmBytes ;i++)
2395 pic14_emitcode("dec","%s",spname);
2399 /* if register bank was saved then unsave them */
2401 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2402 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2404 /* if we hade saved some registers then
2407 unsaveRegisters (ic);
2411 /*-----------------------------------------------------------------*/
2412 /* resultRemat - result is rematerializable */
2413 /*-----------------------------------------------------------------*/
2414 static int resultRemat (iCode *ic)
2416 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2417 if (SKIP_IC(ic) || ic->op == IFX)
2420 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2421 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2422 if (sym->remat && !POINTER_SET(ic))
2429 #if defined(__BORLANDC__) || defined(_MSC_VER)
2430 #define STRCASECMP stricmp
2432 #define STRCASECMP strcasecmp
2435 /*-----------------------------------------------------------------*/
2436 /* inExcludeList - return 1 if the string is in exclude Reg list */
2437 /*-----------------------------------------------------------------*/
2438 static bool inExcludeList(char *s)
2442 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2443 if (options.excludeRegs[i] &&
2444 STRCASECMP(options.excludeRegs[i],"none") == 0)
2447 for ( i = 0 ; options.excludeRegs[i]; i++) {
2448 if (options.excludeRegs[i] &&
2449 STRCASECMP(s,options.excludeRegs[i]) == 0)
2455 /*-----------------------------------------------------------------*/
2456 /* genFunction - generated code for function entry */
2457 /*-----------------------------------------------------------------*/
2458 static void genFunction (iCode *ic)
2463 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2465 labelOffset += (max_key+4);
2469 /* create the function header */
2470 pic14_emitcode(";","-----------------------------------------");
2471 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2472 pic14_emitcode(";","-----------------------------------------");
2474 pic14_emitcode("","%s:",sym->rname);
2475 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2477 ftype = operandType(IC_LEFT(ic));
2479 /* if critical function then turn interrupts off */
2480 if (IFFUNC_ISCRITICAL(ftype))
2481 pic14_emitcode("clr","ea");
2483 /* here we need to generate the equates for the
2484 register bank if required */
2486 if (FUNC_REGBANK(ftype) != rbank) {
2489 rbank = FUNC_REGBANK(ftype);
2490 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2491 if (strcmp(regspic14[i].base,"0") == 0)
2492 pic14_emitcode("","%s = 0x%02x",
2494 8*rbank+regspic14[i].offset);
2496 pic14_emitcode ("","%s = %s + 0x%02x",
2499 8*rbank+regspic14[i].offset);
2504 /* if this is an interrupt service routine then
2505 save acc, b, dpl, dph */
2506 if (IFFUNC_ISISR(sym->type)) {
2508 if (!inExcludeList("acc"))
2509 pic14_emitcode ("push","acc");
2510 if (!inExcludeList("b"))
2511 pic14_emitcode ("push","b");
2512 if (!inExcludeList("dpl"))
2513 pic14_emitcode ("push","dpl");
2514 if (!inExcludeList("dph"))
2515 pic14_emitcode ("push","dph");
2516 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2518 pic14_emitcode ("push", "dpx");
2519 /* Make sure we're using standard DPTR */
2520 pic14_emitcode ("push", "dps");
2521 pic14_emitcode ("mov", "dps, #0x00");
2522 if (options.stack10bit)
2524 /* This ISR could conceivably use DPTR2. Better save it. */
2525 pic14_emitcode ("push", "dpl1");
2526 pic14_emitcode ("push", "dph1");
2527 pic14_emitcode ("push", "dpx1");
2530 /* if this isr has no bank i.e. is going to
2531 run with bank 0 , then we need to save more
2533 if (!FUNC_REGBANK(sym->type)) {
2535 /* if this function does not call any other
2536 function then we can be economical and
2537 save only those registers that are used */
2538 if (! IFFUNC_HASFCALL(sym->type)) {
2541 /* if any registers used */
2542 if (sym->regsUsed) {
2543 /* save the registers used */
2544 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2545 if (bitVectBitValue(sym->regsUsed,i) ||
2546 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2547 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2552 /* this function has a function call cannot
2553 determines register usage so we will have the
2555 saverbank(0,ic,FALSE);
2559 /* if callee-save to be used for this function
2560 then save the registers being used in this function */
2561 if (IFFUNC_CALLEESAVES(sym->type)) {
2564 /* if any registers used */
2565 if (sym->regsUsed) {
2566 /* save the registers used */
2567 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2568 if (bitVectBitValue(sym->regsUsed,i) ||
2569 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2570 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2578 /* set the register bank to the desired value */
2579 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2580 pic14_emitcode("push","psw");
2581 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2584 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2586 if (options.useXstack) {
2587 pic14_emitcode("mov","r0,%s",spname);
2588 pic14_emitcode("mov","a,_bp");
2589 pic14_emitcode("movx","@r0,a");
2590 pic14_emitcode("inc","%s",spname);
2594 /* set up the stack */
2595 pic14_emitcode ("push","_bp"); /* save the callers stack */
2597 pic14_emitcode ("mov","_bp,%s",spname);
2600 /* adjust the stack for the function */
2605 werror(W_STACK_OVERFLOW,sym->name);
2607 if (i > 3 && sym->recvSize < 4) {
2609 pic14_emitcode ("mov","a,sp");
2610 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2611 pic14_emitcode ("mov","sp,a");
2616 pic14_emitcode("inc","sp");
2621 pic14_emitcode ("mov","a,_spx");
2622 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2623 pic14_emitcode ("mov","_spx,a");
2628 /*-----------------------------------------------------------------*/
2629 /* genEndFunction - generates epilogue for functions */
2630 /*-----------------------------------------------------------------*/
2631 static void genEndFunction (iCode *ic)
2633 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2635 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2637 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2639 pic14_emitcode ("mov","%s,_bp",spname);
2642 /* if use external stack but some variables were
2643 added to the local stack then decrement the
2645 if (options.useXstack && sym->stack) {
2646 pic14_emitcode("mov","a,sp");
2647 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2648 pic14_emitcode("mov","sp,a");
2652 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2653 if (options.useXstack) {
2654 pic14_emitcode("mov","r0,%s",spname);
2655 pic14_emitcode("movx","a,@r0");
2656 pic14_emitcode("mov","_bp,a");
2657 pic14_emitcode("dec","%s",spname);
2661 pic14_emitcode ("pop","_bp");
2665 /* restore the register bank */
2666 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2667 pic14_emitcode ("pop","psw");
2669 if (IFFUNC_ISISR(sym->type)) {
2671 /* now we need to restore the registers */
2672 /* if this isr has no bank i.e. is going to
2673 run with bank 0 , then we need to save more
2675 if (!FUNC_REGBANK(sym->type)) {
2677 /* if this function does not call any other
2678 function then we can be economical and
2679 save only those registers that are used */
2680 if (! IFFUNC_HASFCALL(sym->type)) {
2683 /* if any registers used */
2684 if (sym->regsUsed) {
2685 /* save the registers used */
2686 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2687 if (bitVectBitValue(sym->regsUsed,i) ||
2688 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2689 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2694 /* this function has a function call cannot
2695 determines register usage so we will have the
2697 unsaverbank(0,ic,FALSE);
2701 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2703 if (options.stack10bit)
2705 pic14_emitcode ("pop", "dpx1");
2706 pic14_emitcode ("pop", "dph1");
2707 pic14_emitcode ("pop", "dpl1");
2709 pic14_emitcode ("pop", "dps");
2710 pic14_emitcode ("pop", "dpx");
2712 if (!inExcludeList("dph"))
2713 pic14_emitcode ("pop","dph");
2714 if (!inExcludeList("dpl"))
2715 pic14_emitcode ("pop","dpl");
2716 if (!inExcludeList("b"))
2717 pic14_emitcode ("pop","b");
2718 if (!inExcludeList("acc"))
2719 pic14_emitcode ("pop","acc");
2721 if (IFFUNC_ISCRITICAL(sym->type))
2722 pic14_emitcode("setb","ea");
2724 /* if debug then send end of function */
2725 /* if (options.debug && currFunc) { */
2728 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2729 FileBaseName(ic->filename),currFunc->lastLine,
2730 ic->level,ic->block);
2731 if (IS_STATIC(currFunc->etype))
2732 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2734 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2738 pic14_emitcode ("reti","");
2741 if (IFFUNC_ISCRITICAL(sym->type))
2742 pic14_emitcode("setb","ea");
2744 if (IFFUNC_CALLEESAVES(sym->type)) {
2747 /* if any registers used */
2748 if (sym->regsUsed) {
2749 /* save the registers used */
2750 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2751 if (bitVectBitValue(sym->regsUsed,i) ||
2752 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2753 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2759 /* if debug then send end of function */
2762 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2763 FileBaseName(ic->filename),currFunc->lastLine,
2764 ic->level,ic->block);
2765 if (IS_STATIC(currFunc->etype))
2766 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2768 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2772 pic14_emitcode ("return","");
2773 emitpcodeNULLop(POC_RETURN);
2775 /* Mark the end of a function */
2776 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2781 /*-----------------------------------------------------------------*/
2782 /* genRet - generate code for return statement */
2783 /*-----------------------------------------------------------------*/
2784 static void genRet (iCode *ic)
2786 int size,offset = 0 , pushed = 0;
2788 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2789 /* if we have no return value then
2790 just generate the "ret" */
2794 /* we have something to return then
2795 move the return value into place */
2796 aopOp(IC_LEFT(ic),ic,FALSE);
2797 size = AOP_SIZE(IC_LEFT(ic));
2801 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2803 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2805 pic14_emitcode("push","%s",l);
2808 l = aopGet(AOP(IC_LEFT(ic)),offset,
2810 if (strcmp(fReturn[offset],l)) {
2811 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2812 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
2813 pic14_emitcode("movlw","%s",l);
2815 pic14_emitcode("movf","%s,w",l);
2817 pic14_emitcode("movwf","%s",fReturn[offset]);
2826 if (strcmp(fReturn[pushed],"a"))
2827 pic14_emitcode("pop",fReturn[pushed]);
2829 pic14_emitcode("pop","acc");
2832 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2835 /* generate a jump to the return label
2836 if the next is not the return statement */
2837 if (!(ic->next && ic->next->op == LABEL &&
2838 IC_LABEL(ic->next) == returnLabel)) {
2840 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2841 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2846 /*-----------------------------------------------------------------*/
2847 /* genLabel - generates a label */
2848 /*-----------------------------------------------------------------*/
2849 static void genLabel (iCode *ic)
2851 /* special case never generate */
2852 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2853 if (IC_LABEL(ic) == entryLabel)
2856 emitpLabel(IC_LABEL(ic)->key);
2857 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2860 /*-----------------------------------------------------------------*/
2861 /* genGoto - generates a goto */
2862 /*-----------------------------------------------------------------*/
2864 static void genGoto (iCode *ic)
2866 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2867 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2870 /*-----------------------------------------------------------------*/
2871 /* findLabelBackwards: walks back through the iCode chain looking */
2872 /* for the given label. Returns number of iCode instructions */
2873 /* between that label and given ic. */
2874 /* Returns zero if label not found. */
2875 /*-----------------------------------------------------------------*/
2877 static int findLabelBackwards(iCode *ic, int key)
2881 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2887 if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2889 /* printf("findLabelBackwards = %d\n", count); */
2898 /*-----------------------------------------------------------------*/
2899 /* genMultbits :- multiplication of bits */
2900 /*-----------------------------------------------------------------*/
2901 static void genMultbits (operand *left,
2905 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2907 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2908 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2909 pic14_outBitC(result);
2913 /*-----------------------------------------------------------------*/
2914 /* genMultOneByte : 8 bit multiplication & division */
2915 /*-----------------------------------------------------------------*/
2916 static void genMultOneByte (operand *left,
2920 sym_link *opetype = operandType(result);
2925 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2926 /* (if two literals, the value is computed before) */
2927 /* if one literal, literal on the right */
2928 if (AOP_TYPE(left) == AOP_LIT){
2934 size = AOP_SIZE(result);
2935 /* signed or unsigned */
2936 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2937 l = aopGet(AOP(left),0,FALSE,FALSE);
2939 pic14_emitcode("mul","ab");
2940 /* if result size = 1, mul signed = mul unsigned */
2941 aopPut(AOP(result),"a",0);
2943 if (SPEC_USIGN(opetype)){
2944 aopPut(AOP(result),"b",1);
2946 /* for filling the MSBs */
2947 pic14_emitcode("clr","a");
2950 pic14_emitcode("mov","a,b");
2952 /* adjust the MSB if left or right neg */
2954 /* if one literal */
2955 if (AOP_TYPE(right) == AOP_LIT){
2956 /* AND literal negative */
2957 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2958 /* adjust MSB (c==0 after mul) */
2959 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2963 lbl = newiTempLabel(NULL);
2964 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2965 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2966 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2967 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2968 lbl = newiTempLabel(NULL);
2969 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2970 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2971 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2974 lbl = newiTempLabel(NULL);
2975 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2976 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2977 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2978 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2979 lbl = newiTempLabel(NULL);
2980 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2981 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2982 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2984 aopPut(AOP(result),"a",1);
2987 pic14_emitcode("rlc","a");
2988 pic14_emitcode("subb","a,acc");
2995 aopPut(AOP(result),"a",offset++);
2999 /*-----------------------------------------------------------------*/
3000 /* genMult - generates code for multiplication */
3001 /*-----------------------------------------------------------------*/
3002 static void genMult (iCode *ic)
3004 operand *left = IC_LEFT(ic);
3005 operand *right = IC_RIGHT(ic);
3006 operand *result= IC_RESULT(ic);
3008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3009 /* assign the amsops */
3010 aopOp (left,ic,FALSE);
3011 aopOp (right,ic,FALSE);
3012 aopOp (result,ic,TRUE);
3014 /* special cases first */
3016 if (AOP_TYPE(left) == AOP_CRY &&
3017 AOP_TYPE(right)== AOP_CRY) {
3018 genMultbits(left,right,result);
3022 /* if both are of size == 1 */
3023 if (AOP_SIZE(left) == 1 &&
3024 AOP_SIZE(right) == 1 ) {
3025 genMultOneByte(left,right,result);
3029 /* should have been converted to function call */
3033 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3034 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3035 freeAsmop(result,NULL,ic,TRUE);
3038 /*-----------------------------------------------------------------*/
3039 /* genDivbits :- division of bits */
3040 /*-----------------------------------------------------------------*/
3041 static void genDivbits (operand *left,
3048 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3049 /* the result must be bit */
3050 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3051 l = aopGet(AOP(left),0,FALSE,FALSE);
3055 pic14_emitcode("div","ab");
3056 pic14_emitcode("rrc","a");
3057 aopPut(AOP(result),"c",0);
3060 /*-----------------------------------------------------------------*/
3061 /* genDivOneByte : 8 bit division */
3062 /*-----------------------------------------------------------------*/
3063 static void genDivOneByte (operand *left,
3067 sym_link *opetype = operandType(result);
3072 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3073 size = AOP_SIZE(result) - 1;
3075 /* signed or unsigned */
3076 if (SPEC_USIGN(opetype)) {
3077 /* unsigned is easy */
3078 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3079 l = aopGet(AOP(left),0,FALSE,FALSE);
3081 pic14_emitcode("div","ab");
3082 aopPut(AOP(result),"a",0);
3084 aopPut(AOP(result),zero,offset++);
3088 /* signed is a little bit more difficult */
3090 /* save the signs of the operands */
3091 l = aopGet(AOP(left),0,FALSE,FALSE);
3093 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3094 pic14_emitcode("push","acc"); /* save it on the stack */
3096 /* now sign adjust for both left & right */
3097 l = aopGet(AOP(right),0,FALSE,FALSE);
3099 lbl = newiTempLabel(NULL);
3100 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3101 pic14_emitcode("cpl","a");
3102 pic14_emitcode("inc","a");
3103 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3104 pic14_emitcode("mov","b,a");
3106 /* sign adjust left side */
3107 l = aopGet(AOP(left),0,FALSE,FALSE);
3110 lbl = newiTempLabel(NULL);
3111 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3112 pic14_emitcode("cpl","a");
3113 pic14_emitcode("inc","a");
3114 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3116 /* now the division */
3117 pic14_emitcode("div","ab");
3118 /* we are interested in the lower order
3120 pic14_emitcode("mov","b,a");
3121 lbl = newiTempLabel(NULL);
3122 pic14_emitcode("pop","acc");
3123 /* if there was an over flow we don't
3124 adjust the sign of the result */
3125 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3126 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3128 pic14_emitcode("clr","a");
3129 pic14_emitcode("subb","a,b");
3130 pic14_emitcode("mov","b,a");
3131 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3133 /* now we are done */
3134 aopPut(AOP(result),"b",0);
3136 pic14_emitcode("mov","c,b.7");
3137 pic14_emitcode("subb","a,acc");
3140 aopPut(AOP(result),"a",offset++);
3144 /*-----------------------------------------------------------------*/
3145 /* genDiv - generates code for division */
3146 /*-----------------------------------------------------------------*/
3147 static void genDiv (iCode *ic)
3149 operand *left = IC_LEFT(ic);
3150 operand *right = IC_RIGHT(ic);
3151 operand *result= IC_RESULT(ic);
3153 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3154 /* assign the amsops */
3155 aopOp (left,ic,FALSE);
3156 aopOp (right,ic,FALSE);
3157 aopOp (result,ic,TRUE);
3159 /* special cases first */
3161 if (AOP_TYPE(left) == AOP_CRY &&
3162 AOP_TYPE(right)== AOP_CRY) {
3163 genDivbits(left,right,result);
3167 /* if both are of size == 1 */
3168 if (AOP_SIZE(left) == 1 &&
3169 AOP_SIZE(right) == 1 ) {
3170 genDivOneByte(left,right,result);
3174 /* should have been converted to function call */
3177 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3178 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3179 freeAsmop(result,NULL,ic,TRUE);
3182 /*-----------------------------------------------------------------*/
3183 /* genModbits :- modulus of bits */
3184 /*-----------------------------------------------------------------*/
3185 static void genModbits (operand *left,
3192 /* the result must be bit */
3193 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3194 l = aopGet(AOP(left),0,FALSE,FALSE);
3198 pic14_emitcode("div","ab");
3199 pic14_emitcode("mov","a,b");
3200 pic14_emitcode("rrc","a");
3201 aopPut(AOP(result),"c",0);
3204 /*-----------------------------------------------------------------*/
3205 /* genModOneByte : 8 bit modulus */
3206 /*-----------------------------------------------------------------*/
3207 static void genModOneByte (operand *left,
3211 sym_link *opetype = operandType(result);
3215 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3216 /* signed or unsigned */
3217 if (SPEC_USIGN(opetype)) {
3218 /* unsigned is easy */
3219 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3220 l = aopGet(AOP(left),0,FALSE,FALSE);
3222 pic14_emitcode("div","ab");
3223 aopPut(AOP(result),"b",0);
3227 /* signed is a little bit more difficult */
3229 /* save the signs of the operands */
3230 l = aopGet(AOP(left),0,FALSE,FALSE);
3233 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3234 pic14_emitcode("push","acc"); /* save it on the stack */
3236 /* now sign adjust for both left & right */
3237 l = aopGet(AOP(right),0,FALSE,FALSE);
3240 lbl = newiTempLabel(NULL);
3241 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3242 pic14_emitcode("cpl","a");
3243 pic14_emitcode("inc","a");
3244 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3245 pic14_emitcode("mov","b,a");
3247 /* sign adjust left side */
3248 l = aopGet(AOP(left),0,FALSE,FALSE);
3251 lbl = newiTempLabel(NULL);
3252 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3253 pic14_emitcode("cpl","a");
3254 pic14_emitcode("inc","a");
3255 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3257 /* now the multiplication */
3258 pic14_emitcode("div","ab");
3259 /* we are interested in the lower order
3261 lbl = newiTempLabel(NULL);
3262 pic14_emitcode("pop","acc");
3263 /* if there was an over flow we don't
3264 adjust the sign of the result */
3265 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3266 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3268 pic14_emitcode("clr","a");
3269 pic14_emitcode("subb","a,b");
3270 pic14_emitcode("mov","b,a");
3271 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3273 /* now we are done */
3274 aopPut(AOP(result),"b",0);
3278 /*-----------------------------------------------------------------*/
3279 /* genMod - generates code for division */
3280 /*-----------------------------------------------------------------*/
3281 static void genMod (iCode *ic)
3283 operand *left = IC_LEFT(ic);
3284 operand *right = IC_RIGHT(ic);
3285 operand *result= IC_RESULT(ic);
3287 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3288 /* assign the amsops */
3289 aopOp (left,ic,FALSE);
3290 aopOp (right,ic,FALSE);
3291 aopOp (result,ic,TRUE);
3293 /* special cases first */
3295 if (AOP_TYPE(left) == AOP_CRY &&
3296 AOP_TYPE(right)== AOP_CRY) {
3297 genModbits(left,right,result);
3301 /* if both are of size == 1 */
3302 if (AOP_SIZE(left) == 1 &&
3303 AOP_SIZE(right) == 1 ) {
3304 genModOneByte(left,right,result);
3308 /* should have been converted to function call */
3312 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3313 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3314 freeAsmop(result,NULL,ic,TRUE);
3317 /*-----------------------------------------------------------------*/
3318 /* genIfxJump :- will create a jump depending on the ifx */
3319 /*-----------------------------------------------------------------*/
3321 note: May need to add parameter to indicate when a variable is in bit space.
3323 static void genIfxJump (iCode *ic, char *jval)
3326 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3327 /* if true label then we jump if condition
3329 if ( IC_TRUE(ic) ) {
3331 if(strcmp(jval,"a") == 0)
3333 else if (strcmp(jval,"c") == 0)
3336 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3337 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3340 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3341 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3345 /* false label is present */
3346 if(strcmp(jval,"a") == 0)
3348 else if (strcmp(jval,"c") == 0)
3351 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3352 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3355 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3356 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3361 /* mark the icode as generated */
3365 /*-----------------------------------------------------------------*/
3367 /*-----------------------------------------------------------------*/
3368 static void genSkip(iCode *ifx,int status_bit)
3373 if ( IC_TRUE(ifx) ) {
3374 switch(status_bit) {
3389 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3390 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3394 switch(status_bit) {
3408 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3409 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3415 /*-----------------------------------------------------------------*/
3417 /*-----------------------------------------------------------------*/
3418 static void genSkipc(resolvedIfx *rifx)
3428 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3429 rifx->generated = 1;
3432 /*-----------------------------------------------------------------*/
3434 /*-----------------------------------------------------------------*/
3435 static void genSkipz(iCode *ifx, int condition)
3446 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3448 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3451 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3453 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3456 /*-----------------------------------------------------------------*/
3457 /* genCmp :- greater or less than comparison */
3458 /*-----------------------------------------------------------------*/
3459 static void genCmp (operand *left,operand *right,
3460 operand *result, iCode *ifx, int sign)
3462 int size, offset = 0 ;
3463 unsigned long lit = 0L,i = 0;
3466 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3468 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3469 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3472 resolveIfx(&rIfx,ifx);
3474 /* if left & right are bit variables */
3475 if (AOP_TYPE(left) == AOP_CRY &&
3476 AOP_TYPE(right) == AOP_CRY ) {
3477 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3478 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3480 /* subtract right from left if at the
3481 end the carry flag is set then we know that
3482 left is greater than right */
3483 size = max(AOP_SIZE(left),AOP_SIZE(right));
3485 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3486 if((size == 1) && !sign &&
3487 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3488 symbol *lbl = newiTempLabel(NULL);
3489 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3490 aopGet(AOP(left),offset,FALSE,FALSE),
3491 aopGet(AOP(right),offset,FALSE,FALSE),
3493 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3496 if(AOP_TYPE(right) == AOP_LIT) {
3497 symbol *lbl = newiTempLabel(NULL);
3499 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3501 DEBUGpic14_emitcode(";right lit","lit = %d,sign=%d",lit,sign);
3504 i = (lit >> (size*8)) & 0xff;
3507 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3509 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3511 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3514 emitpcode(POC_MOVLW, popGetLit(i));
3515 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3517 i = (lit >> (size*8)) & 0xff;
3518 emitpcode(POC_MOVLW, popGetLit(i));
3520 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3524 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3525 //genSkipc(ifx,0,1); //IC_TRUE(ifx) == NULL);
3528 emitpLabel(lbl->key);
3535 if(AOP_TYPE(left) == AOP_LIT) {
3536 //symbol *lbl = newiTempLabel(NULL);
3538 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3540 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3545 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3547 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3550 if(IC_TRUE(ifx) != NULL)
3551 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3553 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3556 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3557 emitpcode(POC_SUBFW, popGet(AOP(right),0,FALSE,FALSE));
3558 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3559 rIfx.condition ^= 1;
3560 genSkipc(&rIfx);// if(ifx) genSkipc(ifx,1,1);//IC_TRUE(ifx)!=NULL);
3564 i = (lit >> (size*8)) & 0xff;
3568 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3570 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3573 if(IC_TRUE(ifx) != NULL)
3574 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3576 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3580 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3581 emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3583 i = (lit >> (size*8)) & 0xff;
3584 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3586 emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3588 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3589 genSkipc(&rIfx);// if(ifx) genSkipc(ifx,0,1); //IC_TRUE(ifx) == NULL);
3594 emitpLabel(lbl->key);
3596 if(ifx) ifx->generated = 1;
3602 DEBUGpic14_emitcode(";sign","%d",sign);
3604 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3605 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3607 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3608 emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3613 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3615 emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3616 emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE));
3619 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3621 pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3622 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3630 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3631 pic14_outBitC(result);
3633 /* if the result is used in the next
3634 ifx conditional branch then generate
3635 code a little differently */
3637 genIfxJump (ifx,"c");
3639 pic14_outBitC(result);
3640 /* leave the result in acc */
3645 /*-----------------------------------------------------------------*/
3646 /* genCmpGt :- greater than comparison */
3647 /*-----------------------------------------------------------------*/
3648 static void genCmpGt (iCode *ic, iCode *ifx)
3650 operand *left, *right, *result;
3651 sym_link *letype , *retype;
3654 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3656 right= IC_RIGHT(ic);
3657 result = IC_RESULT(ic);
3659 letype = getSpec(operandType(left));
3660 retype =getSpec(operandType(right));
3661 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3662 /* assign the amsops */
3663 aopOp (left,ic,FALSE);
3664 aopOp (right,ic,FALSE);
3665 aopOp (result,ic,TRUE);
3667 genCmp(right, left, result, ifx, sign);
3669 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3670 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3671 freeAsmop(result,NULL,ic,TRUE);
3674 /*-----------------------------------------------------------------*/
3675 /* genCmpLt - less than comparisons */
3676 /*-----------------------------------------------------------------*/
3677 static void genCmpLt (iCode *ic, iCode *ifx)
3679 operand *left, *right, *result;
3680 sym_link *letype , *retype;
3683 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3685 right= IC_RIGHT(ic);
3686 result = IC_RESULT(ic);
3688 letype = getSpec(operandType(left));
3689 retype =getSpec(operandType(right));
3690 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3692 /* assign the amsops */
3693 aopOp (left,ic,FALSE);
3694 aopOp (right,ic,FALSE);
3695 aopOp (result,ic,TRUE);
3697 genCmp(left, right, result, ifx, sign);
3699 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3700 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3701 freeAsmop(result,NULL,ic,TRUE);
3704 /*-----------------------------------------------------------------*/
3705 /* genc16bit2lit - compare a 16 bit value to a literal */
3706 /*-----------------------------------------------------------------*/
3707 static void genc16bit2lit(operand *op, int lit, int offset)
3711 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
3712 if( (lit&0xff) == 0)
3717 switch( BYTEofLONG(lit,i)) {
3719 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3722 emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3725 emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3728 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3729 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
3734 switch( BYTEofLONG(lit,i)) {
3736 emitpcode(POC_IORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3740 emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3744 emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3747 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
3749 emitpcode(POC_XORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3755 /*-----------------------------------------------------------------*/
3756 /* gencjneshort - compare and jump if not equal */
3757 /*-----------------------------------------------------------------*/
3758 static void gencjne(operand *left, operand *right, iCode *ifx)
3760 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3766 unsigned long lit = 0L;
3767 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3768 DEBUGpic14_emitcode ("; ","left %s=%s, right %s=%s, size = %d",
3769 AopType(AOP_TYPE(left)),
3770 aopGet(AOP(left),0,TRUE,FALSE),
3771 AopType(AOP_TYPE(right)),
3772 aopGet(AOP(right),0,FALSE,FALSE),
3775 resolveIfx(&rIfx,ifx);
3776 lbl = newiTempLabel(NULL);
3779 /* if the left side is a literal or
3780 if the right is in a pointer register and left
3782 if ((AOP_TYPE(left) == AOP_LIT) ||
3783 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3788 if(AOP_TYPE(right) == AOP_LIT)
3789 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3791 /* if the right side is a literal then anything goes */
3792 if (AOP_TYPE(right) == AOP_LIT &&
3793 AOP_TYPE(left) != AOP_DIR ) {
3796 genc16bit2lit(left, lit, 0);
3798 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3799 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3804 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3805 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3806 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3807 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3809 emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3810 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3814 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3815 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3823 /* if the right side is in a register or in direct space or
3824 if the left is a pointer register & right is not */
3825 else if (AOP_TYPE(right) == AOP_REG ||
3826 AOP_TYPE(right) == AOP_DIR ||
3827 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3828 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3831 genc16bit2lit(left, lit, 0);
3833 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3834 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3839 if((AOP_TYPE(left) == AOP_DIR) &&
3840 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
3842 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3843 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3845 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
3847 switch (lit & 0xff) {
3849 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3852 emitpcode(POC_DECFSZ,popGet(AOP(left),offset,FALSE,FALSE));
3853 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3857 emitpcode(POC_INCFSZ,popGet(AOP(left),offset,FALSE,FALSE));
3858 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3862 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3863 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3868 emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3869 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3872 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
3877 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3886 } else if(AOP_TYPE(right) == AOP_REG &&
3887 AOP_TYPE(left) != AOP_DIR){
3890 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3891 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3892 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
3897 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3902 /* right is a pointer reg need both a & b */
3904 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3906 pic14_emitcode("mov","b,%s",l);
3907 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3908 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
3912 emitpLabel(lbl->key);
3919 /*-----------------------------------------------------------------*/
3920 /* gencjne - compare and jump if not equal */
3921 /*-----------------------------------------------------------------*/
3922 static void gencjne(operand *left, operand *right, iCode *ifx)
3924 symbol *tlbl = newiTempLabel(NULL);
3926 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3927 gencjneshort(left, right, lbl);
3929 pic14_emitcode("mov","a,%s",one);
3930 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3931 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3932 pic14_emitcode("clr","a");
3933 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
3935 emitpLabel(lbl->key);
3936 emitpLabel(tlbl->key);
3941 /*-----------------------------------------------------------------*/
3942 /* genCmpEq - generates code for equal to */
3943 /*-----------------------------------------------------------------*/
3944 static void genCmpEq (iCode *ic, iCode *ifx)
3946 operand *left, *right, *result;
3947 unsigned long lit = 0L;
3950 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3953 DEBUGpic14_emitcode ("; ifx is non-null","");
3955 DEBUGpic14_emitcode ("; ifx is null","");
3957 aopOp((left=IC_LEFT(ic)),ic,FALSE);
3958 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
3959 aopOp((result=IC_RESULT(ic)),ic,TRUE);
3962 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
3963 AopType(AOP_TYPE(IC_RESULT(ic))),
3964 AopType(AOP_TYPE(IC_LEFT(ic))),
3965 AopType(AOP_TYPE(IC_RIGHT(ic))));
3967 size = max(AOP_SIZE(left),AOP_SIZE(right));
3968 DEBUGpic14_emitcode ("; ","result %s=%s, left %s=%s, right %s=%s, size = %d",
3969 AopType(AOP_TYPE(result)),
3970 aopGet(AOP(result),0,TRUE,FALSE),
3971 AopType(AOP_TYPE(left)),
3972 aopGet(AOP(left),0,TRUE,FALSE),
3973 AopType(AOP_TYPE(right)),
3974 aopGet(AOP(right),0,FALSE,FALSE),
3978 /* if literal, literal on the right or
3979 if the right is in a pointer register and left
3981 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
3982 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3983 operand *t = IC_RIGHT(ic);
3984 IC_RIGHT(ic) = IC_LEFT(ic);
3988 if(ifx && !AOP_SIZE(result)){
3990 /* if they are both bit variables */
3991 if (AOP_TYPE(left) == AOP_CRY &&
3992 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3993 if(AOP_TYPE(right) == AOP_LIT){
3994 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3996 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3997 pic14_emitcode("cpl","c");
3998 } else if(lit == 1L) {
3999 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4001 pic14_emitcode("clr","c");
4003 /* AOP_TYPE(right) == AOP_CRY */
4005 symbol *lbl = newiTempLabel(NULL);
4006 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4007 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4008 pic14_emitcode("cpl","c");
4009 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4011 /* if true label then we jump if condition
4013 tlbl = newiTempLabel(NULL);
4014 if ( IC_TRUE(ifx) ) {
4015 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4016 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4018 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4019 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4021 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4024 /* They're not both bit variables. Is the right a literal? */
4025 if(AOP_TYPE(right) == AOP_LIT) {
4026 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4032 switch(lit & 0xff) {
4034 if ( IC_TRUE(ifx) ) {
4035 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
4037 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4039 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4040 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4044 if ( IC_TRUE(ifx) ) {
4045 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
4047 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4049 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4050 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4054 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4056 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4061 /* end of size == 1 */
4065 genc16bit2lit(left,lit,offset);
4068 /* end of size == 2 */
4073 emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
4074 emitpcode(POC_IORFW,popGet(AOP(left),1,FALSE,FALSE));
4075 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
4076 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
4080 /* search for patterns that can be optimized */
4082 genc16bit2lit(left,lit,0);
4085 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4087 genc16bit2lit(left,lit,2);
4089 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
4090 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
4103 } else if(AOP_TYPE(right) == AOP_CRY ) {
4104 /* we know the left is not a bit, but that the right is */
4105 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4106 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4107 popGet(AOP(right),offset,FALSE,FALSE));
4108 emitpcode(POC_XORLW,popGetLit(1));
4110 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4112 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4113 AOP(right)->aopu.aop_dir,
4114 AOP(right)->aopu.aop_dir);
4116 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4117 AOP(right)->aopu.aop_dir,
4118 AOP(right)->aopu.aop_dir);
4120 pic14_emitcode("xorlw","1");
4122 /* if the two are equal, then W will be 0 and the Z bit is set
4123 * we could test Z now, or go ahead and check the high order bytes if
4124 * the variable we're comparing is larger than a byte. */
4127 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
4128 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4130 if ( IC_TRUE(ifx) ) {
4132 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4133 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4136 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4137 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4141 /* They're both variables that are larger than bits */
4144 tlbl = newiTempLabel(NULL);
4147 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4148 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
4150 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4151 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4153 if ( IC_TRUE(ifx) ) {
4156 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4157 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4160 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4161 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4165 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4166 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4170 if(s>1 && IC_TRUE(ifx)) {
4171 emitpLabel(tlbl->key);
4172 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4176 /* mark the icode as generated */
4181 /* if they are both bit variables */
4182 if (AOP_TYPE(left) == AOP_CRY &&
4183 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4184 if(AOP_TYPE(right) == AOP_LIT){
4185 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4187 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4188 pic14_emitcode("cpl","c");
4189 } else if(lit == 1L) {
4190 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4192 pic14_emitcode("clr","c");
4194 /* AOP_TYPE(right) == AOP_CRY */
4196 symbol *lbl = newiTempLabel(NULL);
4197 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4198 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4199 pic14_emitcode("cpl","c");
4200 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4203 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4204 pic14_outBitC(result);
4208 genIfxJump (ifx,"c");
4211 /* if the result is used in an arithmetic operation
4212 then put the result in place */
4213 pic14_outBitC(result);
4216 gencjne(left,right,ifx);
4219 gencjne(left,right,newiTempLabel(NULL));
4221 if(IC_TRUE(ifx)->key)
4222 gencjne(left,right,IC_TRUE(ifx)->key);
4224 gencjne(left,right,IC_FALSE(ifx)->key);
4228 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4229 aopPut(AOP(result),"a",0);
4234 genIfxJump (ifx,"a");
4238 /* if the result is used in an arithmetic operation
4239 then put the result in place */
4240 if (AOP_TYPE(result) != AOP_CRY)
4241 pic14_outAcc(result);
4242 /* leave the result in acc */
4246 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4247 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4248 freeAsmop(result,NULL,ic,TRUE);
4251 /*-----------------------------------------------------------------*/
4252 /* ifxForOp - returns the icode containing the ifx for operand */
4253 /*-----------------------------------------------------------------*/
4254 static iCode *ifxForOp ( operand *op, iCode *ic )
4256 /* if true symbol then needs to be assigned */
4257 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4258 if (IS_TRUE_SYMOP(op))
4261 /* if this has register type condition and
4262 the next instruction is ifx with the same operand
4263 and live to of the operand is upto the ifx only then */
4265 ic->next->op == IFX &&
4266 IC_COND(ic->next)->key == op->key &&
4267 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4271 ic->next->op == IFX &&
4272 IC_COND(ic->next)->key == op->key) {
4273 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4277 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4279 ic->next->op == IFX)
4280 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4283 ic->next->op == IFX &&
4284 IC_COND(ic->next)->key == op->key) {
4285 DEBUGpic14_emitcode ("; "," key is okay");
4286 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4287 OP_SYMBOL(op)->liveTo,
4294 /*-----------------------------------------------------------------*/
4295 /* genAndOp - for && operation */
4296 /*-----------------------------------------------------------------*/
4297 static void genAndOp (iCode *ic)
4299 operand *left,*right, *result;
4302 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4303 /* note here that && operations that are in an
4304 if statement are taken away by backPatchLabels
4305 only those used in arthmetic operations remain */
4306 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4307 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4308 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4310 /* if both are bit variables */
4311 if (AOP_TYPE(left) == AOP_CRY &&
4312 AOP_TYPE(right) == AOP_CRY ) {
4313 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4314 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4315 pic14_outBitC(result);
4317 tlbl = newiTempLabel(NULL);
4318 pic14_toBoolean(left);
4319 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4320 pic14_toBoolean(right);
4321 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4322 pic14_outBitAcc(result);
4325 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4326 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4327 freeAsmop(result,NULL,ic,TRUE);
4331 /*-----------------------------------------------------------------*/
4332 /* genOrOp - for || operation */
4333 /*-----------------------------------------------------------------*/
4336 modified this code, but it doesn't appear to ever get called
4339 static void genOrOp (iCode *ic)
4341 operand *left,*right, *result;
4344 /* note here that || operations that are in an
4345 if statement are taken away by backPatchLabels
4346 only those used in arthmetic operations remain */
4347 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4348 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4349 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4350 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4352 /* if both are bit variables */
4353 if (AOP_TYPE(left) == AOP_CRY &&
4354 AOP_TYPE(right) == AOP_CRY ) {
4355 pic14_emitcode("clrc","");
4356 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4357 AOP(left)->aopu.aop_dir,
4358 AOP(left)->aopu.aop_dir);
4359 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4360 AOP(right)->aopu.aop_dir,
4361 AOP(right)->aopu.aop_dir);
4362 pic14_emitcode("setc","");
4365 tlbl = newiTempLabel(NULL);
4366 pic14_toBoolean(left);
4368 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4369 pic14_toBoolean(right);
4370 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4372 pic14_outBitAcc(result);
4375 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4376 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4377 freeAsmop(result,NULL,ic,TRUE);
4380 /*-----------------------------------------------------------------*/
4381 /* isLiteralBit - test if lit == 2^n */
4382 /*-----------------------------------------------------------------*/
4383 static int isLiteralBit(unsigned long lit)
4385 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4386 0x100L,0x200L,0x400L,0x800L,
4387 0x1000L,0x2000L,0x4000L,0x8000L,
4388 0x10000L,0x20000L,0x40000L,0x80000L,
4389 0x100000L,0x200000L,0x400000L,0x800000L,
4390 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4391 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4394 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4395 for(idx = 0; idx < 32; idx++)
4401 /*-----------------------------------------------------------------*/
4402 /* continueIfTrue - */
4403 /*-----------------------------------------------------------------*/
4404 static void continueIfTrue (iCode *ic)
4406 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4408 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4412 /*-----------------------------------------------------------------*/
4414 /*-----------------------------------------------------------------*/
4415 static void jumpIfTrue (iCode *ic)
4417 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4419 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4423 /*-----------------------------------------------------------------*/
4424 /* jmpTrueOrFalse - */
4425 /*-----------------------------------------------------------------*/
4426 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4428 // ugly but optimized by peephole
4429 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4431 symbol *nlbl = newiTempLabel(NULL);
4432 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4433 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4434 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4435 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4438 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4439 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4444 /*-----------------------------------------------------------------*/
4445 /* genAnd - code for and */
4446 /*-----------------------------------------------------------------*/
4447 static void genAnd (iCode *ic, iCode *ifx)
4449 operand *left, *right, *result;
4451 unsigned long lit = 0L;
4455 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4456 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4457 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4458 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4461 pic14_emitcode("","; Type res[%d] = l[%d]&r[%d]",
4463 AOP_TYPE(left), AOP_TYPE(right));
4464 pic14_emitcode("","; Size res[%d] = l[%d]&r[%d]",
4466 AOP_SIZE(left), AOP_SIZE(right));
4469 /* if left is a literal & right is not then exchange them */
4470 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4471 AOP_NEEDSACC(left)) {
4472 operand *tmp = right ;
4477 /* if result = right then exchange them */
4478 if(pic14_sameRegs(AOP(result),AOP(right))){
4479 operand *tmp = right ;
4484 /* if right is bit then exchange them */
4485 if (AOP_TYPE(right) == AOP_CRY &&
4486 AOP_TYPE(left) != AOP_CRY){
4487 operand *tmp = right ;
4491 if(AOP_TYPE(right) == AOP_LIT)
4492 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4494 size = AOP_SIZE(result);
4497 // result = bit & yy;
4498 if (AOP_TYPE(left) == AOP_CRY){
4499 // c = bit & literal;
4500 if(AOP_TYPE(right) == AOP_LIT){
4502 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4505 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4508 if(size && (AOP_TYPE(result) == AOP_CRY)){
4509 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4512 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4516 pic14_emitcode("clr","c");
4519 if (AOP_TYPE(right) == AOP_CRY){
4521 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4522 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4525 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4527 pic14_emitcode("rrc","a");
4528 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4534 pic14_outBitC(result);
4536 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4537 genIfxJump(ifx, "c");
4541 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4542 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4543 if((AOP_TYPE(right) == AOP_LIT) &&
4544 (AOP_TYPE(result) == AOP_CRY) &&
4545 (AOP_TYPE(left) != AOP_CRY)){
4546 int posbit = isLiteralBit(lit);
4550 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4553 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4558 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4559 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4561 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4562 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4569 symbol *tlbl = newiTempLabel(NULL);
4570 int sizel = AOP_SIZE(left);
4572 pic14_emitcode("setb","c");
4574 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4575 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4577 if((posbit = isLiteralBit(bytelit)) != 0)
4578 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4580 if(bytelit != 0x0FFL)
4581 pic14_emitcode("anl","a,%s",
4582 aopGet(AOP(right),offset,FALSE,TRUE));
4583 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4588 // bit = left & literal
4590 pic14_emitcode("clr","c");
4591 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4593 // if(left & literal)
4596 jmpTrueOrFalse(ifx, tlbl);
4600 pic14_outBitC(result);
4604 /* if left is same as result */
4605 if(pic14_sameRegs(AOP(result),AOP(left))){
4607 for(;size--; offset++,lit>>=8) {
4608 if(AOP_TYPE(right) == AOP_LIT){
4609 switch(lit & 0xff) {
4611 /* and'ing with 0 has clears the result */
4612 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4613 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4616 /* and'ing with 0xff is a nop when the result and left are the same */
4621 int p = my_powof2( (~lit) & 0xff );
4623 /* only one bit is set in the literal, so use a bcf instruction */
4624 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4625 //emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
4626 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4629 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4630 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4631 if(know_W != (lit&0xff))
4632 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4634 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
4639 if (AOP_TYPE(left) == AOP_ACC) {
4640 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4642 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4643 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,FALSE));
4650 // left & result in different registers
4651 if(AOP_TYPE(result) == AOP_CRY){
4653 // if(size), result in bit
4654 // if(!size && ifx), conditional oper: if(left & right)
4655 symbol *tlbl = newiTempLabel(NULL);
4656 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4658 pic14_emitcode("setb","c");
4660 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4661 pic14_emitcode("anl","a,%s",
4662 aopGet(AOP(left),offset,FALSE,FALSE));
4663 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4668 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4669 pic14_outBitC(result);
4671 jmpTrueOrFalse(ifx, tlbl);
4673 for(;(size--);offset++) {
4675 // result = left & right
4676 if(AOP_TYPE(right) == AOP_LIT){
4677 int t = (lit >> (offset*8)) & 0x0FFL;
4680 pic14_emitcode("clrf","%s",
4681 aopGet(AOP(result),offset,FALSE,FALSE));
4682 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4685 pic14_emitcode("movf","%s,w",
4686 aopGet(AOP(left),offset,FALSE,FALSE));
4687 pic14_emitcode("movwf","%s",
4688 aopGet(AOP(result),offset,FALSE,FALSE));
4689 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4690 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4693 pic14_emitcode("movlw","0x%x",t);
4694 pic14_emitcode("andwf","%s,w",
4695 aopGet(AOP(left),offset,FALSE,FALSE));
4696 pic14_emitcode("movwf","%s",
4697 aopGet(AOP(result),offset,FALSE,FALSE));
4699 emitpcode(POC_MOVLW, popGetLit(t));
4700 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4701 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4706 if (AOP_TYPE(left) == AOP_ACC) {
4707 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4708 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4710 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4711 pic14_emitcode("andwf","%s,w",
4712 aopGet(AOP(left),offset,FALSE,FALSE));
4713 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4714 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4716 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4717 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4723 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4724 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4725 freeAsmop(result,NULL,ic,TRUE);
4728 /*-----------------------------------------------------------------*/
4729 /* genOr - code for or */
4730 /*-----------------------------------------------------------------*/
4731 static void genOr (iCode *ic, iCode *ifx)
4733 operand *left, *right, *result;
4735 unsigned long lit = 0L;
4737 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4739 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4740 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4741 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4744 /* if left is a literal & right is not then exchange them */
4745 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4746 AOP_NEEDSACC(left)) {
4747 operand *tmp = right ;
4752 /* if result = right then exchange them */
4753 if(pic14_sameRegs(AOP(result),AOP(right))){
4754 operand *tmp = right ;
4759 /* if right is bit then exchange them */
4760 if (AOP_TYPE(right) == AOP_CRY &&
4761 AOP_TYPE(left) != AOP_CRY){
4762 operand *tmp = right ;
4767 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
4768 AopType(AOP_TYPE(result)),
4769 AopType(AOP_TYPE(left)),
4770 AopType(AOP_TYPE(right)));
4772 if(AOP_TYPE(right) == AOP_LIT)
4773 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4775 size = AOP_SIZE(result);
4779 if (AOP_TYPE(left) == AOP_CRY){
4780 if(AOP_TYPE(right) == AOP_LIT){
4781 // c = bit & literal;
4783 // lit != 0 => result = 1
4784 if(AOP_TYPE(result) == AOP_CRY){
4786 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4787 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4788 // AOP(result)->aopu.aop_dir,
4789 // AOP(result)->aopu.aop_dir);
4791 continueIfTrue(ifx);
4795 // lit == 0 => result = left
4796 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4798 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4801 if (AOP_TYPE(right) == AOP_CRY){
4802 if(pic14_sameRegs(AOP(result),AOP(left))){
4804 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4805 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4806 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4808 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4809 AOP(result)->aopu.aop_dir,
4810 AOP(result)->aopu.aop_dir);
4811 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4812 AOP(right)->aopu.aop_dir,
4813 AOP(right)->aopu.aop_dir);
4814 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4815 AOP(result)->aopu.aop_dir,
4816 AOP(result)->aopu.aop_dir);
4818 if( AOP_TYPE(result) == AOP_ACC) {
4819 emitpcode(POC_MOVLW, popGetLit(0));
4820 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4821 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4822 emitpcode(POC_MOVLW, popGetLit(1));
4826 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4827 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4828 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4829 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4831 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4832 AOP(result)->aopu.aop_dir,
4833 AOP(result)->aopu.aop_dir);
4834 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4835 AOP(right)->aopu.aop_dir,
4836 AOP(right)->aopu.aop_dir);
4837 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4838 AOP(left)->aopu.aop_dir,
4839 AOP(left)->aopu.aop_dir);
4840 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4841 AOP(result)->aopu.aop_dir,
4842 AOP(result)->aopu.aop_dir);
4847 symbol *tlbl = newiTempLabel(NULL);
4848 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4851 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4852 if( AOP_TYPE(right) == AOP_ACC) {
4853 emitpcode(POC_IORLW, popGetLit(0));
4855 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4856 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4861 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4862 pic14_emitcode(";XXX setb","c");
4863 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4864 AOP(left)->aopu.aop_dir,tlbl->key+100);
4865 pic14_toBoolean(right);
4866 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4867 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4868 jmpTrueOrFalse(ifx, tlbl);
4872 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4879 pic14_outBitC(result);
4881 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4882 genIfxJump(ifx, "c");
4886 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4887 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4888 if((AOP_TYPE(right) == AOP_LIT) &&
4889 (AOP_TYPE(result) == AOP_CRY) &&
4890 (AOP_TYPE(left) != AOP_CRY)){
4892 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4895 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4897 continueIfTrue(ifx);
4900 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4901 // lit = 0, result = boolean(left)
4903 pic14_emitcode(";XXX setb","c");
4904 pic14_toBoolean(right);
4906 symbol *tlbl = newiTempLabel(NULL);
4907 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4909 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4911 genIfxJump (ifx,"a");
4915 pic14_outBitC(result);
4919 /* if left is same as result */
4920 if(pic14_sameRegs(AOP(result),AOP(left))){
4922 for(;size--; offset++,lit>>=8) {
4923 if(AOP_TYPE(right) == AOP_LIT){
4924 if((lit & 0xff) == 0)
4925 /* or'ing with 0 has no effect */
4928 int p = my_powof2(lit & 0xff);
4930 /* only one bit is set in the literal, so use a bsf instruction */
4932 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4934 if(know_W != (lit & 0xff))
4935 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4936 know_W = lit & 0xff;
4937 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4942 if (AOP_TYPE(left) == AOP_ACC) {
4943 emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE));
4944 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4946 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4947 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4949 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4950 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4956 // left & result in different registers
4957 if(AOP_TYPE(result) == AOP_CRY){
4959 // if(size), result in bit
4960 // if(!size && ifx), conditional oper: if(left | right)
4961 symbol *tlbl = newiTempLabel(NULL);
4962 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4963 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4967 pic14_emitcode(";XXX setb","c");
4969 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4970 pic14_emitcode(";XXX orl","a,%s",
4971 aopGet(AOP(left),offset,FALSE,FALSE));
4972 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4977 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4978 pic14_outBitC(result);
4980 jmpTrueOrFalse(ifx, tlbl);
4981 } else for(;(size--);offset++){
4983 // result = left & right
4984 if(AOP_TYPE(right) == AOP_LIT){
4985 int t = (lit >> (offset*8)) & 0x0FFL;
4988 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
4989 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4991 pic14_emitcode("movf","%s,w",
4992 aopGet(AOP(left),offset,FALSE,FALSE));
4993 pic14_emitcode("movwf","%s",
4994 aopGet(AOP(result),offset,FALSE,FALSE));
4997 emitpcode(POC_MOVLW, popGetLit(t));
4998 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4999 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
5001 pic14_emitcode("movlw","0x%x",t);
5002 pic14_emitcode("iorwf","%s,w",
5003 aopGet(AOP(left),offset,FALSE,FALSE));
5004 pic14_emitcode("movwf","%s",
5005 aopGet(AOP(result),offset,FALSE,FALSE));
5011 // faster than result <- left, anl result,right
5012 // and better if result is SFR
5013 if (AOP_TYPE(left) == AOP_ACC) {
5014 emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE));
5015 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5017 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
5018 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
5020 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5021 pic14_emitcode("iorwf","%s,w",
5022 aopGet(AOP(left),offset,FALSE,FALSE));
5024 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
5025 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5030 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5031 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5032 freeAsmop(result,NULL,ic,TRUE);
5035 /*-----------------------------------------------------------------*/
5036 /* genXor - code for xclusive or */
5037 /*-----------------------------------------------------------------*/
5038 static void genXor (iCode *ic, iCode *ifx)
5040 operand *left, *right, *result;
5042 unsigned long lit = 0L;
5044 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5046 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5047 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5048 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5050 /* if left is a literal & right is not ||
5051 if left needs acc & right does not */
5052 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5053 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5054 operand *tmp = right ;
5059 /* if result = right then exchange them */
5060 if(pic14_sameRegs(AOP(result),AOP(right))){
5061 operand *tmp = right ;
5066 /* if right is bit then exchange them */
5067 if (AOP_TYPE(right) == AOP_CRY &&
5068 AOP_TYPE(left) != AOP_CRY){
5069 operand *tmp = right ;
5073 if(AOP_TYPE(right) == AOP_LIT)
5074 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5076 size = AOP_SIZE(result);
5080 if (AOP_TYPE(left) == AOP_CRY){
5081 if(AOP_TYPE(right) == AOP_LIT){
5082 // c = bit & literal;
5084 // lit>>1 != 0 => result = 1
5085 if(AOP_TYPE(result) == AOP_CRY){
5087 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
5089 continueIfTrue(ifx);
5092 pic14_emitcode("setb","c");
5096 // lit == 0, result = left
5097 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5099 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5101 // lit == 1, result = not(left)
5102 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5103 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5106 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5107 pic14_emitcode("cpl","c");
5114 symbol *tlbl = newiTempLabel(NULL);
5115 if (AOP_TYPE(right) == AOP_CRY){
5117 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5120 int sizer = AOP_SIZE(right);
5122 // if val>>1 != 0, result = 1
5123 pic14_emitcode("setb","c");
5125 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5127 // test the msb of the lsb
5128 pic14_emitcode("anl","a,#0xfe");
5129 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5133 pic14_emitcode("rrc","a");
5135 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5136 pic14_emitcode("cpl","c");
5137 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5142 pic14_outBitC(result);
5144 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5145 genIfxJump(ifx, "c");
5149 if(pic14_sameRegs(AOP(result),AOP(left))){
5150 /* if left is same as result */
5151 for(;size--; offset++) {
5152 if(AOP_TYPE(right) == AOP_LIT){
5153 int t = (lit >> (offset*8)) & 0x0FFL;
5157 if (IS_AOP_PREG(left)) {
5158 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5159 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5160 aopPut(AOP(result),"a",offset);
5162 emitpcode(POC_MOVLW, popGetLit(t));
5163 emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
5164 pic14_emitcode("xrl","%s,%s",
5165 aopGet(AOP(left),offset,FALSE,TRUE),
5166 aopGet(AOP(right),offset,FALSE,FALSE));
5169 if (AOP_TYPE(left) == AOP_ACC)
5170 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5172 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5173 if (IS_AOP_PREG(left)) {
5174 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5175 aopPut(AOP(result),"a",offset);
5177 pic14_emitcode("xrl","%s,a",
5178 aopGet(AOP(left),offset,FALSE,TRUE));
5183 // left & result in different registers
5184 if(AOP_TYPE(result) == AOP_CRY){
5186 // if(size), result in bit
5187 // if(!size && ifx), conditional oper: if(left ^ right)
5188 symbol *tlbl = newiTempLabel(NULL);
5189 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5191 pic14_emitcode("setb","c");
5193 if((AOP_TYPE(right) == AOP_LIT) &&
5194 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5195 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5197 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5198 pic14_emitcode("xrl","a,%s",
5199 aopGet(AOP(left),offset,FALSE,FALSE));
5201 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5206 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5207 pic14_outBitC(result);
5209 jmpTrueOrFalse(ifx, tlbl);
5210 } else for(;(size--);offset++){
5212 // result = left & right
5213 if(AOP_TYPE(right) == AOP_LIT){
5214 int t = (lit >> (offset*8)) & 0x0FFL;
5217 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
5218 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5219 pic14_emitcode("movf","%s,w",
5220 aopGet(AOP(left),offset,FALSE,FALSE));
5221 pic14_emitcode("movwf","%s",
5222 aopGet(AOP(result),offset,FALSE,FALSE));
5225 emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
5226 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5227 pic14_emitcode("comf","%s,w",
5228 aopGet(AOP(left),offset,FALSE,FALSE));
5229 pic14_emitcode("movwf","%s",
5230 aopGet(AOP(result),offset,FALSE,FALSE));
5233 emitpcode(POC_MOVLW, popGetLit(t));
5234 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5235 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5236 pic14_emitcode("movlw","0x%x",t);
5237 pic14_emitcode("xorwf","%s,w",
5238 aopGet(AOP(left),offset,FALSE,FALSE));
5239 pic14_emitcode("movwf","%s",
5240 aopGet(AOP(result),offset,FALSE,FALSE));
5246 // faster than result <- left, anl result,right
5247 // and better if result is SFR
5248 if (AOP_TYPE(left) == AOP_ACC) {
5249 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
5250 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5252 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
5253 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5254 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5255 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5257 if ( AOP_TYPE(result) != AOP_ACC){
5258 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5259 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5265 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5266 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5267 freeAsmop(result,NULL,ic,TRUE);
5270 /*-----------------------------------------------------------------*/
5271 /* genInline - write the inline code out */
5272 /*-----------------------------------------------------------------*/
5273 static void genInline (iCode *ic)
5275 char *buffer, *bp, *bp1;
5277 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5279 _G.inLine += (!options.asmpeep);
5281 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5282 strcpy(buffer,IC_INLINE(ic));
5284 /* emit each line as a code */
5288 pic14_emitcode(bp1,"");
5295 pic14_emitcode(bp1,"");
5302 pic14_emitcode(bp1,"");
5303 /* pic14_emitcode("",buffer); */
5304 _G.inLine -= (!options.asmpeep);
5307 /*-----------------------------------------------------------------*/
5308 /* genRRC - rotate right with carry */
5309 /*-----------------------------------------------------------------*/
5310 static void genRRC (iCode *ic)
5312 operand *left , *result ;
5313 int size, offset = 0;
5316 /* rotate right with carry */
5318 result=IC_RESULT(ic);
5319 aopOp (left,ic,FALSE);
5320 aopOp (result,ic,FALSE);
5322 /* move it to the result */
5323 size = AOP_SIZE(result);
5327 l = aopGet(AOP(left),offset,FALSE,FALSE);
5329 pic14_emitcode("rrc","a");
5330 if (AOP_SIZE(result) > 1)
5331 aopPut(AOP(result),"a",offset--);
5333 /* now we need to put the carry into the
5334 highest order byte of the result */
5335 if (AOP_SIZE(result) > 1) {
5336 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5339 pic14_emitcode("mov","acc.7,c");
5340 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5341 freeAsmop(left,NULL,ic,TRUE);
5342 freeAsmop(result,NULL,ic,TRUE);
5345 /*-----------------------------------------------------------------*/
5346 /* genRLC - generate code for rotate left with carry */
5347 /*-----------------------------------------------------------------*/
5348 static void genRLC (iCode *ic)
5350 operand *left , *result ;
5351 int size, offset = 0;
5354 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5355 /* rotate right with carry */
5357 result=IC_RESULT(ic);
5358 aopOp (left,ic,FALSE);
5359 aopOp (result,ic,FALSE);
5361 /* move it to the result */
5362 size = AOP_SIZE(result);
5365 l = aopGet(AOP(left),offset,FALSE,FALSE);
5367 pic14_emitcode("add","a,acc");
5368 if (AOP_SIZE(result) > 1)
5369 aopPut(AOP(result),"a",offset++);
5371 l = aopGet(AOP(left),offset,FALSE,FALSE);
5373 pic14_emitcode("rlc","a");
5374 if (AOP_SIZE(result) > 1)
5375 aopPut(AOP(result),"a",offset++);
5378 /* now we need to put the carry into the
5379 highest order byte of the result */
5380 if (AOP_SIZE(result) > 1) {
5381 l = aopGet(AOP(result),0,FALSE,FALSE);
5384 pic14_emitcode("mov","acc.0,c");
5385 aopPut(AOP(result),"a",0);
5386 freeAsmop(left,NULL,ic,TRUE);
5387 freeAsmop(result,NULL,ic,TRUE);
5390 /*-----------------------------------------------------------------*/
5391 /* genGetHbit - generates code get highest order bit */
5392 /*-----------------------------------------------------------------*/
5393 static void genGetHbit (iCode *ic)
5395 operand *left, *result;
5397 result=IC_RESULT(ic);
5398 aopOp (left,ic,FALSE);
5399 aopOp (result,ic,FALSE);
5401 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5402 /* get the highest order byte into a */
5403 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5404 if(AOP_TYPE(result) == AOP_CRY){
5405 pic14_emitcode("rlc","a");
5406 pic14_outBitC(result);
5409 pic14_emitcode("rl","a");
5410 pic14_emitcode("anl","a,#0x01");
5411 pic14_outAcc(result);
5415 freeAsmop(left,NULL,ic,TRUE);
5416 freeAsmop(result,NULL,ic,TRUE);
5419 /*-----------------------------------------------------------------*/
5420 /* AccRol - rotate left accumulator by known count */
5421 /*-----------------------------------------------------------------*/
5422 static void AccRol (int shCount)
5424 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5425 shCount &= 0x0007; // shCount : 0..7
5430 pic14_emitcode("rl","a");
5433 pic14_emitcode("rl","a");
5434 pic14_emitcode("rl","a");
5437 pic14_emitcode("swap","a");
5438 pic14_emitcode("rr","a");
5441 pic14_emitcode("swap","a");
5444 pic14_emitcode("swap","a");
5445 pic14_emitcode("rl","a");
5448 pic14_emitcode("rr","a");
5449 pic14_emitcode("rr","a");
5452 pic14_emitcode("rr","a");
5457 /*-----------------------------------------------------------------*/
5458 /* AccLsh - left shift accumulator by known count */
5459 /*-----------------------------------------------------------------*/
5460 static void AccLsh (int shCount)
5462 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5465 pic14_emitcode("add","a,acc");
5468 pic14_emitcode("add","a,acc");
5469 pic14_emitcode("add","a,acc");
5471 /* rotate left accumulator */
5473 /* and kill the lower order bits */
5474 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5479 /*-----------------------------------------------------------------*/
5480 /* AccRsh - right shift accumulator by known count */
5481 /*-----------------------------------------------------------------*/
5482 static void AccRsh (int shCount)
5484 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5488 pic14_emitcode("rrc","a");
5490 /* rotate right accumulator */
5491 AccRol(8 - shCount);
5492 /* and kill the higher order bits */
5493 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5499 /*-----------------------------------------------------------------*/
5500 /* AccSRsh - signed right shift accumulator by known count */
5501 /*-----------------------------------------------------------------*/
5502 static void AccSRsh (int shCount)
5505 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5508 pic14_emitcode("mov","c,acc.7");
5509 pic14_emitcode("rrc","a");
5510 } else if(shCount == 2){
5511 pic14_emitcode("mov","c,acc.7");
5512 pic14_emitcode("rrc","a");
5513 pic14_emitcode("mov","c,acc.7");
5514 pic14_emitcode("rrc","a");
5516 tlbl = newiTempLabel(NULL);
5517 /* rotate right accumulator */
5518 AccRol(8 - shCount);
5519 /* and kill the higher order bits */
5520 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5521 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5522 pic14_emitcode("orl","a,#0x%02x",
5523 (unsigned char)~SRMask[shCount]);
5524 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5529 /*-----------------------------------------------------------------*/
5530 /* shiftR1Left2Result - shift right one byte from left to result */
5531 /*-----------------------------------------------------------------*/
5532 static void shiftR1Left2ResultSigned (operand *left, int offl,
5533 operand *result, int offr,
5538 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5540 same = (left == result) || (AOP(left) == AOP(result));
5544 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5546 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5548 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5549 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5559 /*-----------------------------------------------------------------*/
5560 /* shiftR1Left2Result - shift right one byte from left to result */
5561 /*-----------------------------------------------------------------*/
5562 static void shiftR1Left2Result (operand *left, int offl,
5563 operand *result, int offr,
5564 int shCount, int sign)
5568 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5570 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5572 /* Copy the msb into the carry if signed. */
5574 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5584 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5586 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5587 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5593 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5595 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5596 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5599 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5604 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5606 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5607 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5610 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5611 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5612 emitpcode(POC_ANDLW, popGetLit(0x1f));
5613 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5617 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5618 emitpcode(POC_ANDLW, popGetLit(0x0f));
5619 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5623 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5624 emitpcode(POC_ANDLW, popGetLit(0x0f));
5625 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5627 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5632 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5633 emitpcode(POC_ANDLW, popGetLit(0x80));
5634 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5635 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5636 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5641 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5642 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5643 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5654 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5656 /* shift right accumulator */
5661 aopPut(AOP(result),"a",offr);
5665 /*-----------------------------------------------------------------*/
5666 /* shiftL1Left2Result - shift left one byte from left to result */
5667 /*-----------------------------------------------------------------*/
5668 static void shiftL1Left2Result (operand *left, int offl,
5669 operand *result, int offr, int shCount)
5674 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5676 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5677 DEBUGpic14_emitcode ("; ***","same = %d",same);
5678 // l = aopGet(AOP(left),offl,FALSE,FALSE);
5680 /* shift left accumulator */
5681 //AccLsh(shCount); // don't comment out just yet...
5682 // aopPut(AOP(result),"a",offr);
5686 /* Shift left 1 bit position */
5687 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5689 emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
5691 emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
5692 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5696 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5697 emitpcode(POC_ANDLW,popGetLit(0x7e));
5698 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5699 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5702 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5703 emitpcode(POC_ANDLW,popGetLit(0x3e));
5704 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5705 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5706 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5709 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5710 emitpcode(POC_ANDLW, popGetLit(0xf0));
5711 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5714 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5715 emitpcode(POC_ANDLW, popGetLit(0xf0));
5716 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5717 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5720 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5721 emitpcode(POC_ANDLW, popGetLit(0x30));
5722 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5723 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5724 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5727 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5728 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5729 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5733 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5738 /*-----------------------------------------------------------------*/
5739 /* movLeft2Result - move byte from left to result */
5740 /*-----------------------------------------------------------------*/
5741 static void movLeft2Result (operand *left, int offl,
5742 operand *result, int offr, int sign)
5745 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5746 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5747 l = aopGet(AOP(left),offl,FALSE,FALSE);
5749 if (*l == '@' && (IS_AOP_PREG(result))) {
5750 pic14_emitcode("mov","a,%s",l);
5751 aopPut(AOP(result),"a",offr);
5754 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5755 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5757 //aopPut(AOP(result),l,offr);
5759 /* MSB sign in acc.7 ! */
5760 if(pic14_getDataSize(left) == offl+1){
5761 pic14_emitcode("mov","a,%s",l);
5762 aopPut(AOP(result),"a",offr);
5769 /*-----------------------------------------------------------------*/
5770 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5771 /*-----------------------------------------------------------------*/
5772 static void AccAXRrl1 (char *x)
5774 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5775 pic14_emitcode("rrc","a");
5776 pic14_emitcode("xch","a,%s", x);
5777 pic14_emitcode("rrc","a");
5778 pic14_emitcode("xch","a,%s", x);
5781 /*-----------------------------------------------------------------*/
5782 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5783 /*-----------------------------------------------------------------*/
5784 static void AccAXLrl1 (char *x)
5786 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5787 pic14_emitcode("xch","a,%s",x);
5788 pic14_emitcode("rlc","a");
5789 pic14_emitcode("xch","a,%s",x);
5790 pic14_emitcode("rlc","a");
5793 /*-----------------------------------------------------------------*/
5794 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5795 /*-----------------------------------------------------------------*/
5796 static void AccAXLsh1 (char *x)
5798 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5799 pic14_emitcode("xch","a,%s",x);
5800 pic14_emitcode("add","a,acc");
5801 pic14_emitcode("xch","a,%s",x);
5802 pic14_emitcode("rlc","a");
5806 /*-----------------------------------------------------------------*/
5807 /* AccAXLsh - left shift a:x by known count (0..7) */
5808 /*-----------------------------------------------------------------*/
5809 static void AccAXLsh (char *x, int shCount)
5811 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5824 case 5 : // AAAAABBB:CCCCCDDD
5825 AccRol(shCount); // BBBAAAAA:CCCCCDDD
5826 pic14_emitcode("anl","a,#0x%02x",
5827 SLMask[shCount]); // BBB00000:CCCCCDDD
5828 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
5829 AccRol(shCount); // DDDCCCCC:BBB00000
5830 pic14_emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
5831 pic14_emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
5832 pic14_emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
5833 pic14_emitcode("anl","a,#0x%02x",
5834 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5835 pic14_emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
5836 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
5838 case 6 : // AAAAAABB:CCCCCCDD
5839 pic14_emitcode("anl","a,#0x%02x",
5840 SRMask[shCount]); // 000000BB:CCCCCCDD
5841 pic14_emitcode("mov","c,acc.0"); // c = B
5842 pic14_emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
5843 AccAXRrl1(x); // BCCCCCCD:D000000B
5844 AccAXRrl1(x); // BBCCCCCC:DD000000
5846 case 7 : // a:x <<= 7
5847 pic14_emitcode("anl","a,#0x%02x",
5848 SRMask[shCount]); // 0000000B:CCCCCCCD
5849 pic14_emitcode("mov","c,acc.0"); // c = B
5850 pic14_emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
5851 AccAXRrl1(x); // BCCCCCCC:D0000000
5859 /*-----------------------------------------------------------------*/
5860 /* AccAXRsh - right shift a:x known count (0..7) */
5861 /*-----------------------------------------------------------------*/
5862 static void AccAXRsh (char *x, int shCount)
5864 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5870 AccAXRrl1(x); // 0->a:x
5874 AccAXRrl1(x); // 0->a:x
5876 AccAXRrl1(x); // 0->a:x
5880 case 5 : // AAAAABBB:CCCCCDDD = a:x
5881 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5882 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5883 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5884 pic14_emitcode("anl","a,#0x%02x",
5885 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5886 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5887 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5888 pic14_emitcode("anl","a,#0x%02x",
5889 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5890 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5891 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5892 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5894 case 6 : // AABBBBBB:CCDDDDDD
5895 pic14_emitcode("mov","c,acc.7");
5896 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5897 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5898 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5899 pic14_emitcode("anl","a,#0x%02x",
5900 SRMask[shCount]); // 000000AA:BBBBBBCC
5902 case 7 : // ABBBBBBB:CDDDDDDD
5903 pic14_emitcode("mov","c,acc.7"); // c = A
5904 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5905 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5906 pic14_emitcode("anl","a,#0x%02x",
5907 SRMask[shCount]); // 0000000A:BBBBBBBC
5914 /*-----------------------------------------------------------------*/
5915 /* AccAXRshS - right shift signed a:x known count (0..7) */
5916 /*-----------------------------------------------------------------*/
5917 static void AccAXRshS (char *x, int shCount)
5920 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5925 pic14_emitcode("mov","c,acc.7");
5926 AccAXRrl1(x); // s->a:x
5929 pic14_emitcode("mov","c,acc.7");
5930 AccAXRrl1(x); // s->a:x
5931 pic14_emitcode("mov","c,acc.7");
5932 AccAXRrl1(x); // s->a:x
5936 case 5 : // AAAAABBB:CCCCCDDD = a:x
5937 tlbl = newiTempLabel(NULL);
5938 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
5939 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5940 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5941 pic14_emitcode("anl","a,#0x%02x",
5942 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5943 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5944 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5945 pic14_emitcode("anl","a,#0x%02x",
5946 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5947 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5948 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5949 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
5950 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5951 pic14_emitcode("orl","a,#0x%02x",
5952 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5953 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5954 break; // SSSSAAAA:BBBCCCCC
5955 case 6 : // AABBBBBB:CCDDDDDD
5956 tlbl = newiTempLabel(NULL);
5957 pic14_emitcode("mov","c,acc.7");
5958 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5959 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5960 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5961 pic14_emitcode("anl","a,#0x%02x",
5962 SRMask[shCount]); // 000000AA:BBBBBBCC
5963 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5964 pic14_emitcode("orl","a,#0x%02x",
5965 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
5966 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5968 case 7 : // ABBBBBBB:CDDDDDDD
5969 tlbl = newiTempLabel(NULL);
5970 pic14_emitcode("mov","c,acc.7"); // c = A
5971 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5972 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5973 pic14_emitcode("anl","a,#0x%02x",
5974 SRMask[shCount]); // 0000000A:BBBBBBBC
5975 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5976 pic14_emitcode("orl","a,#0x%02x",
5977 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
5978 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5985 /*-----------------------------------------------------------------*/
5986 /* shiftL2Left2Result - shift left two bytes from left to result */
5987 /*-----------------------------------------------------------------*/
5988 static void shiftL2Left2Result (operand *left, int offl,
5989 operand *result, int offr, int shCount)
5993 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5995 if(pic14_sameRegs(AOP(result), AOP(left))) {
6003 emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
6004 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
6005 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6009 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6010 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6016 emitpcode(POC_MOVLW, popGetLit(0x0f));
6017 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6018 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6019 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6020 emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
6021 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6022 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6024 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6025 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6029 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6030 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6031 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6032 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6033 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6034 emitpcode(POC_ANDLW,popGetLit(0xc0));
6035 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6036 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6037 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6038 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6041 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6042 emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
6043 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6044 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6045 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6055 /* note, use a mov/add for the shift since the mov has a
6056 chance of getting optimized out */
6057 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
6058 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6059 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6060 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6061 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6065 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6066 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6072 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6073 emitpcode(POC_ANDLW, popGetLit(0xF0));
6074 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6075 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
6076 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6077 emitpcode(POC_ANDLW, popGetLit(0xF0));
6078 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6079 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6083 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6084 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6088 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6089 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6090 emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
6091 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6093 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6094 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6095 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6096 emitpcode(POC_ANDLW,popGetLit(0xc0));
6097 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6098 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6099 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6100 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6103 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6104 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6105 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6106 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6107 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6112 /*-----------------------------------------------------------------*/
6113 /* shiftR2Left2Result - shift right two bytes from left to result */
6114 /*-----------------------------------------------------------------*/
6115 static void shiftR2Left2Result (operand *left, int offl,
6116 operand *result, int offr,
6117 int shCount, int sign)
6121 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6122 same = pic14_sameRegs(AOP(result), AOP(left));
6124 if(same && ((offl + MSB16) == offr)){
6126 /* don't crash result[offr] */
6127 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6128 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6130 movLeft2Result(left,offl, result, offr, 0);
6131 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6133 /* a:x >> shCount (x = lsb(result))*/
6135 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6137 //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6147 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6148 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6151 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6152 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6153 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6154 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6159 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6160 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6167 emitpcode(POC_MOVLW, popGetLit(0xf0));
6168 emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
6169 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6171 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6172 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6173 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6174 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6176 emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
6177 emitpcode(POC_ANDLW, popGetLit(0x0f));
6178 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6180 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6181 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6182 emitpcode(POC_ANDLW, popGetLit(0xf0));
6183 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6184 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6188 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6189 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6197 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6198 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6200 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6201 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6202 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6203 emitpcode(POC_ANDLW,popGetLit(0x03));
6204 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6205 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6206 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6207 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6209 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6210 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6211 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
6212 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6213 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6214 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6215 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6216 emitpcode(POC_ANDLW,popGetLit(0x03));
6217 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6222 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6223 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6224 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6225 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6226 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6231 /*-----------------------------------------------------------------*/
6232 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6233 /*-----------------------------------------------------------------*/
6234 static void shiftLLeftOrResult (operand *left, int offl,
6235 operand *result, int offr, int shCount)
6237 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6238 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6239 /* shift left accumulator */
6241 /* or with result */
6242 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6243 /* back to result */
6244 aopPut(AOP(result),"a",offr);
6247 /*-----------------------------------------------------------------*/
6248 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6249 /*-----------------------------------------------------------------*/
6250 static void shiftRLeftOrResult (operand *left, int offl,
6251 operand *result, int offr, int shCount)
6253 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6254 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6255 /* shift right accumulator */
6257 /* or with result */
6258 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6259 /* back to result */
6260 aopPut(AOP(result),"a",offr);
6263 /*-----------------------------------------------------------------*/
6264 /* genlshOne - left shift a one byte quantity by known count */
6265 /*-----------------------------------------------------------------*/
6266 static void genlshOne (operand *result, operand *left, int shCount)
6268 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6269 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6272 /*-----------------------------------------------------------------*/
6273 /* genlshTwo - left shift two bytes by known amount != 0 */
6274 /*-----------------------------------------------------------------*/
6275 static void genlshTwo (operand *result,operand *left, int shCount)
6279 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6280 size = pic14_getDataSize(result);
6282 /* if shCount >= 8 */
6288 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6290 movLeft2Result(left, LSB, result, MSB16, 0);
6292 emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6295 /* 1 <= shCount <= 7 */
6298 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6300 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6304 /*-----------------------------------------------------------------*/
6305 /* shiftLLong - shift left one long from left to result */
6306 /* offl = LSB or MSB16 */
6307 /*-----------------------------------------------------------------*/
6308 static void shiftLLong (operand *left, operand *result, int offr )
6311 int size = AOP_SIZE(result);
6313 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6314 if(size >= LSB+offr){
6315 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6317 pic14_emitcode("add","a,acc");
6318 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6319 size >= MSB16+offr && offr != LSB )
6320 pic14_emitcode("xch","a,%s",
6321 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6323 aopPut(AOP(result),"a",LSB+offr);
6326 if(size >= MSB16+offr){
6327 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6328 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6331 pic14_emitcode("rlc","a");
6332 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6333 size >= MSB24+offr && offr != LSB)
6334 pic14_emitcode("xch","a,%s",
6335 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6337 aopPut(AOP(result),"a",MSB16+offr);
6340 if(size >= MSB24+offr){
6341 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6342 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6345 pic14_emitcode("rlc","a");
6346 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6347 size >= MSB32+offr && offr != LSB )
6348 pic14_emitcode("xch","a,%s",
6349 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6351 aopPut(AOP(result),"a",MSB24+offr);
6354 if(size > MSB32+offr){
6355 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6356 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6359 pic14_emitcode("rlc","a");
6360 aopPut(AOP(result),"a",MSB32+offr);
6363 aopPut(AOP(result),zero,LSB);
6366 /*-----------------------------------------------------------------*/
6367 /* genlshFour - shift four byte by a known amount != 0 */
6368 /*-----------------------------------------------------------------*/
6369 static void genlshFour (operand *result, operand *left, int shCount)
6373 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6374 size = AOP_SIZE(result);
6376 /* if shifting more that 3 bytes */
6377 if (shCount >= 24 ) {
6380 /* lowest order of left goes to the highest
6381 order of the destination */
6382 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6384 movLeft2Result(left, LSB, result, MSB32, 0);
6385 aopPut(AOP(result),zero,LSB);
6386 aopPut(AOP(result),zero,MSB16);
6387 aopPut(AOP(result),zero,MSB32);
6391 /* more than two bytes */
6392 else if ( shCount >= 16 ) {
6393 /* lower order two bytes goes to higher order two bytes */
6395 /* if some more remaining */
6397 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6399 movLeft2Result(left, MSB16, result, MSB32, 0);
6400 movLeft2Result(left, LSB, result, MSB24, 0);
6402 aopPut(AOP(result),zero,MSB16);
6403 aopPut(AOP(result),zero,LSB);
6407 /* if more than 1 byte */
6408 else if ( shCount >= 8 ) {
6409 /* lower order three bytes goes to higher order three bytes */
6413 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6415 movLeft2Result(left, LSB, result, MSB16, 0);
6417 else{ /* size = 4 */
6419 movLeft2Result(left, MSB24, result, MSB32, 0);
6420 movLeft2Result(left, MSB16, result, MSB24, 0);
6421 movLeft2Result(left, LSB, result, MSB16, 0);
6422 aopPut(AOP(result),zero,LSB);
6424 else if(shCount == 1)
6425 shiftLLong(left, result, MSB16);
6427 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6428 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6429 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6430 aopPut(AOP(result),zero,LSB);
6435 /* 1 <= shCount <= 7 */
6436 else if(shCount <= 2){
6437 shiftLLong(left, result, LSB);
6439 shiftLLong(result, result, LSB);
6441 /* 3 <= shCount <= 7, optimize */
6443 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6444 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6445 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6449 /*-----------------------------------------------------------------*/
6450 /* genLeftShiftLiteral - left shifting by known count */
6451 /*-----------------------------------------------------------------*/
6452 static void genLeftShiftLiteral (operand *left,
6457 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6460 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6461 freeAsmop(right,NULL,ic,TRUE);
6463 aopOp(left,ic,FALSE);
6464 aopOp(result,ic,FALSE);
6466 size = getSize(operandType(result));
6469 pic14_emitcode("; shift left ","result %d, left %d",size,
6473 /* I suppose that the left size >= result size */
6476 movLeft2Result(left, size, result, size, 0);
6480 else if(shCount >= (size * 8))
6482 aopPut(AOP(result),zero,size);
6486 genlshOne (result,left,shCount);
6491 genlshTwo (result,left,shCount);
6495 genlshFour (result,left,shCount);
6499 freeAsmop(left,NULL,ic,TRUE);
6500 freeAsmop(result,NULL,ic,TRUE);
6503 /*-----------------------------------------------------------------*/
6504 /* genLeftShift - generates code for left shifting */
6505 /*-----------------------------------------------------------------*/
6506 static void genLeftShift (iCode *ic)
6508 operand *left,*right, *result;
6511 symbol *tlbl , *tlbl1;
6513 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6515 right = IC_RIGHT(ic);
6517 result = IC_RESULT(ic);
6519 aopOp(right,ic,FALSE);
6521 /* if the shift count is known then do it
6522 as efficiently as possible */
6523 if (AOP_TYPE(right) == AOP_LIT) {
6524 genLeftShiftLiteral (left,right,result,ic);
6528 /* shift count is unknown then we have to form
6529 a loop get the loop count in B : Note: we take
6530 only the lower order byte since shifting
6531 more that 32 bits make no sense anyway, ( the
6532 largest size of an object can be only 32 bits ) */
6535 aopOp(left,ic,FALSE);
6536 aopOp(result,ic,FALSE);
6538 /* now move the left to the result if they are not the
6540 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6541 AOP_SIZE(result) > 1) {
6543 size = AOP_SIZE(result);
6546 l = aopGet(AOP(left),offset,FALSE,TRUE);
6547 if (*l == '@' && (IS_AOP_PREG(result))) {
6549 pic14_emitcode("mov","a,%s",l);
6550 aopPut(AOP(result),"a",offset);
6552 aopPut(AOP(result),l,offset);
6557 size = AOP_SIZE(result);
6559 /* if it is only one byte then */
6561 if(optimized_for_speed) {
6562 emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6563 emitpcode(POC_ANDLW, popGetLit(0xf0));
6564 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6565 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6566 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6567 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6568 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6569 emitpcode(POC_RLFW, popGet(AOP(result),0,FALSE,FALSE));
6570 emitpcode(POC_ANDLW, popGetLit(0xfe));
6571 emitpcode(POC_ADDFW, popGet(AOP(result),0,FALSE,FALSE));
6572 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6573 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6576 tlbl = newiTempLabel(NULL);
6577 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6578 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6579 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6582 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6583 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6584 emitpLabel(tlbl->key);
6585 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6586 emitpcode(POC_ADDLW, popGetLit(1));
6588 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6594 tlbl = newiTempLabel(NULL);
6596 tlbl1 = newiTempLabel(NULL);
6598 reAdjustPreg(AOP(result));
6600 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6601 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6602 l = aopGet(AOP(result),offset,FALSE,FALSE);
6604 pic14_emitcode("add","a,acc");
6605 aopPut(AOP(result),"a",offset++);
6607 l = aopGet(AOP(result),offset,FALSE,FALSE);
6609 pic14_emitcode("rlc","a");
6610 aopPut(AOP(result),"a",offset++);
6612 reAdjustPreg(AOP(result));
6614 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6615 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6617 freeAsmop (right,NULL,ic,TRUE);
6618 freeAsmop(left,NULL,ic,TRUE);
6619 freeAsmop(result,NULL,ic,TRUE);
6622 /*-----------------------------------------------------------------*/
6623 /* genrshOne - right shift a one byte quantity by known count */
6624 /*-----------------------------------------------------------------*/
6625 static void genrshOne (operand *result, operand *left,
6626 int shCount, int sign)
6628 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6629 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6632 /*-----------------------------------------------------------------*/
6633 /* genrshTwo - right shift two bytes by known amount != 0 */
6634 /*-----------------------------------------------------------------*/
6635 static void genrshTwo (operand *result,operand *left,
6636 int shCount, int sign)
6638 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6639 /* if shCount >= 8 */
6643 shiftR1Left2Result(left, MSB16, result, LSB,
6646 movLeft2Result(left, MSB16, result, LSB, sign);
6648 addSign(result, MSB16, sign);
6650 emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6654 /* 1 <= shCount <= 7 */
6656 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6659 /*-----------------------------------------------------------------*/
6660 /* shiftRLong - shift right one long from left to result */
6661 /* offl = LSB or MSB16 */
6662 /*-----------------------------------------------------------------*/
6663 static void shiftRLong (operand *left, int offl,
6664 operand *result, int sign)
6666 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6668 pic14_emitcode("clr","c");
6669 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6671 pic14_emitcode("mov","c,acc.7");
6672 pic14_emitcode("rrc","a");
6673 aopPut(AOP(result),"a",MSB32-offl);
6675 /* add sign of "a" */
6676 addSign(result, MSB32, sign);
6678 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6679 pic14_emitcode("rrc","a");
6680 aopPut(AOP(result),"a",MSB24-offl);
6682 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6683 pic14_emitcode("rrc","a");
6684 aopPut(AOP(result),"a",MSB16-offl);
6687 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6688 pic14_emitcode("rrc","a");
6689 aopPut(AOP(result),"a",LSB);
6693 /*-----------------------------------------------------------------*/
6694 /* genrshFour - shift four byte by a known amount != 0 */
6695 /*-----------------------------------------------------------------*/
6696 static void genrshFour (operand *result, operand *left,
6697 int shCount, int sign)
6699 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6700 /* if shifting more that 3 bytes */
6701 if(shCount >= 24 ) {
6704 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6706 movLeft2Result(left, MSB32, result, LSB, sign);
6707 addSign(result, MSB16, sign);
6709 else if(shCount >= 16){
6712 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6714 movLeft2Result(left, MSB24, result, LSB, 0);
6715 movLeft2Result(left, MSB32, result, MSB16, sign);
6717 addSign(result, MSB24, sign);
6719 else if(shCount >= 8){
6722 shiftRLong(left, MSB16, result, sign);
6723 else if(shCount == 0){
6724 movLeft2Result(left, MSB16, result, LSB, 0);
6725 movLeft2Result(left, MSB24, result, MSB16, 0);
6726 movLeft2Result(left, MSB32, result, MSB24, sign);
6727 addSign(result, MSB32, sign);
6730 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6731 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6732 /* the last shift is signed */
6733 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6734 addSign(result, MSB32, sign);
6737 else{ /* 1 <= shCount <= 7 */
6739 shiftRLong(left, LSB, result, sign);
6741 shiftRLong(result, LSB, result, sign);
6744 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6745 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6746 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6751 /*-----------------------------------------------------------------*/
6752 /* genRightShiftLiteral - right shifting by known count */
6753 /*-----------------------------------------------------------------*/
6754 static void genRightShiftLiteral (operand *left,
6760 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6763 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6764 freeAsmop(right,NULL,ic,TRUE);
6766 aopOp(left,ic,FALSE);
6767 aopOp(result,ic,FALSE);
6770 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6774 size = pic14_getDataSize(left);
6775 /* test the LEFT size !!! */
6777 /* I suppose that the left size >= result size */
6779 size = pic14_getDataSize(result);
6781 movLeft2Result(left, size, result, size, 0);
6784 else if(shCount >= (size * 8)){
6786 /* get sign in acc.7 */
6787 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6788 addSign(result, LSB, sign);
6792 genrshOne (result,left,shCount,sign);
6796 genrshTwo (result,left,shCount,sign);
6800 genrshFour (result,left,shCount,sign);
6806 freeAsmop(left,NULL,ic,TRUE);
6807 freeAsmop(result,NULL,ic,TRUE);
6811 /*-----------------------------------------------------------------*/
6812 /* genSignedRightShift - right shift of signed number */
6813 /*-----------------------------------------------------------------*/
6814 static void genSignedRightShift (iCode *ic)
6816 operand *right, *left, *result;
6819 symbol *tlbl, *tlbl1 ;
6821 /* we do it the hard way put the shift count in b
6822 and loop thru preserving the sign */
6823 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6825 right = IC_RIGHT(ic);
6827 result = IC_RESULT(ic);
6829 aopOp(right,ic,FALSE);
6832 if ( AOP_TYPE(right) == AOP_LIT) {
6833 genRightShiftLiteral (left,right,result,ic,1);
6836 /* shift count is unknown then we have to form
6837 a loop get the loop count in B : Note: we take
6838 only the lower order byte since shifting
6839 more that 32 bits make no sense anyway, ( the
6840 largest size of an object can be only 32 bits ) */
6842 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6843 pic14_emitcode("inc","b");
6844 freeAsmop (right,NULL,ic,TRUE);
6845 aopOp(left,ic,FALSE);
6846 aopOp(result,ic,FALSE);
6848 /* now move the left to the result if they are not the
6850 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6851 AOP_SIZE(result) > 1) {
6853 size = AOP_SIZE(result);
6856 l = aopGet(AOP(left),offset,FALSE,TRUE);
6857 if (*l == '@' && IS_AOP_PREG(result)) {
6859 pic14_emitcode("mov","a,%s",l);
6860 aopPut(AOP(result),"a",offset);
6862 aopPut(AOP(result),l,offset);
6867 /* mov the highest order bit to OVR */
6868 tlbl = newiTempLabel(NULL);
6869 tlbl1= newiTempLabel(NULL);
6871 size = AOP_SIZE(result);
6873 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6874 pic14_emitcode("rlc","a");
6875 pic14_emitcode("mov","ov,c");
6876 /* if it is only one byte then */
6878 l = aopGet(AOP(left),0,FALSE,FALSE);
6880 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6881 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6882 pic14_emitcode("mov","c,ov");
6883 pic14_emitcode("rrc","a");
6884 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6885 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6886 aopPut(AOP(result),"a",0);
6890 reAdjustPreg(AOP(result));
6891 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6892 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6893 pic14_emitcode("mov","c,ov");
6895 l = aopGet(AOP(result),offset,FALSE,FALSE);
6897 pic14_emitcode("rrc","a");
6898 aopPut(AOP(result),"a",offset--);
6900 reAdjustPreg(AOP(result));
6901 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6902 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6905 freeAsmop(left,NULL,ic,TRUE);
6906 freeAsmop(result,NULL,ic,TRUE);
6909 /*-----------------------------------------------------------------*/
6910 /* genRightShift - generate code for right shifting */
6911 /*-----------------------------------------------------------------*/
6912 static void genRightShift (iCode *ic)
6914 operand *right, *left, *result;
6918 symbol *tlbl, *tlbl1 ;
6920 /* if signed then we do it the hard way preserve the
6921 sign bit moving it inwards */
6922 retype = getSpec(operandType(IC_RESULT(ic)));
6923 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6925 if (!SPEC_USIGN(retype)) {
6926 genSignedRightShift (ic);
6930 /* signed & unsigned types are treated the same : i.e. the
6931 signed is NOT propagated inwards : quoting from the
6932 ANSI - standard : "for E1 >> E2, is equivalent to division
6933 by 2**E2 if unsigned or if it has a non-negative value,
6934 otherwise the result is implementation defined ", MY definition
6935 is that the sign does not get propagated */
6937 right = IC_RIGHT(ic);
6939 result = IC_RESULT(ic);
6941 aopOp(right,ic,FALSE);
6943 /* if the shift count is known then do it
6944 as efficiently as possible */
6945 if (AOP_TYPE(right) == AOP_LIT) {
6946 genRightShiftLiteral (left,right,result,ic, 0);
6950 /* shift count is unknown then we have to form
6951 a loop get the loop count in B : Note: we take
6952 only the lower order byte since shifting
6953 more that 32 bits make no sense anyway, ( the
6954 largest size of an object can be only 32 bits ) */
6956 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6957 pic14_emitcode("inc","b");
6958 aopOp(left,ic,FALSE);
6959 aopOp(result,ic,FALSE);
6961 /* now move the left to the result if they are not the
6963 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6964 AOP_SIZE(result) > 1) {
6966 size = AOP_SIZE(result);
6969 l = aopGet(AOP(left),offset,FALSE,TRUE);
6970 if (*l == '@' && IS_AOP_PREG(result)) {
6972 pic14_emitcode("mov","a,%s",l);
6973 aopPut(AOP(result),"a",offset);
6975 aopPut(AOP(result),l,offset);
6980 tlbl = newiTempLabel(NULL);
6981 tlbl1= newiTempLabel(NULL);
6982 size = AOP_SIZE(result);
6985 /* if it is only one byte then */
6988 l = aopGet(AOP(left),0,FALSE,FALSE);
6990 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6991 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6993 pic14_emitcode("rrc","a");
6994 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6995 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6996 aopPut(AOP(result),"a",0);
6998 tlbl = newiTempLabel(NULL);
6999 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7000 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
7001 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
7004 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
7005 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
7006 emitpLabel(tlbl->key);
7007 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
7008 emitpcode(POC_ADDLW, popGetLit(1));
7010 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7015 reAdjustPreg(AOP(result));
7016 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7017 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7020 l = aopGet(AOP(result),offset,FALSE,FALSE);
7022 pic14_emitcode("rrc","a");
7023 aopPut(AOP(result),"a",offset--);
7025 reAdjustPreg(AOP(result));
7027 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7028 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7031 freeAsmop(left,NULL,ic,TRUE);
7032 freeAsmop (right,NULL,ic,TRUE);
7033 freeAsmop(result,NULL,ic,TRUE);
7036 /*-----------------------------------------------------------------*/
7037 /* genUnpackBits - generates code for unpacking bits */
7038 /*-----------------------------------------------------------------*/
7039 static void genUnpackBits (operand *result, char *rname, int ptype)
7046 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7047 etype = getSpec(operandType(result));
7049 /* read the first byte */
7054 pic14_emitcode("mov","a,@%s",rname);
7058 pic14_emitcode("movx","a,@%s",rname);
7062 pic14_emitcode("movx","a,@dptr");
7066 pic14_emitcode("clr","a");
7067 pic14_emitcode("movc","a","@a+dptr");
7071 pic14_emitcode("lcall","__gptrget");
7075 /* if we have bitdisplacement then it fits */
7076 /* into this byte completely or if length is */
7077 /* less than a byte */
7078 if ((shCnt = SPEC_BSTR(etype)) ||
7079 (SPEC_BLEN(etype) <= 8)) {
7081 /* shift right acc */
7084 pic14_emitcode("anl","a,#0x%02x",
7085 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7086 aopPut(AOP(result),"a",offset);
7090 /* bit field did not fit in a byte */
7091 rlen = SPEC_BLEN(etype) - 8;
7092 aopPut(AOP(result),"a",offset++);
7099 pic14_emitcode("inc","%s",rname);
7100 pic14_emitcode("mov","a,@%s",rname);
7104 pic14_emitcode("inc","%s",rname);
7105 pic14_emitcode("movx","a,@%s",rname);
7109 pic14_emitcode("inc","dptr");
7110 pic14_emitcode("movx","a,@dptr");
7114 pic14_emitcode("clr","a");
7115 pic14_emitcode("inc","dptr");
7116 pic14_emitcode("movc","a","@a+dptr");
7120 pic14_emitcode("inc","dptr");
7121 pic14_emitcode("lcall","__gptrget");
7126 /* if we are done */
7130 aopPut(AOP(result),"a",offset++);
7135 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7136 aopPut(AOP(result),"a",offset);
7143 /*-----------------------------------------------------------------*/
7144 /* genDataPointerGet - generates code when ptr offset is known */
7145 /*-----------------------------------------------------------------*/
7146 static void genDataPointerGet (operand *left,
7150 int size , offset = 0;
7153 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7156 /* optimization - most of the time, left and result are the same
7157 * address, but different types. for the pic code, we could omit
7161 aopOp(result,ic,TRUE);
7163 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
7165 size = AOP_SIZE(result);
7168 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
7172 freeAsmop(left,NULL,ic,TRUE);
7173 freeAsmop(result,NULL,ic,TRUE);
7176 /*-----------------------------------------------------------------*/
7177 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7178 /*-----------------------------------------------------------------*/
7179 static void genNearPointerGet (operand *left,
7186 sym_link *rtype, *retype;
7187 sym_link *ltype = operandType(left);
7190 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7192 rtype = operandType(result);
7193 retype= getSpec(rtype);
7195 aopOp(left,ic,FALSE);
7197 /* if left is rematerialisable and
7198 result is not bit variable type and
7199 the left is pointer to data space i.e
7200 lower 128 bytes of space */
7201 if (AOP_TYPE(left) == AOP_IMMD &&
7202 !IS_BITVAR(retype) &&
7203 DCL_TYPE(ltype) == POINTER) {
7204 genDataPointerGet (left,result,ic);
7208 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7210 /* if the value is already in a pointer register
7211 then don't need anything more */
7212 if (!AOP_INPREG(AOP(left))) {
7213 /* otherwise get a free pointer register */
7214 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7216 preg = getFreePtr(ic,&aop,FALSE);
7217 pic14_emitcode("mov","%s,%s",
7219 aopGet(AOP(left),0,FALSE,TRUE));
7220 rname = preg->name ;
7222 rname = aopGet(AOP(left),0,FALSE,FALSE);
7224 freeAsmop(left,NULL,ic,TRUE);
7225 aopOp (result,ic,FALSE);
7227 /* if bitfield then unpack the bits */
7228 if (IS_BITVAR(retype))
7229 genUnpackBits (result,rname,POINTER);
7231 /* we have can just get the values */
7232 int size = AOP_SIZE(result);
7235 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7237 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7239 pic14_emitcode("mov","a,@%s",rname);
7240 aopPut(AOP(result),"a",offset);
7242 sprintf(buffer,"@%s",rname);
7243 aopPut(AOP(result),buffer,offset);
7247 pic14_emitcode("inc","%s",rname);
7251 /* now some housekeeping stuff */
7253 /* we had to allocate for this iCode */
7254 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7255 freeAsmop(NULL,aop,ic,TRUE);
7257 /* we did not allocate which means left
7258 already in a pointer register, then
7259 if size > 0 && this could be used again
7260 we have to point it back to where it
7262 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7263 if (AOP_SIZE(result) > 1 &&
7264 !OP_SYMBOL(left)->remat &&
7265 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7267 int size = AOP_SIZE(result) - 1;
7269 pic14_emitcode("dec","%s",rname);
7274 freeAsmop(result,NULL,ic,TRUE);
7278 /*-----------------------------------------------------------------*/
7279 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7280 /*-----------------------------------------------------------------*/
7281 static void genPagedPointerGet (operand *left,
7288 sym_link *rtype, *retype;
7290 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7292 rtype = operandType(result);
7293 retype= getSpec(rtype);
7295 aopOp(left,ic,FALSE);
7297 /* if the value is already in a pointer register
7298 then don't need anything more */
7299 if (!AOP_INPREG(AOP(left))) {
7300 /* otherwise get a free pointer register */
7302 preg = getFreePtr(ic,&aop,FALSE);
7303 pic14_emitcode("mov","%s,%s",
7305 aopGet(AOP(left),0,FALSE,TRUE));
7306 rname = preg->name ;
7308 rname = aopGet(AOP(left),0,FALSE,FALSE);
7310 freeAsmop(left,NULL,ic,TRUE);
7311 aopOp (result,ic,FALSE);
7313 /* if bitfield then unpack the bits */
7314 if (IS_BITVAR(retype))
7315 genUnpackBits (result,rname,PPOINTER);
7317 /* we have can just get the values */
7318 int size = AOP_SIZE(result);
7323 pic14_emitcode("movx","a,@%s",rname);
7324 aopPut(AOP(result),"a",offset);
7329 pic14_emitcode("inc","%s",rname);
7333 /* now some housekeeping stuff */
7335 /* we had to allocate for this iCode */
7336 freeAsmop(NULL,aop,ic,TRUE);
7338 /* we did not allocate which means left
7339 already in a pointer register, then
7340 if size > 0 && this could be used again
7341 we have to point it back to where it
7343 if (AOP_SIZE(result) > 1 &&
7344 !OP_SYMBOL(left)->remat &&
7345 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7347 int size = AOP_SIZE(result) - 1;
7349 pic14_emitcode("dec","%s",rname);
7354 freeAsmop(result,NULL,ic,TRUE);
7359 /*-----------------------------------------------------------------*/
7360 /* genFarPointerGet - gget value from far space */
7361 /*-----------------------------------------------------------------*/
7362 static void genFarPointerGet (operand *left,
7363 operand *result, iCode *ic)
7366 sym_link *retype = getSpec(operandType(result));
7368 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7370 aopOp(left,ic,FALSE);
7372 /* if the operand is already in dptr
7373 then we do nothing else we move the value to dptr */
7374 if (AOP_TYPE(left) != AOP_STR) {
7375 /* if this is remateriazable */
7376 if (AOP_TYPE(left) == AOP_IMMD)
7377 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7378 else { /* we need to get it byte by byte */
7379 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7380 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7381 if (options.model == MODEL_FLAT24)
7383 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7387 /* so dptr know contains the address */
7388 freeAsmop(left,NULL,ic,TRUE);
7389 aopOp(result,ic,FALSE);
7391 /* if bit then unpack */
7392 if (IS_BITVAR(retype))
7393 genUnpackBits(result,"dptr",FPOINTER);
7395 size = AOP_SIZE(result);
7399 pic14_emitcode("movx","a,@dptr");
7400 aopPut(AOP(result),"a",offset++);
7402 pic14_emitcode("inc","dptr");
7406 freeAsmop(result,NULL,ic,TRUE);
7409 /*-----------------------------------------------------------------*/
7410 /* pic14_emitcodePointerGet - gget value from code space */
7411 /*-----------------------------------------------------------------*/
7412 static void pic14_emitcodePointerGet (operand *left,
7413 operand *result, iCode *ic)
7416 sym_link *retype = getSpec(operandType(result));
7418 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7420 aopOp(left,ic,FALSE);
7422 /* if the operand is already in dptr
7423 then we do nothing else we move the value to dptr */
7424 if (AOP_TYPE(left) != AOP_STR) {
7425 /* if this is remateriazable */
7426 if (AOP_TYPE(left) == AOP_IMMD)
7427 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7428 else { /* we need to get it byte by byte */
7429 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7430 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7431 if (options.model == MODEL_FLAT24)
7433 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7437 /* so dptr know contains the address */
7438 freeAsmop(left,NULL,ic,TRUE);
7439 aopOp(result,ic,FALSE);
7441 /* if bit then unpack */
7442 if (IS_BITVAR(retype))
7443 genUnpackBits(result,"dptr",CPOINTER);
7445 size = AOP_SIZE(result);
7449 pic14_emitcode("clr","a");
7450 pic14_emitcode("movc","a,@a+dptr");
7451 aopPut(AOP(result),"a",offset++);
7453 pic14_emitcode("inc","dptr");
7457 freeAsmop(result,NULL,ic,TRUE);
7460 /*-----------------------------------------------------------------*/
7461 /* genGenPointerGet - gget value from generic pointer space */
7462 /*-----------------------------------------------------------------*/
7463 static void genGenPointerGet (operand *left,
7464 operand *result, iCode *ic)
7467 sym_link *retype = getSpec(operandType(result));
7469 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7470 aopOp(left,ic,FALSE);
7471 aopOp(result,ic,FALSE);
7474 DEBUGpic14_emitcode ("; ","result %s, left %s",
7475 AopType(AOP_TYPE(result)),
7476 AopType(AOP_TYPE(left)));
7478 /* if the operand is already in dptr
7479 then we do nothing else we move the value to dptr */
7480 if (AOP_TYPE(left) != AOP_STR) {
7481 /* if this is remateriazable */
7482 if (AOP_TYPE(left) == AOP_IMMD) {
7483 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7484 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7486 else { /* we need to get it byte by byte */
7488 size = AOP_SIZE(result);
7492 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7493 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7495 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7500 /* so dptr know contains the address */
7502 /* if bit then unpack */
7503 if (IS_BITVAR(retype))
7504 genUnpackBits(result,"dptr",GPOINTER);
7507 freeAsmop(left,NULL,ic,TRUE);
7508 freeAsmop(result,NULL,ic,TRUE);
7512 /*-----------------------------------------------------------------*/
7513 /* genPointerGet - generate code for pointer get */
7514 /*-----------------------------------------------------------------*/
7515 static void genPointerGet (iCode *ic)
7517 operand *left, *result ;
7518 sym_link *type, *etype;
7521 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7524 result = IC_RESULT(ic) ;
7526 /* depending on the type of pointer we need to
7527 move it to the correct pointer register */
7528 type = operandType(left);
7529 etype = getSpec(type);
7530 /* if left is of type of pointer then it is simple */
7531 if (IS_PTR(type) && !IS_FUNC(type->next))
7532 p_type = DCL_TYPE(type);
7534 /* we have to go by the storage class */
7535 p_type = PTR_TYPE(SPEC_OCLS(etype));
7537 /* if (SPEC_OCLS(etype)->codesp ) { */
7538 /* p_type = CPOINTER ; */
7541 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7542 /* p_type = FPOINTER ; */
7544 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7545 /* p_type = PPOINTER; */
7547 /* if (SPEC_OCLS(etype) == idata ) */
7548 /* p_type = IPOINTER; */
7550 /* p_type = POINTER ; */
7553 /* now that we have the pointer type we assign
7554 the pointer values */
7559 genNearPointerGet (left,result,ic);
7563 genPagedPointerGet(left,result,ic);
7567 genFarPointerGet (left,result,ic);
7571 pic14_emitcodePointerGet (left,result,ic);
7575 genGenPointerGet (left,result,ic);
7581 /*-----------------------------------------------------------------*/
7582 /* genPackBits - generates code for packed bit storage */
7583 /*-----------------------------------------------------------------*/
7584 static void genPackBits (sym_link *etype ,
7586 char *rname, int p_type)
7594 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7595 blen = SPEC_BLEN(etype);
7596 bstr = SPEC_BSTR(etype);
7598 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7601 /* if the bit lenth is less than or */
7602 /* it exactly fits a byte then */
7603 if (SPEC_BLEN(etype) <= 8 ) {
7604 shCount = SPEC_BSTR(etype) ;
7606 /* shift left acc */
7609 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7614 pic14_emitcode ("mov","b,a");
7615 pic14_emitcode("mov","a,@%s",rname);
7619 pic14_emitcode ("mov","b,a");
7620 pic14_emitcode("movx","a,@dptr");
7624 pic14_emitcode ("push","b");
7625 pic14_emitcode ("push","acc");
7626 pic14_emitcode ("lcall","__gptrget");
7627 pic14_emitcode ("pop","b");
7631 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7632 ((unsigned char)(0xFF << (blen+bstr)) |
7633 (unsigned char)(0xFF >> (8-bstr)) ) );
7634 pic14_emitcode ("orl","a,b");
7635 if (p_type == GPOINTER)
7636 pic14_emitcode("pop","b");
7642 pic14_emitcode("mov","@%s,a",rname);
7646 pic14_emitcode("movx","@dptr,a");
7650 DEBUGpic14_emitcode(";lcall","__gptrput");
7655 if ( SPEC_BLEN(etype) <= 8 )
7658 pic14_emitcode("inc","%s",rname);
7659 rLen = SPEC_BLEN(etype) ;
7661 /* now generate for lengths greater than one byte */
7664 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7674 pic14_emitcode("mov","@%s,a",rname);
7676 pic14_emitcode("mov","@%s,%s",rname,l);
7681 pic14_emitcode("movx","@dptr,a");
7686 DEBUGpic14_emitcode(";lcall","__gptrput");
7689 pic14_emitcode ("inc","%s",rname);
7694 /* last last was not complete */
7696 /* save the byte & read byte */
7699 pic14_emitcode ("mov","b,a");
7700 pic14_emitcode("mov","a,@%s",rname);
7704 pic14_emitcode ("mov","b,a");
7705 pic14_emitcode("movx","a,@dptr");
7709 pic14_emitcode ("push","b");
7710 pic14_emitcode ("push","acc");
7711 pic14_emitcode ("lcall","__gptrget");
7712 pic14_emitcode ("pop","b");
7716 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7717 pic14_emitcode ("orl","a,b");
7720 if (p_type == GPOINTER)
7721 pic14_emitcode("pop","b");
7726 pic14_emitcode("mov","@%s,a",rname);
7730 pic14_emitcode("movx","@dptr,a");
7734 DEBUGpic14_emitcode(";lcall","__gptrput");
7738 /*-----------------------------------------------------------------*/
7739 /* genDataPointerSet - remat pointer to data space */
7740 /*-----------------------------------------------------------------*/
7741 static void genDataPointerSet(operand *right,
7745 int size, offset = 0 ;
7746 char *l, buffer[256];
7748 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7749 aopOp(right,ic,FALSE);
7751 l = aopGet(AOP(result),0,FALSE,TRUE);
7752 size = AOP_SIZE(right);
7753 // tsd, was l+1 - the underline `_' prefix was being stripped
7756 sprintf(buffer,"(%s + %d)",l,offset);
7758 sprintf(buffer,"%s",l);
7760 if (AOP_TYPE(right) == AOP_LIT) {
7761 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7762 lit = lit >> (8*offset);
7764 pic14_emitcode("movlw","%d",lit);
7765 pic14_emitcode("movwf","%s",buffer);
7767 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7768 emitpcode(POC_MOVWF, popRegFromString(buffer));
7771 pic14_emitcode("clrf","%s",buffer);
7772 emitpcode(POC_CLRF, popRegFromString(buffer));
7775 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7776 pic14_emitcode("movwf","%s",buffer);
7778 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7779 emitpcode(POC_MOVWF, popRegFromString(buffer));
7786 freeAsmop(right,NULL,ic,TRUE);
7787 freeAsmop(result,NULL,ic,TRUE);
7790 /*-----------------------------------------------------------------*/
7791 /* genNearPointerSet - pic14_emitcode for near pointer put */
7792 /*-----------------------------------------------------------------*/
7793 static void genNearPointerSet (operand *right,
7800 sym_link *ptype = operandType(result);
7803 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7804 retype= getSpec(operandType(right));
7806 aopOp(result,ic,FALSE);
7808 /* if the result is rematerializable &
7809 in data space & not a bit variable */
7810 if (AOP_TYPE(result) == AOP_IMMD &&
7811 DCL_TYPE(ptype) == POINTER &&
7812 !IS_BITVAR(retype)) {
7813 genDataPointerSet (right,result,ic);
7817 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7819 /* if the value is already in a pointer register
7820 then don't need anything more */
7821 if (!AOP_INPREG(AOP(result))) {
7822 /* otherwise get a free pointer register */
7823 //aop = newAsmop(0);
7824 //preg = getFreePtr(ic,&aop,FALSE);
7825 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7826 //pic14_emitcode("mov","%s,%s",
7828 // aopGet(AOP(result),0,FALSE,TRUE));
7829 //rname = preg->name ;
7830 pic14_emitcode("movwf","fsr");
7832 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7834 freeAsmop(result,NULL,ic,TRUE);
7835 aopOp (right,ic,FALSE);
7836 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7838 /* if bitfield then unpack the bits */
7839 if (IS_BITVAR(retype)) {
7840 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7841 "The programmer is obviously confused");
7842 //genPackBits (retype,right,rname,POINTER);
7846 /* we have can just get the values */
7847 int size = AOP_SIZE(right);
7850 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7852 l = aopGet(AOP(right),offset,FALSE,TRUE);
7855 //pic14_emitcode("mov","@%s,a",rname);
7856 pic14_emitcode("movf","indf,w ;1");
7859 if (AOP_TYPE(right) == AOP_LIT) {
7860 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7862 pic14_emitcode("movlw","%s",l);
7863 pic14_emitcode("movwf","indf ;2");
7865 pic14_emitcode("clrf","indf");
7867 pic14_emitcode("movf","%s,w",l);
7868 pic14_emitcode("movwf","indf ;2");
7870 //pic14_emitcode("mov","@%s,%s",rname,l);
7873 pic14_emitcode("incf","fsr,f ;3");
7874 //pic14_emitcode("inc","%s",rname);
7879 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7880 /* now some housekeeping stuff */
7882 /* we had to allocate for this iCode */
7883 freeAsmop(NULL,aop,ic,TRUE);
7885 /* we did not allocate which means left
7886 already in a pointer register, then
7887 if size > 0 && this could be used again
7888 we have to point it back to where it
7890 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7891 if (AOP_SIZE(right) > 1 &&
7892 !OP_SYMBOL(result)->remat &&
7893 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7895 int size = AOP_SIZE(right) - 1;
7897 pic14_emitcode("decf","fsr,f");
7898 //pic14_emitcode("dec","%s",rname);
7902 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7904 freeAsmop(right,NULL,ic,TRUE);
7909 /*-----------------------------------------------------------------*/
7910 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7911 /*-----------------------------------------------------------------*/
7912 static void genPagedPointerSet (operand *right,
7921 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7923 retype= getSpec(operandType(right));
7925 aopOp(result,ic,FALSE);
7927 /* if the value is already in a pointer register
7928 then don't need anything more */
7929 if (!AOP_INPREG(AOP(result))) {
7930 /* otherwise get a free pointer register */
7932 preg = getFreePtr(ic,&aop,FALSE);
7933 pic14_emitcode("mov","%s,%s",
7935 aopGet(AOP(result),0,FALSE,TRUE));
7936 rname = preg->name ;
7938 rname = aopGet(AOP(result),0,FALSE,FALSE);
7940 freeAsmop(result,NULL,ic,TRUE);
7941 aopOp (right,ic,FALSE);
7943 /* if bitfield then unpack the bits */
7944 if (IS_BITVAR(retype))
7945 genPackBits (retype,right,rname,PPOINTER);
7947 /* we have can just get the values */
7948 int size = AOP_SIZE(right);
7952 l = aopGet(AOP(right),offset,FALSE,TRUE);
7955 pic14_emitcode("movx","@%s,a",rname);
7958 pic14_emitcode("inc","%s",rname);
7964 /* now some housekeeping stuff */
7966 /* we had to allocate for this iCode */
7967 freeAsmop(NULL,aop,ic,TRUE);
7969 /* we did not allocate which means left
7970 already in a pointer register, then
7971 if size > 0 && this could be used again
7972 we have to point it back to where it
7974 if (AOP_SIZE(right) > 1 &&
7975 !OP_SYMBOL(result)->remat &&
7976 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7978 int size = AOP_SIZE(right) - 1;
7980 pic14_emitcode("dec","%s",rname);
7985 freeAsmop(right,NULL,ic,TRUE);
7990 /*-----------------------------------------------------------------*/
7991 /* genFarPointerSet - set value from far space */
7992 /*-----------------------------------------------------------------*/
7993 static void genFarPointerSet (operand *right,
7994 operand *result, iCode *ic)
7997 sym_link *retype = getSpec(operandType(right));
7999 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8000 aopOp(result,ic,FALSE);
8002 /* if the operand is already in dptr
8003 then we do nothing else we move the value to dptr */
8004 if (AOP_TYPE(result) != AOP_STR) {
8005 /* if this is remateriazable */
8006 if (AOP_TYPE(result) == AOP_IMMD)
8007 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8008 else { /* we need to get it byte by byte */
8009 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8010 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8011 if (options.model == MODEL_FLAT24)
8013 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8017 /* so dptr know contains the address */
8018 freeAsmop(result,NULL,ic,TRUE);
8019 aopOp(right,ic,FALSE);
8021 /* if bit then unpack */
8022 if (IS_BITVAR(retype))
8023 genPackBits(retype,right,"dptr",FPOINTER);
8025 size = AOP_SIZE(right);
8029 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8031 pic14_emitcode("movx","@dptr,a");
8033 pic14_emitcode("inc","dptr");
8037 freeAsmop(right,NULL,ic,TRUE);
8040 /*-----------------------------------------------------------------*/
8041 /* genGenPointerSet - set value from generic pointer space */
8042 /*-----------------------------------------------------------------*/
8043 static void genGenPointerSet (operand *right,
8044 operand *result, iCode *ic)
8047 sym_link *retype = getSpec(operandType(right));
8049 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8051 aopOp(result,ic,FALSE);
8052 aopOp(right,ic,FALSE);
8053 size = AOP_SIZE(right);
8055 DEBUGpic14_emitcode ("; ","result %s=%s, right %s=%s, size = %d",
8056 AopType(AOP_TYPE(result)),
8057 aopGet(AOP(result),0,TRUE,FALSE),
8058 AopType(AOP_TYPE(right)),
8059 aopGet(AOP(right),0,FALSE,FALSE),
8062 /* if the operand is already in dptr
8063 then we do nothing else we move the value to dptr */
8064 if (AOP_TYPE(result) != AOP_STR) {
8065 /* if this is remateriazable */
8066 if (AOP_TYPE(result) == AOP_IMMD) {
8067 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8068 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8070 else { /* we need to get it byte by byte */
8071 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8072 size = AOP_SIZE(right);
8075 /* hack hack! see if this the FSR. If so don't load W */
8076 if(AOP_TYPE(right) != AOP_ACC) {
8079 emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8082 emitpcode(POC_MOVLW,popGetLit(0xfd));
8083 emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8087 emitpcode(POC_MOVFW,popGet(AOP(right),offset++,FALSE,FALSE));
8088 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8091 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8098 if(aopIdx(AOP(result),0) != 4) {
8100 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8104 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8109 /* so dptr know contains the address */
8112 /* if bit then unpack */
8113 if (IS_BITVAR(retype))
8114 genPackBits(retype,right,"dptr",GPOINTER);
8116 size = AOP_SIZE(right);
8120 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8122 pic14_emitcode("incf","fsr,f");
8123 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8124 pic14_emitcode("movwf","indf");
8126 //DEBUGpic14_emitcode(";lcall","__gptrput");
8128 // pic14_emitcode("inc","dptr");
8133 freeAsmop(right,NULL,ic,TRUE);
8134 freeAsmop(result,NULL,ic,TRUE);
8137 /*-----------------------------------------------------------------*/
8138 /* genPointerSet - stores the value into a pointer location */
8139 /*-----------------------------------------------------------------*/
8140 static void genPointerSet (iCode *ic)
8142 operand *right, *result ;
8143 sym_link *type, *etype;
8146 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8148 right = IC_RIGHT(ic);
8149 result = IC_RESULT(ic) ;
8151 /* depending on the type of pointer we need to
8152 move it to the correct pointer register */
8153 type = operandType(result);
8154 etype = getSpec(type);
8155 /* if left is of type of pointer then it is simple */
8156 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8157 p_type = DCL_TYPE(type);
8160 /* we have to go by the storage class */
8161 p_type = PTR_TYPE(SPEC_OCLS(etype));
8163 /* if (SPEC_OCLS(etype)->codesp ) { */
8164 /* p_type = CPOINTER ; */
8167 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8168 /* p_type = FPOINTER ; */
8170 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8171 /* p_type = PPOINTER ; */
8173 /* if (SPEC_OCLS(etype) == idata ) */
8174 /* p_type = IPOINTER ; */
8176 /* p_type = POINTER ; */
8179 /* now that we have the pointer type we assign
8180 the pointer values */
8185 genNearPointerSet (right,result,ic);
8189 genPagedPointerSet (right,result,ic);
8193 genFarPointerSet (right,result,ic);
8197 genGenPointerSet (right,result,ic);
8203 /*-----------------------------------------------------------------*/
8204 /* genIfx - generate code for Ifx statement */
8205 /*-----------------------------------------------------------------*/
8206 static void genIfx (iCode *ic, iCode *popIc)
8208 operand *cond = IC_COND(ic);
8211 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8213 aopOp(cond,ic,FALSE);
8215 /* get the value into acc */
8216 if (AOP_TYPE(cond) != AOP_CRY)
8217 pic14_toBoolean(cond);
8220 /* the result is now in the accumulator */
8221 freeAsmop(cond,NULL,ic,TRUE);
8223 /* if there was something to be popped then do it */
8227 /* if the condition is a bit variable */
8228 if (isbit && IS_ITEMP(cond) &&
8230 genIfxJump(ic,SPIL_LOC(cond)->rname);
8231 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8234 if (isbit && !IS_ITEMP(cond))
8235 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8243 /*-----------------------------------------------------------------*/
8244 /* genAddrOf - generates code for address of */
8245 /*-----------------------------------------------------------------*/
8246 static void genAddrOf (iCode *ic)
8248 //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8249 operand *right, *result, *left;
8250 //int size, offset ;
8252 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8255 //aopOp(IC_RESULT(ic),ic,FALSE);
8257 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8258 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8259 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8262 DEBUGpic14_emitcode ("; ","result %s",
8263 AopType(AOP_TYPE(IC_RESULT(ic))));
8266 DEBUGpic14_emitcode ("; ","left %s",
8267 AopType(AOP_TYPE(IC_LEFT(ic))));
8269 DEBUGpic14_emitcode ("; ","right %s",
8270 AopType(AOP_TYPE(IC_RIGHT(ic))));
8272 emitpcode(POC_MOVLW, popGet(AOP(left),0,FALSE,FALSE));
8273 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
8276 /* object not on stack then we need the name */
8277 size = AOP_SIZE(IC_RESULT(ic));
8281 char s[SDCC_NAME_MAX];
8283 sprintf(s,"#(%s >> %d)",
8287 sprintf(s,"#%s",sym->rname);
8288 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8293 // freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8294 freeAsmop(left,NULL,ic,FALSE);
8295 freeAsmop(result,NULL,ic,TRUE);
8300 /*-----------------------------------------------------------------*/
8301 /* genFarFarAssign - assignment when both are in far space */
8302 /*-----------------------------------------------------------------*/
8303 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8305 int size = AOP_SIZE(right);
8308 /* first push the right side on to the stack */
8310 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8312 pic14_emitcode ("push","acc");
8315 freeAsmop(right,NULL,ic,FALSE);
8316 /* now assign DPTR to result */
8317 aopOp(result,ic,FALSE);
8318 size = AOP_SIZE(result);
8320 pic14_emitcode ("pop","acc");
8321 aopPut(AOP(result),"a",--offset);
8323 freeAsmop(result,NULL,ic,FALSE);
8328 /*-----------------------------------------------------------------*/
8329 /* genAssign - generate code for assignment */
8330 /*-----------------------------------------------------------------*/
8331 static void genAssign (iCode *ic)
8333 operand *result, *right;
8334 int size, offset,know_W;
8335 unsigned long lit = 0L;
8337 result = IC_RESULT(ic);
8338 right = IC_RIGHT(ic) ;
8340 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8342 /* if they are the same */
8343 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8346 aopOp(right,ic,FALSE);
8347 aopOp(result,ic,TRUE);
8349 DEBUGpic14_emitcode ("; ","result %s, right %s, size = %d",
8350 AopType(AOP_TYPE(IC_RESULT(ic))),
8351 AopType(AOP_TYPE(IC_RIGHT(ic))),
8354 /* if they are the same registers */
8355 if (pic14_sameRegs(AOP(right),AOP(result)))
8358 /* if the result is a bit */
8359 if (AOP_TYPE(result) == AOP_CRY) {
8361 /* if the right size is a literal then
8362 we know what the value is */
8363 if (AOP_TYPE(right) == AOP_LIT) {
8365 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8366 popGet(AOP(result),0,FALSE,FALSE));
8368 if (((int) operandLitValue(right)))
8369 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8370 AOP(result)->aopu.aop_dir,
8371 AOP(result)->aopu.aop_dir);
8373 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8374 AOP(result)->aopu.aop_dir,
8375 AOP(result)->aopu.aop_dir);
8379 /* the right is also a bit variable */
8380 if (AOP_TYPE(right) == AOP_CRY) {
8381 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8382 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8383 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8385 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8386 AOP(result)->aopu.aop_dir,
8387 AOP(result)->aopu.aop_dir);
8388 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8389 AOP(right)->aopu.aop_dir,
8390 AOP(right)->aopu.aop_dir);
8391 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8392 AOP(result)->aopu.aop_dir,
8393 AOP(result)->aopu.aop_dir);
8398 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8399 pic14_toBoolean(right);
8401 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8402 //aopPut(AOP(result),"a",0);
8406 /* bit variables done */
8408 size = AOP_SIZE(result);
8410 if(AOP_TYPE(right) == AOP_LIT)
8411 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8413 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8414 if(aopIdx(AOP(result),0) == 4) {
8415 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8416 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8419 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8424 if(AOP_TYPE(right) == AOP_LIT) {
8426 if(know_W != (lit&0xff))
8427 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8429 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8431 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8435 } else if (AOP_TYPE(right) == AOP_CRY) {
8436 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8438 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8439 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8442 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8443 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8451 freeAsmop (right,NULL,ic,FALSE);
8452 freeAsmop (result,NULL,ic,TRUE);
8455 /*-----------------------------------------------------------------*/
8456 /* genJumpTab - genrates code for jump table */
8457 /*-----------------------------------------------------------------*/
8458 static void genJumpTab (iCode *ic)
8463 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8465 aopOp(IC_JTCOND(ic),ic,FALSE);
8466 /* get the condition into accumulator */
8467 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8469 /* multiply by three */
8470 pic14_emitcode("add","a,acc");
8471 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8473 jtab = newiTempLabel(NULL);
8474 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8475 pic14_emitcode("jmp","@a+dptr");
8476 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8478 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8479 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8481 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8482 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8483 emitpLabel(jtab->key);
8485 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8487 /* now generate the jump labels */
8488 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8489 jtab = setNextItem(IC_JTLABELS(ic))) {
8490 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8491 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8497 /*-----------------------------------------------------------------*/
8498 /* genMixedOperation - gen code for operators between mixed types */
8499 /*-----------------------------------------------------------------*/
8501 TSD - Written for the PIC port - but this unfortunately is buggy.
8502 This routine is good in that it is able to efficiently promote
8503 types to different (larger) sizes. Unfortunately, the temporary
8504 variables that are optimized out by this routine are sometimes
8505 used in other places. So until I know how to really parse the
8506 iCode tree, I'm going to not be using this routine :(.
8508 static int genMixedOperation (iCode *ic)
8511 operand *result = IC_RESULT(ic);
8512 sym_link *ctype = operandType(IC_LEFT(ic));
8513 operand *right = IC_RIGHT(ic);
8519 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8521 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8527 nextright = IC_RIGHT(nextic);
8528 nextleft = IC_LEFT(nextic);
8529 nextresult = IC_RESULT(nextic);
8531 aopOp(right,ic,FALSE);
8532 aopOp(result,ic,FALSE);
8533 aopOp(nextright, nextic, FALSE);
8534 aopOp(nextleft, nextic, FALSE);
8535 aopOp(nextresult, nextic, FALSE);
8537 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8543 pic14_emitcode(";remove right +","");
8545 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8551 pic14_emitcode(";remove left +","");
8555 big = AOP_SIZE(nextleft);
8556 small = AOP_SIZE(nextright);
8558 switch(nextic->op) {
8561 pic14_emitcode(";optimize a +","");
8562 /* if unsigned or not an integral type */
8563 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8564 pic14_emitcode(";add a bit to something","");
8567 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8569 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8570 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8571 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8573 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8581 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8582 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8583 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8586 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8588 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8589 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8590 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8591 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8592 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8595 pic14_emitcode("rlf","known_zero,w");
8602 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8603 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8604 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8606 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8616 freeAsmop(right,NULL,ic,TRUE);
8617 freeAsmop(result,NULL,ic,TRUE);
8618 freeAsmop(nextright,NULL,ic,TRUE);
8619 freeAsmop(nextleft,NULL,ic,TRUE);
8621 nextic->generated = 1;
8628 /*-----------------------------------------------------------------*/
8629 /* genCast - gen code for casting */
8630 /*-----------------------------------------------------------------*/
8631 static void genCast (iCode *ic)
8633 operand *result = IC_RESULT(ic);
8634 sym_link *ctype = operandType(IC_LEFT(ic));
8635 operand *right = IC_RIGHT(ic);
8638 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8639 /* if they are equivalent then do nothing */
8640 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8643 aopOp(right,ic,FALSE) ;
8644 aopOp(result,ic,FALSE);
8646 /* if the result is a bit */
8647 if (AOP_TYPE(result) == AOP_CRY) {
8648 /* if the right size is a literal then
8649 we know what the value is */
8650 if (AOP_TYPE(right) == AOP_LIT) {
8652 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8653 popGet(AOP(result),0,FALSE,FALSE));
8655 if (((int) operandLitValue(right)))
8656 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8657 AOP(result)->aopu.aop_dir,
8658 AOP(result)->aopu.aop_dir);
8660 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8661 AOP(result)->aopu.aop_dir,
8662 AOP(result)->aopu.aop_dir);
8667 /* the right is also a bit variable */
8668 if (AOP_TYPE(right) == AOP_CRY) {
8671 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8673 pic14_emitcode("clrc","");
8674 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8675 AOP(right)->aopu.aop_dir,
8676 AOP(right)->aopu.aop_dir);
8677 aopPut(AOP(result),"c",0);
8682 pic14_toBoolean(right);
8683 aopPut(AOP(result),"a",0);
8687 /* if they are the same size : or less */
8688 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8690 /* if they are in the same place */
8691 if (pic14_sameRegs(AOP(right),AOP(result)))
8694 /* if they in different places then copy */
8695 size = AOP_SIZE(result);
8699 aopGet(AOP(right),offset,FALSE,FALSE),
8707 /* if the result is of type pointer */
8708 if (IS_PTR(ctype)) {
8711 sym_link *type = operandType(right);
8712 sym_link *etype = getSpec(type);
8714 /* pointer to generic pointer */
8715 if (IS_GENPTR(ctype)) {
8719 p_type = DCL_TYPE(type);
8721 /* we have to go by the storage class */
8722 p_type = PTR_TYPE(SPEC_OCLS(etype));
8724 /* if (SPEC_OCLS(etype)->codesp ) */
8725 /* p_type = CPOINTER ; */
8727 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8728 /* p_type = FPOINTER ; */
8730 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8731 /* p_type = PPOINTER; */
8733 /* if (SPEC_OCLS(etype) == idata ) */
8734 /* p_type = IPOINTER ; */
8736 /* p_type = POINTER ; */
8739 /* the first two bytes are known */
8740 size = GPTRSIZE - 1;
8744 aopGet(AOP(right),offset,FALSE,FALSE),
8748 /* the last byte depending on type */
8765 /* this should never happen */
8766 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8767 "got unknown pointer type");
8770 aopPut(AOP(result),l, GPTRSIZE - 1);
8774 /* just copy the pointers */
8775 size = AOP_SIZE(result);
8779 aopGet(AOP(right),offset,FALSE,FALSE),
8787 if (AOP_TYPE(right) == AOP_CRY) {
8789 size = AOP_SIZE(right);
8791 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8792 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8793 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8795 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8796 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8797 AOP(right)->aopu.aop_dir,
8798 AOP(right)->aopu.aop_dir);
8799 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8801 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8802 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8807 /* so we now know that the size of destination is greater
8808 than the size of the source.
8809 Now, if the next iCode is an operator then we might be
8810 able to optimize the operation without performing a cast.
8812 if(genMixedOperation(ic))
8816 /* we move to result for the size of source */
8817 size = AOP_SIZE(right);
8820 pic14_emitcode(";","%d",__LINE__);
8821 /* aopPut(AOP(result),
8822 aopGet(AOP(right),offset,FALSE,FALSE),
8824 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8825 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8829 /* now depending on the sign of the destination */
8830 size = AOP_SIZE(result) - AOP_SIZE(right);
8831 /* if unsigned or not an integral type */
8832 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8834 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8835 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8839 /* we need to extend the sign :{ */
8841 emitpcodeNULLop(POC_CLRW);
8844 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8846 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8848 emitpcode(POC_MOVLW, popGetLit(0xff));
8850 pic14_emitcode("clrw","");
8851 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8852 AOP(right)->aopu.aop_dir,
8853 AOP(right)->aopu.aop_dir);
8854 pic14_emitcode("movlw","0xff");
8856 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8857 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8859 // aopPut(AOP(result),"a",offset++);
8864 /* we are done hurray !!!! */
8867 freeAsmop(right,NULL,ic,TRUE);
8868 freeAsmop(result,NULL,ic,TRUE);
8872 /*-----------------------------------------------------------------*/
8873 /* genDjnz - generate decrement & jump if not zero instrucion */
8874 /*-----------------------------------------------------------------*/
8875 static int genDjnz (iCode *ic, iCode *ifx)
8878 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8883 /* if the if condition has a false label
8884 then we cannot save */
8888 /* if the minus is not of the form
8890 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8891 !IS_OP_LITERAL(IC_RIGHT(ic)))
8894 if (operandLitValue(IC_RIGHT(ic)) != 1)
8897 /* if the size of this greater than one then no
8899 if (getSize(operandType(IC_RESULT(ic))) > 1)
8902 /* otherwise we can save BIG */
8903 lbl = newiTempLabel(NULL);
8904 lbl1= newiTempLabel(NULL);
8906 aopOp(IC_RESULT(ic),ic,FALSE);
8908 if (IS_AOP_PREG(IC_RESULT(ic))) {
8909 pic14_emitcode("dec","%s",
8910 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8911 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8912 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8916 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8917 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8919 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8920 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8923 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8924 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8925 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8926 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8929 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8934 /*-----------------------------------------------------------------*/
8935 /* genReceive - generate code for a receive iCode */
8936 /*-----------------------------------------------------------------*/
8937 static void genReceive (iCode *ic)
8939 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8941 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8942 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8943 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8945 int size = getSize(operandType(IC_RESULT(ic)));
8946 int offset = fReturnSizePic - size;
8948 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8949 fReturn[fReturnSizePic - offset - 1] : "acc"));
8952 aopOp(IC_RESULT(ic),ic,FALSE);
8953 size = AOP_SIZE(IC_RESULT(ic));
8956 pic14_emitcode ("pop","acc");
8957 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8962 aopOp(IC_RESULT(ic),ic,FALSE);
8964 assignResultValue(IC_RESULT(ic));
8967 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8970 /*-----------------------------------------------------------------*/
8971 /* genpic14Code - generate code for pic14 based controllers */
8972 /*-----------------------------------------------------------------*/
8974 * At this point, ralloc.c has gone through the iCode and attempted
8975 * to optimize in a way suitable for a PIC. Now we've got to generate
8976 * PIC instructions that correspond to the iCode.
8978 * Once the instructions are generated, we'll pass through both the
8979 * peep hole optimizer and the pCode optimizer.
8980 *-----------------------------------------------------------------*/
8982 void genpic14Code (iCode *lic)
8987 lineHead = lineCurr = NULL;
8989 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8992 /* if debug information required */
8993 /* if (options.debug && currFunc) { */
8995 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8997 if (IS_STATIC(currFunc->etype)) {
8998 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8999 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9001 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9002 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9008 for (ic = lic ; ic ; ic = ic->next ) {
9010 DEBUGpic14_emitcode(";ic","");
9011 if ( cln != ic->lineno ) {
9012 if ( options.debug ) {
9014 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9015 FileBaseName(ic->filename),ic->lineno,
9016 ic->level,ic->block);
9019 pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
9022 /* if the result is marked as
9023 spilt and rematerializable or code for
9024 this has already been generated then
9026 if (resultRemat(ic) || ic->generated )
9029 /* depending on the operation */
9048 /* IPOP happens only when trying to restore a
9049 spilt live range, if there is an ifx statement
9050 following this pop then the if statement might
9051 be using some of the registers being popped which
9052 would destory the contents of the register so
9053 we need to check for this condition and handle it */
9055 ic->next->op == IFX &&
9056 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9057 genIfx (ic->next,ic);
9075 genEndFunction (ic);
9095 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9112 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9116 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9123 /* note these two are xlated by algebraic equivalence
9124 during parsing SDCC.y */
9125 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9126 "got '>=' or '<=' shouldn't have come here");
9130 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9142 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9146 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9150 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9177 case GET_VALUE_AT_ADDRESS:
9182 if (POINTER_SET(ic))
9209 addSet(&_G.sendSet,ic);
9218 /* now we are ready to call the
9219 peep hole optimizer */
9220 if (!options.nopeep) {
9221 printf("peep hole optimizing\n");
9222 peepHole (&lineHead);
9224 /* now do the actual printing */
9225 printLine (lineHead,codeOutFile);
9227 printf("printing pBlock\n\n");
9228 printpBlock(stdout,pb);