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"
40 #define __FUNCTION__ __FILE__
43 #ifdef HAVE_SYS_ISA_DEFS_H
44 #include <sys/isa_defs.h>
49 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
50 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
51 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
57 #include "SDCCpeeph.h"
62 static int labelOffset=0;
63 static int debug_verbose=1;
65 unsigned int pic14aopLiteral (value *val, int offset);
67 /* this is the down and dirty file with all kinds of
68 kludgy & hacky stuff. This is what it is all about
69 CODE GENERATION for a specific MCU . some of the
70 routines may be reusable, will have to see */
72 static char *zero = "#0x00";
73 static char *one = "#0x01";
74 static char *spname = "sp";
76 char *fReturnpic14[] = {"FSR","dph","b","a" };
77 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
78 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
79 static char **fReturn = fReturnpic14;
81 static char *accUse[] = {"a","b"};
83 //static short rbank = -1;
95 char *Safe_strdup(char *str); // in pcode.c
97 extern int pic14_ptrRegReq ;
98 extern int pic14_nRegs;
99 extern FILE *codeOutFile;
100 static void saverbank (int, iCode *,bool);
102 static lineNode *lineHead = NULL;
103 static lineNode *lineCurr = NULL;
105 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
106 0xE0, 0xC0, 0x80, 0x00};
107 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
108 0x07, 0x03, 0x01, 0x00};
112 /*-----------------------------------------------------------------*/
113 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
114 /* exponent of 2 is returned, otherwise -1 is */
116 /* note that this is similar to the function `powof2' in SDCCsymt */
120 /*-----------------------------------------------------------------*/
121 static int my_powof2 (unsigned long num)
124 if( (num & (num-1)) == 0) {
137 static void emitpLabel(int key)
139 addpCode2pBlock(pb,newpCodeLabel(key));
142 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
145 addpCode2pBlock(pb,newpCode(poc,pcop));
148 /*-----------------------------------------------------------------*/
149 /* pic14_emitcode - writes the code into a file : for now it is simple */
150 /*-----------------------------------------------------------------*/
151 void pic14_emitcode (char *inst,char *fmt, ...)
154 char lb[MAX_INLINEASM];
161 sprintf(lb,"%s\t",inst);
163 sprintf(lb,"%s",inst);
164 vsprintf(lb+(strlen(lb)),fmt,ap);
168 while (isspace(*lbp)) lbp++;
171 lineCurr = (lineCurr ?
172 connectLine(lineCurr,newLineNode(lb)) :
173 (lineHead = newLineNode(lb)));
174 lineCurr->isInline = _G.inLine;
175 lineCurr->isDebug = _G.debugLine;
178 addpCode2pBlock(pb,newpCodeCharP(lb));
183 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
186 char lb[MAX_INLINEASM];
196 sprintf(lb,"%s\t",inst);
198 sprintf(lb,"%s",inst);
199 vsprintf(lb+(strlen(lb)),fmt,ap);
203 while (isspace(*lbp)) lbp++;
206 lineCurr = (lineCurr ?
207 connectLine(lineCurr,newLineNode(lb)) :
208 (lineHead = newLineNode(lb)));
209 lineCurr->isInline = _G.inLine;
210 lineCurr->isDebug = _G.debugLine;
212 addpCode2pBlock(pb,newpCodeCharP(lb));
218 /*-----------------------------------------------------------------*/
219 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
220 /*-----------------------------------------------------------------*/
221 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
223 bool r0iu = FALSE , r1iu = FALSE;
224 bool r0ou = FALSE , r1ou = FALSE;
226 /* the logic: if r0 & r1 used in the instruction
227 then we are in trouble otherwise */
229 /* first check if r0 & r1 are used by this
230 instruction, in which case we are in trouble */
231 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
232 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
237 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
238 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
240 /* if no usage of r0 then return it */
241 if (!r0iu && !r0ou) {
242 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
243 (*aopp)->type = AOP_R0;
245 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
248 /* if no usage of r1 then return it */
249 if (!r1iu && !r1ou) {
250 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
251 (*aopp)->type = AOP_R1;
253 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
256 /* now we know they both have usage */
257 /* if r0 not used in this instruction */
259 /* push it if not already pushed */
261 pic14_emitcode ("push","%s",
262 pic14_regWithIdx(R0_IDX)->dname);
266 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
267 (*aopp)->type = AOP_R0;
269 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
272 /* if r1 not used then */
275 /* push it if not already pushed */
277 pic14_emitcode ("push","%s",
278 pic14_regWithIdx(R1_IDX)->dname);
282 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
283 (*aopp)->type = AOP_R1;
284 return pic14_regWithIdx(R1_IDX);
288 /* I said end of world but not quite end of world yet */
289 /* if this is a result then we can push it on the stack*/
291 (*aopp)->type = AOP_STK;
296 /* other wise this is true end of the world */
297 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
298 "getFreePtr should never reach here");
302 /*-----------------------------------------------------------------*/
303 /* newAsmop - creates a new asmOp */
304 /*-----------------------------------------------------------------*/
305 asmop *newAsmop (short type)
309 aop = Safe_calloc(1,sizeof(asmop));
314 static void genSetDPTR(int n)
318 pic14_emitcode(";", "Select standard DPTR");
319 pic14_emitcode("mov", "dps, #0x00");
323 pic14_emitcode(";", "Select alternate DPTR");
324 pic14_emitcode("mov", "dps, #0x01");
328 /*-----------------------------------------------------------------*/
329 /* pointerCode - returns the code for a pointer type */
330 /*-----------------------------------------------------------------*/
331 static int pointerCode (sym_link *etype)
334 return PTR_TYPE(SPEC_OCLS(etype));
338 /*-----------------------------------------------------------------*/
339 /* aopForSym - for a true symbol */
340 /*-----------------------------------------------------------------*/
341 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
344 memmap *space= SPEC_OCLS(sym->etype);
346 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
347 /* if already has one */
351 /* assign depending on the storage class */
352 /* if it is on the stack or indirectly addressable */
353 /* space we need to assign either r0 or r1 to it */
354 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
355 sym->aop = aop = newAsmop(0);
356 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
357 aop->size = getSize(sym->type);
359 /* now assign the address of the variable to
360 the pointer register */
361 if (aop->type != AOP_STK) {
365 pic14_emitcode("push","acc");
367 pic14_emitcode("mov","a,_bp");
368 pic14_emitcode("add","a,#0x%02x",
370 ((char)(sym->stack - _G.nRegsSaved )) :
371 ((char)sym->stack)) & 0xff);
372 pic14_emitcode("mov","%s,a",
373 aop->aopu.aop_ptr->name);
376 pic14_emitcode("pop","acc");
378 pic14_emitcode("mov","%s,#%s",
379 aop->aopu.aop_ptr->name,
381 aop->paged = space->paged;
383 aop->aopu.aop_stk = sym->stack;
387 if (sym->onStack && options.stack10bit)
389 /* It's on the 10 bit stack, which is located in
393 //DEBUGpic14_emitcode(";","%d",__LINE__);
396 pic14_emitcode("push","acc");
398 pic14_emitcode("mov","a,_bp");
399 pic14_emitcode("add","a,#0x%02x",
401 ((char)(sym->stack - _G.nRegsSaved )) :
402 ((char)sym->stack)) & 0xff);
405 pic14_emitcode ("mov","dpx1,#0x40");
406 pic14_emitcode ("mov","dph1,#0x00");
407 pic14_emitcode ("mov","dpl1, a");
411 pic14_emitcode("pop","acc");
413 sym->aop = aop = newAsmop(AOP_DPTR2);
414 aop->size = getSize(sym->type);
418 //DEBUGpic14_emitcode(";","%d",__LINE__);
419 /* if in bit space */
420 if (IN_BITSPACE(space)) {
421 sym->aop = aop = newAsmop (AOP_CRY);
422 aop->aopu.aop_dir = sym->rname ;
423 aop->size = getSize(sym->type);
424 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
427 /* if it is in direct space */
428 if (IN_DIRSPACE(space)) {
429 sym->aop = aop = newAsmop (AOP_DIR);
430 aop->aopu.aop_dir = sym->rname ;
431 aop->size = getSize(sym->type);
432 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
436 /* special case for a function */
437 if (IS_FUNC(sym->type)) {
438 sym->aop = aop = newAsmop(AOP_IMMD);
439 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
440 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
441 strcpy(aop->aopu.aop_immd,sym->rname);
442 aop->size = FPTRSIZE;
447 /* only remaining is far space */
448 /* in which case DPTR gets the address */
449 sym->aop = aop = newAsmop(AOP_DPTR);
450 pic14_emitcode ("mov","dptr,#%s", sym->rname);
451 aop->size = getSize(sym->type);
453 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
454 /* if it is in code space */
455 if (IN_CODESPACE(space))
461 /*-----------------------------------------------------------------*/
462 /* aopForRemat - rematerialzes an object */
463 /*-----------------------------------------------------------------*/
464 static asmop *aopForRemat (symbol *sym)
466 iCode *ic = sym->rematiCode;
467 asmop *aop = newAsmop(AOP_IMMD);
469 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
472 val += operandLitValue(IC_RIGHT(ic));
473 else if (ic->op == '-')
474 val -= operandLitValue(IC_RIGHT(ic));
478 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
482 sprintf(buffer,"(%s %c 0x%04x)",
483 OP_SYMBOL(IC_LEFT(ic))->rname,
484 val >= 0 ? '+' : '-',
487 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
489 //DEBUGpic14_emitcode(";","%s",buffer);
490 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
491 strcpy(aop->aopu.aop_immd,buffer);
495 /*-----------------------------------------------------------------*/
496 /* regsInCommon - two operands have some registers in common */
497 /*-----------------------------------------------------------------*/
498 static bool regsInCommon (operand *op1, operand *op2)
503 /* if they have registers in common */
504 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
507 sym1 = OP_SYMBOL(op1);
508 sym2 = OP_SYMBOL(op2);
510 if (sym1->nRegs == 0 || sym2->nRegs == 0)
513 for (i = 0 ; i < sym1->nRegs ; i++) {
518 for (j = 0 ; j < sym2->nRegs ;j++ ) {
522 if (sym2->regs[j] == sym1->regs[i])
530 /*-----------------------------------------------------------------*/
531 /* operandsEqu - equivalent */
532 /*-----------------------------------------------------------------*/
533 static bool operandsEqu ( operand *op1, operand *op2)
537 /* if they not symbols */
538 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
541 sym1 = OP_SYMBOL(op1);
542 sym2 = OP_SYMBOL(op2);
544 /* if both are itemps & one is spilt
545 and the other is not then false */
546 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
547 sym1->isspilt != sym2->isspilt )
550 /* if they are the same */
554 if (strcmp(sym1->rname,sym2->rname) == 0)
558 /* if left is a tmp & right is not */
562 (sym1->usl.spillLoc == sym2))
569 (sym2->usl.spillLoc == sym1))
575 /*-----------------------------------------------------------------*/
576 /* pic14_sameRegs - two asmops have the same registers */
577 /*-----------------------------------------------------------------*/
578 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
585 if (aop1->type != AOP_REG ||
586 aop2->type != AOP_REG )
589 if (aop1->size != aop2->size )
592 for (i = 0 ; i < aop1->size ; i++ )
593 if (aop1->aopu.aop_reg[i] !=
594 aop2->aopu.aop_reg[i] )
600 /*-----------------------------------------------------------------*/
601 /* aopOp - allocates an asmop for an operand : */
602 /*-----------------------------------------------------------------*/
603 void aopOp (operand *op, iCode *ic, bool result)
612 DEBUGpic14_emitcode(";","%d",__LINE__);
613 /* if this a literal */
614 if (IS_OP_LITERAL(op)) {
615 DEBUGpic14_emitcode(";","%d",__LINE__);
616 op->aop = aop = newAsmop(AOP_LIT);
617 aop->aopu.aop_lit = op->operand.valOperand;
618 aop->size = getSize(operandType(op));
622 /* if already has a asmop then continue */
626 /* if the underlying symbol has a aop */
627 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
628 DEBUGpic14_emitcode(";","%d",__LINE__);
629 op->aop = OP_SYMBOL(op)->aop;
633 /* if this is a true symbol */
634 if (IS_TRUE_SYMOP(op)) {
635 DEBUGpic14_emitcode(";","%d",__LINE__);
636 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
640 /* this is a temporary : this has
646 e) can be a return use only */
651 /* if the type is a conditional */
652 if (sym->regType == REG_CND) {
653 DEBUGpic14_emitcode(";","%d",__LINE__);
654 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
659 /* if it is spilt then two situations
661 b) has a spill location */
662 if (sym->isspilt || sym->nRegs == 0) {
664 DEBUGpic14_emitcode(";","%d",__LINE__);
665 /* rematerialize it NOW */
667 sym->aop = op->aop = aop =
669 aop->size = getSize(sym->type);
670 DEBUGpic14_emitcode(";","%d",__LINE__);
676 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
677 aop->size = getSize(sym->type);
678 for ( i = 0 ; i < 2 ; i++ )
679 aop->aopu.aop_str[i] = accUse[i];
680 DEBUGpic14_emitcode(";","%d",__LINE__);
686 aop = op->aop = sym->aop = newAsmop(AOP_STR);
687 aop->size = getSize(sym->type);
688 for ( i = 0 ; i < fReturnSizePic ; i++ )
689 aop->aopu.aop_str[i] = fReturn[i];
690 DEBUGpic14_emitcode(";","%d",__LINE__);
694 /* else spill location */
695 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
696 sym->aop = op->aop = aop =
697 aopForSym(ic,sym->usl.spillLoc,result);
698 aop->size = getSize(sym->type);
702 /* must be in a register */
703 sym->aop = op->aop = aop = newAsmop(AOP_REG);
704 aop->size = sym->nRegs;
705 for ( i = 0 ; i < sym->nRegs ;i++)
706 aop->aopu.aop_reg[i] = sym->regs[i];
709 /*-----------------------------------------------------------------*/
710 /* freeAsmop - free up the asmop given to an operand */
711 /*----------------------------------------------------------------*/
712 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
729 /* depending on the asmop type only three cases need work AOP_RO
730 , AOP_R1 && AOP_STK */
735 pic14_emitcode ("pop","ar0");
739 bitVectUnSetBit(ic->rUsed,R0_IDX);
745 pic14_emitcode ("pop","ar1");
749 bitVectUnSetBit(ic->rUsed,R1_IDX);
755 int stk = aop->aopu.aop_stk + aop->size;
756 bitVectUnSetBit(ic->rUsed,R0_IDX);
757 bitVectUnSetBit(ic->rUsed,R1_IDX);
759 getFreePtr(ic,&aop,FALSE);
761 if (options.stack10bit)
763 /* I'm not sure what to do here yet... */
766 "*** Warning: probably generating bad code for "
767 "10 bit stack mode.\n");
771 pic14_emitcode ("mov","a,_bp");
772 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
773 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
775 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
779 pic14_emitcode("pop","acc");
780 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
782 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
785 freeAsmop(op,NULL,ic,TRUE);
787 pic14_emitcode("pop","ar0");
792 pic14_emitcode("pop","ar1");
799 /* all other cases just dealloc */
803 OP_SYMBOL(op)->aop = NULL;
804 /* if the symbol has a spill */
806 SPIL_LOC(op)->aop = NULL;
811 /*-----------------------------------------------------------------*/
812 /* aopGet - for fetching value of the aop */
813 /*-----------------------------------------------------------------*/
814 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
819 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
820 /* offset is greater than
822 if (offset > (aop->size - 1) &&
823 aop->type != AOP_LIT)
826 /* depending on type */
831 DEBUGpic14_emitcode(";","%d",__LINE__);
832 /* if we need to increment it */
833 while (offset > aop->coff) {
834 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
838 while (offset < aop->coff) {
839 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
845 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
846 return (dname ? "acc" : "a");
848 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
849 rs = Safe_calloc(1,strlen(s)+1);
855 DEBUGpic14_emitcode(";","%d",__LINE__);
856 if (aop->type == AOP_DPTR2)
861 while (offset > aop->coff) {
862 pic14_emitcode ("inc","dptr");
866 while (offset < aop->coff) {
867 pic14_emitcode("lcall","__decdptr");
873 pic14_emitcode("clr","a");
874 pic14_emitcode("movc","a,@a+dptr");
877 pic14_emitcode("movx","a,@dptr");
880 if (aop->type == AOP_DPTR2)
885 return (dname ? "acc" : "a");
889 DEBUGpic14_emitcode(";","%d",__LINE__);
891 sprintf (s,"%s",aop->aopu.aop_immd);
894 sprintf(s,"(%s >> %d)",
900 rs = Safe_calloc(1,strlen(s)+1);
906 sprintf(s,"(%s + %d)",
910 sprintf(s,"%s",aop->aopu.aop_dir);
911 rs = Safe_calloc(1,strlen(s)+1);
916 DEBUGpic14_emitcode(";","%d",__LINE__);
918 return aop->aopu.aop_reg[offset]->dname;
920 return aop->aopu.aop_reg[offset]->name;
923 pic14_emitcode(";","%d",__LINE__);
924 //pic14_emitcode("clr","a");
925 //pic14_emitcode("mov","c,%s",aop->aopu.aop_dir);
926 //pic14_emitcode("rlc","a") ;
927 //return (dname ? "acc" : "a");
928 return aop->aopu.aop_dir;
931 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
932 //if (!offset && dname)
934 //return aop->aopu.aop_str[offset];
935 return "AOP_accumulator_bug";
938 DEBUGpic14_emitcode(";","%d",__LINE__);
939 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
940 rs = Safe_calloc(1,strlen(s)+1);
945 DEBUGpic14_emitcode(";","%d",__LINE__);
947 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
951 return aop->aopu.aop_str[offset];
955 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
956 "aopget got unsupported aop->type");
960 /*-----------------------------------------------------------------*/
961 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
962 /*-----------------------------------------------------------------*/
963 pCodeOp *popGetLabel(unsigned int key)
965 return newpCodeOpLabel(key+100+labelOffset);
968 /*-----------------------------------------------------------------*/
969 /* popCopyReg - copy a pcode operator */
970 /*-----------------------------------------------------------------*/
971 pCodeOp *popCopyReg(pCodeOpReg *pc)
975 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
976 pcor->pcop.type = pc->pcop.type;
977 if(!(pcor->pcop.name = strdup(pc->pcop.name)))
978 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
980 pcor->rIdx = pc->rIdx;
986 /*-----------------------------------------------------------------*/
987 /* popCopy - copy a pcode operator */
988 /*-----------------------------------------------------------------*/
989 pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval)
993 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
995 if(!(pcop->name = strdup(pc->pcop.name)))
996 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
997 ((pCodeOpBit *)pcop)->bit = bitval;
999 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1004 /*-----------------------------------------------------------------*/
1005 /* popGet - asm operator to pcode operator conversion */
1006 /*-----------------------------------------------------------------*/
1007 pCodeOp *popGetLit(unsigned int lit)
1010 return newpCodeOpLit(lit);
1014 /*-----------------------------------------------------------------*/
1015 /* popGet - asm operator to pcode operator conversion */
1016 /*-----------------------------------------------------------------*/
1017 pCodeOp *popGetWithString(char *str)
1023 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1027 pcop = newpCodeOp(str,PO_STR);
1032 pCodeOp *popRegFromString(char *str)
1035 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1036 pcop->type = PO_GPR_REGISTER;
1038 PCOR(pcop)->rIdx = -1;
1039 PCOR(pcop)->r = NULL;
1041 DEBUGpic14_emitcode(";","%d",__LINE__);
1042 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1047 /*-----------------------------------------------------------------*/
1048 /* popGet - asm operator to pcode operator conversion */
1049 /*-----------------------------------------------------------------*/
1050 pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
1057 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1058 /* offset is greater than
1061 if (offset > (aop->size - 1) &&
1062 aop->type != AOP_LIT)
1063 return NULL; //zero;
1065 /* depending on type */
1066 switch (aop->type) {
1073 DEBUGpic14_emitcode(";8051 legacy","%d",__LINE__);
1074 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1075 pcop->type = PO_SFR_REGISTER;
1077 PCOR(pcop)->rIdx = -1;
1078 PCOR(pcop)->r = NULL;
1079 // Really nasty hack to check for temporary registers
1081 pcop->name = Safe_strdup("BAD_REGISTER");
1086 DEBUGpic14_emitcode(";","%d",__LINE__);
1087 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1088 pcop->type = PO_IMMEDIATE;
1090 sprintf (s,"%s",aop->aopu.aop_immd);
1093 sprintf(s,"(%s >> %d)",
1098 aop->aopu.aop_immd);
1099 pcop->name = Safe_calloc(1,strlen(s)+1);
1100 strcpy(pcop->name,s);
1104 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1105 pcop->type = PO_DIR;
1107 sprintf(s,"(%s + %d)",
1111 sprintf(s,"%s",aop->aopu.aop_dir);
1112 pcop->name = Safe_calloc(1,strlen(s)+1);
1113 strcpy(pcop->name,s);
1118 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1120 DEBUGpic14_emitcode(";","%d",__LINE__);
1121 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1122 pcop->type = PO_GPR_REGISTER;
1123 PCOR(pcop)->rIdx = rIdx;
1124 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1125 pcop->type = PCOR(pcop)->r->pc_type;
1128 rs = aop->aopu.aop_reg[offset]->dname;
1130 rs = aop->aopu.aop_reg[offset]->name;
1132 DEBUGpic14_emitcode(";","%d %s",__LINE__,rs);
1138 pcop = newpCodeOpBit(aop->aopu.aop_dir,0);
1142 DEBUGpic14_emitcode(";","%d",__LINE__);
1143 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1146 DEBUGpic14_emitcode(";","%d",__LINE__);
1148 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1149 pcop->type = PO_STR;
1151 //aop->coff = offset ;
1152 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1153 sprintf(s,"%s","acc");
1155 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1156 pcop->name = Safe_calloc(1,strlen(s)+1);
1157 strcpy(pcop->name,s);
1162 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1163 "popGet got unsupported aop->type");
1166 /*-----------------------------------------------------------------*/
1167 /* aopPut - puts a string for a aop */
1168 /*-----------------------------------------------------------------*/
1169 void aopPut (asmop *aop, char *s, int offset)
1174 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1176 if (aop->size && offset > ( aop->size - 1)) {
1177 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1178 "aopPut got offset > aop->size");
1182 /* will assign value to value */
1183 /* depending on where it is ofcourse */
1184 switch (aop->type) {
1187 sprintf(d,"(%s + %d)",
1188 aop->aopu.aop_dir,offset);
1190 sprintf(d,"%s",aop->aopu.aop_dir);
1193 DEBUGpic14_emitcode(";","%d",__LINE__);
1195 pic14_emitcode("movf","%s,w",s);
1196 pic14_emitcode("movwf","%s",d);
1199 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1200 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1207 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1208 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1211 strcmp(s,"r0") == 0 ||
1212 strcmp(s,"r1") == 0 ||
1213 strcmp(s,"r2") == 0 ||
1214 strcmp(s,"r3") == 0 ||
1215 strcmp(s,"r4") == 0 ||
1216 strcmp(s,"r5") == 0 ||
1217 strcmp(s,"r6") == 0 ||
1218 strcmp(s,"r7") == 0 )
1219 pic14_emitcode("mov","%s,%s ; %d",
1220 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1225 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1227 pic14_emitcode("movwf","%s",
1228 aop->aopu.aop_reg[offset]->name);
1231 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1232 pcop->type = PO_GPR_REGISTER;
1234 PCOR(pcop)->rIdx = -1;
1235 PCOR(pcop)->r = NULL;
1237 DEBUGpic14_emitcode(";","%d",__LINE__);
1238 pcop->name = Safe_strdup(s);
1239 emitpcode(POC_MOVFW,pcop);
1241 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1249 if (aop->type == AOP_DPTR2)
1255 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1256 "aopPut writting to code space");
1260 while (offset > aop->coff) {
1262 pic14_emitcode ("inc","dptr");
1265 while (offset < aop->coff) {
1267 pic14_emitcode("lcall","__decdptr");
1272 /* if not in accumulater */
1275 pic14_emitcode ("movx","@dptr,a");
1277 if (aop->type == AOP_DPTR2)
1285 while (offset > aop->coff) {
1287 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1289 while (offset < aop->coff) {
1291 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1297 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1302 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1304 if (strcmp(s,"r0") == 0 ||
1305 strcmp(s,"r1") == 0 ||
1306 strcmp(s,"r2") == 0 ||
1307 strcmp(s,"r3") == 0 ||
1308 strcmp(s,"r4") == 0 ||
1309 strcmp(s,"r5") == 0 ||
1310 strcmp(s,"r6") == 0 ||
1311 strcmp(s,"r7") == 0 ) {
1313 sprintf(buffer,"a%s",s);
1314 pic14_emitcode("mov","@%s,%s",
1315 aop->aopu.aop_ptr->name,buffer);
1317 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1322 if (strcmp(s,"a") == 0)
1323 pic14_emitcode("push","acc");
1325 pic14_emitcode("push","%s",s);
1330 /* if bit variable */
1331 if (!aop->aopu.aop_dir) {
1332 pic14_emitcode("clr","a");
1333 pic14_emitcode("rlc","a");
1336 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1339 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1342 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1344 lbl = newiTempLabel(NULL);
1346 if (strcmp(s,"a")) {
1349 pic14_emitcode("clr","c");
1350 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1351 pic14_emitcode("cpl","c");
1352 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1353 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1360 if (strcmp(aop->aopu.aop_str[offset],s))
1361 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1366 if (!offset && (strcmp(s,"acc") == 0))
1369 if (strcmp(aop->aopu.aop_str[offset],s))
1370 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1374 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1375 "aopPut got unsupported aop->type");
1381 /*-----------------------------------------------------------------*/
1382 /* reAdjustPreg - points a register back to where it should */
1383 /*-----------------------------------------------------------------*/
1384 static void reAdjustPreg (asmop *aop)
1388 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1390 if ((size = aop->size) <= 1)
1393 switch (aop->type) {
1397 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1401 if (aop->type == AOP_DPTR2)
1407 pic14_emitcode("lcall","__decdptr");
1410 if (aop->type == AOP_DPTR2)
1420 /*-----------------------------------------------------------------*/
1421 /* genNotFloat - generates not for float operations */
1422 /*-----------------------------------------------------------------*/
1423 static void genNotFloat (operand *op, operand *res)
1429 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1430 /* we will put 127 in the first byte of
1432 aopPut(AOP(res),"#127",0);
1433 size = AOP_SIZE(op) - 1;
1436 l = aopGet(op->aop,offset++,FALSE,FALSE);
1440 pic14_emitcode("orl","a,%s",
1442 offset++,FALSE,FALSE));
1444 tlbl = newiTempLabel(NULL);
1446 tlbl = newiTempLabel(NULL);
1447 aopPut(res->aop,one,1);
1448 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1449 aopPut(res->aop,zero,1);
1450 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1452 size = res->aop->size - 2;
1454 /* put zeros in the rest */
1456 aopPut(res->aop,zero,offset++);
1460 /*-----------------------------------------------------------------*/
1461 /* opIsGptr: returns non-zero if the passed operand is */
1462 /* a generic pointer type. */
1463 /*-----------------------------------------------------------------*/
1464 static int opIsGptr(operand *op)
1466 sym_link *type = operandType(op);
1468 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1469 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1477 /*-----------------------------------------------------------------*/
1478 /* pic14_getDataSize - get the operand data size */
1479 /*-----------------------------------------------------------------*/
1480 int pic14_getDataSize(operand *op)
1482 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1485 return AOP_SIZE(op);
1487 // tsd- in the pic port, the genptr size is 1, so this code here
1488 // fails. ( in the 8051 port, the size was 4).
1491 size = AOP_SIZE(op);
1492 if (size == GPTRSIZE)
1494 sym_link *type = operandType(op);
1495 if (IS_GENPTR(type))
1497 /* generic pointer; arithmetic operations
1498 * should ignore the high byte (pointer type).
1501 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1508 /*-----------------------------------------------------------------*/
1509 /* pic14_outAcc - output Acc */
1510 /*-----------------------------------------------------------------*/
1511 void pic14_outAcc(operand *result)
1514 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1515 size = pic14_getDataSize(result);
1517 aopPut(AOP(result),"a",0);
1520 /* unsigned or positive */
1522 aopPut(AOP(result),zero,offset++);
1527 /*-----------------------------------------------------------------*/
1528 /* pic14_outBitC - output a bit C */
1529 /*-----------------------------------------------------------------*/
1530 void pic14_outBitC(operand *result)
1533 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1534 /* if the result is bit */
1535 if (AOP_TYPE(result) == AOP_CRY)
1536 aopPut(AOP(result),"c",0);
1538 pic14_emitcode("clr","a ; %d", __LINE__);
1539 pic14_emitcode("rlc","a");
1540 pic14_outAcc(result);
1544 /*-----------------------------------------------------------------*/
1545 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1546 /*-----------------------------------------------------------------*/
1547 void pic14_toBoolean(operand *oper)
1549 int size = AOP_SIZE(oper) - 1;
1552 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1554 if ( AOP_TYPE(oper) != AOP_ACC) {
1555 emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1556 pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1559 pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1560 emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1565 /*-----------------------------------------------------------------*/
1566 /* genNot - generate code for ! operation */
1567 /*-----------------------------------------------------------------*/
1568 static void genNot (iCode *ic)
1571 sym_link *optype = operandType(IC_LEFT(ic));
1573 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1574 /* assign asmOps to operand & result */
1575 aopOp (IC_LEFT(ic),ic,FALSE);
1576 aopOp (IC_RESULT(ic),ic,TRUE);
1578 /* if in bit space then a special case */
1579 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1580 pic14_emitcode("movlw","1<<%s");
1581 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1582 //pic14_emitcode("cpl","c");
1583 //pic14_outBitC(IC_RESULT(ic));
1587 /* if type float then do float */
1588 if (IS_FLOAT(optype)) {
1589 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1593 pic14_toBoolean(IC_LEFT(ic));
1595 tlbl = newiTempLabel(NULL);
1596 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1597 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1598 pic14_outBitC(IC_RESULT(ic));
1601 /* release the aops */
1602 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1603 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1607 /*-----------------------------------------------------------------*/
1608 /* genCpl - generate code for complement */
1609 /*-----------------------------------------------------------------*/
1610 static void genCpl (iCode *ic)
1616 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1617 /* assign asmOps to operand & result */
1618 aopOp (IC_LEFT(ic),ic,FALSE);
1619 aopOp (IC_RESULT(ic),ic,TRUE);
1621 /* if both are in bit space then
1623 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1624 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1626 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1627 pic14_emitcode("cpl","c");
1628 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1632 size = AOP_SIZE(IC_RESULT(ic));
1634 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1636 pic14_emitcode("cpl","a");
1637 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1642 /* release the aops */
1643 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1644 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1647 /*-----------------------------------------------------------------*/
1648 /* genUminusFloat - unary minus for floating points */
1649 /*-----------------------------------------------------------------*/
1650 static void genUminusFloat(operand *op,operand *result)
1652 int size ,offset =0 ;
1655 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1656 /* for this we just need to flip the
1657 first it then copy the rest in place */
1658 size = AOP_SIZE(op) - 1;
1659 l = aopGet(AOP(op),3,FALSE,FALSE);
1663 pic14_emitcode("cpl","acc.7");
1664 aopPut(AOP(result),"a",3);
1668 aopGet(AOP(op),offset,FALSE,FALSE),
1674 /*-----------------------------------------------------------------*/
1675 /* genUminus - unary minus code generation */
1676 /*-----------------------------------------------------------------*/
1677 static void genUminus (iCode *ic)
1680 sym_link *optype, *rtype;
1683 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1685 aopOp(IC_LEFT(ic),ic,FALSE);
1686 aopOp(IC_RESULT(ic),ic,TRUE);
1688 /* if both in bit space then special
1690 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1691 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1693 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1694 pic14_emitcode("cpl","c");
1695 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1699 optype = operandType(IC_LEFT(ic));
1700 rtype = operandType(IC_RESULT(ic));
1702 /* if float then do float stuff */
1703 if (IS_FLOAT(optype)) {
1704 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1708 /* otherwise subtract from zero */
1709 size = AOP_SIZE(IC_LEFT(ic));
1713 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1714 if (!strcmp(l,"a")) {
1715 pic14_emitcode("cpl","a");
1716 pic14_emitcode("inc","a");
1718 pic14_emitcode("clr","a");
1719 pic14_emitcode("subb","a,%s",l);
1721 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1724 /* if any remaining bytes in the result */
1725 /* we just need to propagate the sign */
1726 if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1727 pic14_emitcode("rlc","a");
1728 pic14_emitcode("subb","a,acc");
1730 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1734 /* release the aops */
1735 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1736 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1739 /*-----------------------------------------------------------------*/
1740 /* saveRegisters - will look for a call and save the registers */
1741 /*-----------------------------------------------------------------*/
1742 static void saveRegisters(iCode *lic)
1749 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1751 for (ic = lic ; ic ; ic = ic->next)
1752 if (ic->op == CALL || ic->op == PCALL)
1756 fprintf(stderr,"found parameter push with no function call\n");
1760 /* if the registers have been saved already then
1762 if (ic->regsSaved || (OP_SYMBOL(IC_LEFT(ic))->calleeSave))
1765 /* find the registers in use at this time
1766 and push them away to safety */
1767 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1771 if (options.useXstack) {
1772 if (bitVectBitValue(rsave,R0_IDX))
1773 pic14_emitcode("mov","b,r0");
1774 pic14_emitcode("mov","r0,%s",spname);
1775 for (i = 0 ; i < pic14_nRegs ; i++) {
1776 if (bitVectBitValue(rsave,i)) {
1778 pic14_emitcode("mov","a,b");
1780 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1781 pic14_emitcode("movx","@r0,a");
1782 pic14_emitcode("inc","r0");
1785 pic14_emitcode("mov","%s,r0",spname);
1786 if (bitVectBitValue(rsave,R0_IDX))
1787 pic14_emitcode("mov","r0,b");
1789 for (i = 0 ; i < pic14_nRegs ; i++) {
1790 if (bitVectBitValue(rsave,i))
1791 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1794 detype = getSpec(operandType(IC_LEFT(ic)));
1796 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
1797 IS_ISR(currFunc->etype) &&
1800 saverbank(SPEC_BANK(detype),ic,TRUE);
1803 /*-----------------------------------------------------------------*/
1804 /* unsaveRegisters - pop the pushed registers */
1805 /*-----------------------------------------------------------------*/
1806 static void unsaveRegisters (iCode *ic)
1811 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1812 /* find the registers in use at this time
1813 and push them away to safety */
1814 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1817 if (options.useXstack) {
1818 pic14_emitcode("mov","r0,%s",spname);
1819 for (i = pic14_nRegs ; i >= 0 ; i--) {
1820 if (bitVectBitValue(rsave,i)) {
1821 pic14_emitcode("dec","r0");
1822 pic14_emitcode("movx","a,@r0");
1824 pic14_emitcode("mov","b,a");
1826 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1830 pic14_emitcode("mov","%s,r0",spname);
1831 if (bitVectBitValue(rsave,R0_IDX))
1832 pic14_emitcode("mov","r0,b");
1834 for (i = pic14_nRegs ; i >= 0 ; i--) {
1835 if (bitVectBitValue(rsave,i))
1836 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1842 /*-----------------------------------------------------------------*/
1844 /*-----------------------------------------------------------------*/
1845 static void pushSide(operand * oper, int size)
1848 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1850 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1851 if (AOP_TYPE(oper) != AOP_REG &&
1852 AOP_TYPE(oper) != AOP_DIR &&
1854 pic14_emitcode("mov","a,%s",l);
1855 pic14_emitcode("push","acc");
1857 pic14_emitcode("push","%s",l);
1861 /*-----------------------------------------------------------------*/
1862 /* assignResultValue - */
1863 /*-----------------------------------------------------------------*/
1864 static void assignResultValue(operand * oper)
1867 int size = AOP_SIZE(oper);
1869 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1871 // The last byte in the assignment is in W
1872 aopPut(AOP(oper),"W",size-1);
1876 aopPut(AOP(oper),fReturn[offset],offset);
1884 /*-----------------------------------------------------------------*/
1885 /* genXpush - pushes onto the external stack */
1886 /*-----------------------------------------------------------------*/
1887 static void genXpush (iCode *ic)
1889 asmop *aop = newAsmop(0);
1891 int size,offset = 0;
1893 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1894 aopOp(IC_LEFT(ic),ic,FALSE);
1895 r = getFreePtr(ic,&aop,FALSE);
1898 pic14_emitcode("mov","%s,_spx",r->name);
1900 size = AOP_SIZE(IC_LEFT(ic));
1903 char *l = aopGet(AOP(IC_LEFT(ic)),
1904 offset++,FALSE,FALSE);
1906 pic14_emitcode("movx","@%s,a",r->name);
1907 pic14_emitcode("inc","%s",r->name);
1912 pic14_emitcode("mov","_spx,%s",r->name);
1914 freeAsmop(NULL,aop,ic,TRUE);
1915 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
1918 /*-----------------------------------------------------------------*/
1919 /* genIpush - genrate code for pushing this gets a little complex */
1920 /*-----------------------------------------------------------------*/
1921 static void genIpush (iCode *ic)
1923 int size, offset = 0 ;
1927 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1928 /* if this is not a parm push : ie. it is spill push
1929 and spill push is always done on the local stack */
1930 if (!ic->parmPush) {
1932 /* and the item is spilt then do nothing */
1933 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
1936 aopOp(IC_LEFT(ic),ic,FALSE);
1937 size = AOP_SIZE(IC_LEFT(ic));
1938 /* push it on the stack */
1940 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1945 pic14_emitcode("push","%s",l);
1950 /* this is a paramter push: in this case we call
1951 the routine to find the call and save those
1952 registers that need to be saved */
1955 /* if use external stack then call the external
1956 stack pushing routine */
1957 if (options.useXstack) {
1962 /* then do the push */
1963 aopOp(IC_LEFT(ic),ic,FALSE);
1966 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
1967 size = AOP_SIZE(IC_LEFT(ic));
1970 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1971 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
1972 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
1974 pic14_emitcode("mov","a,%s",l);
1975 pic14_emitcode("push","acc");
1977 pic14_emitcode("push","%s",l);
1980 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
1983 /*-----------------------------------------------------------------*/
1984 /* genIpop - recover the registers: can happen only for spilling */
1985 /*-----------------------------------------------------------------*/
1986 static void genIpop (iCode *ic)
1991 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1992 /* if the temp was not pushed then */
1993 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
1996 aopOp(IC_LEFT(ic),ic,FALSE);
1997 size = AOP_SIZE(IC_LEFT(ic));
2000 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2003 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2006 /*-----------------------------------------------------------------*/
2007 /* unsaverbank - restores the resgister bank from stack */
2008 /*-----------------------------------------------------------------*/
2009 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2015 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2017 if (options.useXstack) {
2019 r = getFreePtr(ic,&aop,FALSE);
2022 pic14_emitcode("mov","%s,_spx",r->name);
2023 pic14_emitcode("movx","a,@%s",r->name);
2024 pic14_emitcode("mov","psw,a");
2025 pic14_emitcode("dec","%s",r->name);
2028 pic14_emitcode ("pop","psw");
2031 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2032 if (options.useXstack) {
2033 pic14_emitcode("movx","a,@%s",r->name);
2034 //pic14_emitcode("mov","(%s+%d),a",
2035 // regspic14[i].base,8*bank+regspic14[i].offset);
2036 pic14_emitcode("dec","%s",r->name);
2039 pic14_emitcode("pop",""); //"(%s+%d)",
2040 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2043 if (options.useXstack) {
2045 pic14_emitcode("mov","_spx,%s",r->name);
2046 freeAsmop(NULL,aop,ic,TRUE);
2051 /*-----------------------------------------------------------------*/
2052 /* saverbank - saves an entire register bank on the stack */
2053 /*-----------------------------------------------------------------*/
2054 static void saverbank (int bank, iCode *ic, bool pushPsw)
2060 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2061 if (options.useXstack) {
2064 r = getFreePtr(ic,&aop,FALSE);
2065 pic14_emitcode("mov","%s,_spx",r->name);
2069 for (i = 0 ; i < pic14_nRegs ;i++) {
2070 if (options.useXstack) {
2071 pic14_emitcode("inc","%s",r->name);
2072 //pic14_emitcode("mov","a,(%s+%d)",
2073 // regspic14[i].base,8*bank+regspic14[i].offset);
2074 pic14_emitcode("movx","@%s,a",r->name);
2076 pic14_emitcode("push","");// "(%s+%d)",
2077 //regspic14[i].base,8*bank+regspic14[i].offset);
2081 if (options.useXstack) {
2082 pic14_emitcode("mov","a,psw");
2083 pic14_emitcode("movx","@%s,a",r->name);
2084 pic14_emitcode("inc","%s",r->name);
2085 pic14_emitcode("mov","_spx,%s",r->name);
2086 freeAsmop (NULL,aop,ic,TRUE);
2089 pic14_emitcode("push","psw");
2091 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2097 /*-----------------------------------------------------------------*/
2098 /* genCall - generates a call statement */
2099 /*-----------------------------------------------------------------*/
2100 static void genCall (iCode *ic)
2104 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2106 /* if caller saves & we have not saved then */
2110 /* if we are calling a function that is not using
2111 the same register bank then we need to save the
2112 destination registers on the stack */
2113 detype = getSpec(operandType(IC_LEFT(ic)));
2115 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
2116 IS_ISR(currFunc->etype) &&
2119 saverbank(SPEC_BANK(detype),ic,TRUE);
2121 /* if send set is not empty the assign */
2125 for (sic = setFirstItem(_G.sendSet) ; sic ;
2126 sic = setNextItem(_G.sendSet)) {
2127 int size, offset = 0;
2129 aopOp(IC_LEFT(sic),sic,FALSE);
2130 size = AOP_SIZE(IC_LEFT(sic));
2132 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2134 DEBUGpic14_emitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
2136 if (strcmp(l,fReturn[offset])) {
2138 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2139 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2140 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2141 //pic14_emitcode("movlw","%s",l);
2143 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2144 //pic14_emitcode("movf","%s,w",l);
2146 // The last one is passed in W
2148 pic14_emitcode("movwf","%s",fReturn[offset]);
2152 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2157 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2158 OP_SYMBOL(IC_LEFT(ic))->rname :
2159 OP_SYMBOL(IC_LEFT(ic))->name));
2161 pic14_emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2162 OP_SYMBOL(IC_LEFT(ic))->rname :
2163 OP_SYMBOL(IC_LEFT(ic))->name));
2165 /* if we need assign a result value */
2166 if ((IS_ITEMP(IC_RESULT(ic)) &&
2167 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2168 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2169 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2172 aopOp(IC_RESULT(ic),ic,FALSE);
2175 assignResultValue(IC_RESULT(ic));
2177 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2180 /* adjust the stack for parameters if
2182 if (ic->parmBytes) {
2184 if (ic->parmBytes > 3) {
2185 pic14_emitcode("mov","a,%s",spname);
2186 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2187 pic14_emitcode("mov","%s,a",spname);
2189 for ( i = 0 ; i < ic->parmBytes ;i++)
2190 pic14_emitcode("dec","%s",spname);
2194 /* if register bank was saved then pop them */
2196 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2198 /* if we hade saved some registers then unsave them */
2199 if (ic->regsSaved && !(OP_SYMBOL(IC_LEFT(ic))->calleeSave))
2200 unsaveRegisters (ic);
2205 /*-----------------------------------------------------------------*/
2206 /* genPcall - generates a call by pointer statement */
2207 /*-----------------------------------------------------------------*/
2208 static void genPcall (iCode *ic)
2211 symbol *rlbl = newiTempLabel(NULL);
2214 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2215 /* if caller saves & we have not saved then */
2219 /* if we are calling a function that is not using
2220 the same register bank then we need to save the
2221 destination registers on the stack */
2222 detype = getSpec(operandType(IC_LEFT(ic)));
2224 IS_ISR(currFunc->etype) &&
2225 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)))
2226 saverbank(SPEC_BANK(detype),ic,TRUE);
2229 /* push the return address on to the stack */
2230 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2231 pic14_emitcode("push","acc");
2232 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2233 pic14_emitcode("push","acc");
2235 if (options.model == MODEL_FLAT24)
2237 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2238 pic14_emitcode("push","acc");
2241 /* now push the calling address */
2242 aopOp(IC_LEFT(ic),ic,FALSE);
2244 pushSide(IC_LEFT(ic), FPTRSIZE);
2246 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2248 /* if send set is not empty the assign */
2252 for (sic = setFirstItem(_G.sendSet) ; sic ;
2253 sic = setNextItem(_G.sendSet)) {
2254 int size, offset = 0;
2255 aopOp(IC_LEFT(sic),sic,FALSE);
2256 size = AOP_SIZE(IC_LEFT(sic));
2258 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2260 if (strcmp(l,fReturn[offset]))
2261 pic14_emitcode("mov","%s,%s",
2266 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2271 pic14_emitcode("ret","");
2272 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2275 /* if we need assign a result value */
2276 if ((IS_ITEMP(IC_RESULT(ic)) &&
2277 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2278 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2279 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2282 aopOp(IC_RESULT(ic),ic,FALSE);
2285 assignResultValue(IC_RESULT(ic));
2287 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2290 /* adjust the stack for parameters if
2292 if (ic->parmBytes) {
2294 if (ic->parmBytes > 3) {
2295 pic14_emitcode("mov","a,%s",spname);
2296 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2297 pic14_emitcode("mov","%s,a",spname);
2299 for ( i = 0 ; i < ic->parmBytes ;i++)
2300 pic14_emitcode("dec","%s",spname);
2304 /* if register bank was saved then unsave them */
2306 (SPEC_BANK(currFunc->etype) !=
2308 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2310 /* if we hade saved some registers then
2313 unsaveRegisters (ic);
2317 /*-----------------------------------------------------------------*/
2318 /* resultRemat - result is rematerializable */
2319 /*-----------------------------------------------------------------*/
2320 static int resultRemat (iCode *ic)
2322 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2323 if (SKIP_IC(ic) || ic->op == IFX)
2326 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2327 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2328 if (sym->remat && !POINTER_SET(ic))
2335 #if defined(__BORLANDC__) || defined(_MSC_VER)
2336 #define STRCASECMP stricmp
2338 #define STRCASECMP strcasecmp
2341 /*-----------------------------------------------------------------*/
2342 /* inExcludeList - return 1 if the string is in exclude Reg list */
2343 /*-----------------------------------------------------------------*/
2344 static bool inExcludeList(char *s)
2348 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2349 if (options.excludeRegs[i] &&
2350 STRCASECMP(options.excludeRegs[i],"none") == 0)
2353 for ( i = 0 ; options.excludeRegs[i]; i++) {
2354 if (options.excludeRegs[i] &&
2355 STRCASECMP(s,options.excludeRegs[i]) == 0)
2361 /*-----------------------------------------------------------------*/
2362 /* genFunction - generated code for function entry */
2363 /*-----------------------------------------------------------------*/
2364 static void genFunction (iCode *ic)
2369 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2370 labelOffset += FUNCTION_LABEL_INC;
2373 /* create the function header */
2374 pic14_emitcode(";","-----------------------------------------");
2375 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2376 pic14_emitcode(";","-----------------------------------------");
2378 pic14_emitcode("","%s:",sym->rname);
2379 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2381 fetype = getSpec(operandType(IC_LEFT(ic)));
2383 /* if critical function then turn interrupts off */
2384 if (SPEC_CRTCL(fetype))
2385 pic14_emitcode("clr","ea");
2387 /* here we need to generate the equates for the
2388 register bank if required */
2390 if (SPEC_BANK(fetype) != rbank) {
2393 rbank = SPEC_BANK(fetype);
2394 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2395 if (strcmp(regspic14[i].base,"0") == 0)
2396 pic14_emitcode("","%s = 0x%02x",
2398 8*rbank+regspic14[i].offset);
2400 pic14_emitcode ("","%s = %s + 0x%02x",
2403 8*rbank+regspic14[i].offset);
2408 /* if this is an interrupt service routine then
2409 save acc, b, dpl, dph */
2410 if (IS_ISR(sym->etype)) {
2412 if (!inExcludeList("acc"))
2413 pic14_emitcode ("push","acc");
2414 if (!inExcludeList("b"))
2415 pic14_emitcode ("push","b");
2416 if (!inExcludeList("dpl"))
2417 pic14_emitcode ("push","dpl");
2418 if (!inExcludeList("dph"))
2419 pic14_emitcode ("push","dph");
2420 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2422 pic14_emitcode ("push", "dpx");
2423 /* Make sure we're using standard DPTR */
2424 pic14_emitcode ("push", "dps");
2425 pic14_emitcode ("mov", "dps, #0x00");
2426 if (options.stack10bit)
2428 /* This ISR could conceivably use DPTR2. Better save it. */
2429 pic14_emitcode ("push", "dpl1");
2430 pic14_emitcode ("push", "dph1");
2431 pic14_emitcode ("push", "dpx1");
2434 /* if this isr has no bank i.e. is going to
2435 run with bank 0 , then we need to save more
2437 if (!SPEC_BANK(sym->etype)) {
2439 /* if this function does not call any other
2440 function then we can be economical and
2441 save only those registers that are used */
2442 if (! sym->hasFcall) {
2445 /* if any registers used */
2446 if (sym->regsUsed) {
2447 /* save the registers used */
2448 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2449 if (bitVectBitValue(sym->regsUsed,i) ||
2450 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2451 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2456 /* this function has a function call cannot
2457 determines register usage so we will have the
2459 saverbank(0,ic,FALSE);
2463 /* if callee-save to be used for this function
2464 then save the registers being used in this function */
2465 if (sym->calleeSave) {
2468 /* if any registers used */
2469 if (sym->regsUsed) {
2470 /* save the registers used */
2471 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2472 if (bitVectBitValue(sym->regsUsed,i) ||
2473 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2474 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2482 /* set the register bank to the desired value */
2483 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) {
2484 pic14_emitcode("push","psw");
2485 pic14_emitcode("mov","psw,#0x%02x",(SPEC_BANK(sym->etype) << 3)&0x00ff);
2488 if (IS_RENT(sym->etype) || options.stackAuto) {
2490 if (options.useXstack) {
2491 pic14_emitcode("mov","r0,%s",spname);
2492 pic14_emitcode("mov","a,_bp");
2493 pic14_emitcode("movx","@r0,a");
2494 pic14_emitcode("inc","%s",spname);
2498 /* set up the stack */
2499 pic14_emitcode ("push","_bp"); /* save the callers stack */
2501 pic14_emitcode ("mov","_bp,%s",spname);
2504 /* adjust the stack for the function */
2509 werror(W_STACK_OVERFLOW,sym->name);
2511 if (i > 3 && sym->recvSize < 4) {
2513 pic14_emitcode ("mov","a,sp");
2514 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2515 pic14_emitcode ("mov","sp,a");
2520 pic14_emitcode("inc","sp");
2525 pic14_emitcode ("mov","a,_spx");
2526 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2527 pic14_emitcode ("mov","_spx,a");
2532 /*-----------------------------------------------------------------*/
2533 /* genEndFunction - generates epilogue for functions */
2534 /*-----------------------------------------------------------------*/
2535 static void genEndFunction (iCode *ic)
2537 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2539 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2541 if (IS_RENT(sym->etype) || options.stackAuto)
2543 pic14_emitcode ("mov","%s,_bp",spname);
2546 /* if use external stack but some variables were
2547 added to the local stack then decrement the
2549 if (options.useXstack && sym->stack) {
2550 pic14_emitcode("mov","a,sp");
2551 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2552 pic14_emitcode("mov","sp,a");
2556 if ((IS_RENT(sym->etype) || options.stackAuto)) {
2557 if (options.useXstack) {
2558 pic14_emitcode("mov","r0,%s",spname);
2559 pic14_emitcode("movx","a,@r0");
2560 pic14_emitcode("mov","_bp,a");
2561 pic14_emitcode("dec","%s",spname);
2565 pic14_emitcode ("pop","_bp");
2569 /* restore the register bank */
2570 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype))
2571 pic14_emitcode ("pop","psw");
2573 if (IS_ISR(sym->etype)) {
2575 /* now we need to restore the registers */
2576 /* if this isr has no bank i.e. is going to
2577 run with bank 0 , then we need to save more
2579 if (!SPEC_BANK(sym->etype)) {
2581 /* if this function does not call any other
2582 function then we can be economical and
2583 save only those registers that are used */
2584 if (! sym->hasFcall) {
2587 /* if any registers used */
2588 if (sym->regsUsed) {
2589 /* save the registers used */
2590 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2591 if (bitVectBitValue(sym->regsUsed,i) ||
2592 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2593 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2598 /* this function has a function call cannot
2599 determines register usage so we will have the
2601 unsaverbank(0,ic,FALSE);
2605 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2607 if (options.stack10bit)
2609 pic14_emitcode ("pop", "dpx1");
2610 pic14_emitcode ("pop", "dph1");
2611 pic14_emitcode ("pop", "dpl1");
2613 pic14_emitcode ("pop", "dps");
2614 pic14_emitcode ("pop", "dpx");
2616 if (!inExcludeList("dph"))
2617 pic14_emitcode ("pop","dph");
2618 if (!inExcludeList("dpl"))
2619 pic14_emitcode ("pop","dpl");
2620 if (!inExcludeList("b"))
2621 pic14_emitcode ("pop","b");
2622 if (!inExcludeList("acc"))
2623 pic14_emitcode ("pop","acc");
2625 if (SPEC_CRTCL(sym->etype))
2626 pic14_emitcode("setb","ea");
2628 /* if debug then send end of function */
2629 /* if (options.debug && currFunc) { */
2632 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2633 FileBaseName(ic->filename),currFunc->lastLine,
2634 ic->level,ic->block);
2635 if (IS_STATIC(currFunc->etype))
2636 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2638 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2642 pic14_emitcode ("reti","");
2645 if (SPEC_CRTCL(sym->etype))
2646 pic14_emitcode("setb","ea");
2648 if (sym->calleeSave) {
2651 /* if any registers used */
2652 if (sym->regsUsed) {
2653 /* save the registers used */
2654 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2655 if (bitVectBitValue(sym->regsUsed,i) ||
2656 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2657 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2663 /* if debug then send end of function */
2666 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2667 FileBaseName(ic->filename),currFunc->lastLine,
2668 ic->level,ic->block);
2669 if (IS_STATIC(currFunc->etype))
2670 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2672 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2676 pic14_emitcode ("return","");
2677 emitpcode(POC_RETURN,NULL);
2679 /* Mark the end of a function */
2680 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2685 /*-----------------------------------------------------------------*/
2686 /* genRet - generate code for return statement */
2687 /*-----------------------------------------------------------------*/
2688 static void genRet (iCode *ic)
2690 int size,offset = 0 , pushed = 0;
2692 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2693 /* if we have no return value then
2694 just generate the "ret" */
2698 /* we have something to return then
2699 move the return value into place */
2700 aopOp(IC_LEFT(ic),ic,FALSE);
2701 size = AOP_SIZE(IC_LEFT(ic));
2705 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2707 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2709 pic14_emitcode("push","%s",l);
2712 l = aopGet(AOP(IC_LEFT(ic)),offset,
2714 if (strcmp(fReturn[offset],l)) {
2715 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2716 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
2717 pic14_emitcode("movlw","%s",l);
2719 pic14_emitcode("movf","%s,w",l);
2721 pic14_emitcode("movwf","%s",fReturn[offset]);
2730 if (strcmp(fReturn[pushed],"a"))
2731 pic14_emitcode("pop",fReturn[pushed]);
2733 pic14_emitcode("pop","acc");
2736 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2739 /* generate a jump to the return label
2740 if the next is not the return statement */
2741 if (!(ic->next && ic->next->op == LABEL &&
2742 IC_LABEL(ic->next) == returnLabel))
2744 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2748 /*-----------------------------------------------------------------*/
2749 /* genLabel - generates a label */
2750 /*-----------------------------------------------------------------*/
2751 static void genLabel (iCode *ic)
2753 /* special case never generate */
2754 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2755 if (IC_LABEL(ic) == entryLabel)
2758 emitpLabel(IC_LABEL(ic)->key+100 + labelOffset);
2759 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2762 /*-----------------------------------------------------------------*/
2763 /* genGoto - generates a goto */
2764 /*-----------------------------------------------------------------*/
2766 static void genGoto (iCode *ic)
2768 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2771 /*-----------------------------------------------------------------*/
2772 /* findLabelBackwards: walks back through the iCode chain looking */
2773 /* for the given label. Returns number of iCode instructions */
2774 /* between that label and given ic. */
2775 /* Returns zero if label not found. */
2776 /*-----------------------------------------------------------------*/
2778 static int findLabelBackwards(iCode *ic, int key)
2782 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2788 if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2790 /* printf("findLabelBackwards = %d\n", count); */
2799 /*-----------------------------------------------------------------*/
2800 /* genMultbits :- multiplication of bits */
2801 /*-----------------------------------------------------------------*/
2802 static void genMultbits (operand *left,
2806 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2808 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2809 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2810 pic14_outBitC(result);
2814 /*-----------------------------------------------------------------*/
2815 /* genMultOneByte : 8 bit multiplication & division */
2816 /*-----------------------------------------------------------------*/
2817 static void genMultOneByte (operand *left,
2821 sym_link *opetype = operandType(result);
2826 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2827 /* (if two literals, the value is computed before) */
2828 /* if one literal, literal on the right */
2829 if (AOP_TYPE(left) == AOP_LIT){
2835 size = AOP_SIZE(result);
2836 /* signed or unsigned */
2837 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2838 l = aopGet(AOP(left),0,FALSE,FALSE);
2840 pic14_emitcode("mul","ab");
2841 /* if result size = 1, mul signed = mul unsigned */
2842 aopPut(AOP(result),"a",0);
2844 if (SPEC_USIGN(opetype)){
2845 aopPut(AOP(result),"b",1);
2847 /* for filling the MSBs */
2848 pic14_emitcode("clr","a");
2851 pic14_emitcode("mov","a,b");
2853 /* adjust the MSB if left or right neg */
2855 /* if one literal */
2856 if (AOP_TYPE(right) == AOP_LIT){
2857 /* AND literal negative */
2858 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2859 /* adjust MSB (c==0 after mul) */
2860 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2864 lbl = newiTempLabel(NULL);
2865 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2866 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2867 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2868 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2869 lbl = newiTempLabel(NULL);
2870 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2871 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2872 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2875 lbl = newiTempLabel(NULL);
2876 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2877 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2878 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2879 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2880 lbl = newiTempLabel(NULL);
2881 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2882 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2883 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2885 aopPut(AOP(result),"a",1);
2888 pic14_emitcode("rlc","a");
2889 pic14_emitcode("subb","a,acc");
2896 aopPut(AOP(result),"a",offset++);
2900 /*-----------------------------------------------------------------*/
2901 /* genMult - generates code for multiplication */
2902 /*-----------------------------------------------------------------*/
2903 static void genMult (iCode *ic)
2905 operand *left = IC_LEFT(ic);
2906 operand *right = IC_RIGHT(ic);
2907 operand *result= IC_RESULT(ic);
2909 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2910 /* assign the amsops */
2911 aopOp (left,ic,FALSE);
2912 aopOp (right,ic,FALSE);
2913 aopOp (result,ic,TRUE);
2915 /* special cases first */
2917 if (AOP_TYPE(left) == AOP_CRY &&
2918 AOP_TYPE(right)== AOP_CRY) {
2919 genMultbits(left,right,result);
2923 /* if both are of size == 1 */
2924 if (AOP_SIZE(left) == 1 &&
2925 AOP_SIZE(right) == 1 ) {
2926 genMultOneByte(left,right,result);
2930 /* should have been converted to function call */
2934 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2935 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2936 freeAsmop(result,NULL,ic,TRUE);
2939 /*-----------------------------------------------------------------*/
2940 /* genDivbits :- division of bits */
2941 /*-----------------------------------------------------------------*/
2942 static void genDivbits (operand *left,
2949 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2950 /* the result must be bit */
2951 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
2952 l = aopGet(AOP(left),0,FALSE,FALSE);
2956 pic14_emitcode("div","ab");
2957 pic14_emitcode("rrc","a");
2958 aopPut(AOP(result),"c",0);
2961 /*-----------------------------------------------------------------*/
2962 /* genDivOneByte : 8 bit division */
2963 /*-----------------------------------------------------------------*/
2964 static void genDivOneByte (operand *left,
2968 sym_link *opetype = operandType(result);
2973 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2974 size = AOP_SIZE(result) - 1;
2976 /* signed or unsigned */
2977 if (SPEC_USIGN(opetype)) {
2978 /* unsigned is easy */
2979 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2980 l = aopGet(AOP(left),0,FALSE,FALSE);
2982 pic14_emitcode("div","ab");
2983 aopPut(AOP(result),"a",0);
2985 aopPut(AOP(result),zero,offset++);
2989 /* signed is a little bit more difficult */
2991 /* save the signs of the operands */
2992 l = aopGet(AOP(left),0,FALSE,FALSE);
2994 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
2995 pic14_emitcode("push","acc"); /* save it on the stack */
2997 /* now sign adjust for both left & right */
2998 l = aopGet(AOP(right),0,FALSE,FALSE);
3000 lbl = newiTempLabel(NULL);
3001 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3002 pic14_emitcode("cpl","a");
3003 pic14_emitcode("inc","a");
3004 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3005 pic14_emitcode("mov","b,a");
3007 /* sign adjust left side */
3008 l = aopGet(AOP(left),0,FALSE,FALSE);
3011 lbl = newiTempLabel(NULL);
3012 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3013 pic14_emitcode("cpl","a");
3014 pic14_emitcode("inc","a");
3015 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3017 /* now the division */
3018 pic14_emitcode("div","ab");
3019 /* we are interested in the lower order
3021 pic14_emitcode("mov","b,a");
3022 lbl = newiTempLabel(NULL);
3023 pic14_emitcode("pop","acc");
3024 /* if there was an over flow we don't
3025 adjust the sign of the result */
3026 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3027 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3029 pic14_emitcode("clr","a");
3030 pic14_emitcode("subb","a,b");
3031 pic14_emitcode("mov","b,a");
3032 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3034 /* now we are done */
3035 aopPut(AOP(result),"b",0);
3037 pic14_emitcode("mov","c,b.7");
3038 pic14_emitcode("subb","a,acc");
3041 aopPut(AOP(result),"a",offset++);
3045 /*-----------------------------------------------------------------*/
3046 /* genDiv - generates code for division */
3047 /*-----------------------------------------------------------------*/
3048 static void genDiv (iCode *ic)
3050 operand *left = IC_LEFT(ic);
3051 operand *right = IC_RIGHT(ic);
3052 operand *result= IC_RESULT(ic);
3054 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3055 /* assign the amsops */
3056 aopOp (left,ic,FALSE);
3057 aopOp (right,ic,FALSE);
3058 aopOp (result,ic,TRUE);
3060 /* special cases first */
3062 if (AOP_TYPE(left) == AOP_CRY &&
3063 AOP_TYPE(right)== AOP_CRY) {
3064 genDivbits(left,right,result);
3068 /* if both are of size == 1 */
3069 if (AOP_SIZE(left) == 1 &&
3070 AOP_SIZE(right) == 1 ) {
3071 genDivOneByte(left,right,result);
3075 /* should have been converted to function call */
3078 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3079 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3080 freeAsmop(result,NULL,ic,TRUE);
3083 /*-----------------------------------------------------------------*/
3084 /* genModbits :- modulus of bits */
3085 /*-----------------------------------------------------------------*/
3086 static void genModbits (operand *left,
3093 /* the result must be bit */
3094 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3095 l = aopGet(AOP(left),0,FALSE,FALSE);
3099 pic14_emitcode("div","ab");
3100 pic14_emitcode("mov","a,b");
3101 pic14_emitcode("rrc","a");
3102 aopPut(AOP(result),"c",0);
3105 /*-----------------------------------------------------------------*/
3106 /* genModOneByte : 8 bit modulus */
3107 /*-----------------------------------------------------------------*/
3108 static void genModOneByte (operand *left,
3112 sym_link *opetype = operandType(result);
3116 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3117 /* signed or unsigned */
3118 if (SPEC_USIGN(opetype)) {
3119 /* unsigned is easy */
3120 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3121 l = aopGet(AOP(left),0,FALSE,FALSE);
3123 pic14_emitcode("div","ab");
3124 aopPut(AOP(result),"b",0);
3128 /* signed is a little bit more difficult */
3130 /* save the signs of the operands */
3131 l = aopGet(AOP(left),0,FALSE,FALSE);
3134 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3135 pic14_emitcode("push","acc"); /* save it on the stack */
3137 /* now sign adjust for both left & right */
3138 l = aopGet(AOP(right),0,FALSE,FALSE);
3141 lbl = newiTempLabel(NULL);
3142 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3143 pic14_emitcode("cpl","a");
3144 pic14_emitcode("inc","a");
3145 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3146 pic14_emitcode("mov","b,a");
3148 /* sign adjust left side */
3149 l = aopGet(AOP(left),0,FALSE,FALSE);
3152 lbl = newiTempLabel(NULL);
3153 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3154 pic14_emitcode("cpl","a");
3155 pic14_emitcode("inc","a");
3156 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3158 /* now the multiplication */
3159 pic14_emitcode("div","ab");
3160 /* we are interested in the lower order
3162 lbl = newiTempLabel(NULL);
3163 pic14_emitcode("pop","acc");
3164 /* if there was an over flow we don't
3165 adjust the sign of the result */
3166 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3167 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3169 pic14_emitcode("clr","a");
3170 pic14_emitcode("subb","a,b");
3171 pic14_emitcode("mov","b,a");
3172 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3174 /* now we are done */
3175 aopPut(AOP(result),"b",0);
3179 /*-----------------------------------------------------------------*/
3180 /* genMod - generates code for division */
3181 /*-----------------------------------------------------------------*/
3182 static void genMod (iCode *ic)
3184 operand *left = IC_LEFT(ic);
3185 operand *right = IC_RIGHT(ic);
3186 operand *result= IC_RESULT(ic);
3188 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3189 /* assign the amsops */
3190 aopOp (left,ic,FALSE);
3191 aopOp (right,ic,FALSE);
3192 aopOp (result,ic,TRUE);
3194 /* special cases first */
3196 if (AOP_TYPE(left) == AOP_CRY &&
3197 AOP_TYPE(right)== AOP_CRY) {
3198 genModbits(left,right,result);
3202 /* if both are of size == 1 */
3203 if (AOP_SIZE(left) == 1 &&
3204 AOP_SIZE(right) == 1 ) {
3205 genModOneByte(left,right,result);
3209 /* should have been converted to function call */
3213 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3214 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3215 freeAsmop(result,NULL,ic,TRUE);
3218 /*-----------------------------------------------------------------*/
3219 /* genIfxJump :- will create a jump depending on the ifx */
3220 /*-----------------------------------------------------------------*/
3221 static void genIfxJump (iCode *ic, char *jval)
3224 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3225 /* if true label then we jump if condition
3227 if ( IC_TRUE(ic) ) {
3229 if(strcmp(jval,"a") == 0)
3231 else if (strcmp(jval,"c") == 0)
3234 //pCodeOp *p = popGetWithString(jval);
3236 //emitpcode(POC_BTFSC, p);
3237 emitpcode(POC_BTFSC, newpCodeOpBit(jval,0));
3238 //pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",jval,jval);
3241 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3242 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3246 /* false label is present */
3247 if(strcmp(jval,"a") == 0)
3249 else if (strcmp(jval,"c") == 0)
3252 //pCodeOp *p = popGetWithString(jval);
3254 //emitpcode(POC_BTFSS, p);
3255 emitpcode(POC_BTFSS, newpCodeOpBit(jval,0));
3257 // pic14_emitcode("btfss","(%s >> 3),(%s & 7)",jval,jval);
3260 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3261 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3266 /* mark the icode as generated */
3270 /*-----------------------------------------------------------------*/
3272 /*-----------------------------------------------------------------*/
3273 static void genSkip(iCode *ifx,int status_bit)
3278 if ( IC_TRUE(ifx) ) {
3279 switch(status_bit) {
3294 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3295 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3299 switch(status_bit) {
3313 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3314 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3320 /*-----------------------------------------------------------------*/
3322 /*-----------------------------------------------------------------*/
3323 static void genSkipc(iCode *ifx, int condition)
3334 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3336 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3339 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3341 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3345 /*-----------------------------------------------------------------*/
3347 /*-----------------------------------------------------------------*/
3348 static void genSkipz(iCode *ifx, int condition)
3359 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3361 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3364 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3366 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3369 /*-----------------------------------------------------------------*/
3370 /* genCmp :- greater or less than comparison */
3371 /*-----------------------------------------------------------------*/
3372 static void genCmp (operand *left,operand *right,
3373 operand *result, iCode *ifx, int sign)
3375 int size, offset = 0 ;
3376 unsigned long lit = 0L,i = 0;
3378 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3379 /* if left & right are bit variables */
3380 if (AOP_TYPE(left) == AOP_CRY &&
3381 AOP_TYPE(right) == AOP_CRY ) {
3382 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3383 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3385 /* subtract right from left if at the
3386 end the carry flag is set then we know that
3387 left is greater than right */
3388 size = max(AOP_SIZE(left),AOP_SIZE(right));
3390 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3391 if((size == 1) && !sign &&
3392 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3393 symbol *lbl = newiTempLabel(NULL);
3394 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3395 aopGet(AOP(left),offset,FALSE,FALSE),
3396 aopGet(AOP(right),offset,FALSE,FALSE),
3398 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3401 if(AOP_TYPE(right) == AOP_LIT) {
3403 DEBUGpic14_emitcode(";right lit","%d",sign);
3405 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3408 i = (lit >> (size*8)) & 0xff;
3410 emitpcode(POC_MOVFW, popGet(AOP(left),size,FALSE,FALSE));
3411 pic14_emitcode("movf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
3412 genSkipz(ifx,IC_TRUE(ifx) == NULL);
3414 emitpcode(POC_MOVLW, popGetLit(i));
3415 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3417 pic14_emitcode("movlw","0x%x",i);
3418 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
3419 genSkipc(ifx,IC_TRUE(ifx) == NULL);
3426 if(AOP_TYPE(left) == AOP_LIT) {
3428 DEBUGpic14_emitcode(";left lit","%d",sign);
3430 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit))+1;
3434 i = (lit >> (size*8)) & 0xff;
3436 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3437 pic14_emitcode("movf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3438 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3439 } else if( i == 1 ) {
3440 emitpcode(POC_DECFW, popGet(AOP(right),size,FALSE,FALSE));
3441 pic14_emitcode("decf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3442 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3445 emitpcode(POC_MOVLW, popGetLit(i));
3446 emitpcode(POC_SUBFW, popGet(AOP(right),size,FALSE,FALSE));
3448 pic14_emitcode("movlw","0x%x",i);
3449 pic14_emitcode("subwf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3450 genSkipc(ifx,IC_TRUE(ifx) != NULL);
3459 DEBUGpic14_emitcode(";sign","%d",sign);
3461 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3462 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3464 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3465 emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3470 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3472 emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3473 emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE));
3476 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3478 pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3479 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3487 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3488 pic14_outBitC(result);
3490 /* if the result is used in the next
3491 ifx conditional branch then generate
3492 code a little differently */
3494 genIfxJump (ifx,"c");
3496 pic14_outBitC(result);
3497 /* leave the result in acc */
3502 /*-----------------------------------------------------------------*/
3503 /* genCmpGt :- greater than comparison */
3504 /*-----------------------------------------------------------------*/
3505 static void genCmpGt (iCode *ic, iCode *ifx)
3507 operand *left, *right, *result;
3508 sym_link *letype , *retype;
3511 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3513 right= IC_RIGHT(ic);
3514 result = IC_RESULT(ic);
3516 letype = getSpec(operandType(left));
3517 retype =getSpec(operandType(right));
3518 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3519 /* assign the amsops */
3520 aopOp (left,ic,FALSE);
3521 aopOp (right,ic,FALSE);
3522 aopOp (result,ic,TRUE);
3524 genCmp(right, left, result, ifx, sign);
3526 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3527 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3528 freeAsmop(result,NULL,ic,TRUE);
3531 /*-----------------------------------------------------------------*/
3532 /* genCmpLt - less than comparisons */
3533 /*-----------------------------------------------------------------*/
3534 static void genCmpLt (iCode *ic, iCode *ifx)
3536 operand *left, *right, *result;
3537 sym_link *letype , *retype;
3540 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3542 right= IC_RIGHT(ic);
3543 result = IC_RESULT(ic);
3545 letype = getSpec(operandType(left));
3546 retype =getSpec(operandType(right));
3547 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3549 /* assign the amsops */
3550 aopOp (left,ic,FALSE);
3551 aopOp (right,ic,FALSE);
3552 aopOp (result,ic,TRUE);
3554 genCmp(left, right, result, ifx, sign);
3556 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3557 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3558 freeAsmop(result,NULL,ic,TRUE);
3561 /*-----------------------------------------------------------------*/
3562 /* gencjneshort - compare and jump if not equal */
3563 /*-----------------------------------------------------------------*/
3564 static void gencjneshort(operand *left, operand *right, symbol *lbl)
3566 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3568 unsigned long lit = 0L;
3570 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3571 /* if the left side is a literal or
3572 if the right is in a pointer register and left
3574 if ((AOP_TYPE(left) == AOP_LIT) ||
3575 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3580 if(AOP_TYPE(right) == AOP_LIT)
3581 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3583 /* if the right side is a literal then anything goes */
3584 if (AOP_TYPE(right) == AOP_LIT &&
3585 AOP_TYPE(left) != AOP_DIR ) {
3588 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3589 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3591 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3594 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3600 /* if the right side is in a register or in direct space or
3601 if the left is a pointer register & right is not */
3602 else if (AOP_TYPE(right) == AOP_REG ||
3603 AOP_TYPE(right) == AOP_DIR ||
3604 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3605 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3607 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3608 ( (lit & 0xff) != 0)) {
3609 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3610 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3613 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3616 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3619 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
3620 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3621 ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0))
3622 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
3624 pic14_emitcode("cjne","a,%s,%05d_DS_",
3625 aopGet(AOP(right),offset,FALSE,TRUE),
3631 /* right is a pointer reg need both a & b */
3633 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3635 pic14_emitcode("mov","b,%s",l);
3636 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3637 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
3643 /*-----------------------------------------------------------------*/
3644 /* gencjne - compare and jump if not equal */
3645 /*-----------------------------------------------------------------*/
3646 static void gencjne(operand *left, operand *right, symbol *lbl)
3648 symbol *tlbl = newiTempLabel(NULL);
3650 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3651 gencjneshort(left, right, lbl);
3653 pic14_emitcode("mov","a,%s",one);
3654 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3655 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3656 pic14_emitcode("clr","a");
3657 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
3661 /*-----------------------------------------------------------------*/
3662 /* genCmpEq - generates code for equal to */
3663 /*-----------------------------------------------------------------*/
3664 static void genCmpEq (iCode *ic, iCode *ifx)
3666 operand *left, *right, *result;
3667 unsigned long lit = 0L;
3670 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3672 DEBUGpic14_emitcode ("; ifx is non-null","");
3674 DEBUGpic14_emitcode ("; ifx is null","");
3676 aopOp((left=IC_LEFT(ic)),ic,FALSE);
3677 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
3678 aopOp((result=IC_RESULT(ic)),ic,TRUE);
3680 size = max(AOP_SIZE(left),AOP_SIZE(right));
3682 /* if literal, literal on the right or
3683 if the right is in a pointer register and left
3685 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
3686 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3687 operand *t = IC_RIGHT(ic);
3688 IC_RIGHT(ic) = IC_LEFT(ic);
3692 if(ifx && !AOP_SIZE(result)){
3694 /* if they are both bit variables */
3695 if (AOP_TYPE(left) == AOP_CRY &&
3696 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3697 if(AOP_TYPE(right) == AOP_LIT){
3698 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3700 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3701 pic14_emitcode("cpl","c");
3702 } else if(lit == 1L) {
3703 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3705 pic14_emitcode("clr","c");
3707 /* AOP_TYPE(right) == AOP_CRY */
3709 symbol *lbl = newiTempLabel(NULL);
3710 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3711 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3712 pic14_emitcode("cpl","c");
3713 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3715 /* if true label then we jump if condition
3717 tlbl = newiTempLabel(NULL);
3718 if ( IC_TRUE(ifx) ) {
3719 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
3720 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
3722 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
3723 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
3725 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
3728 /* They're not both bit variables. Is the right a literal? */
3729 if(AOP_TYPE(right) == AOP_LIT) {
3731 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3736 int h = (lit>>8) & 0xff;
3739 /* Check special cases for integers */
3740 switch(lit & 0xffff) {
3742 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3743 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3744 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3745 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3750 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3751 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3752 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3753 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3758 emitpcode(POC_DECFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3759 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3760 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3761 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3766 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3767 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3768 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3769 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3774 emitpcode(POC_INCFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3775 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3776 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3777 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3783 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3784 emitpcode(POC_XORLW,popGetLit(l));
3785 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3787 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3788 pic14_emitcode("xorlw","0x%x",l);
3789 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3792 } else if (l == 0) {
3793 emitpcode(POC_MOVFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3794 emitpcode(POC_XORLW,popGetLit(h));
3795 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3797 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3798 pic14_emitcode("xorlw","0x%x",h);
3799 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3803 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3804 emitpcode(POC_XORLW,popGetLit(l));
3805 emitpcode(POC_MOVLW,popGetLit(h));
3807 emitpcode(POC_XORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3809 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3810 pic14_emitcode("xorlw","0x%x",l);
3811 pic14_emitcode("movlw","0x%x",h);
3813 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3830 switch(lit & 0xff) {
3832 if ( IC_TRUE(ifx) ) {
3834 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3836 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3838 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3840 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3842 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3843 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3845 pic14_emitcode("decfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3846 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3850 if ( IC_TRUE(ifx) ) {
3851 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3853 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3855 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3857 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3859 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3860 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3862 pic14_emitcode("incfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3863 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3867 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3868 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3870 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3871 //pic14_emitcode("xorlw","0x%x",lit & 0xff);
3876 // pic14_emitcode("goto","_%05d_DS_",tlbl->key+100+labelOffset);
3877 //pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
3882 } else if(AOP_TYPE(right) == AOP_CRY ) {
3883 /* we know the left is not a bit, but that the right is */
3884 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3885 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
3886 popGet(AOP(right),offset,FALSE,FALSE));
3887 emitpcode(POC_XORLW,popGetLit(1));
3889 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3891 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
3892 AOP(right)->aopu.aop_dir,
3893 AOP(right)->aopu.aop_dir);
3895 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
3896 AOP(right)->aopu.aop_dir,
3897 AOP(right)->aopu.aop_dir);
3899 pic14_emitcode("xorlw","1");
3901 /* if the two are equal, then W will be 0 and the Z bit is set
3902 * we could test Z now, or go ahead and check the high order bytes if
3903 * the variable we're comparing is larger than a byte. */
3906 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3907 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3909 if ( IC_TRUE(ifx) ) {
3911 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3912 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3915 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3916 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3920 /* They're both variables that are larger than bits */
3923 tlbl = newiTempLabel(NULL);
3926 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3927 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3929 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3930 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3932 if ( IC_TRUE(ifx) ) {
3935 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
3936 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
3939 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3940 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3944 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3945 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3949 if(s>1 && IC_TRUE(ifx)) {
3950 emitpLabel(tlbl->key+100+labelOffset);
3951 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
3955 /* mark the icode as generated */
3960 /* if they are both bit variables */
3961 if (AOP_TYPE(left) == AOP_CRY &&
3962 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3963 if(AOP_TYPE(right) == AOP_LIT){
3964 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3966 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3967 pic14_emitcode("cpl","c");
3968 } else if(lit == 1L) {
3969 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3971 pic14_emitcode("clr","c");
3973 /* AOP_TYPE(right) == AOP_CRY */
3975 symbol *lbl = newiTempLabel(NULL);
3976 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3977 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3978 pic14_emitcode("cpl","c");
3979 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3982 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
3983 pic14_outBitC(result);
3987 genIfxJump (ifx,"c");
3990 /* if the result is used in an arithmetic operation
3991 then put the result in place */
3992 pic14_outBitC(result);
3994 gencjne(left,right,newiTempLabel(NULL));
3995 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3996 aopPut(AOP(result),"a",0);
4000 genIfxJump (ifx,"a");
4003 /* if the result is used in an arithmetic operation
4004 then put the result in place */
4005 if (AOP_TYPE(result) != AOP_CRY)
4006 pic14_outAcc(result);
4007 /* leave the result in acc */
4011 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4012 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4013 freeAsmop(result,NULL,ic,TRUE);
4016 /*-----------------------------------------------------------------*/
4017 /* ifxForOp - returns the icode containing the ifx for operand */
4018 /*-----------------------------------------------------------------*/
4019 static iCode *ifxForOp ( operand *op, iCode *ic )
4021 /* if true symbol then needs to be assigned */
4022 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4023 if (IS_TRUE_SYMOP(op))
4026 /* if this has register type condition and
4027 the next instruction is ifx with the same operand
4028 and live to of the operand is upto the ifx only then */
4030 ic->next->op == IFX &&
4031 IC_COND(ic->next)->key == op->key &&
4032 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4037 /*-----------------------------------------------------------------*/
4038 /* genAndOp - for && operation */
4039 /*-----------------------------------------------------------------*/
4040 static void genAndOp (iCode *ic)
4042 operand *left,*right, *result;
4045 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4046 /* note here that && operations that are in an
4047 if statement are taken away by backPatchLabels
4048 only those used in arthmetic operations remain */
4049 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4050 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4051 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4053 /* if both are bit variables */
4054 if (AOP_TYPE(left) == AOP_CRY &&
4055 AOP_TYPE(right) == AOP_CRY ) {
4056 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4057 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4058 pic14_outBitC(result);
4060 tlbl = newiTempLabel(NULL);
4061 pic14_toBoolean(left);
4062 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4063 pic14_toBoolean(right);
4064 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4065 pic14_outBitAcc(result);
4068 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4069 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4070 freeAsmop(result,NULL,ic,TRUE);
4074 /*-----------------------------------------------------------------*/
4075 /* genOrOp - for || operation */
4076 /*-----------------------------------------------------------------*/
4079 modified this code, but it doesn't appear to ever get called
4082 static void genOrOp (iCode *ic)
4084 operand *left,*right, *result;
4087 /* note here that || operations that are in an
4088 if statement are taken away by backPatchLabels
4089 only those used in arthmetic operations remain */
4090 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4091 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4092 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4093 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4095 /* if both are bit variables */
4096 if (AOP_TYPE(left) == AOP_CRY &&
4097 AOP_TYPE(right) == AOP_CRY ) {
4098 pic14_emitcode("clrc","");
4099 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4100 AOP(left)->aopu.aop_dir,
4101 AOP(left)->aopu.aop_dir);
4102 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4103 AOP(right)->aopu.aop_dir,
4104 AOP(right)->aopu.aop_dir);
4105 pic14_emitcode("setc","");
4108 tlbl = newiTempLabel(NULL);
4109 pic14_toBoolean(left);
4111 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4112 pic14_toBoolean(right);
4113 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4115 pic14_outBitAcc(result);
4118 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4119 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4120 freeAsmop(result,NULL,ic,TRUE);
4123 /*-----------------------------------------------------------------*/
4124 /* isLiteralBit - test if lit == 2^n */
4125 /*-----------------------------------------------------------------*/
4126 static int isLiteralBit(unsigned long lit)
4128 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4129 0x100L,0x200L,0x400L,0x800L,
4130 0x1000L,0x2000L,0x4000L,0x8000L,
4131 0x10000L,0x20000L,0x40000L,0x80000L,
4132 0x100000L,0x200000L,0x400000L,0x800000L,
4133 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4134 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4137 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4138 for(idx = 0; idx < 32; idx++)
4144 /*-----------------------------------------------------------------*/
4145 /* continueIfTrue - */
4146 /*-----------------------------------------------------------------*/
4147 static void continueIfTrue (iCode *ic)
4149 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4151 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4155 /*-----------------------------------------------------------------*/
4157 /*-----------------------------------------------------------------*/
4158 static void jumpIfTrue (iCode *ic)
4160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4162 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4166 /*-----------------------------------------------------------------*/
4167 /* jmpTrueOrFalse - */
4168 /*-----------------------------------------------------------------*/
4169 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4171 // ugly but optimized by peephole
4172 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4174 symbol *nlbl = newiTempLabel(NULL);
4175 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4176 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4177 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4178 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4181 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4182 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4187 /*-----------------------------------------------------------------*/
4188 /* genAnd - code for and */
4189 /*-----------------------------------------------------------------*/
4190 static void genAnd (iCode *ic, iCode *ifx)
4192 operand *left, *right, *result;
4194 unsigned long lit = 0L;
4198 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4199 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4200 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4201 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4204 pic14_emitcode("","; Type res[%d] = l[%d]&r[%d]",
4206 AOP_TYPE(left), AOP_TYPE(right));
4207 pic14_emitcode("","; Size res[%d] = l[%d]&r[%d]",
4209 AOP_SIZE(left), AOP_SIZE(right));
4212 /* if left is a literal & right is not then exchange them */
4213 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4214 AOP_NEEDSACC(left)) {
4215 operand *tmp = right ;
4220 /* if result = right then exchange them */
4221 if(pic14_sameRegs(AOP(result),AOP(right))){
4222 operand *tmp = right ;
4227 /* if right is bit then exchange them */
4228 if (AOP_TYPE(right) == AOP_CRY &&
4229 AOP_TYPE(left) != AOP_CRY){
4230 operand *tmp = right ;
4234 if(AOP_TYPE(right) == AOP_LIT)
4235 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4237 size = AOP_SIZE(result);
4240 // result = bit & yy;
4241 if (AOP_TYPE(left) == AOP_CRY){
4242 // c = bit & literal;
4243 if(AOP_TYPE(right) == AOP_LIT){
4245 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4248 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4251 if(size && (AOP_TYPE(result) == AOP_CRY)){
4252 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4255 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4259 pic14_emitcode("clr","c");
4262 if (AOP_TYPE(right) == AOP_CRY){
4264 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4265 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4268 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4270 pic14_emitcode("rrc","a");
4271 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4277 pic14_outBitC(result);
4279 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4280 genIfxJump(ifx, "c");
4284 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4285 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4286 if((AOP_TYPE(right) == AOP_LIT) &&
4287 (AOP_TYPE(result) == AOP_CRY) &&
4288 (AOP_TYPE(left) != AOP_CRY)){
4289 int posbit = isLiteralBit(lit);
4293 MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4296 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4300 sprintf(buffer,"acc.%d",posbit&0x07);
4301 genIfxJump(ifx, buffer);
4306 symbol *tlbl = newiTempLabel(NULL);
4307 int sizel = AOP_SIZE(left);
4309 pic14_emitcode("setb","c");
4311 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4312 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4314 if((posbit = isLiteralBit(bytelit)) != 0)
4315 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4317 if(bytelit != 0x0FFL)
4318 pic14_emitcode("anl","a,%s",
4319 aopGet(AOP(right),offset,FALSE,TRUE));
4320 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4325 // bit = left & literal
4327 pic14_emitcode("clr","c");
4328 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4330 // if(left & literal)
4333 jmpTrueOrFalse(ifx, tlbl);
4337 pic14_outBitC(result);
4341 /* if left is same as result */
4342 if(pic14_sameRegs(AOP(result),AOP(left))){
4343 for(;size--; offset++,lit>>=8) {
4344 if(AOP_TYPE(right) == AOP_LIT){
4345 switch(lit & 0xff) {
4347 /* and'ing with 0 has clears the result */
4348 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4351 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4356 int p = my_powof2( (~lit) & 0xff );
4358 /* only one bit is set in the literal, so use a bcf instruction */
4359 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4361 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4362 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
4367 if (AOP_TYPE(left) == AOP_ACC)
4368 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4370 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4371 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4378 // left & result in different registers
4379 if(AOP_TYPE(result) == AOP_CRY){
4381 // if(size), result in bit
4382 // if(!size && ifx), conditional oper: if(left & right)
4383 symbol *tlbl = newiTempLabel(NULL);
4384 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4386 pic14_emitcode("setb","c");
4388 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4389 pic14_emitcode("anl","a,%s",
4390 aopGet(AOP(left),offset,FALSE,FALSE));
4391 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4396 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4397 pic14_outBitC(result);
4399 jmpTrueOrFalse(ifx, tlbl);
4401 for(;(size--);offset++) {
4403 // result = left & right
4404 if(AOP_TYPE(right) == AOP_LIT){
4405 int t = (lit >> (offset*8)) & 0x0FFL;
4408 pic14_emitcode("clrf","%s",
4409 aopGet(AOP(result),offset,FALSE,FALSE));
4412 pic14_emitcode("movf","%s,w",
4413 aopGet(AOP(left),offset,FALSE,FALSE));
4414 pic14_emitcode("movwf","%s",
4415 aopGet(AOP(result),offset,FALSE,FALSE));
4418 pic14_emitcode("movlw","0x%x",t);
4419 pic14_emitcode("andwf","%s,w",
4420 aopGet(AOP(left),offset,FALSE,FALSE));
4421 pic14_emitcode("movwf","%s",
4422 aopGet(AOP(result),offset,FALSE,FALSE));
4428 if (AOP_TYPE(left) == AOP_ACC)
4429 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4431 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4432 pic14_emitcode("andwf","%s,w",
4433 aopGet(AOP(left),offset,FALSE,FALSE));
4435 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4441 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4442 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4443 freeAsmop(result,NULL,ic,TRUE);
4446 /*-----------------------------------------------------------------*/
4447 /* genOr - code for or */
4448 /*-----------------------------------------------------------------*/
4449 static void genOr (iCode *ic, iCode *ifx)
4451 operand *left, *right, *result;
4453 unsigned long lit = 0L;
4455 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4457 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4458 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4459 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4462 /* if left is a literal & right is not then exchange them */
4463 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4464 AOP_NEEDSACC(left)) {
4465 operand *tmp = right ;
4470 /* if result = right then exchange them */
4471 if(pic14_sameRegs(AOP(result),AOP(right))){
4472 operand *tmp = right ;
4477 /* if right is bit then exchange them */
4478 if (AOP_TYPE(right) == AOP_CRY &&
4479 AOP_TYPE(left) != AOP_CRY){
4480 operand *tmp = right ;
4485 if(AOP_TYPE(right) == AOP_LIT)
4486 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4488 size = AOP_SIZE(result);
4492 if (AOP_TYPE(left) == AOP_CRY){
4493 if(AOP_TYPE(right) == AOP_LIT){
4494 // c = bit & literal;
4496 // lit != 0 => result = 1
4497 if(AOP_TYPE(result) == AOP_CRY){
4499 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4500 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4501 // AOP(result)->aopu.aop_dir,
4502 // AOP(result)->aopu.aop_dir);
4504 continueIfTrue(ifx);
4508 // lit == 0 => result = left
4509 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4511 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4514 if (AOP_TYPE(right) == AOP_CRY){
4515 if(pic14_sameRegs(AOP(result),AOP(left))){
4517 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4518 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4519 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4521 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4522 AOP(result)->aopu.aop_dir,
4523 AOP(result)->aopu.aop_dir);
4524 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4525 AOP(right)->aopu.aop_dir,
4526 AOP(right)->aopu.aop_dir);
4527 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4528 AOP(result)->aopu.aop_dir,
4529 AOP(result)->aopu.aop_dir);
4532 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4533 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4534 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4535 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4537 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4538 AOP(result)->aopu.aop_dir,
4539 AOP(result)->aopu.aop_dir);
4540 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4541 AOP(right)->aopu.aop_dir,
4542 AOP(right)->aopu.aop_dir);
4543 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4544 AOP(left)->aopu.aop_dir,
4545 AOP(left)->aopu.aop_dir);
4546 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4547 AOP(result)->aopu.aop_dir,
4548 AOP(result)->aopu.aop_dir);
4553 symbol *tlbl = newiTempLabel(NULL);
4554 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4555 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4556 pic14_emitcode(";XXX setb","c");
4557 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4558 AOP(left)->aopu.aop_dir,tlbl->key+100);
4559 pic14_toBoolean(right);
4560 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4561 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4562 jmpTrueOrFalse(ifx, tlbl);
4566 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4573 pic14_outBitC(result);
4575 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4576 genIfxJump(ifx, "c");
4580 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4581 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4582 if((AOP_TYPE(right) == AOP_LIT) &&
4583 (AOP_TYPE(result) == AOP_CRY) &&
4584 (AOP_TYPE(left) != AOP_CRY)){
4586 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4589 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4591 continueIfTrue(ifx);
4594 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4595 // lit = 0, result = boolean(left)
4597 pic14_emitcode(";XXX setb","c");
4598 pic14_toBoolean(right);
4600 symbol *tlbl = newiTempLabel(NULL);
4601 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4603 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4605 genIfxJump (ifx,"a");
4609 pic14_outBitC(result);
4613 /* if left is same as result */
4614 if(pic14_sameRegs(AOP(result),AOP(left))){
4615 for(;size--; offset++,lit>>=8) {
4616 if(AOP_TYPE(right) == AOP_LIT){
4617 if((lit & 0xff) == 0)
4618 /* or'ing with 0 has no effect */
4621 int p = my_powof2(lit & 0xff);
4623 /* only one bit is set in the literal, so use a bsf instruction */
4624 emitpcode(POC_BSF, popGet(AOP(left),offset,FALSE,FALSE));
4625 pic14_emitcode("bsf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4627 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4628 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4630 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4631 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
4636 if (AOP_TYPE(left) == AOP_ACC) {
4637 emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE));
4638 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4640 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4641 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4643 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4644 pic14_emitcode("iorwf","%s,f",aopGet(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 = max(AOP_SIZE(left),AOP_SIZE(right));
4657 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4660 pic14_emitcode(";XXX setb","c");
4662 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4663 pic14_emitcode(";XXX orl","a,%s",
4664 aopGet(AOP(left),offset,FALSE,FALSE));
4665 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4670 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4671 pic14_outBitC(result);
4673 jmpTrueOrFalse(ifx, tlbl);
4674 } else for(;(size--);offset++){
4676 // result = left & right
4677 if(AOP_TYPE(right) == AOP_LIT){
4678 int t = (lit >> (offset*8)) & 0x0FFL;
4681 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
4682 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4684 pic14_emitcode("movf","%s,w",
4685 aopGet(AOP(left),offset,FALSE,FALSE));
4686 pic14_emitcode("movwf","%s",
4687 aopGet(AOP(result),offset,FALSE,FALSE));
4690 emitpcode(POC_MOVLW, popGetLit(t));
4691 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4692 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4694 pic14_emitcode("movlw","0x%x",t);
4695 pic14_emitcode("iorwf","%s,w",
4696 aopGet(AOP(left),offset,FALSE,FALSE));
4697 pic14_emitcode("movwf","%s",
4698 aopGet(AOP(result),offset,FALSE,FALSE));
4704 // faster than result <- left, anl result,right
4705 // and better if result is SFR
4706 if (AOP_TYPE(left) == AOP_ACC) {
4707 emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE));
4708 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4710 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4711 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4713 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4714 pic14_emitcode("iorwf","%s,w",
4715 aopGet(AOP(left),offset,FALSE,FALSE));
4717 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4718 pic14_emitcode("movwf","%s",aopGet(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 /* genXor - code for xclusive or */
4730 /*-----------------------------------------------------------------*/
4731 static void genXor (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);
4743 /* if left is a literal & right is not ||
4744 if left needs acc & right does not */
4745 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4746 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
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 ;
4766 if(AOP_TYPE(right) == AOP_LIT)
4767 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4769 size = AOP_SIZE(result);
4773 if (AOP_TYPE(left) == AOP_CRY){
4774 if(AOP_TYPE(right) == AOP_LIT){
4775 // c = bit & literal;
4777 // lit>>1 != 0 => result = 1
4778 if(AOP_TYPE(result) == AOP_CRY){
4780 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
4782 continueIfTrue(ifx);
4785 pic14_emitcode("setb","c");
4789 // lit == 0, result = left
4790 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4792 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4794 // lit == 1, result = not(left)
4795 if(size && pic14_sameRegs(AOP(result),AOP(left))){
4796 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
4799 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4800 pic14_emitcode("cpl","c");
4807 symbol *tlbl = newiTempLabel(NULL);
4808 if (AOP_TYPE(right) == AOP_CRY){
4810 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4813 int sizer = AOP_SIZE(right);
4815 // if val>>1 != 0, result = 1
4816 pic14_emitcode("setb","c");
4818 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
4820 // test the msb of the lsb
4821 pic14_emitcode("anl","a,#0xfe");
4822 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4826 pic14_emitcode("rrc","a");
4828 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
4829 pic14_emitcode("cpl","c");
4830 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
4835 pic14_outBitC(result);
4837 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4838 genIfxJump(ifx, "c");
4842 if(pic14_sameRegs(AOP(result),AOP(left))){
4843 /* if left is same as result */
4844 for(;size--; offset++) {
4845 if(AOP_TYPE(right) == AOP_LIT){
4846 if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
4849 if (IS_AOP_PREG(left)) {
4850 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4851 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4852 aopPut(AOP(result),"a",offset);
4854 pic14_emitcode("xrl","%s,%s",
4855 aopGet(AOP(left),offset,FALSE,TRUE),
4856 aopGet(AOP(right),offset,FALSE,FALSE));
4858 if (AOP_TYPE(left) == AOP_ACC)
4859 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
4861 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4862 if (IS_AOP_PREG(left)) {
4863 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4864 aopPut(AOP(result),"a",offset);
4866 pic14_emitcode("xrl","%s,a",
4867 aopGet(AOP(left),offset,FALSE,TRUE));
4872 // left & result in different registers
4873 if(AOP_TYPE(result) == AOP_CRY){
4875 // if(size), result in bit
4876 // if(!size && ifx), conditional oper: if(left ^ right)
4877 symbol *tlbl = newiTempLabel(NULL);
4878 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4880 pic14_emitcode("setb","c");
4882 if((AOP_TYPE(right) == AOP_LIT) &&
4883 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
4884 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
4886 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4887 pic14_emitcode("xrl","a,%s",
4888 aopGet(AOP(left),offset,FALSE,FALSE));
4890 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4895 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4896 pic14_outBitC(result);
4898 jmpTrueOrFalse(ifx, tlbl);
4899 } else for(;(size--);offset++){
4901 // result = left & right
4902 if(AOP_TYPE(right) == AOP_LIT){
4903 int t = (lit >> (offset*8)) & 0x0FFL;
4906 pic14_emitcode("movf","%s,w",
4907 aopGet(AOP(left),offset,FALSE,FALSE));
4908 pic14_emitcode("movwf","%s",
4909 aopGet(AOP(result),offset,FALSE,FALSE));
4912 pic14_emitcode("comf","%s,w",
4913 aopGet(AOP(left),offset,FALSE,FALSE));
4914 pic14_emitcode("movwf","%s",
4915 aopGet(AOP(result),offset,FALSE,FALSE));
4918 pic14_emitcode("movlw","0x%x",t);
4919 pic14_emitcode("xorwf","%s,w",
4920 aopGet(AOP(left),offset,FALSE,FALSE));
4921 pic14_emitcode("movwf","%s",
4922 aopGet(AOP(result),offset,FALSE,FALSE));
4928 // faster than result <- left, anl result,right
4929 // and better if result is SFR
4930 if (AOP_TYPE(left) == AOP_ACC)
4931 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4933 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4934 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4936 if ( AOP_TYPE(result) != AOP_ACC)
4937 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4942 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4943 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4944 freeAsmop(result,NULL,ic,TRUE);
4947 /*-----------------------------------------------------------------*/
4948 /* genInline - write the inline code out */
4949 /*-----------------------------------------------------------------*/
4950 static void genInline (iCode *ic)
4952 char buffer[MAX_INLINEASM];
4956 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4958 _G.inLine += (!options.asmpeep);
4959 strcpy(buffer,IC_INLINE(ic));
4961 /* emit each line as a code */
4965 pic14_emitcode(bp1,"");
4972 pic14_emitcode(bp1,"");
4979 pic14_emitcode(bp1,"");
4980 /* pic14_emitcode("",buffer); */
4981 _G.inLine -= (!options.asmpeep);
4984 /*-----------------------------------------------------------------*/
4985 /* genRRC - rotate right with carry */
4986 /*-----------------------------------------------------------------*/
4987 static void genRRC (iCode *ic)
4989 operand *left , *result ;
4990 int size, offset = 0;
4993 /* rotate right with carry */
4995 result=IC_RESULT(ic);
4996 aopOp (left,ic,FALSE);
4997 aopOp (result,ic,FALSE);
4999 /* move it to the result */
5000 size = AOP_SIZE(result);
5004 l = aopGet(AOP(left),offset,FALSE,FALSE);
5006 pic14_emitcode("rrc","a");
5007 if (AOP_SIZE(result) > 1)
5008 aopPut(AOP(result),"a",offset--);
5010 /* now we need to put the carry into the
5011 highest order byte of the result */
5012 if (AOP_SIZE(result) > 1) {
5013 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5016 pic14_emitcode("mov","acc.7,c");
5017 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5018 freeAsmop(left,NULL,ic,TRUE);
5019 freeAsmop(result,NULL,ic,TRUE);
5022 /*-----------------------------------------------------------------*/
5023 /* genRLC - generate code for rotate left with carry */
5024 /*-----------------------------------------------------------------*/
5025 static void genRLC (iCode *ic)
5027 operand *left , *result ;
5028 int size, offset = 0;
5031 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5032 /* rotate right with carry */
5034 result=IC_RESULT(ic);
5035 aopOp (left,ic,FALSE);
5036 aopOp (result,ic,FALSE);
5038 /* move it to the result */
5039 size = AOP_SIZE(result);
5042 l = aopGet(AOP(left),offset,FALSE,FALSE);
5044 pic14_emitcode("add","a,acc");
5045 if (AOP_SIZE(result) > 1)
5046 aopPut(AOP(result),"a",offset++);
5048 l = aopGet(AOP(left),offset,FALSE,FALSE);
5050 pic14_emitcode("rlc","a");
5051 if (AOP_SIZE(result) > 1)
5052 aopPut(AOP(result),"a",offset++);
5055 /* now we need to put the carry into the
5056 highest order byte of the result */
5057 if (AOP_SIZE(result) > 1) {
5058 l = aopGet(AOP(result),0,FALSE,FALSE);
5061 pic14_emitcode("mov","acc.0,c");
5062 aopPut(AOP(result),"a",0);
5063 freeAsmop(left,NULL,ic,TRUE);
5064 freeAsmop(result,NULL,ic,TRUE);
5067 /*-----------------------------------------------------------------*/
5068 /* genGetHbit - generates code get highest order bit */
5069 /*-----------------------------------------------------------------*/
5070 static void genGetHbit (iCode *ic)
5072 operand *left, *result;
5074 result=IC_RESULT(ic);
5075 aopOp (left,ic,FALSE);
5076 aopOp (result,ic,FALSE);
5078 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5079 /* get the highest order byte into a */
5080 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5081 if(AOP_TYPE(result) == AOP_CRY){
5082 pic14_emitcode("rlc","a");
5083 pic14_outBitC(result);
5086 pic14_emitcode("rl","a");
5087 pic14_emitcode("anl","a,#0x01");
5088 pic14_outAcc(result);
5092 freeAsmop(left,NULL,ic,TRUE);
5093 freeAsmop(result,NULL,ic,TRUE);
5096 /*-----------------------------------------------------------------*/
5097 /* AccRol - rotate left accumulator by known count */
5098 /*-----------------------------------------------------------------*/
5099 static void AccRol (int shCount)
5101 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5102 shCount &= 0x0007; // shCount : 0..7
5107 pic14_emitcode("rl","a");
5110 pic14_emitcode("rl","a");
5111 pic14_emitcode("rl","a");
5114 pic14_emitcode("swap","a");
5115 pic14_emitcode("rr","a");
5118 pic14_emitcode("swap","a");
5121 pic14_emitcode("swap","a");
5122 pic14_emitcode("rl","a");
5125 pic14_emitcode("rr","a");
5126 pic14_emitcode("rr","a");
5129 pic14_emitcode("rr","a");
5134 /*-----------------------------------------------------------------*/
5135 /* AccLsh - left shift accumulator by known count */
5136 /*-----------------------------------------------------------------*/
5137 static void AccLsh (int shCount)
5139 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5142 pic14_emitcode("add","a,acc");
5145 pic14_emitcode("add","a,acc");
5146 pic14_emitcode("add","a,acc");
5148 /* rotate left accumulator */
5150 /* and kill the lower order bits */
5151 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5156 /*-----------------------------------------------------------------*/
5157 /* AccRsh - right shift accumulator by known count */
5158 /*-----------------------------------------------------------------*/
5159 static void AccRsh (int shCount)
5161 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5165 pic14_emitcode("rrc","a");
5167 /* rotate right accumulator */
5168 AccRol(8 - shCount);
5169 /* and kill the higher order bits */
5170 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5175 /*-----------------------------------------------------------------*/
5176 /* AccSRsh - signed right shift accumulator by known count */
5177 /*-----------------------------------------------------------------*/
5178 static void AccSRsh (int shCount)
5181 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5184 pic14_emitcode("mov","c,acc.7");
5185 pic14_emitcode("rrc","a");
5186 } else if(shCount == 2){
5187 pic14_emitcode("mov","c,acc.7");
5188 pic14_emitcode("rrc","a");
5189 pic14_emitcode("mov","c,acc.7");
5190 pic14_emitcode("rrc","a");
5192 tlbl = newiTempLabel(NULL);
5193 /* rotate right accumulator */
5194 AccRol(8 - shCount);
5195 /* and kill the higher order bits */
5196 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5197 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5198 pic14_emitcode("orl","a,#0x%02x",
5199 (unsigned char)~SRMask[shCount]);
5200 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5205 /*-----------------------------------------------------------------*/
5206 /* shiftR1Left2Result - shift right one byte from left to result */
5207 /*-----------------------------------------------------------------*/
5208 static void shiftR1Left2Result (operand *left, int offl,
5209 operand *result, int offr,
5210 int shCount, int sign)
5212 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5213 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5214 /* shift right accumulator */
5219 aopPut(AOP(result),"a",offr);
5222 /*-----------------------------------------------------------------*/
5223 /* shiftL1Left2Result - shift left one byte from left to result */
5224 /*-----------------------------------------------------------------*/
5225 static void shiftL1Left2Result (operand *left, int offl,
5226 operand *result, int offr, int shCount)
5229 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5230 l = aopGet(AOP(left),offl,FALSE,FALSE);
5232 /* shift left accumulator */
5234 aopPut(AOP(result),"a",offr);
5237 /*-----------------------------------------------------------------*/
5238 /* movLeft2Result - move byte from left to result */
5239 /*-----------------------------------------------------------------*/
5240 static void movLeft2Result (operand *left, int offl,
5241 operand *result, int offr, int sign)
5244 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5245 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5246 l = aopGet(AOP(left),offl,FALSE,FALSE);
5248 if (*l == '@' && (IS_AOP_PREG(result))) {
5249 pic14_emitcode("mov","a,%s",l);
5250 aopPut(AOP(result),"a",offr);
5253 aopPut(AOP(result),l,offr);
5255 /* MSB sign in acc.7 ! */
5256 if(pic14_getDataSize(left) == offl+1){
5257 pic14_emitcode("mov","a,%s",l);
5258 aopPut(AOP(result),"a",offr);
5265 /*-----------------------------------------------------------------*/
5266 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5267 /*-----------------------------------------------------------------*/
5268 static void AccAXRrl1 (char *x)
5270 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5271 pic14_emitcode("rrc","a");
5272 pic14_emitcode("xch","a,%s", x);
5273 pic14_emitcode("rrc","a");
5274 pic14_emitcode("xch","a,%s", x);
5277 /*-----------------------------------------------------------------*/
5278 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5279 /*-----------------------------------------------------------------*/
5280 static void AccAXLrl1 (char *x)
5282 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5283 pic14_emitcode("xch","a,%s",x);
5284 pic14_emitcode("rlc","a");
5285 pic14_emitcode("xch","a,%s",x);
5286 pic14_emitcode("rlc","a");
5289 /*-----------------------------------------------------------------*/
5290 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5291 /*-----------------------------------------------------------------*/
5292 static void AccAXLsh1 (char *x)
5294 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5295 pic14_emitcode("xch","a,%s",x);
5296 pic14_emitcode("add","a,acc");
5297 pic14_emitcode("xch","a,%s",x);
5298 pic14_emitcode("rlc","a");
5301 /*-----------------------------------------------------------------*/
5302 /* AccAXLsh - left shift a:x by known count (0..7) */
5303 /*-----------------------------------------------------------------*/
5304 static void AccAXLsh (char *x, int shCount)
5306 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5319 case 5 : // AAAAABBB:CCCCCDDD
5320 AccRol(shCount); // BBBAAAAA:CCCCCDDD
5321 pic14_emitcode("anl","a,#0x%02x",
5322 SLMask[shCount]); // BBB00000:CCCCCDDD
5323 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
5324 AccRol(shCount); // DDDCCCCC:BBB00000
5325 pic14_emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
5326 pic14_emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
5327 pic14_emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
5328 pic14_emitcode("anl","a,#0x%02x",
5329 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5330 pic14_emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
5331 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
5333 case 6 : // AAAAAABB:CCCCCCDD
5334 pic14_emitcode("anl","a,#0x%02x",
5335 SRMask[shCount]); // 000000BB:CCCCCCDD
5336 pic14_emitcode("mov","c,acc.0"); // c = B
5337 pic14_emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
5338 AccAXRrl1(x); // BCCCCCCD:D000000B
5339 AccAXRrl1(x); // BBCCCCCC:DD000000
5341 case 7 : // a:x <<= 7
5342 pic14_emitcode("anl","a,#0x%02x",
5343 SRMask[shCount]); // 0000000B:CCCCCCCD
5344 pic14_emitcode("mov","c,acc.0"); // c = B
5345 pic14_emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
5346 AccAXRrl1(x); // BCCCCCCC:D0000000
5353 /*-----------------------------------------------------------------*/
5354 /* AccAXRsh - right shift a:x known count (0..7) */
5355 /*-----------------------------------------------------------------*/
5356 static void AccAXRsh (char *x, int shCount)
5358 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5364 AccAXRrl1(x); // 0->a:x
5368 AccAXRrl1(x); // 0->a:x
5370 AccAXRrl1(x); // 0->a:x
5374 case 5 : // AAAAABBB:CCCCCDDD = a:x
5375 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5376 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5377 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5378 pic14_emitcode("anl","a,#0x%02x",
5379 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5380 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5381 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5382 pic14_emitcode("anl","a,#0x%02x",
5383 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5384 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5385 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5386 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5388 case 6 : // AABBBBBB:CCDDDDDD
5389 pic14_emitcode("mov","c,acc.7");
5390 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5391 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5392 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5393 pic14_emitcode("anl","a,#0x%02x",
5394 SRMask[shCount]); // 000000AA:BBBBBBCC
5396 case 7 : // ABBBBBBB:CDDDDDDD
5397 pic14_emitcode("mov","c,acc.7"); // c = A
5398 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5399 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5400 pic14_emitcode("anl","a,#0x%02x",
5401 SRMask[shCount]); // 0000000A:BBBBBBBC
5408 /*-----------------------------------------------------------------*/
5409 /* AccAXRshS - right shift signed a:x known count (0..7) */
5410 /*-----------------------------------------------------------------*/
5411 static void AccAXRshS (char *x, int shCount)
5414 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5419 pic14_emitcode("mov","c,acc.7");
5420 AccAXRrl1(x); // s->a:x
5423 pic14_emitcode("mov","c,acc.7");
5424 AccAXRrl1(x); // s->a:x
5425 pic14_emitcode("mov","c,acc.7");
5426 AccAXRrl1(x); // s->a:x
5430 case 5 : // AAAAABBB:CCCCCDDD = a:x
5431 tlbl = newiTempLabel(NULL);
5432 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
5433 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5434 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5435 pic14_emitcode("anl","a,#0x%02x",
5436 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5437 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5438 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5439 pic14_emitcode("anl","a,#0x%02x",
5440 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5441 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5442 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5443 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
5444 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5445 pic14_emitcode("orl","a,#0x%02x",
5446 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5447 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5448 break; // SSSSAAAA:BBBCCCCC
5449 case 6 : // AABBBBBB:CCDDDDDD
5450 tlbl = newiTempLabel(NULL);
5451 pic14_emitcode("mov","c,acc.7");
5452 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5453 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5454 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5455 pic14_emitcode("anl","a,#0x%02x",
5456 SRMask[shCount]); // 000000AA:BBBBBBCC
5457 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5458 pic14_emitcode("orl","a,#0x%02x",
5459 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
5460 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5462 case 7 : // ABBBBBBB:CDDDDDDD
5463 tlbl = newiTempLabel(NULL);
5464 pic14_emitcode("mov","c,acc.7"); // c = A
5465 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5466 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5467 pic14_emitcode("anl","a,#0x%02x",
5468 SRMask[shCount]); // 0000000A:BBBBBBBC
5469 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5470 pic14_emitcode("orl","a,#0x%02x",
5471 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
5472 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5479 /*-----------------------------------------------------------------*/
5480 /* shiftL2Left2Result - shift left two bytes from left to result */
5481 /*-----------------------------------------------------------------*/
5482 static void shiftL2Left2Result (operand *left, int offl,
5483 operand *result, int offr, int shCount)
5485 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5486 if(pic14_sameRegs(AOP(result), AOP(left)) &&
5487 ((offl + MSB16) == offr)){
5488 /* don't crash result[offr] */
5489 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5490 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5492 movLeft2Result(left,offl, result, offr, 0);
5493 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5495 /* ax << shCount (x = lsb(result))*/
5496 AccAXLsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5497 aopPut(AOP(result),"a",offr+MSB16);
5501 /*-----------------------------------------------------------------*/
5502 /* shiftR2Left2Result - shift right two bytes from left to result */
5503 /*-----------------------------------------------------------------*/
5504 static void shiftR2Left2Result (operand *left, int offl,
5505 operand *result, int offr,
5506 int shCount, int sign)
5508 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5509 if(pic14_sameRegs(AOP(result), AOP(left)) &&
5510 ((offl + MSB16) == offr)){
5511 /* don't crash result[offr] */
5512 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5513 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5515 movLeft2Result(left,offl, result, offr, 0);
5516 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5518 /* a:x >> shCount (x = lsb(result))*/
5520 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5522 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5523 if(pic14_getDataSize(result) > 1)
5524 aopPut(AOP(result),"a",offr+MSB16);
5527 /*-----------------------------------------------------------------*/
5528 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
5529 /*-----------------------------------------------------------------*/
5530 static void shiftLLeftOrResult (operand *left, int offl,
5531 operand *result, int offr, int shCount)
5533 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5534 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5535 /* shift left accumulator */
5537 /* or with result */
5538 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5539 /* back to result */
5540 aopPut(AOP(result),"a",offr);
5543 /*-----------------------------------------------------------------*/
5544 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
5545 /*-----------------------------------------------------------------*/
5546 static void shiftRLeftOrResult (operand *left, int offl,
5547 operand *result, int offr, int shCount)
5549 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5550 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5551 /* shift right accumulator */
5553 /* or with result */
5554 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5555 /* back to result */
5556 aopPut(AOP(result),"a",offr);
5559 /*-----------------------------------------------------------------*/
5560 /* genlshOne - left shift a one byte quantity by known count */
5561 /*-----------------------------------------------------------------*/
5562 static void genlshOne (operand *result, operand *left, int shCount)
5564 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5565 shiftL1Left2Result(left, LSB, result, LSB, shCount);
5568 /*-----------------------------------------------------------------*/
5569 /* genlshTwo - left shift two bytes by known amount != 0 */
5570 /*-----------------------------------------------------------------*/
5571 static void genlshTwo (operand *result,operand *left, int shCount)
5575 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5576 size = pic14_getDataSize(result);
5578 /* if shCount >= 8 */
5584 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
5586 movLeft2Result(left, LSB, result, MSB16, 0);
5588 aopPut(AOP(result),zero,LSB);
5591 /* 1 <= shCount <= 7 */
5594 shiftL1Left2Result(left, LSB, result, LSB, shCount);
5596 shiftL2Left2Result(left, LSB, result, LSB, shCount);
5600 /*-----------------------------------------------------------------*/
5601 /* shiftLLong - shift left one long from left to result */
5602 /* offl = LSB or MSB16 */
5603 /*-----------------------------------------------------------------*/
5604 static void shiftLLong (operand *left, operand *result, int offr )
5607 int size = AOP_SIZE(result);
5609 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5610 if(size >= LSB+offr){
5611 l = aopGet(AOP(left),LSB,FALSE,FALSE);
5613 pic14_emitcode("add","a,acc");
5614 if (pic14_sameRegs(AOP(left),AOP(result)) &&
5615 size >= MSB16+offr && offr != LSB )
5616 pic14_emitcode("xch","a,%s",
5617 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
5619 aopPut(AOP(result),"a",LSB+offr);
5622 if(size >= MSB16+offr){
5623 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
5624 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
5627 pic14_emitcode("rlc","a");
5628 if (pic14_sameRegs(AOP(left),AOP(result)) &&
5629 size >= MSB24+offr && offr != LSB)
5630 pic14_emitcode("xch","a,%s",
5631 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
5633 aopPut(AOP(result),"a",MSB16+offr);
5636 if(size >= MSB24+offr){
5637 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
5638 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
5641 pic14_emitcode("rlc","a");
5642 if (pic14_sameRegs(AOP(left),AOP(result)) &&
5643 size >= MSB32+offr && offr != LSB )
5644 pic14_emitcode("xch","a,%s",
5645 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
5647 aopPut(AOP(result),"a",MSB24+offr);
5650 if(size > MSB32+offr){
5651 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
5652 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
5655 pic14_emitcode("rlc","a");
5656 aopPut(AOP(result),"a",MSB32+offr);
5659 aopPut(AOP(result),zero,LSB);
5662 /*-----------------------------------------------------------------*/
5663 /* genlshFour - shift four byte by a known amount != 0 */
5664 /*-----------------------------------------------------------------*/
5665 static void genlshFour (operand *result, operand *left, int shCount)
5669 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5670 size = AOP_SIZE(result);
5672 /* if shifting more that 3 bytes */
5673 if (shCount >= 24 ) {
5676 /* lowest order of left goes to the highest
5677 order of the destination */
5678 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
5680 movLeft2Result(left, LSB, result, MSB32, 0);
5681 aopPut(AOP(result),zero,LSB);
5682 aopPut(AOP(result),zero,MSB16);
5683 aopPut(AOP(result),zero,MSB32);
5687 /* more than two bytes */
5688 else if ( shCount >= 16 ) {
5689 /* lower order two bytes goes to higher order two bytes */
5691 /* if some more remaining */
5693 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
5695 movLeft2Result(left, MSB16, result, MSB32, 0);
5696 movLeft2Result(left, LSB, result, MSB24, 0);
5698 aopPut(AOP(result),zero,MSB16);
5699 aopPut(AOP(result),zero,LSB);
5703 /* if more than 1 byte */
5704 else if ( shCount >= 8 ) {
5705 /* lower order three bytes goes to higher order three bytes */
5709 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
5711 movLeft2Result(left, LSB, result, MSB16, 0);
5713 else{ /* size = 4 */
5715 movLeft2Result(left, MSB24, result, MSB32, 0);
5716 movLeft2Result(left, MSB16, result, MSB24, 0);
5717 movLeft2Result(left, LSB, result, MSB16, 0);
5718 aopPut(AOP(result),zero,LSB);
5720 else if(shCount == 1)
5721 shiftLLong(left, result, MSB16);
5723 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
5724 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
5725 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
5726 aopPut(AOP(result),zero,LSB);
5731 /* 1 <= shCount <= 7 */
5732 else if(shCount <= 2){
5733 shiftLLong(left, result, LSB);
5735 shiftLLong(result, result, LSB);
5737 /* 3 <= shCount <= 7, optimize */
5739 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
5740 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
5741 shiftL2Left2Result(left, LSB, result, LSB, shCount);
5745 /*-----------------------------------------------------------------*/
5746 /* genLeftShiftLiteral - left shifting by known count */
5747 /*-----------------------------------------------------------------*/
5748 static void genLeftShiftLiteral (operand *left,
5753 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
5756 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5757 freeAsmop(right,NULL,ic,TRUE);
5759 aopOp(left,ic,FALSE);
5760 aopOp(result,ic,FALSE);
5762 size = getSize(operandType(result));
5765 pic14_emitcode("; shift left ","result %d, left %d",size,
5769 /* I suppose that the left size >= result size */
5772 movLeft2Result(left, size, result, size, 0);
5776 else if(shCount >= (size * 8))
5778 aopPut(AOP(result),zero,size);
5782 genlshOne (result,left,shCount);
5787 genlshTwo (result,left,shCount);
5791 genlshFour (result,left,shCount);
5795 freeAsmop(left,NULL,ic,TRUE);
5796 freeAsmop(result,NULL,ic,TRUE);
5799 /*-----------------------------------------------------------------*/
5800 /* genLeftShift - generates code for left shifting */
5801 /*-----------------------------------------------------------------*/
5802 static void genLeftShift (iCode *ic)
5804 operand *left,*right, *result;
5807 symbol *tlbl , *tlbl1;
5809 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5811 right = IC_RIGHT(ic);
5813 result = IC_RESULT(ic);
5815 aopOp(right,ic,FALSE);
5817 /* if the shift count is known then do it
5818 as efficiently as possible */
5819 if (AOP_TYPE(right) == AOP_LIT) {
5820 genLeftShiftLiteral (left,right,result,ic);
5824 /* shift count is unknown then we have to form
5825 a loop get the loop count in B : Note: we take
5826 only the lower order byte since shifting
5827 more that 32 bits make no sense anyway, ( the
5828 largest size of an object can be only 32 bits ) */
5830 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
5831 pic14_emitcode("inc","b");
5832 freeAsmop (right,NULL,ic,TRUE);
5833 aopOp(left,ic,FALSE);
5834 aopOp(result,ic,FALSE);
5836 /* now move the left to the result if they are not the
5838 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
5839 AOP_SIZE(result) > 1) {
5841 size = AOP_SIZE(result);
5844 l = aopGet(AOP(left),offset,FALSE,TRUE);
5845 if (*l == '@' && (IS_AOP_PREG(result))) {
5847 pic14_emitcode("mov","a,%s",l);
5848 aopPut(AOP(result),"a",offset);
5850 aopPut(AOP(result),l,offset);
5855 tlbl = newiTempLabel(NULL);
5856 size = AOP_SIZE(result);
5858 tlbl1 = newiTempLabel(NULL);
5860 /* if it is only one byte then */
5862 symbol *tlbl1 = newiTempLabel(NULL);
5864 l = aopGet(AOP(left),0,FALSE,FALSE);
5866 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
5867 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5868 pic14_emitcode("add","a,acc");
5869 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
5870 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
5871 aopPut(AOP(result),"a",0);
5875 reAdjustPreg(AOP(result));
5877 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
5878 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5879 l = aopGet(AOP(result),offset,FALSE,FALSE);
5881 pic14_emitcode("add","a,acc");
5882 aopPut(AOP(result),"a",offset++);
5884 l = aopGet(AOP(result),offset,FALSE,FALSE);
5886 pic14_emitcode("rlc","a");
5887 aopPut(AOP(result),"a",offset++);
5889 reAdjustPreg(AOP(result));
5891 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
5892 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
5894 freeAsmop(left,NULL,ic,TRUE);
5895 freeAsmop(result,NULL,ic,TRUE);
5898 /*-----------------------------------------------------------------*/
5899 /* genrshOne - right shift a one byte quantity by known count */
5900 /*-----------------------------------------------------------------*/
5901 static void genrshOne (operand *result, operand *left,
5902 int shCount, int sign)
5904 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5905 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
5908 /*-----------------------------------------------------------------*/
5909 /* genrshTwo - right shift two bytes by known amount != 0 */
5910 /*-----------------------------------------------------------------*/
5911 static void genrshTwo (operand *result,operand *left,
5912 int shCount, int sign)
5914 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5915 /* if shCount >= 8 */
5919 shiftR1Left2Result(left, MSB16, result, LSB,
5922 movLeft2Result(left, MSB16, result, LSB, sign);
5923 addSign(result, MSB16, sign);
5926 /* 1 <= shCount <= 7 */
5928 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
5931 /*-----------------------------------------------------------------*/
5932 /* shiftRLong - shift right one long from left to result */
5933 /* offl = LSB or MSB16 */
5934 /*-----------------------------------------------------------------*/
5935 static void shiftRLong (operand *left, int offl,
5936 operand *result, int sign)
5938 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5940 pic14_emitcode("clr","c");
5941 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
5943 pic14_emitcode("mov","c,acc.7");
5944 pic14_emitcode("rrc","a");
5945 aopPut(AOP(result),"a",MSB32-offl);
5947 /* add sign of "a" */
5948 addSign(result, MSB32, sign);
5950 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
5951 pic14_emitcode("rrc","a");
5952 aopPut(AOP(result),"a",MSB24-offl);
5954 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
5955 pic14_emitcode("rrc","a");
5956 aopPut(AOP(result),"a",MSB16-offl);
5959 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
5960 pic14_emitcode("rrc","a");
5961 aopPut(AOP(result),"a",LSB);
5965 /*-----------------------------------------------------------------*/
5966 /* genrshFour - shift four byte by a known amount != 0 */
5967 /*-----------------------------------------------------------------*/
5968 static void genrshFour (operand *result, operand *left,
5969 int shCount, int sign)
5971 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5972 /* if shifting more that 3 bytes */
5973 if(shCount >= 24 ) {
5976 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
5978 movLeft2Result(left, MSB32, result, LSB, sign);
5979 addSign(result, MSB16, sign);
5981 else if(shCount >= 16){
5984 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
5986 movLeft2Result(left, MSB24, result, LSB, 0);
5987 movLeft2Result(left, MSB32, result, MSB16, sign);
5989 addSign(result, MSB24, sign);
5991 else if(shCount >= 8){
5994 shiftRLong(left, MSB16, result, sign);
5995 else if(shCount == 0){
5996 movLeft2Result(left, MSB16, result, LSB, 0);
5997 movLeft2Result(left, MSB24, result, MSB16, 0);
5998 movLeft2Result(left, MSB32, result, MSB24, sign);
5999 addSign(result, MSB32, sign);
6002 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6003 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6004 /* the last shift is signed */
6005 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6006 addSign(result, MSB32, sign);
6009 else{ /* 1 <= shCount <= 7 */
6011 shiftRLong(left, LSB, result, sign);
6013 shiftRLong(result, LSB, result, sign);
6016 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6017 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6018 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6023 /*-----------------------------------------------------------------*/
6024 /* genRightShiftLiteral - right shifting by known count */
6025 /*-----------------------------------------------------------------*/
6026 static void genRightShiftLiteral (operand *left,
6032 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6035 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6036 freeAsmop(right,NULL,ic,TRUE);
6038 aopOp(left,ic,FALSE);
6039 aopOp(result,ic,FALSE);
6042 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6046 size = pic14_getDataSize(left);
6047 /* test the LEFT size !!! */
6049 /* I suppose that the left size >= result size */
6051 size = pic14_getDataSize(result);
6053 movLeft2Result(left, size, result, size, 0);
6056 else if(shCount >= (size * 8)){
6058 /* get sign in acc.7 */
6059 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6060 addSign(result, LSB, sign);
6064 genrshOne (result,left,shCount,sign);
6068 genrshTwo (result,left,shCount,sign);
6072 genrshFour (result,left,shCount,sign);
6078 freeAsmop(left,NULL,ic,TRUE);
6079 freeAsmop(result,NULL,ic,TRUE);
6083 /*-----------------------------------------------------------------*/
6084 /* genSignedRightShift - right shift of signed number */
6085 /*-----------------------------------------------------------------*/
6086 static void genSignedRightShift (iCode *ic)
6088 operand *right, *left, *result;
6091 symbol *tlbl, *tlbl1 ;
6093 /* we do it the hard way put the shift count in b
6094 and loop thru preserving the sign */
6095 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6097 right = IC_RIGHT(ic);
6099 result = IC_RESULT(ic);
6101 aopOp(right,ic,FALSE);
6104 if ( AOP_TYPE(right) == AOP_LIT) {
6105 genRightShiftLiteral (left,right,result,ic,1);
6108 /* shift count is unknown then we have to form
6109 a loop get the loop count in B : Note: we take
6110 only the lower order byte since shifting
6111 more that 32 bits make no sense anyway, ( the
6112 largest size of an object can be only 32 bits ) */
6114 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6115 pic14_emitcode("inc","b");
6116 freeAsmop (right,NULL,ic,TRUE);
6117 aopOp(left,ic,FALSE);
6118 aopOp(result,ic,FALSE);
6120 /* now move the left to the result if they are not the
6122 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6123 AOP_SIZE(result) > 1) {
6125 size = AOP_SIZE(result);
6128 l = aopGet(AOP(left),offset,FALSE,TRUE);
6129 if (*l == '@' && IS_AOP_PREG(result)) {
6131 pic14_emitcode("mov","a,%s",l);
6132 aopPut(AOP(result),"a",offset);
6134 aopPut(AOP(result),l,offset);
6139 /* mov the highest order bit to OVR */
6140 tlbl = newiTempLabel(NULL);
6141 tlbl1= newiTempLabel(NULL);
6143 size = AOP_SIZE(result);
6145 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6146 pic14_emitcode("rlc","a");
6147 pic14_emitcode("mov","ov,c");
6148 /* if it is only one byte then */
6150 l = aopGet(AOP(left),0,FALSE,FALSE);
6152 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6153 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6154 pic14_emitcode("mov","c,ov");
6155 pic14_emitcode("rrc","a");
6156 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6157 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6158 aopPut(AOP(result),"a",0);
6162 reAdjustPreg(AOP(result));
6163 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6164 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6165 pic14_emitcode("mov","c,ov");
6167 l = aopGet(AOP(result),offset,FALSE,FALSE);
6169 pic14_emitcode("rrc","a");
6170 aopPut(AOP(result),"a",offset--);
6172 reAdjustPreg(AOP(result));
6173 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6174 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6177 freeAsmop(left,NULL,ic,TRUE);
6178 freeAsmop(result,NULL,ic,TRUE);
6181 /*-----------------------------------------------------------------*/
6182 /* genRightShift - generate code for right shifting */
6183 /*-----------------------------------------------------------------*/
6184 static void genRightShift (iCode *ic)
6186 operand *right, *left, *result;
6190 symbol *tlbl, *tlbl1 ;
6192 /* if signed then we do it the hard way preserve the
6193 sign bit moving it inwards */
6194 retype = getSpec(operandType(IC_RESULT(ic)));
6195 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6197 if (!SPEC_USIGN(retype)) {
6198 genSignedRightShift (ic);
6202 /* signed & unsigned types are treated the same : i.e. the
6203 signed is NOT propagated inwards : quoting from the
6204 ANSI - standard : "for E1 >> E2, is equivalent to division
6205 by 2**E2 if unsigned or if it has a non-negative value,
6206 otherwise the result is implementation defined ", MY definition
6207 is that the sign does not get propagated */
6209 right = IC_RIGHT(ic);
6211 result = IC_RESULT(ic);
6213 aopOp(right,ic,FALSE);
6215 /* if the shift count is known then do it
6216 as efficiently as possible */
6217 if (AOP_TYPE(right) == AOP_LIT) {
6218 genRightShiftLiteral (left,right,result,ic, 0);
6222 /* shift count is unknown then we have to form
6223 a loop get the loop count in B : Note: we take
6224 only the lower order byte since shifting
6225 more that 32 bits make no sense anyway, ( the
6226 largest size of an object can be only 32 bits ) */
6228 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6229 pic14_emitcode("inc","b");
6230 freeAsmop (right,NULL,ic,TRUE);
6231 aopOp(left,ic,FALSE);
6232 aopOp(result,ic,FALSE);
6234 /* now move the left to the result if they are not the
6236 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6237 AOP_SIZE(result) > 1) {
6239 size = AOP_SIZE(result);
6242 l = aopGet(AOP(left),offset,FALSE,TRUE);
6243 if (*l == '@' && IS_AOP_PREG(result)) {
6245 pic14_emitcode("mov","a,%s",l);
6246 aopPut(AOP(result),"a",offset);
6248 aopPut(AOP(result),l,offset);
6253 tlbl = newiTempLabel(NULL);
6254 tlbl1= newiTempLabel(NULL);
6255 size = AOP_SIZE(result);
6258 /* if it is only one byte then */
6260 l = aopGet(AOP(left),0,FALSE,FALSE);
6262 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6263 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6265 pic14_emitcode("rrc","a");
6266 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6267 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6268 aopPut(AOP(result),"a",0);
6272 reAdjustPreg(AOP(result));
6273 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6274 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6277 l = aopGet(AOP(result),offset,FALSE,FALSE);
6279 pic14_emitcode("rrc","a");
6280 aopPut(AOP(result),"a",offset--);
6282 reAdjustPreg(AOP(result));
6284 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6285 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6288 freeAsmop(left,NULL,ic,TRUE);
6289 freeAsmop(result,NULL,ic,TRUE);
6292 /*-----------------------------------------------------------------*/
6293 /* genUnpackBits - generates code for unpacking bits */
6294 /*-----------------------------------------------------------------*/
6295 static void genUnpackBits (operand *result, char *rname, int ptype)
6302 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6303 etype = getSpec(operandType(result));
6305 /* read the first byte */
6310 pic14_emitcode("mov","a,@%s",rname);
6314 pic14_emitcode("movx","a,@%s",rname);
6318 pic14_emitcode("movx","a,@dptr");
6322 pic14_emitcode("clr","a");
6323 pic14_emitcode("movc","a","@a+dptr");
6327 pic14_emitcode("lcall","__gptrget");
6331 /* if we have bitdisplacement then it fits */
6332 /* into this byte completely or if length is */
6333 /* less than a byte */
6334 if ((shCnt = SPEC_BSTR(etype)) ||
6335 (SPEC_BLEN(etype) <= 8)) {
6337 /* shift right acc */
6340 pic14_emitcode("anl","a,#0x%02x",
6341 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6342 aopPut(AOP(result),"a",offset);
6346 /* bit field did not fit in a byte */
6347 rlen = SPEC_BLEN(etype) - 8;
6348 aopPut(AOP(result),"a",offset++);
6355 pic14_emitcode("inc","%s",rname);
6356 pic14_emitcode("mov","a,@%s",rname);
6360 pic14_emitcode("inc","%s",rname);
6361 pic14_emitcode("movx","a,@%s",rname);
6365 pic14_emitcode("inc","dptr");
6366 pic14_emitcode("movx","a,@dptr");
6370 pic14_emitcode("clr","a");
6371 pic14_emitcode("inc","dptr");
6372 pic14_emitcode("movc","a","@a+dptr");
6376 pic14_emitcode("inc","dptr");
6377 pic14_emitcode("lcall","__gptrget");
6382 /* if we are done */
6386 aopPut(AOP(result),"a",offset++);
6391 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
6392 aopPut(AOP(result),"a",offset);
6399 /*-----------------------------------------------------------------*/
6400 /* genDataPointerGet - generates code when ptr offset is known */
6401 /*-----------------------------------------------------------------*/
6402 static void genDataPointerGet (operand *left,
6406 int size , offset = 0;
6409 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6412 /* optimization - most of the time, left and result are the same
6413 * address, but different types. for the pic code, we could omit
6417 aopOp(result,ic,TRUE);
6419 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
6421 size = AOP_SIZE(result);
6424 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
6428 freeAsmop(left,NULL,ic,TRUE);
6429 freeAsmop(result,NULL,ic,TRUE);
6432 /*-----------------------------------------------------------------*/
6433 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
6434 /*-----------------------------------------------------------------*/
6435 static void genNearPointerGet (operand *left,
6442 sym_link *rtype, *retype;
6443 sym_link *ltype = operandType(left);
6446 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6448 rtype = operandType(result);
6449 retype= getSpec(rtype);
6451 aopOp(left,ic,FALSE);
6453 /* if left is rematerialisable and
6454 result is not bit variable type and
6455 the left is pointer to data space i.e
6456 lower 128 bytes of space */
6457 if (AOP_TYPE(left) == AOP_IMMD &&
6458 !IS_BITVAR(retype) &&
6459 DCL_TYPE(ltype) == POINTER) {
6460 genDataPointerGet (left,result,ic);
6464 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6466 /* if the value is already in a pointer register
6467 then don't need anything more */
6468 if (!AOP_INPREG(AOP(left))) {
6469 /* otherwise get a free pointer register */
6470 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6472 preg = getFreePtr(ic,&aop,FALSE);
6473 pic14_emitcode("mov","%s,%s",
6475 aopGet(AOP(left),0,FALSE,TRUE));
6476 rname = preg->name ;
6478 rname = aopGet(AOP(left),0,FALSE,FALSE);
6480 freeAsmop(left,NULL,ic,TRUE);
6481 aopOp (result,ic,FALSE);
6483 /* if bitfield then unpack the bits */
6484 if (IS_BITVAR(retype))
6485 genUnpackBits (result,rname,POINTER);
6487 /* we have can just get the values */
6488 int size = AOP_SIZE(result);
6491 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6493 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
6495 pic14_emitcode("mov","a,@%s",rname);
6496 aopPut(AOP(result),"a",offset);
6498 sprintf(buffer,"@%s",rname);
6499 aopPut(AOP(result),buffer,offset);
6503 pic14_emitcode("inc","%s",rname);
6507 /* now some housekeeping stuff */
6509 /* we had to allocate for this iCode */
6510 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6511 freeAsmop(NULL,aop,ic,TRUE);
6513 /* we did not allocate which means left
6514 already in a pointer register, then
6515 if size > 0 && this could be used again
6516 we have to point it back to where it
6518 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6519 if (AOP_SIZE(result) > 1 &&
6520 !OP_SYMBOL(left)->remat &&
6521 ( OP_SYMBOL(left)->liveTo > ic->seq ||
6523 int size = AOP_SIZE(result) - 1;
6525 pic14_emitcode("dec","%s",rname);
6530 freeAsmop(result,NULL,ic,TRUE);
6534 /*-----------------------------------------------------------------*/
6535 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
6536 /*-----------------------------------------------------------------*/
6537 static void genPagedPointerGet (operand *left,
6544 sym_link *rtype, *retype;
6546 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6548 rtype = operandType(result);
6549 retype= getSpec(rtype);
6551 aopOp(left,ic,FALSE);
6553 /* if the value is already in a pointer register
6554 then don't need anything more */
6555 if (!AOP_INPREG(AOP(left))) {
6556 /* otherwise get a free pointer register */
6558 preg = getFreePtr(ic,&aop,FALSE);
6559 pic14_emitcode("mov","%s,%s",
6561 aopGet(AOP(left),0,FALSE,TRUE));
6562 rname = preg->name ;
6564 rname = aopGet(AOP(left),0,FALSE,FALSE);
6566 freeAsmop(left,NULL,ic,TRUE);
6567 aopOp (result,ic,FALSE);
6569 /* if bitfield then unpack the bits */
6570 if (IS_BITVAR(retype))
6571 genUnpackBits (result,rname,PPOINTER);
6573 /* we have can just get the values */
6574 int size = AOP_SIZE(result);
6579 pic14_emitcode("movx","a,@%s",rname);
6580 aopPut(AOP(result),"a",offset);
6585 pic14_emitcode("inc","%s",rname);
6589 /* now some housekeeping stuff */
6591 /* we had to allocate for this iCode */
6592 freeAsmop(NULL,aop,ic,TRUE);
6594 /* we did not allocate which means left
6595 already in a pointer register, then
6596 if size > 0 && this could be used again
6597 we have to point it back to where it
6599 if (AOP_SIZE(result) > 1 &&
6600 !OP_SYMBOL(left)->remat &&
6601 ( OP_SYMBOL(left)->liveTo > ic->seq ||
6603 int size = AOP_SIZE(result) - 1;
6605 pic14_emitcode("dec","%s",rname);
6610 freeAsmop(result,NULL,ic,TRUE);
6615 /*-----------------------------------------------------------------*/
6616 /* genFarPointerGet - gget value from far space */
6617 /*-----------------------------------------------------------------*/
6618 static void genFarPointerGet (operand *left,
6619 operand *result, iCode *ic)
6622 sym_link *retype = getSpec(operandType(result));
6624 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6626 aopOp(left,ic,FALSE);
6628 /* if the operand is already in dptr
6629 then we do nothing else we move the value to dptr */
6630 if (AOP_TYPE(left) != AOP_STR) {
6631 /* if this is remateriazable */
6632 if (AOP_TYPE(left) == AOP_IMMD)
6633 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
6634 else { /* we need to get it byte by byte */
6635 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
6636 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
6637 if (options.model == MODEL_FLAT24)
6639 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
6643 /* so dptr know contains the address */
6644 freeAsmop(left,NULL,ic,TRUE);
6645 aopOp(result,ic,FALSE);
6647 /* if bit then unpack */
6648 if (IS_BITVAR(retype))
6649 genUnpackBits(result,"dptr",FPOINTER);
6651 size = AOP_SIZE(result);
6655 pic14_emitcode("movx","a,@dptr");
6656 aopPut(AOP(result),"a",offset++);
6658 pic14_emitcode("inc","dptr");
6662 freeAsmop(result,NULL,ic,TRUE);
6665 /*-----------------------------------------------------------------*/
6666 /* pic14_emitcodePointerGet - gget value from code space */
6667 /*-----------------------------------------------------------------*/
6668 static void pic14_emitcodePointerGet (operand *left,
6669 operand *result, iCode *ic)
6672 sym_link *retype = getSpec(operandType(result));
6674 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6676 aopOp(left,ic,FALSE);
6678 /* if the operand is already in dptr
6679 then we do nothing else we move the value to dptr */
6680 if (AOP_TYPE(left) != AOP_STR) {
6681 /* if this is remateriazable */
6682 if (AOP_TYPE(left) == AOP_IMMD)
6683 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
6684 else { /* we need to get it byte by byte */
6685 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
6686 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
6687 if (options.model == MODEL_FLAT24)
6689 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
6693 /* so dptr know contains the address */
6694 freeAsmop(left,NULL,ic,TRUE);
6695 aopOp(result,ic,FALSE);
6697 /* if bit then unpack */
6698 if (IS_BITVAR(retype))
6699 genUnpackBits(result,"dptr",CPOINTER);
6701 size = AOP_SIZE(result);
6705 pic14_emitcode("clr","a");
6706 pic14_emitcode("movc","a,@a+dptr");
6707 aopPut(AOP(result),"a",offset++);
6709 pic14_emitcode("inc","dptr");
6713 freeAsmop(result,NULL,ic,TRUE);
6716 /*-----------------------------------------------------------------*/
6717 /* genGenPointerGet - gget value from generic pointer space */
6718 /*-----------------------------------------------------------------*/
6719 static void genGenPointerGet (operand *left,
6720 operand *result, iCode *ic)
6723 sym_link *retype = getSpec(operandType(result));
6725 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6726 aopOp(left,ic,FALSE);
6728 /* if the operand is already in dptr
6729 then we do nothing else we move the value to dptr */
6730 if (AOP_TYPE(left) != AOP_STR) {
6731 /* if this is remateriazable */
6732 if (AOP_TYPE(left) == AOP_IMMD) {
6733 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
6734 pic14_emitcode("mov","b,#%d",pointerCode(retype));
6736 else { /* we need to get it byte by byte */
6737 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
6738 //emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
6739 //emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
6740 pic14_emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
6741 pic14_emitcode("movwf","FSR");
6743 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
6744 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
6745 if (options.model == MODEL_FLAT24)
6747 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
6748 pic14_emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
6752 pic14_emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
6757 /* so dptr know contains the address */
6758 freeAsmop(left,NULL,ic,TRUE);
6759 aopOp(result,ic,FALSE);
6761 /* if bit then unpack */
6762 if (IS_BITVAR(retype))
6763 genUnpackBits(result,"dptr",GPOINTER);
6765 size = AOP_SIZE(result);
6769 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
6771 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
6773 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
6775 pic14_emitcode("movf","indf,w");
6776 pic14_emitcode("movwf","%s",
6777 aopGet(AOP(result),offset++,FALSE,FALSE));
6779 pic14_emitcode("incf","fsr,f");
6784 freeAsmop(result,NULL,ic,TRUE);
6787 /*-----------------------------------------------------------------*/
6788 /* genPointerGet - generate code for pointer get */
6789 /*-----------------------------------------------------------------*/
6790 static void genPointerGet (iCode *ic)
6792 operand *left, *result ;
6793 sym_link *type, *etype;
6796 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6799 result = IC_RESULT(ic) ;
6801 /* depending on the type of pointer we need to
6802 move it to the correct pointer register */
6803 type = operandType(left);
6804 etype = getSpec(type);
6805 /* if left is of type of pointer then it is simple */
6806 if (IS_PTR(type) && !IS_FUNC(type->next))
6807 p_type = DCL_TYPE(type);
6809 /* we have to go by the storage class */
6810 p_type = PTR_TYPE(SPEC_OCLS(etype));
6812 /* if (SPEC_OCLS(etype)->codesp ) { */
6813 /* p_type = CPOINTER ; */
6816 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
6817 /* p_type = FPOINTER ; */
6819 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
6820 /* p_type = PPOINTER; */
6822 /* if (SPEC_OCLS(etype) == idata ) */
6823 /* p_type = IPOINTER; */
6825 /* p_type = POINTER ; */
6828 /* now that we have the pointer type we assign
6829 the pointer values */
6834 genNearPointerGet (left,result,ic);
6838 genPagedPointerGet(left,result,ic);
6842 genFarPointerGet (left,result,ic);
6846 pic14_emitcodePointerGet (left,result,ic);
6850 genGenPointerGet (left,result,ic);
6856 /*-----------------------------------------------------------------*/
6857 /* genPackBits - generates code for packed bit storage */
6858 /*-----------------------------------------------------------------*/
6859 static void genPackBits (sym_link *etype ,
6861 char *rname, int p_type)
6869 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6870 blen = SPEC_BLEN(etype);
6871 bstr = SPEC_BSTR(etype);
6873 l = aopGet(AOP(right),offset++,FALSE,FALSE);
6876 /* if the bit lenth is less than or */
6877 /* it exactly fits a byte then */
6878 if (SPEC_BLEN(etype) <= 8 ) {
6879 shCount = SPEC_BSTR(etype) ;
6881 /* shift left acc */
6884 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
6889 pic14_emitcode ("mov","b,a");
6890 pic14_emitcode("mov","a,@%s",rname);
6894 pic14_emitcode ("mov","b,a");
6895 pic14_emitcode("movx","a,@dptr");
6899 pic14_emitcode ("push","b");
6900 pic14_emitcode ("push","acc");
6901 pic14_emitcode ("lcall","__gptrget");
6902 pic14_emitcode ("pop","b");
6906 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
6907 ((unsigned char)(0xFF << (blen+bstr)) |
6908 (unsigned char)(0xFF >> (8-bstr)) ) );
6909 pic14_emitcode ("orl","a,b");
6910 if (p_type == GPOINTER)
6911 pic14_emitcode("pop","b");
6917 pic14_emitcode("mov","@%s,a",rname);
6921 pic14_emitcode("movx","@dptr,a");
6925 DEBUGpic14_emitcode(";lcall","__gptrput");
6930 if ( SPEC_BLEN(etype) <= 8 )
6933 pic14_emitcode("inc","%s",rname);
6934 rLen = SPEC_BLEN(etype) ;
6936 /* now generate for lengths greater than one byte */
6939 l = aopGet(AOP(right),offset++,FALSE,TRUE);
6949 pic14_emitcode("mov","@%s,a",rname);
6951 pic14_emitcode("mov","@%s,%s",rname,l);
6956 pic14_emitcode("movx","@dptr,a");
6961 DEBUGpic14_emitcode(";lcall","__gptrput");
6964 pic14_emitcode ("inc","%s",rname);
6969 /* last last was not complete */
6971 /* save the byte & read byte */
6974 pic14_emitcode ("mov","b,a");
6975 pic14_emitcode("mov","a,@%s",rname);
6979 pic14_emitcode ("mov","b,a");
6980 pic14_emitcode("movx","a,@dptr");
6984 pic14_emitcode ("push","b");
6985 pic14_emitcode ("push","acc");
6986 pic14_emitcode ("lcall","__gptrget");
6987 pic14_emitcode ("pop","b");
6991 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
6992 pic14_emitcode ("orl","a,b");
6995 if (p_type == GPOINTER)
6996 pic14_emitcode("pop","b");
7001 pic14_emitcode("mov","@%s,a",rname);
7005 pic14_emitcode("movx","@dptr,a");
7009 DEBUGpic14_emitcode(";lcall","__gptrput");
7013 /*-----------------------------------------------------------------*/
7014 /* genDataPointerSet - remat pointer to data space */
7015 /*-----------------------------------------------------------------*/
7016 static void genDataPointerSet(operand *right,
7020 int size, offset = 0 ;
7021 char *l, buffer[256];
7023 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7024 aopOp(right,ic,FALSE);
7026 l = aopGet(AOP(result),0,FALSE,TRUE);
7027 size = AOP_SIZE(right);
7028 // tsd, was l+1 - the underline `_' prefix was being stripped
7031 sprintf(buffer,"(%s + %d)",l,offset);
7033 sprintf(buffer,"%s",l);
7035 if (AOP_TYPE(right) == AOP_LIT) {
7036 unsigned int lit = floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7037 lit = lit >> (8*offset);
7039 pic14_emitcode("movlw","%d",lit);
7040 pic14_emitcode("movwf","%s",buffer);
7042 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7043 emitpcode(POC_MOVWF, popRegFromString(buffer));
7046 pic14_emitcode("clrf","%s",buffer);
7047 emitpcode(POC_CLRF, popRegFromString(buffer));
7050 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7051 pic14_emitcode("movwf","%s",buffer);
7053 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7054 emitpcode(POC_MOVWF, popRegFromString(buffer));
7061 freeAsmop(right,NULL,ic,TRUE);
7062 freeAsmop(result,NULL,ic,TRUE);
7065 /*-----------------------------------------------------------------*/
7066 /* genNearPointerSet - pic14_emitcode for near pointer put */
7067 /*-----------------------------------------------------------------*/
7068 static void genNearPointerSet (operand *right,
7075 sym_link *ptype = operandType(result);
7078 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7079 retype= getSpec(operandType(right));
7081 aopOp(result,ic,FALSE);
7083 /* if the result is rematerializable &
7084 in data space & not a bit variable */
7085 if (AOP_TYPE(result) == AOP_IMMD &&
7086 DCL_TYPE(ptype) == POINTER &&
7087 !IS_BITVAR(retype)) {
7088 genDataPointerSet (right,result,ic);
7092 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7094 /* if the value is already in a pointer register
7095 then don't need anything more */
7096 if (!AOP_INPREG(AOP(result))) {
7097 /* otherwise get a free pointer register */
7098 //aop = newAsmop(0);
7099 //preg = getFreePtr(ic,&aop,FALSE);
7100 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7101 //pic14_emitcode("mov","%s,%s",
7103 // aopGet(AOP(result),0,FALSE,TRUE));
7104 //rname = preg->name ;
7105 pic14_emitcode("movwf","fsr");
7107 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7109 freeAsmop(result,NULL,ic,TRUE);
7110 aopOp (right,ic,FALSE);
7111 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7113 /* if bitfield then unpack the bits */
7114 if (IS_BITVAR(retype)) {
7115 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7116 "The programmer is obviously confused");
7117 //genPackBits (retype,right,rname,POINTER);
7121 /* we have can just get the values */
7122 int size = AOP_SIZE(right);
7125 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7127 l = aopGet(AOP(right),offset,FALSE,TRUE);
7130 //pic14_emitcode("mov","@%s,a",rname);
7131 pic14_emitcode("movf","indf,w ;1");
7134 if (AOP_TYPE(right) == AOP_LIT) {
7135 unsigned int lit = floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7137 pic14_emitcode("movlw","%s",l);
7138 pic14_emitcode("movwf","indf ;2");
7140 pic14_emitcode("clrf","indf");
7142 pic14_emitcode("movf","%s,w",l);
7143 pic14_emitcode("movwf","indf ;2");
7145 //pic14_emitcode("mov","@%s,%s",rname,l);
7148 pic14_emitcode("incf","fsr,f ;3");
7149 //pic14_emitcode("inc","%s",rname);
7154 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7155 /* now some housekeeping stuff */
7157 /* we had to allocate for this iCode */
7158 freeAsmop(NULL,aop,ic,TRUE);
7160 /* we did not allocate which means left
7161 already in a pointer register, then
7162 if size > 0 && this could be used again
7163 we have to point it back to where it
7165 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7166 if (AOP_SIZE(right) > 1 &&
7167 !OP_SYMBOL(result)->remat &&
7168 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7170 int size = AOP_SIZE(right) - 1;
7172 pic14_emitcode("decf","fsr,f");
7173 //pic14_emitcode("dec","%s",rname);
7177 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7179 freeAsmop(right,NULL,ic,TRUE);
7184 /*-----------------------------------------------------------------*/
7185 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7186 /*-----------------------------------------------------------------*/
7187 static void genPagedPointerSet (operand *right,
7196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7198 retype= getSpec(operandType(right));
7200 aopOp(result,ic,FALSE);
7202 /* if the value is already in a pointer register
7203 then don't need anything more */
7204 if (!AOP_INPREG(AOP(result))) {
7205 /* otherwise get a free pointer register */
7207 preg = getFreePtr(ic,&aop,FALSE);
7208 pic14_emitcode("mov","%s,%s",
7210 aopGet(AOP(result),0,FALSE,TRUE));
7211 rname = preg->name ;
7213 rname = aopGet(AOP(result),0,FALSE,FALSE);
7215 freeAsmop(result,NULL,ic,TRUE);
7216 aopOp (right,ic,FALSE);
7218 /* if bitfield then unpack the bits */
7219 if (IS_BITVAR(retype))
7220 genPackBits (retype,right,rname,PPOINTER);
7222 /* we have can just get the values */
7223 int size = AOP_SIZE(right);
7227 l = aopGet(AOP(right),offset,FALSE,TRUE);
7230 pic14_emitcode("movx","@%s,a",rname);
7233 pic14_emitcode("inc","%s",rname);
7239 /* now some housekeeping stuff */
7241 /* we had to allocate for this iCode */
7242 freeAsmop(NULL,aop,ic,TRUE);
7244 /* we did not allocate which means left
7245 already in a pointer register, then
7246 if size > 0 && this could be used again
7247 we have to point it back to where it
7249 if (AOP_SIZE(right) > 1 &&
7250 !OP_SYMBOL(result)->remat &&
7251 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7253 int size = AOP_SIZE(right) - 1;
7255 pic14_emitcode("dec","%s",rname);
7260 freeAsmop(right,NULL,ic,TRUE);
7265 /*-----------------------------------------------------------------*/
7266 /* genFarPointerSet - set value from far space */
7267 /*-----------------------------------------------------------------*/
7268 static void genFarPointerSet (operand *right,
7269 operand *result, iCode *ic)
7272 sym_link *retype = getSpec(operandType(right));
7274 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7275 aopOp(result,ic,FALSE);
7277 /* if the operand is already in dptr
7278 then we do nothing else we move the value to dptr */
7279 if (AOP_TYPE(result) != AOP_STR) {
7280 /* if this is remateriazable */
7281 if (AOP_TYPE(result) == AOP_IMMD)
7282 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7283 else { /* we need to get it byte by byte */
7284 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7285 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7286 if (options.model == MODEL_FLAT24)
7288 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7292 /* so dptr know contains the address */
7293 freeAsmop(result,NULL,ic,TRUE);
7294 aopOp(right,ic,FALSE);
7296 /* if bit then unpack */
7297 if (IS_BITVAR(retype))
7298 genPackBits(retype,right,"dptr",FPOINTER);
7300 size = AOP_SIZE(right);
7304 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7306 pic14_emitcode("movx","@dptr,a");
7308 pic14_emitcode("inc","dptr");
7312 freeAsmop(right,NULL,ic,TRUE);
7315 /*-----------------------------------------------------------------*/
7316 /* genGenPointerSet - set value from generic pointer space */
7317 /*-----------------------------------------------------------------*/
7318 static void genGenPointerSet (operand *right,
7319 operand *result, iCode *ic)
7322 sym_link *retype = getSpec(operandType(right));
7324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7326 aopOp(result,ic,FALSE);
7328 /* if the operand is already in dptr
7329 then we do nothing else we move the value to dptr */
7330 if (AOP_TYPE(result) != AOP_STR) {
7331 /* if this is remateriazable */
7332 if (AOP_TYPE(result) == AOP_IMMD) {
7333 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7334 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7336 else { /* we need to get it byte by byte */
7337 char *l = aopGet(AOP(result),0,FALSE,FALSE);
7340 emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
7341 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7344 pic14_emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
7346 pic14_emitcode("movwf","INDF");
7349 /* so dptr know contains the address */
7350 freeAsmop(result,NULL,ic,TRUE);
7351 aopOp(right,ic,FALSE);
7353 /* if bit then unpack */
7354 if (IS_BITVAR(retype))
7355 genPackBits(retype,right,"dptr",GPOINTER);
7357 size = AOP_SIZE(right);
7361 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7363 pic14_emitcode("incf","fsr,f");
7364 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
7365 pic14_emitcode("movwf","indf");
7367 //DEBUGpic14_emitcode(";lcall","__gptrput");
7369 // pic14_emitcode("inc","dptr");
7373 freeAsmop(right,NULL,ic,TRUE);
7376 /*-----------------------------------------------------------------*/
7377 /* genPointerSet - stores the value into a pointer location */
7378 /*-----------------------------------------------------------------*/
7379 static void genPointerSet (iCode *ic)
7381 operand *right, *result ;
7382 sym_link *type, *etype;
7385 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7387 right = IC_RIGHT(ic);
7388 result = IC_RESULT(ic) ;
7390 /* depending on the type of pointer we need to
7391 move it to the correct pointer register */
7392 type = operandType(result);
7393 etype = getSpec(type);
7394 /* if left is of type of pointer then it is simple */
7395 if (IS_PTR(type) && !IS_FUNC(type->next)) {
7396 p_type = DCL_TYPE(type);
7399 /* we have to go by the storage class */
7400 p_type = PTR_TYPE(SPEC_OCLS(etype));
7402 /* if (SPEC_OCLS(etype)->codesp ) { */
7403 /* p_type = CPOINTER ; */
7406 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7407 /* p_type = FPOINTER ; */
7409 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7410 /* p_type = PPOINTER ; */
7412 /* if (SPEC_OCLS(etype) == idata ) */
7413 /* p_type = IPOINTER ; */
7415 /* p_type = POINTER ; */
7418 /* now that we have the pointer type we assign
7419 the pointer values */
7424 genNearPointerSet (right,result,ic);
7428 genPagedPointerSet (right,result,ic);
7432 genFarPointerSet (right,result,ic);
7436 genGenPointerSet (right,result,ic);
7442 /*-----------------------------------------------------------------*/
7443 /* genIfx - generate code for Ifx statement */
7444 /*-----------------------------------------------------------------*/
7445 static void genIfx (iCode *ic, iCode *popIc)
7447 operand *cond = IC_COND(ic);
7450 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7451 aopOp(cond,ic,FALSE);
7453 /* get the value into acc */
7454 if (AOP_TYPE(cond) != AOP_CRY)
7455 pic14_toBoolean(cond);
7458 /* the result is now in the accumulator */
7459 freeAsmop(cond,NULL,ic,TRUE);
7461 /* if there was something to be popped then do it */
7465 /* if the condition is a bit variable */
7466 if (isbit && IS_ITEMP(cond) &&
7468 genIfxJump(ic,SPIL_LOC(cond)->rname);
7469 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
7473 if (isbit && !IS_ITEMP(cond))
7474 DEBUGpic14_emitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
7476 DEBUGpic14_emitcode ("; isbit","a");
7479 if (isbit && !IS_ITEMP(cond))
7480 genIfxJump(ic,OP_SYMBOL(cond)->rname);
7487 /*-----------------------------------------------------------------*/
7488 /* genAddrOf - generates code for address of */
7489 /*-----------------------------------------------------------------*/
7490 static void genAddrOf (iCode *ic)
7492 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
7495 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7497 aopOp(IC_RESULT(ic),ic,FALSE);
7499 /* if the operand is on the stack then we
7500 need to get the stack offset of this
7503 /* if it has an offset then we need to compute
7506 pic14_emitcode("mov","a,_bp");
7507 pic14_emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
7508 aopPut(AOP(IC_RESULT(ic)),"a",0);
7510 /* we can just move _bp */
7511 aopPut(AOP(IC_RESULT(ic)),"_bp",0);
7513 /* fill the result with zero */
7514 size = AOP_SIZE(IC_RESULT(ic)) - 1;
7517 if (options.stack10bit && size < (FPTRSIZE - 1))
7520 "*** warning: pointer to stack var truncated.\n");
7527 if (options.stack10bit && offset == 2)
7529 aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
7533 aopPut(AOP(IC_RESULT(ic)),zero,offset++);
7540 /* object not on stack then we need the name */
7541 size = AOP_SIZE(IC_RESULT(ic));
7545 char s[SDCC_NAME_MAX];
7547 sprintf(s,"#(%s >> %d)",
7551 sprintf(s,"#%s",sym->rname);
7552 aopPut(AOP(IC_RESULT(ic)),s,offset++);
7556 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
7561 /*-----------------------------------------------------------------*/
7562 /* genFarFarAssign - assignment when both are in far space */
7563 /*-----------------------------------------------------------------*/
7564 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
7566 int size = AOP_SIZE(right);
7569 /* first push the right side on to the stack */
7571 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7573 pic14_emitcode ("push","acc");
7576 freeAsmop(right,NULL,ic,FALSE);
7577 /* now assign DPTR to result */
7578 aopOp(result,ic,FALSE);
7579 size = AOP_SIZE(result);
7581 pic14_emitcode ("pop","acc");
7582 aopPut(AOP(result),"a",--offset);
7584 freeAsmop(result,NULL,ic,FALSE);
7589 /*-----------------------------------------------------------------*/
7590 /* genAssign - generate code for assignment */
7591 /*-----------------------------------------------------------------*/
7592 static void genAssign (iCode *ic)
7594 operand *result, *right;
7596 unsigned long lit = 0L;
7598 result = IC_RESULT(ic);
7599 right = IC_RIGHT(ic) ;
7601 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7603 /* if they are the same */
7604 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
7607 aopOp(right,ic,FALSE);
7608 aopOp(result,ic,TRUE);
7610 /* if they are the same registers */
7611 if (pic14_sameRegs(AOP(right),AOP(result)))
7614 /* if the result is a bit */
7615 if (AOP_TYPE(result) == AOP_CRY) {
7617 /* if the right size is a literal then
7618 we know what the value is */
7619 if (AOP_TYPE(right) == AOP_LIT) {
7621 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
7622 popGet(AOP(result),0,FALSE,FALSE));
7624 if (((int) operandLitValue(right)))
7625 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
7626 AOP(result)->aopu.aop_dir,
7627 AOP(result)->aopu.aop_dir);
7629 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
7630 AOP(result)->aopu.aop_dir,
7631 AOP(result)->aopu.aop_dir);
7635 /* the right is also a bit variable */
7636 if (AOP_TYPE(right) == AOP_CRY) {
7637 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
7638 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
7639 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
7641 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
7642 AOP(result)->aopu.aop_dir,
7643 AOP(result)->aopu.aop_dir);
7644 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
7645 AOP(right)->aopu.aop_dir,
7646 AOP(right)->aopu.aop_dir);
7647 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
7648 AOP(result)->aopu.aop_dir,
7649 AOP(result)->aopu.aop_dir);
7654 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
7655 pic14_toBoolean(right);
7657 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
7658 //aopPut(AOP(result),"a",0);
7662 /* bit variables done */
7664 size = AOP_SIZE(result);
7666 if(AOP_TYPE(right) == AOP_LIT)
7667 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
7668 if((AOP_TYPE(result) != AOP_REG) &&
7669 (AOP_TYPE(right) == AOP_LIT) &&
7670 !IS_FLOAT(operandType(right)) &&
7674 if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) {
7675 //pic14_emitcode("clrf","%s", aopGet(AOP(result),size,FALSE,FALSE));
7676 emitpcode(POC_CLRF,popGet(AOP(result),size,FALSE,FALSE));
7678 emitpcode(POC_MOVLW,popGet(AOP(right),size,FALSE,FALSE));
7679 emitpcode(POC_MOVWF,popGet(AOP(result),size,FALSE,FALSE));
7680 //pic14_emitcode("movlw","%s", aopGet(AOP(right),size,FALSE,FALSE));
7681 //pic14_emitcode("movwf","%s", aopGet(AOP(result),size,FALSE,FALSE));
7686 if(AOP_TYPE(right) == AOP_LIT) {
7687 emitpcode(POC_MOVLW, popGet(AOP(right),offset,FALSE,FALSE));
7688 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
7690 } else if (AOP_TYPE(right) == AOP_CRY) {
7691 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
7693 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
7694 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
7697 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7698 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
7701 //pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE));
7707 freeAsmop (right,NULL,ic,FALSE);
7708 freeAsmop (result,NULL,ic,TRUE);
7711 /*-----------------------------------------------------------------*/
7712 /* genJumpTab - genrates code for jump table */
7713 /*-----------------------------------------------------------------*/
7714 static void genJumpTab (iCode *ic)
7719 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7721 aopOp(IC_JTCOND(ic),ic,FALSE);
7722 /* get the condition into accumulator */
7723 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
7725 /* multiply by three */
7726 pic14_emitcode("add","a,acc");
7727 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
7728 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
7730 jtab = newiTempLabel(NULL);
7731 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
7732 pic14_emitcode("jmp","@a+dptr");
7733 pic14_emitcode("","%05d_DS_:",jtab->key+100);
7734 /* now generate the jump labels */
7735 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
7736 jtab = setNextItem(IC_JTLABELS(ic)))
7737 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
7741 /*-----------------------------------------------------------------*/
7742 /* genMixedOperation - gen code for operators between mixed types */
7743 /*-----------------------------------------------------------------*/
7745 TSD - Written for the PIC port - but this unfortunately is buggy.
7746 This routine is good in that it is able to efficiently promote
7747 types to different (larger) sizes. Unfortunately, the temporary
7748 variables that are optimized out by this routine are sometimes
7749 used in other places. So until I know how to really parse the
7750 iCode tree, I'm going to not be using this routine :(.
7752 static int genMixedOperation (iCode *ic)
7755 operand *result = IC_RESULT(ic);
7756 sym_link *ctype = operandType(IC_LEFT(ic));
7757 operand *right = IC_RIGHT(ic);
7763 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
7765 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
7771 nextright = IC_RIGHT(nextic);
7772 nextleft = IC_LEFT(nextic);
7773 nextresult = IC_RESULT(nextic);
7775 aopOp(right,ic,FALSE);
7776 aopOp(result,ic,FALSE);
7777 aopOp(nextright, nextic, FALSE);
7778 aopOp(nextleft, nextic, FALSE);
7779 aopOp(nextresult, nextic, FALSE);
7781 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
7787 pic14_emitcode(";remove right +","");
7789 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
7795 pic14_emitcode(";remove left +","");
7799 big = AOP_SIZE(nextleft);
7800 small = AOP_SIZE(nextright);
7802 switch(nextic->op) {
7805 pic14_emitcode(";optimize a +","");
7806 /* if unsigned or not an integral type */
7807 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
7808 pic14_emitcode(";add a bit to something","");
7811 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
7813 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
7814 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
7815 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
7817 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
7825 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
7826 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
7827 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
7830 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
7832 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
7833 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
7834 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
7835 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
7836 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
7839 pic14_emitcode("rlf","known_zero,w");
7846 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
7847 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
7848 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
7850 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
7860 freeAsmop(right,NULL,ic,TRUE);
7861 freeAsmop(result,NULL,ic,TRUE);
7862 freeAsmop(nextright,NULL,ic,TRUE);
7863 freeAsmop(nextleft,NULL,ic,TRUE);
7865 nextic->generated = 1;
7872 /*-----------------------------------------------------------------*/
7873 /* genCast - gen code for casting */
7874 /*-----------------------------------------------------------------*/
7875 static void genCast (iCode *ic)
7877 operand *result = IC_RESULT(ic);
7878 sym_link *ctype = operandType(IC_LEFT(ic));
7879 operand *right = IC_RIGHT(ic);
7882 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
7883 /* if they are equivalent then do nothing */
7884 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
7887 aopOp(right,ic,FALSE) ;
7888 aopOp(result,ic,FALSE);
7890 /* if the result is a bit */
7891 if (AOP_TYPE(result) == AOP_CRY) {
7892 /* if the right size is a literal then
7893 we know what the value is */
7894 if (AOP_TYPE(right) == AOP_LIT) {
7896 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
7897 popGet(AOP(result),0,FALSE,FALSE));
7899 if (((int) operandLitValue(right)))
7900 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
7901 AOP(result)->aopu.aop_dir,
7902 AOP(result)->aopu.aop_dir);
7904 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
7905 AOP(result)->aopu.aop_dir,
7906 AOP(result)->aopu.aop_dir);
7911 /* the right is also a bit variable */
7912 if (AOP_TYPE(right) == AOP_CRY) {
7915 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
7917 pic14_emitcode("clrc","");
7918 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
7919 AOP(right)->aopu.aop_dir,
7920 AOP(right)->aopu.aop_dir);
7921 aopPut(AOP(result),"c",0);
7926 pic14_toBoolean(right);
7927 aopPut(AOP(result),"a",0);
7931 /* if they are the same size : or less */
7932 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
7934 /* if they are in the same place */
7935 if (pic14_sameRegs(AOP(right),AOP(result)))
7938 /* if they in different places then copy */
7939 size = AOP_SIZE(result);
7943 aopGet(AOP(right),offset,FALSE,FALSE),
7951 /* if the result is of type pointer */
7952 if (IS_PTR(ctype)) {
7955 sym_link *type = operandType(right);
7956 sym_link *etype = getSpec(type);
7958 /* pointer to generic pointer */
7959 if (IS_GENPTR(ctype)) {
7963 p_type = DCL_TYPE(type);
7965 /* we have to go by the storage class */
7966 p_type = PTR_TYPE(SPEC_OCLS(etype));
7968 /* if (SPEC_OCLS(etype)->codesp ) */
7969 /* p_type = CPOINTER ; */
7971 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7972 /* p_type = FPOINTER ; */
7974 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7975 /* p_type = PPOINTER; */
7977 /* if (SPEC_OCLS(etype) == idata ) */
7978 /* p_type = IPOINTER ; */
7980 /* p_type = POINTER ; */
7983 /* the first two bytes are known */
7984 size = GPTRSIZE - 1;
7988 aopGet(AOP(right),offset,FALSE,FALSE),
7992 /* the last byte depending on type */
8009 /* this should never happen */
8010 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8011 "got unknown pointer type");
8014 aopPut(AOP(result),l, GPTRSIZE - 1);
8018 /* just copy the pointers */
8019 size = AOP_SIZE(result);
8023 aopGet(AOP(right),offset,FALSE,FALSE),
8031 if (AOP_TYPE(right) == AOP_CRY) {
8033 size = AOP_SIZE(right);
8035 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8036 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8037 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8039 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8040 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8041 AOP(right)->aopu.aop_dir,
8042 AOP(right)->aopu.aop_dir);
8043 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8045 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8046 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8051 /* so we now know that the size of destination is greater
8052 than the size of the source.
8053 Now, if the next iCode is an operator then we might be
8054 able to optimize the operation without performing a cast.
8056 if(genMixedOperation(ic))
8060 /* we move to result for the size of source */
8061 size = AOP_SIZE(right);
8064 pic14_emitcode(";","%d",__LINE__);
8066 aopGet(AOP(right),offset,FALSE,FALSE),
8071 /* now depending on the sign of the destination */
8072 size = AOP_SIZE(result) - AOP_SIZE(right);
8073 /* if unsigned or not an integral type */
8074 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8076 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8077 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8081 /* we need to extend the sign :{ */
8082 //char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,FALSE,FALSE);
8085 emitpcode(POC_CLRW, NULL);
8086 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8087 emitpcode(POC_MOVLW, popGetLit(0xff));
8089 pic14_emitcode("clrw","");
8090 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8091 AOP(right)->aopu.aop_dir,
8092 AOP(right)->aopu.aop_dir);
8093 pic14_emitcode("movlw","0xff");
8095 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8096 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8098 // aopPut(AOP(result),"a",offset++);
8103 /* we are done hurray !!!! */
8106 freeAsmop(right,NULL,ic,TRUE);
8107 freeAsmop(result,NULL,ic,TRUE);
8111 /*-----------------------------------------------------------------*/
8112 /* genDjnz - generate decrement & jump if not zero instrucion */
8113 /*-----------------------------------------------------------------*/
8114 static int genDjnz (iCode *ic, iCode *ifx)
8117 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8122 /* if the if condition has a false label
8123 then we cannot save */
8127 /* if the minus is not of the form
8129 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8130 !IS_OP_LITERAL(IC_RIGHT(ic)))
8133 if (operandLitValue(IC_RIGHT(ic)) != 1)
8136 /* if the size of this greater than one then no
8138 if (getSize(operandType(IC_RESULT(ic))) > 1)
8141 /* otherwise we can save BIG */
8142 lbl = newiTempLabel(NULL);
8143 lbl1= newiTempLabel(NULL);
8145 aopOp(IC_RESULT(ic),ic,FALSE);
8147 if (IS_AOP_PREG(IC_RESULT(ic))) {
8148 pic14_emitcode("dec","%s",
8149 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8150 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8151 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8155 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8156 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8158 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8159 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8162 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8163 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8164 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8165 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8168 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8173 /*-----------------------------------------------------------------*/
8174 /* genReceive - generate code for a receive iCode */
8175 /*-----------------------------------------------------------------*/
8176 static void genReceive (iCode *ic)
8178 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8180 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8181 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8182 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8184 int size = getSize(operandType(IC_RESULT(ic)));
8185 int offset = fReturnSizePic - size;
8187 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8188 fReturn[fReturnSizePic - offset - 1] : "acc"));
8191 aopOp(IC_RESULT(ic),ic,FALSE);
8192 size = AOP_SIZE(IC_RESULT(ic));
8195 pic14_emitcode ("pop","acc");
8196 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8201 aopOp(IC_RESULT(ic),ic,FALSE);
8203 assignResultValue(IC_RESULT(ic));
8206 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8209 /*-----------------------------------------------------------------*/
8210 /* genpic14Code - generate code for pic14 based controllers */
8211 /*-----------------------------------------------------------------*/
8213 * At this point, ralloc.c has gone through the iCode and attempted
8214 * to optimize in a way suitable for a PIC. Now we've got to generate
8215 * PIC instructions that correspond to the iCode.
8217 * Once the instructions are generated, we'll pass through both the
8218 * peep hole optimizer and the pCode optimizer.
8219 *-----------------------------------------------------------------*/
8221 void genpic14Code (iCode *lic)
8226 lineHead = lineCurr = NULL;
8228 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8231 /* if debug information required */
8232 /* if (options.debug && currFunc) { */
8234 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8236 if (IS_STATIC(currFunc->etype)) {
8237 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8238 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8240 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8241 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8247 for (ic = lic ; ic ; ic = ic->next ) {
8249 DEBUGpic14_emitcode(";ic","");
8250 if ( cln != ic->lineno ) {
8251 if ( options.debug ) {
8253 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8254 FileBaseName(ic->filename),ic->lineno,
8255 ic->level,ic->block);
8258 pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
8261 /* if the result is marked as
8262 spilt and rematerializable or code for
8263 this has already been generated then
8265 if (resultRemat(ic) || ic->generated )
8268 /* depending on the operation */
8287 /* IPOP happens only when trying to restore a
8288 spilt live range, if there is an ifx statement
8289 following this pop then the if statement might
8290 be using some of the registers being popped which
8291 would destory the contents of the register so
8292 we need to check for this condition and handle it */
8294 ic->next->op == IFX &&
8295 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8296 genIfx (ic->next,ic);
8314 genEndFunction (ic);
8334 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
8351 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
8355 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
8362 /* note these two are xlated by algebraic equivalence
8363 during parsing SDCC.y */
8364 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8365 "got '>=' or '<=' shouldn't have come here");
8369 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
8381 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
8385 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
8389 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
8416 case GET_VALUE_AT_ADDRESS:
8421 if (POINTER_SET(ic))
8448 addSet(&_G.sendSet,ic);
8453 /* piCode(ic,stdout); */
8459 /* now we are ready to call the
8460 peep hole optimizer */
8461 if (!options.nopeep) {
8462 printf("peep hole optimizing\n");
8463 peepHole (&lineHead);
8465 /* now do the actual printing */
8466 printLine (lineHead,codeOutFile);
8468 printf("printing pBlock\n\n");
8469 printpBlock(stdout,pb);