1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
57 #include "SDCCpeeph.h"
62 static int labelOffset=0;
63 static int debug_verbose=1;
64 static int optimized_for_speed = 0;
66 unsigned int pic14aopLiteral (value *val, int offset);
68 /* this is the down and dirty file with all kinds of
69 kludgy & hacky stuff. This is what it is all about
70 CODE GENERATION for a specific MCU . some of the
71 routines may be reusable, will have to see */
73 static char *zero = "#0x00";
74 static char *one = "#0x01";
75 static char *spname = "sp";
77 char *fReturnpic14[] = {"FSR","dph","b","a" };
78 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
79 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
80 static char **fReturn = fReturnpic14;
82 static char *accUse[] = {"a","b"};
84 //static short rbank = -1;
96 char *Safe_strdup(char *str); // in pcode.c
98 extern int pic14_ptrRegReq ;
99 extern int pic14_nRegs;
100 extern FILE *codeOutFile;
101 static void saverbank (int, iCode *,bool);
103 static lineNode *lineHead = NULL;
104 static lineNode *lineCurr = NULL;
106 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
107 0xE0, 0xC0, 0x80, 0x00};
108 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
109 0x07, 0x03, 0x01, 0x00};
113 /*-----------------------------------------------------------------*/
114 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
115 /* exponent of 2 is returned, otherwise -1 is */
117 /* note that this is similar to the function `powof2' in SDCCsymt */
121 /*-----------------------------------------------------------------*/
122 static int my_powof2 (unsigned long num)
125 if( (num & (num-1)) == 0) {
138 static void emitpLabel(int key)
140 addpCode2pBlock(pb,newpCodeLabel(key));
143 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
146 addpCode2pBlock(pb,newpCode(poc,pcop));
149 /*-----------------------------------------------------------------*/
150 /* pic14_emitcode - writes the code into a file : for now it is simple */
151 /*-----------------------------------------------------------------*/
152 void pic14_emitcode (char *inst,char *fmt, ...)
155 char lb[INITIAL_INLINEASM];
162 sprintf(lb,"%s\t",inst);
164 sprintf(lb,"%s",inst);
165 vsprintf(lb+(strlen(lb)),fmt,ap);
169 while (isspace(*lbp)) lbp++;
172 lineCurr = (lineCurr ?
173 connectLine(lineCurr,newLineNode(lb)) :
174 (lineHead = newLineNode(lb)));
175 lineCurr->isInline = _G.inLine;
176 lineCurr->isDebug = _G.debugLine;
179 addpCode2pBlock(pb,newpCodeCharP(lb));
184 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
187 char lb[INITIAL_INLINEASM];
197 sprintf(lb,"%s\t",inst);
199 sprintf(lb,"%s",inst);
200 vsprintf(lb+(strlen(lb)),fmt,ap);
204 while (isspace(*lbp)) lbp++;
207 lineCurr = (lineCurr ?
208 connectLine(lineCurr,newLineNode(lb)) :
209 (lineHead = newLineNode(lb)));
210 lineCurr->isInline = _G.inLine;
211 lineCurr->isDebug = _G.debugLine;
213 addpCode2pBlock(pb,newpCodeCharP(lb));
219 /*-----------------------------------------------------------------*/
220 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
221 /*-----------------------------------------------------------------*/
222 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
224 bool r0iu = FALSE , r1iu = FALSE;
225 bool r0ou = FALSE , r1ou = FALSE;
227 /* the logic: if r0 & r1 used in the instruction
228 then we are in trouble otherwise */
230 /* first check if r0 & r1 are used by this
231 instruction, in which case we are in trouble */
232 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
233 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
238 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
239 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
241 /* if no usage of r0 then return it */
242 if (!r0iu && !r0ou) {
243 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
244 (*aopp)->type = AOP_R0;
246 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
249 /* if no usage of r1 then return it */
250 if (!r1iu && !r1ou) {
251 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
252 (*aopp)->type = AOP_R1;
254 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
257 /* now we know they both have usage */
258 /* if r0 not used in this instruction */
260 /* push it if not already pushed */
262 pic14_emitcode ("push","%s",
263 pic14_regWithIdx(R0_IDX)->dname);
267 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
268 (*aopp)->type = AOP_R0;
270 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
273 /* if r1 not used then */
276 /* push it if not already pushed */
278 pic14_emitcode ("push","%s",
279 pic14_regWithIdx(R1_IDX)->dname);
283 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
284 (*aopp)->type = AOP_R1;
285 return pic14_regWithIdx(R1_IDX);
289 /* I said end of world but not quite end of world yet */
290 /* if this is a result then we can push it on the stack*/
292 (*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 += (int) operandLitValue(IC_RIGHT(ic));
473 else if (ic->op == '-')
474 val -= (int) 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 op->aop = aop = newAsmop(AOP_LIT);
616 aop->aopu.aop_lit = op->operand.valOperand;
617 aop->size = getSize(operandType(op));
618 DEBUGpic14_emitcode(";","%d, lit = %d",__LINE__,aop->aopu.aop_lit);
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 - true symop",__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 = Safe_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(pCodeOp *pc, int bitval)
993 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
995 if(!(pcop->name = Safe_strdup(pc->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__);
1122 pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1124 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1125 //pcop->type = PO_GPR_REGISTER;
1126 PCOR(pcop)->rIdx = rIdx;
1127 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1128 pcop->type = PCOR(pcop)->r->pc_type;
1131 rs = aop->aopu.aop_reg[offset]->dname;
1133 rs = aop->aopu.aop_reg[offset]->name;
1135 DEBUGpic14_emitcode(";","%d %s",__LINE__,rs);
1141 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1145 DEBUGpic14_emitcode(";","%d",__LINE__);
1146 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1149 DEBUGpic14_emitcode(";","%d",__LINE__);
1151 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1152 pcop->type = PO_STR;
1154 //aop->coff = offset ;
1155 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1156 sprintf(s,"%s","acc");
1158 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1159 pcop->name = Safe_calloc(1,strlen(s)+1);
1160 strcpy(pcop->name,s);
1165 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1166 "popGet got unsupported aop->type");
1169 /*-----------------------------------------------------------------*/
1170 /* aopPut - puts a string for a aop */
1171 /*-----------------------------------------------------------------*/
1172 void aopPut (asmop *aop, char *s, int offset)
1177 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1179 if (aop->size && offset > ( aop->size - 1)) {
1180 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1181 "aopPut got offset > aop->size");
1185 /* will assign value to value */
1186 /* depending on where it is ofcourse */
1187 switch (aop->type) {
1190 sprintf(d,"(%s + %d)",
1191 aop->aopu.aop_dir,offset);
1193 sprintf(d,"%s",aop->aopu.aop_dir);
1196 DEBUGpic14_emitcode(";","%d",__LINE__);
1198 pic14_emitcode("movf","%s,w",s);
1199 pic14_emitcode("movwf","%s",d);
1202 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1203 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1210 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1211 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1214 strcmp(s,"r0") == 0 ||
1215 strcmp(s,"r1") == 0 ||
1216 strcmp(s,"r2") == 0 ||
1217 strcmp(s,"r3") == 0 ||
1218 strcmp(s,"r4") == 0 ||
1219 strcmp(s,"r5") == 0 ||
1220 strcmp(s,"r6") == 0 ||
1221 strcmp(s,"r7") == 0 )
1222 pic14_emitcode("mov","%s,%s ; %d",
1223 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1228 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1230 pic14_emitcode("movwf","%s",
1231 aop->aopu.aop_reg[offset]->name);
1234 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1235 pcop->type = PO_GPR_REGISTER;
1237 PCOR(pcop)->rIdx = -1;
1238 PCOR(pcop)->r = NULL;
1240 DEBUGpic14_emitcode(";","%d",__LINE__);
1241 pcop->name = Safe_strdup(s);
1242 emitpcode(POC_MOVFW,pcop);
1244 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1252 if (aop->type == AOP_DPTR2)
1258 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1259 "aopPut writting to code space");
1263 while (offset > aop->coff) {
1265 pic14_emitcode ("inc","dptr");
1268 while (offset < aop->coff) {
1270 pic14_emitcode("lcall","__decdptr");
1275 /* if not in accumulater */
1278 pic14_emitcode ("movx","@dptr,a");
1280 if (aop->type == AOP_DPTR2)
1288 while (offset > aop->coff) {
1290 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1292 while (offset < aop->coff) {
1294 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1300 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1305 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1307 if (strcmp(s,"r0") == 0 ||
1308 strcmp(s,"r1") == 0 ||
1309 strcmp(s,"r2") == 0 ||
1310 strcmp(s,"r3") == 0 ||
1311 strcmp(s,"r4") == 0 ||
1312 strcmp(s,"r5") == 0 ||
1313 strcmp(s,"r6") == 0 ||
1314 strcmp(s,"r7") == 0 ) {
1316 sprintf(buffer,"a%s",s);
1317 pic14_emitcode("mov","@%s,%s",
1318 aop->aopu.aop_ptr->name,buffer);
1320 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1325 if (strcmp(s,"a") == 0)
1326 pic14_emitcode("push","acc");
1328 pic14_emitcode("push","%s",s);
1333 /* if bit variable */
1334 if (!aop->aopu.aop_dir) {
1335 pic14_emitcode("clr","a");
1336 pic14_emitcode("rlc","a");
1339 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1342 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1345 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1347 lbl = newiTempLabel(NULL);
1349 if (strcmp(s,"a")) {
1352 pic14_emitcode("clr","c");
1353 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1354 pic14_emitcode("cpl","c");
1355 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1356 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1363 if (strcmp(aop->aopu.aop_str[offset],s))
1364 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1369 if (!offset && (strcmp(s,"acc") == 0))
1372 if (strcmp(aop->aopu.aop_str[offset],s))
1373 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1377 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1378 "aopPut got unsupported aop->type");
1384 /*-----------------------------------------------------------------*/
1385 /* reAdjustPreg - points a register back to where it should */
1386 /*-----------------------------------------------------------------*/
1387 static void reAdjustPreg (asmop *aop)
1391 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1393 if ((size = aop->size) <= 1)
1396 switch (aop->type) {
1400 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1404 if (aop->type == AOP_DPTR2)
1410 pic14_emitcode("lcall","__decdptr");
1413 if (aop->type == AOP_DPTR2)
1423 /*-----------------------------------------------------------------*/
1424 /* genNotFloat - generates not for float operations */
1425 /*-----------------------------------------------------------------*/
1426 static void genNotFloat (operand *op, operand *res)
1432 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1433 /* we will put 127 in the first byte of
1435 aopPut(AOP(res),"#127",0);
1436 size = AOP_SIZE(op) - 1;
1439 l = aopGet(op->aop,offset++,FALSE,FALSE);
1443 pic14_emitcode("orl","a,%s",
1445 offset++,FALSE,FALSE));
1447 tlbl = newiTempLabel(NULL);
1449 tlbl = newiTempLabel(NULL);
1450 aopPut(res->aop,one,1);
1451 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1452 aopPut(res->aop,zero,1);
1453 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1455 size = res->aop->size - 2;
1457 /* put zeros in the rest */
1459 aopPut(res->aop,zero,offset++);
1463 /*-----------------------------------------------------------------*/
1464 /* opIsGptr: returns non-zero if the passed operand is */
1465 /* a generic pointer type. */
1466 /*-----------------------------------------------------------------*/
1467 static int opIsGptr(operand *op)
1469 sym_link *type = operandType(op);
1471 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1472 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1480 /*-----------------------------------------------------------------*/
1481 /* pic14_getDataSize - get the operand data size */
1482 /*-----------------------------------------------------------------*/
1483 int pic14_getDataSize(operand *op)
1485 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1488 return AOP_SIZE(op);
1490 // tsd- in the pic port, the genptr size is 1, so this code here
1491 // fails. ( in the 8051 port, the size was 4).
1494 size = AOP_SIZE(op);
1495 if (size == GPTRSIZE)
1497 sym_link *type = operandType(op);
1498 if (IS_GENPTR(type))
1500 /* generic pointer; arithmetic operations
1501 * should ignore the high byte (pointer type).
1504 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1511 /*-----------------------------------------------------------------*/
1512 /* pic14_outAcc - output Acc */
1513 /*-----------------------------------------------------------------*/
1514 void pic14_outAcc(operand *result)
1517 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1518 size = pic14_getDataSize(result);
1520 aopPut(AOP(result),"a",0);
1523 /* unsigned or positive */
1525 aopPut(AOP(result),zero,offset++);
1530 /*-----------------------------------------------------------------*/
1531 /* pic14_outBitC - output a bit C */
1532 /*-----------------------------------------------------------------*/
1533 void pic14_outBitC(operand *result)
1536 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1537 /* if the result is bit */
1538 if (AOP_TYPE(result) == AOP_CRY)
1539 aopPut(AOP(result),"c",0);
1541 pic14_emitcode("clr","a ; %d", __LINE__);
1542 pic14_emitcode("rlc","a");
1543 pic14_outAcc(result);
1547 /*-----------------------------------------------------------------*/
1548 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1549 /*-----------------------------------------------------------------*/
1550 void pic14_toBoolean(operand *oper)
1552 int size = AOP_SIZE(oper) - 1;
1555 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1557 if ( AOP_TYPE(oper) != AOP_ACC) {
1558 emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1559 pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1562 pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1563 emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1568 /*-----------------------------------------------------------------*/
1569 /* genNot - generate code for ! operation */
1570 /*-----------------------------------------------------------------*/
1571 static void genNot (iCode *ic)
1574 sym_link *optype = operandType(IC_LEFT(ic));
1576 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1577 /* assign asmOps to operand & result */
1578 aopOp (IC_LEFT(ic),ic,FALSE);
1579 aopOp (IC_RESULT(ic),ic,TRUE);
1581 /* if in bit space then a special case */
1582 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1583 pic14_emitcode("movlw","1<<%s");
1584 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1585 //pic14_emitcode("cpl","c");
1586 //pic14_outBitC(IC_RESULT(ic));
1590 /* if type float then do float */
1591 if (IS_FLOAT(optype)) {
1592 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1596 pic14_toBoolean(IC_LEFT(ic));
1598 tlbl = newiTempLabel(NULL);
1599 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1600 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1601 pic14_outBitC(IC_RESULT(ic));
1604 /* release the aops */
1605 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1606 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1610 /*-----------------------------------------------------------------*/
1611 /* genCpl - generate code for complement */
1612 /*-----------------------------------------------------------------*/
1613 static void genCpl (iCode *ic)
1619 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1620 /* assign asmOps to operand & result */
1621 aopOp (IC_LEFT(ic),ic,FALSE);
1622 aopOp (IC_RESULT(ic),ic,TRUE);
1624 /* if both are in bit space then
1626 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1627 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1629 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1630 pic14_emitcode("cpl","c");
1631 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1635 size = AOP_SIZE(IC_RESULT(ic));
1637 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1639 pic14_emitcode("cpl","a");
1640 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1645 /* release the aops */
1646 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1647 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1650 /*-----------------------------------------------------------------*/
1651 /* genUminusFloat - unary minus for floating points */
1652 /*-----------------------------------------------------------------*/
1653 static void genUminusFloat(operand *op,operand *result)
1655 int size ,offset =0 ;
1658 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1659 /* for this we just need to flip the
1660 first it then copy the rest in place */
1661 size = AOP_SIZE(op) - 1;
1662 l = aopGet(AOP(op),3,FALSE,FALSE);
1666 pic14_emitcode("cpl","acc.7");
1667 aopPut(AOP(result),"a",3);
1671 aopGet(AOP(op),offset,FALSE,FALSE),
1677 /*-----------------------------------------------------------------*/
1678 /* genUminus - unary minus code generation */
1679 /*-----------------------------------------------------------------*/
1680 static void genUminus (iCode *ic)
1683 sym_link *optype, *rtype;
1686 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1688 aopOp(IC_LEFT(ic),ic,FALSE);
1689 aopOp(IC_RESULT(ic),ic,TRUE);
1691 /* if both in bit space then special
1693 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1694 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1696 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1697 pic14_emitcode("cpl","c");
1698 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1702 optype = operandType(IC_LEFT(ic));
1703 rtype = operandType(IC_RESULT(ic));
1705 /* if float then do float stuff */
1706 if (IS_FLOAT(optype)) {
1707 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1711 /* otherwise subtract from zero */
1712 size = AOP_SIZE(IC_LEFT(ic));
1716 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1717 if (!strcmp(l,"a")) {
1718 pic14_emitcode("cpl","a");
1719 pic14_emitcode("inc","a");
1721 pic14_emitcode("clr","a");
1722 pic14_emitcode("subb","a,%s",l);
1724 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1727 /* if any remaining bytes in the result */
1728 /* we just need to propagate the sign */
1729 if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1730 pic14_emitcode("rlc","a");
1731 pic14_emitcode("subb","a,acc");
1733 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1737 /* release the aops */
1738 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1739 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1742 /*-----------------------------------------------------------------*/
1743 /* saveRegisters - will look for a call and save the registers */
1744 /*-----------------------------------------------------------------*/
1745 static void saveRegisters(iCode *lic)
1752 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1754 for (ic = lic ; ic ; ic = ic->next)
1755 if (ic->op == CALL || ic->op == PCALL)
1759 fprintf(stderr,"found parameter push with no function call\n");
1763 /* if the registers have been saved already then
1765 if (ic->regsSaved || (OP_SYMBOL(IC_LEFT(ic))->calleeSave))
1768 /* find the registers in use at this time
1769 and push them away to safety */
1770 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1774 if (options.useXstack) {
1775 if (bitVectBitValue(rsave,R0_IDX))
1776 pic14_emitcode("mov","b,r0");
1777 pic14_emitcode("mov","r0,%s",spname);
1778 for (i = 0 ; i < pic14_nRegs ; i++) {
1779 if (bitVectBitValue(rsave,i)) {
1781 pic14_emitcode("mov","a,b");
1783 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1784 pic14_emitcode("movx","@r0,a");
1785 pic14_emitcode("inc","r0");
1788 pic14_emitcode("mov","%s,r0",spname);
1789 if (bitVectBitValue(rsave,R0_IDX))
1790 pic14_emitcode("mov","r0,b");
1792 for (i = 0 ; i < pic14_nRegs ; i++) {
1793 if (bitVectBitValue(rsave,i))
1794 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1797 detype = getSpec(operandType(IC_LEFT(ic)));
1799 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
1800 IS_ISR(currFunc->etype) &&
1803 saverbank(SPEC_BANK(detype),ic,TRUE);
1806 /*-----------------------------------------------------------------*/
1807 /* unsaveRegisters - pop the pushed registers */
1808 /*-----------------------------------------------------------------*/
1809 static void unsaveRegisters (iCode *ic)
1814 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1815 /* find the registers in use at this time
1816 and push them away to safety */
1817 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1820 if (options.useXstack) {
1821 pic14_emitcode("mov","r0,%s",spname);
1822 for (i = pic14_nRegs ; i >= 0 ; i--) {
1823 if (bitVectBitValue(rsave,i)) {
1824 pic14_emitcode("dec","r0");
1825 pic14_emitcode("movx","a,@r0");
1827 pic14_emitcode("mov","b,a");
1829 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1833 pic14_emitcode("mov","%s,r0",spname);
1834 if (bitVectBitValue(rsave,R0_IDX))
1835 pic14_emitcode("mov","r0,b");
1837 for (i = pic14_nRegs ; i >= 0 ; i--) {
1838 if (bitVectBitValue(rsave,i))
1839 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1845 /*-----------------------------------------------------------------*/
1847 /*-----------------------------------------------------------------*/
1848 static void pushSide(operand * oper, int size)
1851 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1853 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1854 if (AOP_TYPE(oper) != AOP_REG &&
1855 AOP_TYPE(oper) != AOP_DIR &&
1857 pic14_emitcode("mov","a,%s",l);
1858 pic14_emitcode("push","acc");
1860 pic14_emitcode("push","%s",l);
1864 /*-----------------------------------------------------------------*/
1865 /* assignResultValue - */
1866 /*-----------------------------------------------------------------*/
1867 static void assignResultValue(operand * oper)
1870 int size = AOP_SIZE(oper);
1872 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1874 // The last byte in the assignment is in W
1875 aopPut(AOP(oper),"W",size-1);
1879 aopPut(AOP(oper),fReturn[offset],offset);
1887 /*-----------------------------------------------------------------*/
1888 /* genXpush - pushes onto the external stack */
1889 /*-----------------------------------------------------------------*/
1890 static void genXpush (iCode *ic)
1892 asmop *aop = newAsmop(0);
1894 int size,offset = 0;
1896 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1897 aopOp(IC_LEFT(ic),ic,FALSE);
1898 r = getFreePtr(ic,&aop,FALSE);
1901 pic14_emitcode("mov","%s,_spx",r->name);
1903 size = AOP_SIZE(IC_LEFT(ic));
1906 char *l = aopGet(AOP(IC_LEFT(ic)),
1907 offset++,FALSE,FALSE);
1909 pic14_emitcode("movx","@%s,a",r->name);
1910 pic14_emitcode("inc","%s",r->name);
1915 pic14_emitcode("mov","_spx,%s",r->name);
1917 freeAsmop(NULL,aop,ic,TRUE);
1918 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
1921 /*-----------------------------------------------------------------*/
1922 /* genIpush - genrate code for pushing this gets a little complex */
1923 /*-----------------------------------------------------------------*/
1924 static void genIpush (iCode *ic)
1926 int size, offset = 0 ;
1930 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1931 /* if this is not a parm push : ie. it is spill push
1932 and spill push is always done on the local stack */
1933 if (!ic->parmPush) {
1935 /* and the item is spilt then do nothing */
1936 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
1939 aopOp(IC_LEFT(ic),ic,FALSE);
1940 size = AOP_SIZE(IC_LEFT(ic));
1941 /* push it on the stack */
1943 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1948 pic14_emitcode("push","%s",l);
1953 /* this is a paramter push: in this case we call
1954 the routine to find the call and save those
1955 registers that need to be saved */
1958 /* if use external stack then call the external
1959 stack pushing routine */
1960 if (options.useXstack) {
1965 /* then do the push */
1966 aopOp(IC_LEFT(ic),ic,FALSE);
1969 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
1970 size = AOP_SIZE(IC_LEFT(ic));
1973 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1974 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
1975 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
1977 pic14_emitcode("mov","a,%s",l);
1978 pic14_emitcode("push","acc");
1980 pic14_emitcode("push","%s",l);
1983 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
1986 /*-----------------------------------------------------------------*/
1987 /* genIpop - recover the registers: can happen only for spilling */
1988 /*-----------------------------------------------------------------*/
1989 static void genIpop (iCode *ic)
1994 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1995 /* if the temp was not pushed then */
1996 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
1999 aopOp(IC_LEFT(ic),ic,FALSE);
2000 size = AOP_SIZE(IC_LEFT(ic));
2003 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2006 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2009 /*-----------------------------------------------------------------*/
2010 /* unsaverbank - restores the resgister bank from stack */
2011 /*-----------------------------------------------------------------*/
2012 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2018 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2020 if (options.useXstack) {
2022 r = getFreePtr(ic,&aop,FALSE);
2025 pic14_emitcode("mov","%s,_spx",r->name);
2026 pic14_emitcode("movx","a,@%s",r->name);
2027 pic14_emitcode("mov","psw,a");
2028 pic14_emitcode("dec","%s",r->name);
2031 pic14_emitcode ("pop","psw");
2034 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2035 if (options.useXstack) {
2036 pic14_emitcode("movx","a,@%s",r->name);
2037 //pic14_emitcode("mov","(%s+%d),a",
2038 // regspic14[i].base,8*bank+regspic14[i].offset);
2039 pic14_emitcode("dec","%s",r->name);
2042 pic14_emitcode("pop",""); //"(%s+%d)",
2043 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2046 if (options.useXstack) {
2048 pic14_emitcode("mov","_spx,%s",r->name);
2049 freeAsmop(NULL,aop,ic,TRUE);
2054 /*-----------------------------------------------------------------*/
2055 /* saverbank - saves an entire register bank on the stack */
2056 /*-----------------------------------------------------------------*/
2057 static void saverbank (int bank, iCode *ic, bool pushPsw)
2063 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2064 if (options.useXstack) {
2067 r = getFreePtr(ic,&aop,FALSE);
2068 pic14_emitcode("mov","%s,_spx",r->name);
2072 for (i = 0 ; i < pic14_nRegs ;i++) {
2073 if (options.useXstack) {
2074 pic14_emitcode("inc","%s",r->name);
2075 //pic14_emitcode("mov","a,(%s+%d)",
2076 // regspic14[i].base,8*bank+regspic14[i].offset);
2077 pic14_emitcode("movx","@%s,a",r->name);
2079 pic14_emitcode("push","");// "(%s+%d)",
2080 //regspic14[i].base,8*bank+regspic14[i].offset);
2084 if (options.useXstack) {
2085 pic14_emitcode("mov","a,psw");
2086 pic14_emitcode("movx","@%s,a",r->name);
2087 pic14_emitcode("inc","%s",r->name);
2088 pic14_emitcode("mov","_spx,%s",r->name);
2089 freeAsmop (NULL,aop,ic,TRUE);
2092 pic14_emitcode("push","psw");
2094 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2100 /*-----------------------------------------------------------------*/
2101 /* genCall - generates a call statement */
2102 /*-----------------------------------------------------------------*/
2103 static void genCall (iCode *ic)
2107 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2109 /* if caller saves & we have not saved then */
2113 /* if we are calling a function that is not using
2114 the same register bank then we need to save the
2115 destination registers on the stack */
2116 detype = getSpec(operandType(IC_LEFT(ic)));
2118 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
2119 IS_ISR(currFunc->etype) &&
2122 saverbank(SPEC_BANK(detype),ic,TRUE);
2124 /* if send set is not empty the assign */
2128 for (sic = setFirstItem(_G.sendSet) ; sic ;
2129 sic = setNextItem(_G.sendSet)) {
2130 int size, offset = 0;
2132 aopOp(IC_LEFT(sic),sic,FALSE);
2133 size = AOP_SIZE(IC_LEFT(sic));
2135 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2137 DEBUGpic14_emitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
2139 if (strcmp(l,fReturn[offset])) {
2141 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2142 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2143 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2144 //pic14_emitcode("movlw","%s",l);
2146 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2147 //pic14_emitcode("movf","%s,w",l);
2149 // The last one is passed in W
2151 pic14_emitcode("movwf","%s",fReturn[offset]);
2155 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2160 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2161 OP_SYMBOL(IC_LEFT(ic))->rname :
2162 OP_SYMBOL(IC_LEFT(ic))->name));
2164 pic14_emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2165 OP_SYMBOL(IC_LEFT(ic))->rname :
2166 OP_SYMBOL(IC_LEFT(ic))->name));
2168 /* if we need assign a result value */
2169 if ((IS_ITEMP(IC_RESULT(ic)) &&
2170 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2171 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2172 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2175 aopOp(IC_RESULT(ic),ic,FALSE);
2178 assignResultValue(IC_RESULT(ic));
2180 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2183 /* adjust the stack for parameters if
2185 if (ic->parmBytes) {
2187 if (ic->parmBytes > 3) {
2188 pic14_emitcode("mov","a,%s",spname);
2189 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2190 pic14_emitcode("mov","%s,a",spname);
2192 for ( i = 0 ; i < ic->parmBytes ;i++)
2193 pic14_emitcode("dec","%s",spname);
2197 /* if register bank was saved then pop them */
2199 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2201 /* if we hade saved some registers then unsave them */
2202 if (ic->regsSaved && !(OP_SYMBOL(IC_LEFT(ic))->calleeSave))
2203 unsaveRegisters (ic);
2208 /*-----------------------------------------------------------------*/
2209 /* genPcall - generates a call by pointer statement */
2210 /*-----------------------------------------------------------------*/
2211 static void genPcall (iCode *ic)
2214 symbol *rlbl = newiTempLabel(NULL);
2217 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2218 /* if caller saves & we have not saved then */
2222 /* if we are calling a function that is not using
2223 the same register bank then we need to save the
2224 destination registers on the stack */
2225 detype = getSpec(operandType(IC_LEFT(ic)));
2227 IS_ISR(currFunc->etype) &&
2228 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)))
2229 saverbank(SPEC_BANK(detype),ic,TRUE);
2232 /* push the return address on to the stack */
2233 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2234 pic14_emitcode("push","acc");
2235 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2236 pic14_emitcode("push","acc");
2238 if (options.model == MODEL_FLAT24)
2240 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2241 pic14_emitcode("push","acc");
2244 /* now push the calling address */
2245 aopOp(IC_LEFT(ic),ic,FALSE);
2247 pushSide(IC_LEFT(ic), FPTRSIZE);
2249 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2251 /* if send set is not empty the assign */
2255 for (sic = setFirstItem(_G.sendSet) ; sic ;
2256 sic = setNextItem(_G.sendSet)) {
2257 int size, offset = 0;
2258 aopOp(IC_LEFT(sic),sic,FALSE);
2259 size = AOP_SIZE(IC_LEFT(sic));
2261 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2263 if (strcmp(l,fReturn[offset]))
2264 pic14_emitcode("mov","%s,%s",
2269 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2274 pic14_emitcode("ret","");
2275 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2278 /* if we need assign a result value */
2279 if ((IS_ITEMP(IC_RESULT(ic)) &&
2280 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2281 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2282 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2285 aopOp(IC_RESULT(ic),ic,FALSE);
2288 assignResultValue(IC_RESULT(ic));
2290 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2293 /* adjust the stack for parameters if
2295 if (ic->parmBytes) {
2297 if (ic->parmBytes > 3) {
2298 pic14_emitcode("mov","a,%s",spname);
2299 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2300 pic14_emitcode("mov","%s,a",spname);
2302 for ( i = 0 ; i < ic->parmBytes ;i++)
2303 pic14_emitcode("dec","%s",spname);
2307 /* if register bank was saved then unsave them */
2309 (SPEC_BANK(currFunc->etype) !=
2311 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2313 /* if we hade saved some registers then
2316 unsaveRegisters (ic);
2320 /*-----------------------------------------------------------------*/
2321 /* resultRemat - result is rematerializable */
2322 /*-----------------------------------------------------------------*/
2323 static int resultRemat (iCode *ic)
2325 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2326 if (SKIP_IC(ic) || ic->op == IFX)
2329 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2330 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2331 if (sym->remat && !POINTER_SET(ic))
2338 #if defined(__BORLANDC__) || defined(_MSC_VER)
2339 #define STRCASECMP stricmp
2341 #define STRCASECMP strcasecmp
2344 /*-----------------------------------------------------------------*/
2345 /* inExcludeList - return 1 if the string is in exclude Reg list */
2346 /*-----------------------------------------------------------------*/
2347 static bool inExcludeList(char *s)
2351 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2352 if (options.excludeRegs[i] &&
2353 STRCASECMP(options.excludeRegs[i],"none") == 0)
2356 for ( i = 0 ; options.excludeRegs[i]; i++) {
2357 if (options.excludeRegs[i] &&
2358 STRCASECMP(s,options.excludeRegs[i]) == 0)
2364 /*-----------------------------------------------------------------*/
2365 /* genFunction - generated code for function entry */
2366 /*-----------------------------------------------------------------*/
2367 static void genFunction (iCode *ic)
2372 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2373 labelOffset += FUNCTION_LABEL_INC;
2376 /* create the function header */
2377 pic14_emitcode(";","-----------------------------------------");
2378 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2379 pic14_emitcode(";","-----------------------------------------");
2381 pic14_emitcode("","%s:",sym->rname);
2382 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2384 fetype = getSpec(operandType(IC_LEFT(ic)));
2386 /* if critical function then turn interrupts off */
2387 if (SPEC_CRTCL(fetype))
2388 pic14_emitcode("clr","ea");
2390 /* here we need to generate the equates for the
2391 register bank if required */
2393 if (SPEC_BANK(fetype) != rbank) {
2396 rbank = SPEC_BANK(fetype);
2397 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2398 if (strcmp(regspic14[i].base,"0") == 0)
2399 pic14_emitcode("","%s = 0x%02x",
2401 8*rbank+regspic14[i].offset);
2403 pic14_emitcode ("","%s = %s + 0x%02x",
2406 8*rbank+regspic14[i].offset);
2411 /* if this is an interrupt service routine then
2412 save acc, b, dpl, dph */
2413 if (IS_ISR(sym->etype)) {
2415 if (!inExcludeList("acc"))
2416 pic14_emitcode ("push","acc");
2417 if (!inExcludeList("b"))
2418 pic14_emitcode ("push","b");
2419 if (!inExcludeList("dpl"))
2420 pic14_emitcode ("push","dpl");
2421 if (!inExcludeList("dph"))
2422 pic14_emitcode ("push","dph");
2423 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2425 pic14_emitcode ("push", "dpx");
2426 /* Make sure we're using standard DPTR */
2427 pic14_emitcode ("push", "dps");
2428 pic14_emitcode ("mov", "dps, #0x00");
2429 if (options.stack10bit)
2431 /* This ISR could conceivably use DPTR2. Better save it. */
2432 pic14_emitcode ("push", "dpl1");
2433 pic14_emitcode ("push", "dph1");
2434 pic14_emitcode ("push", "dpx1");
2437 /* if this isr has no bank i.e. is going to
2438 run with bank 0 , then we need to save more
2440 if (!SPEC_BANK(sym->etype)) {
2442 /* if this function does not call any other
2443 function then we can be economical and
2444 save only those registers that are used */
2445 if (! sym->hasFcall) {
2448 /* if any registers used */
2449 if (sym->regsUsed) {
2450 /* save the registers used */
2451 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2452 if (bitVectBitValue(sym->regsUsed,i) ||
2453 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2454 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2459 /* this function has a function call cannot
2460 determines register usage so we will have the
2462 saverbank(0,ic,FALSE);
2466 /* if callee-save to be used for this function
2467 then save the registers being used in this function */
2468 if (sym->calleeSave) {
2471 /* if any registers used */
2472 if (sym->regsUsed) {
2473 /* save the registers used */
2474 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2475 if (bitVectBitValue(sym->regsUsed,i) ||
2476 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2477 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2485 /* set the register bank to the desired value */
2486 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) {
2487 pic14_emitcode("push","psw");
2488 pic14_emitcode("mov","psw,#0x%02x",(SPEC_BANK(sym->etype) << 3)&0x00ff);
2491 if (IS_RENT(sym->etype) || options.stackAuto) {
2493 if (options.useXstack) {
2494 pic14_emitcode("mov","r0,%s",spname);
2495 pic14_emitcode("mov","a,_bp");
2496 pic14_emitcode("movx","@r0,a");
2497 pic14_emitcode("inc","%s",spname);
2501 /* set up the stack */
2502 pic14_emitcode ("push","_bp"); /* save the callers stack */
2504 pic14_emitcode ("mov","_bp,%s",spname);
2507 /* adjust the stack for the function */
2512 werror(W_STACK_OVERFLOW,sym->name);
2514 if (i > 3 && sym->recvSize < 4) {
2516 pic14_emitcode ("mov","a,sp");
2517 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2518 pic14_emitcode ("mov","sp,a");
2523 pic14_emitcode("inc","sp");
2528 pic14_emitcode ("mov","a,_spx");
2529 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2530 pic14_emitcode ("mov","_spx,a");
2535 /*-----------------------------------------------------------------*/
2536 /* genEndFunction - generates epilogue for functions */
2537 /*-----------------------------------------------------------------*/
2538 static void genEndFunction (iCode *ic)
2540 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2542 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2544 if (IS_RENT(sym->etype) || options.stackAuto)
2546 pic14_emitcode ("mov","%s,_bp",spname);
2549 /* if use external stack but some variables were
2550 added to the local stack then decrement the
2552 if (options.useXstack && sym->stack) {
2553 pic14_emitcode("mov","a,sp");
2554 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2555 pic14_emitcode("mov","sp,a");
2559 if ((IS_RENT(sym->etype) || options.stackAuto)) {
2560 if (options.useXstack) {
2561 pic14_emitcode("mov","r0,%s",spname);
2562 pic14_emitcode("movx","a,@r0");
2563 pic14_emitcode("mov","_bp,a");
2564 pic14_emitcode("dec","%s",spname);
2568 pic14_emitcode ("pop","_bp");
2572 /* restore the register bank */
2573 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype))
2574 pic14_emitcode ("pop","psw");
2576 if (IS_ISR(sym->etype)) {
2578 /* now we need to restore the registers */
2579 /* if this isr has no bank i.e. is going to
2580 run with bank 0 , then we need to save more
2582 if (!SPEC_BANK(sym->etype)) {
2584 /* if this function does not call any other
2585 function then we can be economical and
2586 save only those registers that are used */
2587 if (! sym->hasFcall) {
2590 /* if any registers used */
2591 if (sym->regsUsed) {
2592 /* save the registers used */
2593 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2594 if (bitVectBitValue(sym->regsUsed,i) ||
2595 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2596 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2601 /* this function has a function call cannot
2602 determines register usage so we will have the
2604 unsaverbank(0,ic,FALSE);
2608 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2610 if (options.stack10bit)
2612 pic14_emitcode ("pop", "dpx1");
2613 pic14_emitcode ("pop", "dph1");
2614 pic14_emitcode ("pop", "dpl1");
2616 pic14_emitcode ("pop", "dps");
2617 pic14_emitcode ("pop", "dpx");
2619 if (!inExcludeList("dph"))
2620 pic14_emitcode ("pop","dph");
2621 if (!inExcludeList("dpl"))
2622 pic14_emitcode ("pop","dpl");
2623 if (!inExcludeList("b"))
2624 pic14_emitcode ("pop","b");
2625 if (!inExcludeList("acc"))
2626 pic14_emitcode ("pop","acc");
2628 if (SPEC_CRTCL(sym->etype))
2629 pic14_emitcode("setb","ea");
2631 /* if debug then send end of function */
2632 /* if (options.debug && currFunc) { */
2635 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2636 FileBaseName(ic->filename),currFunc->lastLine,
2637 ic->level,ic->block);
2638 if (IS_STATIC(currFunc->etype))
2639 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2641 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2645 pic14_emitcode ("reti","");
2648 if (SPEC_CRTCL(sym->etype))
2649 pic14_emitcode("setb","ea");
2651 if (sym->calleeSave) {
2654 /* if any registers used */
2655 if (sym->regsUsed) {
2656 /* save the registers used */
2657 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2658 if (bitVectBitValue(sym->regsUsed,i) ||
2659 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2660 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2666 /* if debug then send end of function */
2669 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2670 FileBaseName(ic->filename),currFunc->lastLine,
2671 ic->level,ic->block);
2672 if (IS_STATIC(currFunc->etype))
2673 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2675 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2679 pic14_emitcode ("return","");
2680 emitpcode(POC_RETURN,NULL);
2682 /* Mark the end of a function */
2683 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2688 /*-----------------------------------------------------------------*/
2689 /* genRet - generate code for return statement */
2690 /*-----------------------------------------------------------------*/
2691 static void genRet (iCode *ic)
2693 int size,offset = 0 , pushed = 0;
2695 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2696 /* if we have no return value then
2697 just generate the "ret" */
2701 /* we have something to return then
2702 move the return value into place */
2703 aopOp(IC_LEFT(ic),ic,FALSE);
2704 size = AOP_SIZE(IC_LEFT(ic));
2708 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2710 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2712 pic14_emitcode("push","%s",l);
2715 l = aopGet(AOP(IC_LEFT(ic)),offset,
2717 if (strcmp(fReturn[offset],l)) {
2718 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2719 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
2720 pic14_emitcode("movlw","%s",l);
2722 pic14_emitcode("movf","%s,w",l);
2724 pic14_emitcode("movwf","%s",fReturn[offset]);
2733 if (strcmp(fReturn[pushed],"a"))
2734 pic14_emitcode("pop",fReturn[pushed]);
2736 pic14_emitcode("pop","acc");
2739 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2742 /* generate a jump to the return label
2743 if the next is not the return statement */
2744 if (!(ic->next && ic->next->op == LABEL &&
2745 IC_LABEL(ic->next) == returnLabel)) {
2747 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2748 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2753 /*-----------------------------------------------------------------*/
2754 /* genLabel - generates a label */
2755 /*-----------------------------------------------------------------*/
2756 static void genLabel (iCode *ic)
2758 /* special case never generate */
2759 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2760 if (IC_LABEL(ic) == entryLabel)
2763 emitpLabel(IC_LABEL(ic)->key+100 + labelOffset);
2764 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2767 /*-----------------------------------------------------------------*/
2768 /* genGoto - generates a goto */
2769 /*-----------------------------------------------------------------*/
2771 static void genGoto (iCode *ic)
2773 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2774 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2777 /*-----------------------------------------------------------------*/
2778 /* findLabelBackwards: walks back through the iCode chain looking */
2779 /* for the given label. Returns number of iCode instructions */
2780 /* between that label and given ic. */
2781 /* Returns zero if label not found. */
2782 /*-----------------------------------------------------------------*/
2784 static int findLabelBackwards(iCode *ic, int key)
2788 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2794 if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2796 /* printf("findLabelBackwards = %d\n", count); */
2805 /*-----------------------------------------------------------------*/
2806 /* genMultbits :- multiplication of bits */
2807 /*-----------------------------------------------------------------*/
2808 static void genMultbits (operand *left,
2812 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2814 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2815 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2816 pic14_outBitC(result);
2820 /*-----------------------------------------------------------------*/
2821 /* genMultOneByte : 8 bit multiplication & division */
2822 /*-----------------------------------------------------------------*/
2823 static void genMultOneByte (operand *left,
2827 sym_link *opetype = operandType(result);
2832 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2833 /* (if two literals, the value is computed before) */
2834 /* if one literal, literal on the right */
2835 if (AOP_TYPE(left) == AOP_LIT){
2841 size = AOP_SIZE(result);
2842 /* signed or unsigned */
2843 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2844 l = aopGet(AOP(left),0,FALSE,FALSE);
2846 pic14_emitcode("mul","ab");
2847 /* if result size = 1, mul signed = mul unsigned */
2848 aopPut(AOP(result),"a",0);
2850 if (SPEC_USIGN(opetype)){
2851 aopPut(AOP(result),"b",1);
2853 /* for filling the MSBs */
2854 pic14_emitcode("clr","a");
2857 pic14_emitcode("mov","a,b");
2859 /* adjust the MSB if left or right neg */
2861 /* if one literal */
2862 if (AOP_TYPE(right) == AOP_LIT){
2863 /* AND literal negative */
2864 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2865 /* adjust MSB (c==0 after mul) */
2866 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2870 lbl = newiTempLabel(NULL);
2871 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2872 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2873 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2874 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2875 lbl = newiTempLabel(NULL);
2876 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2877 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2878 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2881 lbl = newiTempLabel(NULL);
2882 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2883 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2884 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2885 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2886 lbl = newiTempLabel(NULL);
2887 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2888 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2889 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2891 aopPut(AOP(result),"a",1);
2894 pic14_emitcode("rlc","a");
2895 pic14_emitcode("subb","a,acc");
2902 aopPut(AOP(result),"a",offset++);
2906 /*-----------------------------------------------------------------*/
2907 /* genMult - generates code for multiplication */
2908 /*-----------------------------------------------------------------*/
2909 static void genMult (iCode *ic)
2911 operand *left = IC_LEFT(ic);
2912 operand *right = IC_RIGHT(ic);
2913 operand *result= IC_RESULT(ic);
2915 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2916 /* assign the amsops */
2917 aopOp (left,ic,FALSE);
2918 aopOp (right,ic,FALSE);
2919 aopOp (result,ic,TRUE);
2921 /* special cases first */
2923 if (AOP_TYPE(left) == AOP_CRY &&
2924 AOP_TYPE(right)== AOP_CRY) {
2925 genMultbits(left,right,result);
2929 /* if both are of size == 1 */
2930 if (AOP_SIZE(left) == 1 &&
2931 AOP_SIZE(right) == 1 ) {
2932 genMultOneByte(left,right,result);
2936 /* should have been converted to function call */
2940 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2941 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2942 freeAsmop(result,NULL,ic,TRUE);
2945 /*-----------------------------------------------------------------*/
2946 /* genDivbits :- division of bits */
2947 /*-----------------------------------------------------------------*/
2948 static void genDivbits (operand *left,
2955 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2956 /* the result must be bit */
2957 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
2958 l = aopGet(AOP(left),0,FALSE,FALSE);
2962 pic14_emitcode("div","ab");
2963 pic14_emitcode("rrc","a");
2964 aopPut(AOP(result),"c",0);
2967 /*-----------------------------------------------------------------*/
2968 /* genDivOneByte : 8 bit division */
2969 /*-----------------------------------------------------------------*/
2970 static void genDivOneByte (operand *left,
2974 sym_link *opetype = operandType(result);
2979 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2980 size = AOP_SIZE(result) - 1;
2982 /* signed or unsigned */
2983 if (SPEC_USIGN(opetype)) {
2984 /* unsigned is easy */
2985 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2986 l = aopGet(AOP(left),0,FALSE,FALSE);
2988 pic14_emitcode("div","ab");
2989 aopPut(AOP(result),"a",0);
2991 aopPut(AOP(result),zero,offset++);
2995 /* signed is a little bit more difficult */
2997 /* save the signs of the operands */
2998 l = aopGet(AOP(left),0,FALSE,FALSE);
3000 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3001 pic14_emitcode("push","acc"); /* save it on the stack */
3003 /* now sign adjust for both left & right */
3004 l = aopGet(AOP(right),0,FALSE,FALSE);
3006 lbl = newiTempLabel(NULL);
3007 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3008 pic14_emitcode("cpl","a");
3009 pic14_emitcode("inc","a");
3010 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3011 pic14_emitcode("mov","b,a");
3013 /* sign adjust left side */
3014 l = aopGet(AOP(left),0,FALSE,FALSE);
3017 lbl = newiTempLabel(NULL);
3018 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3019 pic14_emitcode("cpl","a");
3020 pic14_emitcode("inc","a");
3021 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3023 /* now the division */
3024 pic14_emitcode("div","ab");
3025 /* we are interested in the lower order
3027 pic14_emitcode("mov","b,a");
3028 lbl = newiTempLabel(NULL);
3029 pic14_emitcode("pop","acc");
3030 /* if there was an over flow we don't
3031 adjust the sign of the result */
3032 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3033 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3035 pic14_emitcode("clr","a");
3036 pic14_emitcode("subb","a,b");
3037 pic14_emitcode("mov","b,a");
3038 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3040 /* now we are done */
3041 aopPut(AOP(result),"b",0);
3043 pic14_emitcode("mov","c,b.7");
3044 pic14_emitcode("subb","a,acc");
3047 aopPut(AOP(result),"a",offset++);
3051 /*-----------------------------------------------------------------*/
3052 /* genDiv - generates code for division */
3053 /*-----------------------------------------------------------------*/
3054 static void genDiv (iCode *ic)
3056 operand *left = IC_LEFT(ic);
3057 operand *right = IC_RIGHT(ic);
3058 operand *result= IC_RESULT(ic);
3060 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3061 /* assign the amsops */
3062 aopOp (left,ic,FALSE);
3063 aopOp (right,ic,FALSE);
3064 aopOp (result,ic,TRUE);
3066 /* special cases first */
3068 if (AOP_TYPE(left) == AOP_CRY &&
3069 AOP_TYPE(right)== AOP_CRY) {
3070 genDivbits(left,right,result);
3074 /* if both are of size == 1 */
3075 if (AOP_SIZE(left) == 1 &&
3076 AOP_SIZE(right) == 1 ) {
3077 genDivOneByte(left,right,result);
3081 /* should have been converted to function call */
3084 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3085 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3086 freeAsmop(result,NULL,ic,TRUE);
3089 /*-----------------------------------------------------------------*/
3090 /* genModbits :- modulus of bits */
3091 /*-----------------------------------------------------------------*/
3092 static void genModbits (operand *left,
3099 /* the result must be bit */
3100 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3101 l = aopGet(AOP(left),0,FALSE,FALSE);
3105 pic14_emitcode("div","ab");
3106 pic14_emitcode("mov","a,b");
3107 pic14_emitcode("rrc","a");
3108 aopPut(AOP(result),"c",0);
3111 /*-----------------------------------------------------------------*/
3112 /* genModOneByte : 8 bit modulus */
3113 /*-----------------------------------------------------------------*/
3114 static void genModOneByte (operand *left,
3118 sym_link *opetype = operandType(result);
3122 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3123 /* signed or unsigned */
3124 if (SPEC_USIGN(opetype)) {
3125 /* unsigned is easy */
3126 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3127 l = aopGet(AOP(left),0,FALSE,FALSE);
3129 pic14_emitcode("div","ab");
3130 aopPut(AOP(result),"b",0);
3134 /* signed is a little bit more difficult */
3136 /* save the signs of the operands */
3137 l = aopGet(AOP(left),0,FALSE,FALSE);
3140 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3141 pic14_emitcode("push","acc"); /* save it on the stack */
3143 /* now sign adjust for both left & right */
3144 l = aopGet(AOP(right),0,FALSE,FALSE);
3147 lbl = newiTempLabel(NULL);
3148 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3149 pic14_emitcode("cpl","a");
3150 pic14_emitcode("inc","a");
3151 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3152 pic14_emitcode("mov","b,a");
3154 /* sign adjust left side */
3155 l = aopGet(AOP(left),0,FALSE,FALSE);
3158 lbl = newiTempLabel(NULL);
3159 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3160 pic14_emitcode("cpl","a");
3161 pic14_emitcode("inc","a");
3162 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3164 /* now the multiplication */
3165 pic14_emitcode("div","ab");
3166 /* we are interested in the lower order
3168 lbl = newiTempLabel(NULL);
3169 pic14_emitcode("pop","acc");
3170 /* if there was an over flow we don't
3171 adjust the sign of the result */
3172 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3173 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3175 pic14_emitcode("clr","a");
3176 pic14_emitcode("subb","a,b");
3177 pic14_emitcode("mov","b,a");
3178 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3180 /* now we are done */
3181 aopPut(AOP(result),"b",0);
3185 /*-----------------------------------------------------------------*/
3186 /* genMod - generates code for division */
3187 /*-----------------------------------------------------------------*/
3188 static void genMod (iCode *ic)
3190 operand *left = IC_LEFT(ic);
3191 operand *right = IC_RIGHT(ic);
3192 operand *result= IC_RESULT(ic);
3194 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3195 /* assign the amsops */
3196 aopOp (left,ic,FALSE);
3197 aopOp (right,ic,FALSE);
3198 aopOp (result,ic,TRUE);
3200 /* special cases first */
3202 if (AOP_TYPE(left) == AOP_CRY &&
3203 AOP_TYPE(right)== AOP_CRY) {
3204 genModbits(left,right,result);
3208 /* if both are of size == 1 */
3209 if (AOP_SIZE(left) == 1 &&
3210 AOP_SIZE(right) == 1 ) {
3211 genModOneByte(left,right,result);
3215 /* should have been converted to function call */
3219 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3220 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3221 freeAsmop(result,NULL,ic,TRUE);
3224 /*-----------------------------------------------------------------*/
3225 /* genIfxJump :- will create a jump depending on the ifx */
3226 /*-----------------------------------------------------------------*/
3228 note: May need to add parameter to indicate when a variable is in bit space.
3230 static void genIfxJump (iCode *ic, char *jval)
3233 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3234 /* if true label then we jump if condition
3236 if ( IC_TRUE(ic) ) {
3238 if(strcmp(jval,"a") == 0)
3240 else if (strcmp(jval,"c") == 0)
3243 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3244 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3247 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3248 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3252 /* false label is present */
3253 if(strcmp(jval,"a") == 0)
3255 else if (strcmp(jval,"c") == 0)
3258 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3259 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3262 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3263 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3268 /* mark the icode as generated */
3272 /*-----------------------------------------------------------------*/
3274 /*-----------------------------------------------------------------*/
3275 static void genSkip(iCode *ifx,int status_bit)
3280 if ( IC_TRUE(ifx) ) {
3281 switch(status_bit) {
3296 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3297 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3301 switch(status_bit) {
3315 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3316 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3322 /*-----------------------------------------------------------------*/
3324 /*-----------------------------------------------------------------*/
3325 static void genSkipc(iCode *ifx, int condition)
3336 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3338 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3341 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3343 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3347 /*-----------------------------------------------------------------*/
3349 /*-----------------------------------------------------------------*/
3350 static void genSkipz(iCode *ifx, int condition)
3361 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3363 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3366 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3368 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3371 /*-----------------------------------------------------------------*/
3372 /* genCmp :- greater or less than comparison */
3373 /*-----------------------------------------------------------------*/
3374 static void genCmp (operand *left,operand *right,
3375 operand *result, iCode *ifx, int sign)
3377 int size, offset = 0 ;
3378 unsigned long lit = 0L,i = 0;
3380 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3381 /* if left & right are bit variables */
3382 if (AOP_TYPE(left) == AOP_CRY &&
3383 AOP_TYPE(right) == AOP_CRY ) {
3384 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3385 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3387 /* subtract right from left if at the
3388 end the carry flag is set then we know that
3389 left is greater than right */
3390 size = max(AOP_SIZE(left),AOP_SIZE(right));
3392 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3393 if((size == 1) && !sign &&
3394 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3395 symbol *lbl = newiTempLabel(NULL);
3396 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3397 aopGet(AOP(left),offset,FALSE,FALSE),
3398 aopGet(AOP(right),offset,FALSE,FALSE),
3400 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3403 if(AOP_TYPE(right) == AOP_LIT) {
3405 DEBUGpic14_emitcode(";right lit","%d",sign);
3407 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3410 i = (lit >> (size*8)) & 0xff;
3412 emitpcode(POC_MOVFW, popGet(AOP(left),size,FALSE,FALSE));
3413 pic14_emitcode("movf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
3414 genSkipz(ifx,IC_TRUE(ifx) == NULL);
3416 emitpcode(POC_MOVLW, popGetLit(i));
3417 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3419 pic14_emitcode("movlw","0x%x",i);
3420 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
3421 genSkipc(ifx,IC_TRUE(ifx) == NULL);
3428 if(AOP_TYPE(left) == AOP_LIT) {
3430 DEBUGpic14_emitcode(";left lit","%d",sign);
3432 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit))+1;
3436 i = (lit >> (size*8)) & 0xff;
3438 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3439 pic14_emitcode("movf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3440 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3441 } else if( i == 1 ) {
3442 emitpcode(POC_DECFW, popGet(AOP(right),size,FALSE,FALSE));
3443 pic14_emitcode("decf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3444 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3447 emitpcode(POC_MOVLW, popGetLit(i));
3448 emitpcode(POC_SUBFW, popGet(AOP(right),size,FALSE,FALSE));
3450 pic14_emitcode("movlw","0x%x",i);
3451 pic14_emitcode("subwf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3452 genSkipc(ifx,IC_TRUE(ifx) != NULL);
3461 DEBUGpic14_emitcode(";sign","%d",sign);
3463 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3464 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3466 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3467 emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3472 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3474 emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3475 emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE));
3478 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3480 pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3481 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3489 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3490 pic14_outBitC(result);
3492 /* if the result is used in the next
3493 ifx conditional branch then generate
3494 code a little differently */
3496 genIfxJump (ifx,"c");
3498 pic14_outBitC(result);
3499 /* leave the result in acc */
3504 /*-----------------------------------------------------------------*/
3505 /* genCmpGt :- greater than comparison */
3506 /*-----------------------------------------------------------------*/
3507 static void genCmpGt (iCode *ic, iCode *ifx)
3509 operand *left, *right, *result;
3510 sym_link *letype , *retype;
3513 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3515 right= IC_RIGHT(ic);
3516 result = IC_RESULT(ic);
3518 letype = getSpec(operandType(left));
3519 retype =getSpec(operandType(right));
3520 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3521 /* assign the amsops */
3522 aopOp (left,ic,FALSE);
3523 aopOp (right,ic,FALSE);
3524 aopOp (result,ic,TRUE);
3526 genCmp(right, left, result, ifx, sign);
3528 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3529 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3530 freeAsmop(result,NULL,ic,TRUE);
3533 /*-----------------------------------------------------------------*/
3534 /* genCmpLt - less than comparisons */
3535 /*-----------------------------------------------------------------*/
3536 static void genCmpLt (iCode *ic, iCode *ifx)
3538 operand *left, *right, *result;
3539 sym_link *letype , *retype;
3542 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3544 right= IC_RIGHT(ic);
3545 result = IC_RESULT(ic);
3547 letype = getSpec(operandType(left));
3548 retype =getSpec(operandType(right));
3549 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3551 /* assign the amsops */
3552 aopOp (left,ic,FALSE);
3553 aopOp (right,ic,FALSE);
3554 aopOp (result,ic,TRUE);
3556 genCmp(left, right, result, ifx, sign);
3558 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3559 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3560 freeAsmop(result,NULL,ic,TRUE);
3563 /*-----------------------------------------------------------------*/
3564 /* gencjneshort - compare and jump if not equal */
3565 /*-----------------------------------------------------------------*/
3566 static void gencjneshort(operand *left, operand *right, symbol *lbl)
3568 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3570 unsigned long lit = 0L;
3572 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3573 /* if the left side is a literal or
3574 if the right is in a pointer register and left
3576 if ((AOP_TYPE(left) == AOP_LIT) ||
3577 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3582 if(AOP_TYPE(right) == AOP_LIT)
3583 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3585 /* if the right side is a literal then anything goes */
3586 if (AOP_TYPE(right) == AOP_LIT &&
3587 AOP_TYPE(left) != AOP_DIR ) {
3590 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3591 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3593 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3596 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3602 /* if the right side is in a register or in direct space or
3603 if the left is a pointer register & right is not */
3604 else if (AOP_TYPE(right) == AOP_REG ||
3605 AOP_TYPE(right) == AOP_DIR ||
3606 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3607 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3609 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3610 ( (lit & 0xff) != 0)) {
3611 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3612 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3615 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3618 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3621 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
3622 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3623 ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0))
3624 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
3626 pic14_emitcode("cjne","a,%s,%05d_DS_",
3627 aopGet(AOP(right),offset,FALSE,TRUE),
3633 /* right is a pointer reg need both a & b */
3635 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3637 pic14_emitcode("mov","b,%s",l);
3638 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3639 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
3645 /*-----------------------------------------------------------------*/
3646 /* gencjne - compare and jump if not equal */
3647 /*-----------------------------------------------------------------*/
3648 static void gencjne(operand *left, operand *right, symbol *lbl)
3650 symbol *tlbl = newiTempLabel(NULL);
3652 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3653 gencjneshort(left, right, lbl);
3655 pic14_emitcode("mov","a,%s",one);
3656 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3657 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3658 pic14_emitcode("clr","a");
3659 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
3663 /*-----------------------------------------------------------------*/
3664 /* genCmpEq - generates code for equal to */
3665 /*-----------------------------------------------------------------*/
3666 static void genCmpEq (iCode *ic, iCode *ifx)
3668 operand *left, *right, *result;
3669 unsigned long lit = 0L;
3672 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3674 DEBUGpic14_emitcode ("; ifx is non-null","");
3676 DEBUGpic14_emitcode ("; ifx is null","");
3678 aopOp((left=IC_LEFT(ic)),ic,FALSE);
3679 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
3680 aopOp((result=IC_RESULT(ic)),ic,TRUE);
3682 size = max(AOP_SIZE(left),AOP_SIZE(right));
3684 /* if literal, literal on the right or
3685 if the right is in a pointer register and left
3687 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
3688 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3689 operand *t = IC_RIGHT(ic);
3690 IC_RIGHT(ic) = IC_LEFT(ic);
3694 if(ifx && !AOP_SIZE(result)){
3696 /* if they are both bit variables */
3697 if (AOP_TYPE(left) == AOP_CRY &&
3698 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3699 if(AOP_TYPE(right) == AOP_LIT){
3700 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3702 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3703 pic14_emitcode("cpl","c");
3704 } else if(lit == 1L) {
3705 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3707 pic14_emitcode("clr","c");
3709 /* AOP_TYPE(right) == AOP_CRY */
3711 symbol *lbl = newiTempLabel(NULL);
3712 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3713 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3714 pic14_emitcode("cpl","c");
3715 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3717 /* if true label then we jump if condition
3719 tlbl = newiTempLabel(NULL);
3720 if ( IC_TRUE(ifx) ) {
3721 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
3722 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
3724 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
3725 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
3727 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
3730 /* They're not both bit variables. Is the right a literal? */
3731 if(AOP_TYPE(right) == AOP_LIT) {
3733 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3738 int h = (lit>>8) & 0xff;
3741 /* Check special cases for integers */
3742 switch(lit & 0xffff) {
3744 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3745 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3746 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3747 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3752 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3753 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3754 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3755 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3760 emitpcode(POC_DECFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3761 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3762 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3763 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3768 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3769 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3770 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3771 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3776 emitpcode(POC_INCFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3777 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3778 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3779 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3785 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3786 emitpcode(POC_XORLW,popGetLit(l));
3787 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3789 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3790 pic14_emitcode("xorlw","0x%x",l);
3791 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3794 } else if (l == 0) {
3795 emitpcode(POC_MOVFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3796 emitpcode(POC_XORLW,popGetLit(h));
3797 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3799 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3800 pic14_emitcode("xorlw","0x%x",h);
3801 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3805 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3806 emitpcode(POC_XORLW,popGetLit(l));
3807 emitpcode(POC_MOVLW,popGetLit(h));
3809 emitpcode(POC_XORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3811 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3812 pic14_emitcode("xorlw","0x%x",l);
3813 pic14_emitcode("movlw","0x%x",h);
3815 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3832 switch(lit & 0xff) {
3834 if ( IC_TRUE(ifx) ) {
3836 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3838 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3840 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3842 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3844 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3845 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3847 pic14_emitcode("decfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3848 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3852 if ( IC_TRUE(ifx) ) {
3853 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3855 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3857 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3859 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3861 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3862 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3864 pic14_emitcode("incfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3865 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3869 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3870 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3872 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3873 //pic14_emitcode("xorlw","0x%x",lit & 0xff);
3878 // pic14_emitcode("goto","_%05d_DS_",tlbl->key+100+labelOffset);
3879 //pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
3884 } else if(AOP_TYPE(right) == AOP_CRY ) {
3885 /* we know the left is not a bit, but that the right is */
3886 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3887 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
3888 popGet(AOP(right),offset,FALSE,FALSE));
3889 emitpcode(POC_XORLW,popGetLit(1));
3891 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3893 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
3894 AOP(right)->aopu.aop_dir,
3895 AOP(right)->aopu.aop_dir);
3897 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
3898 AOP(right)->aopu.aop_dir,
3899 AOP(right)->aopu.aop_dir);
3901 pic14_emitcode("xorlw","1");
3903 /* if the two are equal, then W will be 0 and the Z bit is set
3904 * we could test Z now, or go ahead and check the high order bytes if
3905 * the variable we're comparing is larger than a byte. */
3908 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3909 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3911 if ( IC_TRUE(ifx) ) {
3913 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3914 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3917 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3918 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3922 /* They're both variables that are larger than bits */
3925 tlbl = newiTempLabel(NULL);
3928 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3929 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3931 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3932 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3934 if ( IC_TRUE(ifx) ) {
3937 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
3938 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
3941 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3942 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3946 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3947 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3951 if(s>1 && IC_TRUE(ifx)) {
3952 emitpLabel(tlbl->key+100+labelOffset);
3953 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
3957 /* mark the icode as generated */
3962 /* if they are both bit variables */
3963 if (AOP_TYPE(left) == AOP_CRY &&
3964 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3965 if(AOP_TYPE(right) == AOP_LIT){
3966 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3968 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3969 pic14_emitcode("cpl","c");
3970 } else if(lit == 1L) {
3971 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3973 pic14_emitcode("clr","c");
3975 /* AOP_TYPE(right) == AOP_CRY */
3977 symbol *lbl = newiTempLabel(NULL);
3978 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3979 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3980 pic14_emitcode("cpl","c");
3981 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3984 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
3985 pic14_outBitC(result);
3989 genIfxJump (ifx,"c");
3992 /* if the result is used in an arithmetic operation
3993 then put the result in place */
3994 pic14_outBitC(result);
3996 gencjne(left,right,newiTempLabel(NULL));
3997 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3998 aopPut(AOP(result),"a",0);
4002 genIfxJump (ifx,"a");
4005 /* if the result is used in an arithmetic operation
4006 then put the result in place */
4007 if (AOP_TYPE(result) != AOP_CRY)
4008 pic14_outAcc(result);
4009 /* leave the result in acc */
4013 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4014 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4015 freeAsmop(result,NULL,ic,TRUE);
4018 /*-----------------------------------------------------------------*/
4019 /* ifxForOp - returns the icode containing the ifx for operand */
4020 /*-----------------------------------------------------------------*/
4021 static iCode *ifxForOp ( operand *op, iCode *ic )
4023 /* if true symbol then needs to be assigned */
4024 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4025 if (IS_TRUE_SYMOP(op))
4028 /* if this has register type condition and
4029 the next instruction is ifx with the same operand
4030 and live to of the operand is upto the ifx only then */
4032 ic->next->op == IFX &&
4033 IC_COND(ic->next)->key == op->key &&
4034 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4039 /*-----------------------------------------------------------------*/
4040 /* genAndOp - for && operation */
4041 /*-----------------------------------------------------------------*/
4042 static void genAndOp (iCode *ic)
4044 operand *left,*right, *result;
4047 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4048 /* note here that && operations that are in an
4049 if statement are taken away by backPatchLabels
4050 only those used in arthmetic operations remain */
4051 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4052 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4053 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4055 /* if both are bit variables */
4056 if (AOP_TYPE(left) == AOP_CRY &&
4057 AOP_TYPE(right) == AOP_CRY ) {
4058 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4059 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4060 pic14_outBitC(result);
4062 tlbl = newiTempLabel(NULL);
4063 pic14_toBoolean(left);
4064 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4065 pic14_toBoolean(right);
4066 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4067 pic14_outBitAcc(result);
4070 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4071 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4072 freeAsmop(result,NULL,ic,TRUE);
4076 /*-----------------------------------------------------------------*/
4077 /* genOrOp - for || operation */
4078 /*-----------------------------------------------------------------*/
4081 modified this code, but it doesn't appear to ever get called
4084 static void genOrOp (iCode *ic)
4086 operand *left,*right, *result;
4089 /* note here that || operations that are in an
4090 if statement are taken away by backPatchLabels
4091 only those used in arthmetic operations remain */
4092 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4093 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4094 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4095 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4097 /* if both are bit variables */
4098 if (AOP_TYPE(left) == AOP_CRY &&
4099 AOP_TYPE(right) == AOP_CRY ) {
4100 pic14_emitcode("clrc","");
4101 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4102 AOP(left)->aopu.aop_dir,
4103 AOP(left)->aopu.aop_dir);
4104 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4105 AOP(right)->aopu.aop_dir,
4106 AOP(right)->aopu.aop_dir);
4107 pic14_emitcode("setc","");
4110 tlbl = newiTempLabel(NULL);
4111 pic14_toBoolean(left);
4113 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4114 pic14_toBoolean(right);
4115 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4117 pic14_outBitAcc(result);
4120 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4121 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4122 freeAsmop(result,NULL,ic,TRUE);
4125 /*-----------------------------------------------------------------*/
4126 /* isLiteralBit - test if lit == 2^n */
4127 /*-----------------------------------------------------------------*/
4128 static int isLiteralBit(unsigned long lit)
4130 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4131 0x100L,0x200L,0x400L,0x800L,
4132 0x1000L,0x2000L,0x4000L,0x8000L,
4133 0x10000L,0x20000L,0x40000L,0x80000L,
4134 0x100000L,0x200000L,0x400000L,0x800000L,
4135 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4136 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4139 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4140 for(idx = 0; idx < 32; idx++)
4146 /*-----------------------------------------------------------------*/
4147 /* continueIfTrue - */
4148 /*-----------------------------------------------------------------*/
4149 static void continueIfTrue (iCode *ic)
4151 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4153 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4157 /*-----------------------------------------------------------------*/
4159 /*-----------------------------------------------------------------*/
4160 static void jumpIfTrue (iCode *ic)
4162 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4164 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4168 /*-----------------------------------------------------------------*/
4169 /* jmpTrueOrFalse - */
4170 /*-----------------------------------------------------------------*/
4171 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4173 // ugly but optimized by peephole
4174 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4176 symbol *nlbl = newiTempLabel(NULL);
4177 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4178 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4179 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4180 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4183 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4184 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4189 /*-----------------------------------------------------------------*/
4190 /* genAnd - code for and */
4191 /*-----------------------------------------------------------------*/
4192 static void genAnd (iCode *ic, iCode *ifx)
4194 operand *left, *right, *result;
4196 unsigned long lit = 0L;
4200 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4201 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4202 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4203 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4206 pic14_emitcode("","; Type res[%d] = l[%d]&r[%d]",
4208 AOP_TYPE(left), AOP_TYPE(right));
4209 pic14_emitcode("","; Size res[%d] = l[%d]&r[%d]",
4211 AOP_SIZE(left), AOP_SIZE(right));
4214 /* if left is a literal & right is not then exchange them */
4215 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4216 AOP_NEEDSACC(left)) {
4217 operand *tmp = right ;
4222 /* if result = right then exchange them */
4223 if(pic14_sameRegs(AOP(result),AOP(right))){
4224 operand *tmp = right ;
4229 /* if right is bit then exchange them */
4230 if (AOP_TYPE(right) == AOP_CRY &&
4231 AOP_TYPE(left) != AOP_CRY){
4232 operand *tmp = right ;
4236 if(AOP_TYPE(right) == AOP_LIT)
4237 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4239 size = AOP_SIZE(result);
4242 // result = bit & yy;
4243 if (AOP_TYPE(left) == AOP_CRY){
4244 // c = bit & literal;
4245 if(AOP_TYPE(right) == AOP_LIT){
4247 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4250 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4253 if(size && (AOP_TYPE(result) == AOP_CRY)){
4254 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4257 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4261 pic14_emitcode("clr","c");
4264 if (AOP_TYPE(right) == AOP_CRY){
4266 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4267 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4270 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4272 pic14_emitcode("rrc","a");
4273 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4279 pic14_outBitC(result);
4281 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4282 genIfxJump(ifx, "c");
4286 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4287 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4288 if((AOP_TYPE(right) == AOP_LIT) &&
4289 (AOP_TYPE(result) == AOP_CRY) &&
4290 (AOP_TYPE(left) != AOP_CRY)){
4291 int posbit = isLiteralBit(lit);
4295 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4298 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4302 pCodeOp *pcorb = popGet(AOP(left),0,TRUE,FALSE);
4303 PCORB(pcorb)->subtype = PCOP(pcorb)->type;
4304 PCOP(pcorb)->type = PO_GPR_BIT;
4305 PCORB(pcorb)->bit = posbit;
4307 emitpcode(POC_BTFSC, pcorb);
4308 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4310 emitpcode(POC_BTFSS, pcorb);
4311 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4318 symbol *tlbl = newiTempLabel(NULL);
4319 int sizel = AOP_SIZE(left);
4321 pic14_emitcode("setb","c");
4323 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4324 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4326 if((posbit = isLiteralBit(bytelit)) != 0)
4327 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4329 if(bytelit != 0x0FFL)
4330 pic14_emitcode("anl","a,%s",
4331 aopGet(AOP(right),offset,FALSE,TRUE));
4332 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4337 // bit = left & literal
4339 pic14_emitcode("clr","c");
4340 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4342 // if(left & literal)
4345 jmpTrueOrFalse(ifx, tlbl);
4349 pic14_outBitC(result);
4353 /* if left is same as result */
4354 if(pic14_sameRegs(AOP(result),AOP(left))){
4355 for(;size--; offset++,lit>>=8) {
4356 if(AOP_TYPE(right) == AOP_LIT){
4357 switch(lit & 0xff) {
4359 /* and'ing with 0 has clears the result */
4360 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4361 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4364 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4365 emitpcode(POC_MOVWF,popGet(AOP(right),offset,FALSE,FALSE));
4370 int p = my_powof2( (~lit) & 0xff );
4372 /* only one bit is set in the literal, so use a bcf instruction */
4373 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4374 emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
4376 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4377 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4378 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4379 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
4384 if (AOP_TYPE(left) == AOP_ACC) {
4385 pic14_emitcode("?iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4386 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4389 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4390 pic14_emitcode("?iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4391 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4392 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4399 // left & result in different registers
4400 if(AOP_TYPE(result) == AOP_CRY){
4402 // if(size), result in bit
4403 // if(!size && ifx), conditional oper: if(left & right)
4404 symbol *tlbl = newiTempLabel(NULL);
4405 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4407 pic14_emitcode("setb","c");
4409 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4410 pic14_emitcode("anl","a,%s",
4411 aopGet(AOP(left),offset,FALSE,FALSE));
4412 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4417 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4418 pic14_outBitC(result);
4420 jmpTrueOrFalse(ifx, tlbl);
4422 for(;(size--);offset++) {
4424 // result = left & right
4425 if(AOP_TYPE(right) == AOP_LIT){
4426 int t = (lit >> (offset*8)) & 0x0FFL;
4429 pic14_emitcode("clrf","%s",
4430 aopGet(AOP(result),offset,FALSE,FALSE));
4431 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4434 pic14_emitcode("movf","%s,w",
4435 aopGet(AOP(left),offset,FALSE,FALSE));
4436 pic14_emitcode("movwf","%s",
4437 aopGet(AOP(result),offset,FALSE,FALSE));
4438 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4439 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4442 pic14_emitcode("movlw","0x%x",t);
4443 pic14_emitcode("andwf","%s,w",
4444 aopGet(AOP(left),offset,FALSE,FALSE));
4445 pic14_emitcode("movwf","%s",
4446 aopGet(AOP(result),offset,FALSE,FALSE));
4448 emitpcode(POC_MOVLW, popGetLit(t));
4449 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4450 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4455 if (AOP_TYPE(left) == AOP_ACC) {
4456 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4457 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4459 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4460 pic14_emitcode("andwf","%s,w",
4461 aopGet(AOP(left),offset,FALSE,FALSE));
4462 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4463 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4465 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4466 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4472 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4473 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4474 freeAsmop(result,NULL,ic,TRUE);
4477 /*-----------------------------------------------------------------*/
4478 /* genOr - code for or */
4479 /*-----------------------------------------------------------------*/
4480 static void genOr (iCode *ic, iCode *ifx)
4482 operand *left, *right, *result;
4484 unsigned long lit = 0L;
4486 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4488 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4489 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4490 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4493 /* if left is a literal & right is not then exchange them */
4494 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4495 AOP_NEEDSACC(left)) {
4496 operand *tmp = right ;
4501 /* if result = right then exchange them */
4502 if(pic14_sameRegs(AOP(result),AOP(right))){
4503 operand *tmp = right ;
4508 /* if right is bit then exchange them */
4509 if (AOP_TYPE(right) == AOP_CRY &&
4510 AOP_TYPE(left) != AOP_CRY){
4511 operand *tmp = right ;
4516 if(AOP_TYPE(right) == AOP_LIT)
4517 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4519 size = AOP_SIZE(result);
4523 if (AOP_TYPE(left) == AOP_CRY){
4524 if(AOP_TYPE(right) == AOP_LIT){
4525 // c = bit & literal;
4527 // lit != 0 => result = 1
4528 if(AOP_TYPE(result) == AOP_CRY){
4530 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4531 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4532 // AOP(result)->aopu.aop_dir,
4533 // AOP(result)->aopu.aop_dir);
4535 continueIfTrue(ifx);
4539 // lit == 0 => result = left
4540 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4542 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4545 if (AOP_TYPE(right) == AOP_CRY){
4546 if(pic14_sameRegs(AOP(result),AOP(left))){
4548 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4549 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4550 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4552 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4553 AOP(result)->aopu.aop_dir,
4554 AOP(result)->aopu.aop_dir);
4555 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4556 AOP(right)->aopu.aop_dir,
4557 AOP(right)->aopu.aop_dir);
4558 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4559 AOP(result)->aopu.aop_dir,
4560 AOP(result)->aopu.aop_dir);
4563 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4564 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4565 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4566 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4568 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4569 AOP(result)->aopu.aop_dir,
4570 AOP(result)->aopu.aop_dir);
4571 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4572 AOP(right)->aopu.aop_dir,
4573 AOP(right)->aopu.aop_dir);
4574 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4575 AOP(left)->aopu.aop_dir,
4576 AOP(left)->aopu.aop_dir);
4577 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4578 AOP(result)->aopu.aop_dir,
4579 AOP(result)->aopu.aop_dir);
4584 symbol *tlbl = newiTempLabel(NULL);
4585 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4586 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4587 pic14_emitcode(";XXX setb","c");
4588 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4589 AOP(left)->aopu.aop_dir,tlbl->key+100);
4590 pic14_toBoolean(right);
4591 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4592 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4593 jmpTrueOrFalse(ifx, tlbl);
4597 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4604 pic14_outBitC(result);
4606 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4607 genIfxJump(ifx, "c");
4611 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4612 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4613 if((AOP_TYPE(right) == AOP_LIT) &&
4614 (AOP_TYPE(result) == AOP_CRY) &&
4615 (AOP_TYPE(left) != AOP_CRY)){
4617 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4620 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4622 continueIfTrue(ifx);
4625 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4626 // lit = 0, result = boolean(left)
4628 pic14_emitcode(";XXX setb","c");
4629 pic14_toBoolean(right);
4631 symbol *tlbl = newiTempLabel(NULL);
4632 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4634 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4636 genIfxJump (ifx,"a");
4640 pic14_outBitC(result);
4644 /* if left is same as result */
4645 if(pic14_sameRegs(AOP(result),AOP(left))){
4646 for(;size--; offset++,lit>>=8) {
4647 if(AOP_TYPE(right) == AOP_LIT){
4648 if((lit & 0xff) == 0)
4649 /* or'ing with 0 has no effect */
4652 int p = my_powof2(lit & 0xff);
4654 /* only one bit is set in the literal, so use a bsf instruction */
4655 emitpcode(POC_BSF, popGet(AOP(left),offset,FALSE,FALSE));
4656 pic14_emitcode("bsf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4658 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4659 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4661 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4662 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
4667 if (AOP_TYPE(left) == AOP_ACC) {
4668 emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE));
4669 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4671 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4672 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4674 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4675 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4681 // left & result in different registers
4682 if(AOP_TYPE(result) == AOP_CRY){
4684 // if(size), result in bit
4685 // if(!size && ifx), conditional oper: if(left | right)
4686 symbol *tlbl = newiTempLabel(NULL);
4687 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4688 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4691 pic14_emitcode(";XXX setb","c");
4693 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4694 pic14_emitcode(";XXX orl","a,%s",
4695 aopGet(AOP(left),offset,FALSE,FALSE));
4696 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4701 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4702 pic14_outBitC(result);
4704 jmpTrueOrFalse(ifx, tlbl);
4705 } else for(;(size--);offset++){
4707 // result = left & right
4708 if(AOP_TYPE(right) == AOP_LIT){
4709 int t = (lit >> (offset*8)) & 0x0FFL;
4712 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
4713 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4715 pic14_emitcode("movf","%s,w",
4716 aopGet(AOP(left),offset,FALSE,FALSE));
4717 pic14_emitcode("movwf","%s",
4718 aopGet(AOP(result),offset,FALSE,FALSE));
4721 emitpcode(POC_MOVLW, popGetLit(t));
4722 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4723 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4725 pic14_emitcode("movlw","0x%x",t);
4726 pic14_emitcode("iorwf","%s,w",
4727 aopGet(AOP(left),offset,FALSE,FALSE));
4728 pic14_emitcode("movwf","%s",
4729 aopGet(AOP(result),offset,FALSE,FALSE));
4735 // faster than result <- left, anl result,right
4736 // and better if result is SFR
4737 if (AOP_TYPE(left) == AOP_ACC) {
4738 emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE));
4739 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4741 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4742 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4744 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4745 pic14_emitcode("iorwf","%s,w",
4746 aopGet(AOP(left),offset,FALSE,FALSE));
4748 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4749 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4754 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4755 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4756 freeAsmop(result,NULL,ic,TRUE);
4759 /*-----------------------------------------------------------------*/
4760 /* genXor - code for xclusive or */
4761 /*-----------------------------------------------------------------*/
4762 static void genXor (iCode *ic, iCode *ifx)
4764 operand *left, *right, *result;
4766 unsigned long lit = 0L;
4768 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4770 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4771 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4772 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4774 /* if left is a literal & right is not ||
4775 if left needs acc & right does not */
4776 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4777 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
4778 operand *tmp = right ;
4783 /* if result = right then exchange them */
4784 if(pic14_sameRegs(AOP(result),AOP(right))){
4785 operand *tmp = right ;
4790 /* if right is bit then exchange them */
4791 if (AOP_TYPE(right) == AOP_CRY &&
4792 AOP_TYPE(left) != AOP_CRY){
4793 operand *tmp = right ;
4797 if(AOP_TYPE(right) == AOP_LIT)
4798 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4800 size = AOP_SIZE(result);
4804 if (AOP_TYPE(left) == AOP_CRY){
4805 if(AOP_TYPE(right) == AOP_LIT){
4806 // c = bit & literal;
4808 // lit>>1 != 0 => result = 1
4809 if(AOP_TYPE(result) == AOP_CRY){
4811 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
4813 continueIfTrue(ifx);
4816 pic14_emitcode("setb","c");
4820 // lit == 0, result = left
4821 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4823 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4825 // lit == 1, result = not(left)
4826 if(size && pic14_sameRegs(AOP(result),AOP(left))){
4827 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
4830 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4831 pic14_emitcode("cpl","c");
4838 symbol *tlbl = newiTempLabel(NULL);
4839 if (AOP_TYPE(right) == AOP_CRY){
4841 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4844 int sizer = AOP_SIZE(right);
4846 // if val>>1 != 0, result = 1
4847 pic14_emitcode("setb","c");
4849 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
4851 // test the msb of the lsb
4852 pic14_emitcode("anl","a,#0xfe");
4853 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4857 pic14_emitcode("rrc","a");
4859 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
4860 pic14_emitcode("cpl","c");
4861 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
4866 pic14_outBitC(result);
4868 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4869 genIfxJump(ifx, "c");
4873 if(pic14_sameRegs(AOP(result),AOP(left))){
4874 /* if left is same as result */
4875 for(;size--; offset++) {
4876 if(AOP_TYPE(right) == AOP_LIT){
4877 int t = (lit >> (offset*8)) & 0x0FFL;
4881 if (IS_AOP_PREG(left)) {
4882 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4883 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4884 aopPut(AOP(result),"a",offset);
4886 emitpcode(POC_MOVLW, popGetLit(t));
4887 emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
4888 pic14_emitcode("xrl","%s,%s",
4889 aopGet(AOP(left),offset,FALSE,TRUE),
4890 aopGet(AOP(right),offset,FALSE,FALSE));
4893 if (AOP_TYPE(left) == AOP_ACC)
4894 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
4896 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4897 if (IS_AOP_PREG(left)) {
4898 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4899 aopPut(AOP(result),"a",offset);
4901 pic14_emitcode("xrl","%s,a",
4902 aopGet(AOP(left),offset,FALSE,TRUE));
4907 // left & result in different registers
4908 if(AOP_TYPE(result) == AOP_CRY){
4910 // if(size), result in bit
4911 // if(!size && ifx), conditional oper: if(left ^ right)
4912 symbol *tlbl = newiTempLabel(NULL);
4913 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4915 pic14_emitcode("setb","c");
4917 if((AOP_TYPE(right) == AOP_LIT) &&
4918 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
4919 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
4921 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4922 pic14_emitcode("xrl","a,%s",
4923 aopGet(AOP(left),offset,FALSE,FALSE));
4925 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4930 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4931 pic14_outBitC(result);
4933 jmpTrueOrFalse(ifx, tlbl);
4934 } else for(;(size--);offset++){
4936 // result = left & right
4937 if(AOP_TYPE(right) == AOP_LIT){
4938 int t = (lit >> (offset*8)) & 0x0FFL;
4941 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4942 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4943 pic14_emitcode("movf","%s,w",
4944 aopGet(AOP(left),offset,FALSE,FALSE));
4945 pic14_emitcode("movwf","%s",
4946 aopGet(AOP(result),offset,FALSE,FALSE));
4949 emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
4950 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4951 pic14_emitcode("comf","%s,w",
4952 aopGet(AOP(left),offset,FALSE,FALSE));
4953 pic14_emitcode("movwf","%s",
4954 aopGet(AOP(result),offset,FALSE,FALSE));
4957 emitpcode(POC_MOVLW, popGetLit(t));
4958 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
4959 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4960 pic14_emitcode("movlw","0x%x",t);
4961 pic14_emitcode("xorwf","%s,w",
4962 aopGet(AOP(left),offset,FALSE,FALSE));
4963 pic14_emitcode("movwf","%s",
4964 aopGet(AOP(result),offset,FALSE,FALSE));
4970 // faster than result <- left, anl result,right
4971 // and better if result is SFR
4972 if (AOP_TYPE(left) == AOP_ACC) {
4973 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
4974 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4976 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4977 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
4978 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4979 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4981 if ( AOP_TYPE(result) != AOP_ACC){
4982 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4983 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4989 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4990 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4991 freeAsmop(result,NULL,ic,TRUE);
4994 /*-----------------------------------------------------------------*/
4995 /* genInline - write the inline code out */
4996 /*-----------------------------------------------------------------*/
4997 static void genInline (iCode *ic)
4999 char *buffer, *bp, *bp1;
5001 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5003 _G.inLine += (!options.asmpeep);
5005 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5006 strcpy(buffer,IC_INLINE(ic));
5008 /* emit each line as a code */
5012 pic14_emitcode(bp1,"");
5019 pic14_emitcode(bp1,"");
5026 pic14_emitcode(bp1,"");
5027 /* pic14_emitcode("",buffer); */
5028 _G.inLine -= (!options.asmpeep);
5031 /*-----------------------------------------------------------------*/
5032 /* genRRC - rotate right with carry */
5033 /*-----------------------------------------------------------------*/
5034 static void genRRC (iCode *ic)
5036 operand *left , *result ;
5037 int size, offset = 0;
5040 /* rotate right with carry */
5042 result=IC_RESULT(ic);
5043 aopOp (left,ic,FALSE);
5044 aopOp (result,ic,FALSE);
5046 /* move it to the result */
5047 size = AOP_SIZE(result);
5051 l = aopGet(AOP(left),offset,FALSE,FALSE);
5053 pic14_emitcode("rrc","a");
5054 if (AOP_SIZE(result) > 1)
5055 aopPut(AOP(result),"a",offset--);
5057 /* now we need to put the carry into the
5058 highest order byte of the result */
5059 if (AOP_SIZE(result) > 1) {
5060 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5063 pic14_emitcode("mov","acc.7,c");
5064 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5065 freeAsmop(left,NULL,ic,TRUE);
5066 freeAsmop(result,NULL,ic,TRUE);
5069 /*-----------------------------------------------------------------*/
5070 /* genRLC - generate code for rotate left with carry */
5071 /*-----------------------------------------------------------------*/
5072 static void genRLC (iCode *ic)
5074 operand *left , *result ;
5075 int size, offset = 0;
5078 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5079 /* rotate right with carry */
5081 result=IC_RESULT(ic);
5082 aopOp (left,ic,FALSE);
5083 aopOp (result,ic,FALSE);
5085 /* move it to the result */
5086 size = AOP_SIZE(result);
5089 l = aopGet(AOP(left),offset,FALSE,FALSE);
5091 pic14_emitcode("add","a,acc");
5092 if (AOP_SIZE(result) > 1)
5093 aopPut(AOP(result),"a",offset++);
5095 l = aopGet(AOP(left),offset,FALSE,FALSE);
5097 pic14_emitcode("rlc","a");
5098 if (AOP_SIZE(result) > 1)
5099 aopPut(AOP(result),"a",offset++);
5102 /* now we need to put the carry into the
5103 highest order byte of the result */
5104 if (AOP_SIZE(result) > 1) {
5105 l = aopGet(AOP(result),0,FALSE,FALSE);
5108 pic14_emitcode("mov","acc.0,c");
5109 aopPut(AOP(result),"a",0);
5110 freeAsmop(left,NULL,ic,TRUE);
5111 freeAsmop(result,NULL,ic,TRUE);
5114 /*-----------------------------------------------------------------*/
5115 /* genGetHbit - generates code get highest order bit */
5116 /*-----------------------------------------------------------------*/
5117 static void genGetHbit (iCode *ic)
5119 operand *left, *result;
5121 result=IC_RESULT(ic);
5122 aopOp (left,ic,FALSE);
5123 aopOp (result,ic,FALSE);
5125 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5126 /* get the highest order byte into a */
5127 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5128 if(AOP_TYPE(result) == AOP_CRY){
5129 pic14_emitcode("rlc","a");
5130 pic14_outBitC(result);
5133 pic14_emitcode("rl","a");
5134 pic14_emitcode("anl","a,#0x01");
5135 pic14_outAcc(result);
5139 freeAsmop(left,NULL,ic,TRUE);
5140 freeAsmop(result,NULL,ic,TRUE);
5143 /*-----------------------------------------------------------------*/
5144 /* AccRol - rotate left accumulator by known count */
5145 /*-----------------------------------------------------------------*/
5146 static void AccRol (int shCount)
5148 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5149 shCount &= 0x0007; // shCount : 0..7
5154 pic14_emitcode("rl","a");
5157 pic14_emitcode("rl","a");
5158 pic14_emitcode("rl","a");
5161 pic14_emitcode("swap","a");
5162 pic14_emitcode("rr","a");
5165 pic14_emitcode("swap","a");
5168 pic14_emitcode("swap","a");
5169 pic14_emitcode("rl","a");
5172 pic14_emitcode("rr","a");
5173 pic14_emitcode("rr","a");
5176 pic14_emitcode("rr","a");
5181 /*-----------------------------------------------------------------*/
5182 /* AccLsh - left shift accumulator by known count */
5183 /*-----------------------------------------------------------------*/
5184 static void AccLsh (int shCount)
5186 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5189 pic14_emitcode("add","a,acc");
5192 pic14_emitcode("add","a,acc");
5193 pic14_emitcode("add","a,acc");
5195 /* rotate left accumulator */
5197 /* and kill the lower order bits */
5198 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5203 /*-----------------------------------------------------------------*/
5204 /* AccRsh - right shift accumulator by known count */
5205 /*-----------------------------------------------------------------*/
5206 static void AccRsh (int shCount)
5208 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5212 pic14_emitcode("rrc","a");
5214 /* rotate right accumulator */
5215 AccRol(8 - shCount);
5216 /* and kill the higher order bits */
5217 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5223 /*-----------------------------------------------------------------*/
5224 /* AccSRsh - signed right shift accumulator by known count */
5225 /*-----------------------------------------------------------------*/
5226 static void AccSRsh (int shCount)
5229 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5232 pic14_emitcode("mov","c,acc.7");
5233 pic14_emitcode("rrc","a");
5234 } else if(shCount == 2){
5235 pic14_emitcode("mov","c,acc.7");
5236 pic14_emitcode("rrc","a");
5237 pic14_emitcode("mov","c,acc.7");
5238 pic14_emitcode("rrc","a");
5240 tlbl = newiTempLabel(NULL);
5241 /* rotate right accumulator */
5242 AccRol(8 - shCount);
5243 /* and kill the higher order bits */
5244 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5245 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5246 pic14_emitcode("orl","a,#0x%02x",
5247 (unsigned char)~SRMask[shCount]);
5248 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5253 /*-----------------------------------------------------------------*/
5254 /* shiftR1Left2Result - shift right one byte from left to result */
5255 /*-----------------------------------------------------------------*/
5256 static void shiftR1Left2ResultSigned (operand *left, int offl,
5257 operand *result, int offr,
5262 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5264 same = (left == result) || (AOP(left) == AOP(result));
5268 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5270 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5272 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5273 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5283 /*-----------------------------------------------------------------*/
5284 /* shiftR1Left2Result - shift right one byte from left to result */
5285 /*-----------------------------------------------------------------*/
5286 static void shiftR1Left2Result (operand *left, int offl,
5287 operand *result, int offr,
5288 int shCount, int sign)
5292 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5294 same = (left == result) || (AOP(left) == AOP(result));
5296 /* Copy the msb into the carry if signed. */
5298 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5308 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5310 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5311 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5317 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5319 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5320 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5323 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5328 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5330 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5331 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5334 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5335 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5336 emitpcode(POC_ANDLW, popGetLit(0x1f));
5337 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5341 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5342 emitpcode(POC_ANDLW, popGetLit(0x1f));
5343 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5347 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5348 emitpcode(POC_ANDLW, popGetLit(0x1f));
5349 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5351 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5356 emitpcode(POC_RLFW, popGet(AOP(left),offr,FALSE,FALSE));
5357 emitpcode(POC_ANDLW, popGetLit(0x80));
5358 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5359 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5360 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5365 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5366 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5367 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5378 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5380 /* shift right accumulator */
5385 aopPut(AOP(result),"a",offr);
5389 /*-----------------------------------------------------------------*/
5390 /* shiftL1Left2Result - shift left one byte from left to result */
5391 /*-----------------------------------------------------------------*/
5392 static void shiftL1Left2Result (operand *left, int offl,
5393 operand *result, int offr, int shCount)
5398 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5400 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5401 DEBUGpic14_emitcode ("; ***","same = %d",same);
5402 // l = aopGet(AOP(left),offl,FALSE,FALSE);
5404 /* shift left accumulator */
5405 //AccLsh(shCount); // don't comment out just yet...
5406 // aopPut(AOP(result),"a",offr);
5410 /* Shift left 1 bit position */
5411 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5413 emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
5415 emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
5416 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5420 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5421 emitpcode(POC_ANDLW,popGetLit(0x7e));
5422 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5423 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5426 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5427 emitpcode(POC_ANDLW,popGetLit(0x3e));
5428 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5429 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5430 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5433 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5434 emitpcode(POC_ANDLW, popGetLit(0xf0));
5435 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5438 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5439 emitpcode(POC_ANDLW, popGetLit(0xf0));
5440 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5441 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5444 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5445 emitpcode(POC_ANDLW, popGetLit(0x30));
5446 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5447 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5448 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5451 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5452 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5453 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5457 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5462 /*-----------------------------------------------------------------*/
5463 /* movLeft2Result - move byte from left to result */
5464 /*-----------------------------------------------------------------*/
5465 static void movLeft2Result (operand *left, int offl,
5466 operand *result, int offr, int sign)
5469 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5470 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5471 l = aopGet(AOP(left),offl,FALSE,FALSE);
5473 if (*l == '@' && (IS_AOP_PREG(result))) {
5474 pic14_emitcode("mov","a,%s",l);
5475 aopPut(AOP(result),"a",offr);
5478 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5479 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5481 //aopPut(AOP(result),l,offr);
5483 /* MSB sign in acc.7 ! */
5484 if(pic14_getDataSize(left) == offl+1){
5485 pic14_emitcode("mov","a,%s",l);
5486 aopPut(AOP(result),"a",offr);
5493 /*-----------------------------------------------------------------*/
5494 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5495 /*-----------------------------------------------------------------*/
5496 static void AccAXRrl1 (char *x)
5498 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5499 pic14_emitcode("rrc","a");
5500 pic14_emitcode("xch","a,%s", x);
5501 pic14_emitcode("rrc","a");
5502 pic14_emitcode("xch","a,%s", x);
5505 /*-----------------------------------------------------------------*/
5506 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5507 /*-----------------------------------------------------------------*/
5508 static void AccAXLrl1 (char *x)
5510 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5511 pic14_emitcode("xch","a,%s",x);
5512 pic14_emitcode("rlc","a");
5513 pic14_emitcode("xch","a,%s",x);
5514 pic14_emitcode("rlc","a");
5517 /*-----------------------------------------------------------------*/
5518 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5519 /*-----------------------------------------------------------------*/
5520 static void AccAXLsh1 (char *x)
5522 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5523 pic14_emitcode("xch","a,%s",x);
5524 pic14_emitcode("add","a,acc");
5525 pic14_emitcode("xch","a,%s",x);
5526 pic14_emitcode("rlc","a");
5530 /*-----------------------------------------------------------------*/
5531 /* AccAXLsh - left shift a:x by known count (0..7) */
5532 /*-----------------------------------------------------------------*/
5533 static void AccAXLsh (char *x, int shCount)
5535 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5548 case 5 : // AAAAABBB:CCCCCDDD
5549 AccRol(shCount); // BBBAAAAA:CCCCCDDD
5550 pic14_emitcode("anl","a,#0x%02x",
5551 SLMask[shCount]); // BBB00000:CCCCCDDD
5552 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
5553 AccRol(shCount); // DDDCCCCC:BBB00000
5554 pic14_emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
5555 pic14_emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
5556 pic14_emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
5557 pic14_emitcode("anl","a,#0x%02x",
5558 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5559 pic14_emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
5560 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
5562 case 6 : // AAAAAABB:CCCCCCDD
5563 pic14_emitcode("anl","a,#0x%02x",
5564 SRMask[shCount]); // 000000BB:CCCCCCDD
5565 pic14_emitcode("mov","c,acc.0"); // c = B
5566 pic14_emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
5567 AccAXRrl1(x); // BCCCCCCD:D000000B
5568 AccAXRrl1(x); // BBCCCCCC:DD000000
5570 case 7 : // a:x <<= 7
5571 pic14_emitcode("anl","a,#0x%02x",
5572 SRMask[shCount]); // 0000000B:CCCCCCCD
5573 pic14_emitcode("mov","c,acc.0"); // c = B
5574 pic14_emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
5575 AccAXRrl1(x); // BCCCCCCC:D0000000
5582 /*-----------------------------------------------------------------*/
5583 /* AccAXRsh - right shift a:x known count (0..7) */
5584 /*-----------------------------------------------------------------*/
5585 static void AccAXRsh (char *x, int shCount)
5587 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5593 AccAXRrl1(x); // 0->a:x
5597 AccAXRrl1(x); // 0->a:x
5599 AccAXRrl1(x); // 0->a:x
5603 case 5 : // AAAAABBB:CCCCCDDD = a:x
5604 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5605 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5606 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5607 pic14_emitcode("anl","a,#0x%02x",
5608 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5609 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5610 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5611 pic14_emitcode("anl","a,#0x%02x",
5612 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5613 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5614 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5615 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5617 case 6 : // AABBBBBB:CCDDDDDD
5618 pic14_emitcode("mov","c,acc.7");
5619 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5620 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5621 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5622 pic14_emitcode("anl","a,#0x%02x",
5623 SRMask[shCount]); // 000000AA:BBBBBBCC
5625 case 7 : // ABBBBBBB:CDDDDDDD
5626 pic14_emitcode("mov","c,acc.7"); // c = A
5627 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5628 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5629 pic14_emitcode("anl","a,#0x%02x",
5630 SRMask[shCount]); // 0000000A:BBBBBBBC
5637 /*-----------------------------------------------------------------*/
5638 /* AccAXRshS - right shift signed a:x known count (0..7) */
5639 /*-----------------------------------------------------------------*/
5640 static void AccAXRshS (char *x, int shCount)
5643 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5648 pic14_emitcode("mov","c,acc.7");
5649 AccAXRrl1(x); // s->a:x
5652 pic14_emitcode("mov","c,acc.7");
5653 AccAXRrl1(x); // s->a:x
5654 pic14_emitcode("mov","c,acc.7");
5655 AccAXRrl1(x); // s->a:x
5659 case 5 : // AAAAABBB:CCCCCDDD = a:x
5660 tlbl = newiTempLabel(NULL);
5661 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
5662 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5663 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5664 pic14_emitcode("anl","a,#0x%02x",
5665 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5666 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5667 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5668 pic14_emitcode("anl","a,#0x%02x",
5669 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5670 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5671 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5672 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
5673 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5674 pic14_emitcode("orl","a,#0x%02x",
5675 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5676 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5677 break; // SSSSAAAA:BBBCCCCC
5678 case 6 : // AABBBBBB:CCDDDDDD
5679 tlbl = newiTempLabel(NULL);
5680 pic14_emitcode("mov","c,acc.7");
5681 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5682 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5683 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5684 pic14_emitcode("anl","a,#0x%02x",
5685 SRMask[shCount]); // 000000AA:BBBBBBCC
5686 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5687 pic14_emitcode("orl","a,#0x%02x",
5688 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
5689 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5691 case 7 : // ABBBBBBB:CDDDDDDD
5692 tlbl = newiTempLabel(NULL);
5693 pic14_emitcode("mov","c,acc.7"); // c = A
5694 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5695 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5696 pic14_emitcode("anl","a,#0x%02x",
5697 SRMask[shCount]); // 0000000A:BBBBBBBC
5698 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5699 pic14_emitcode("orl","a,#0x%02x",
5700 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
5701 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5708 /*-----------------------------------------------------------------*/
5709 /* shiftL2Left2Result - shift left two bytes from left to result */
5710 /*-----------------------------------------------------------------*/
5711 static void shiftL2Left2Result (operand *left, int offl,
5712 operand *result, int offr, int shCount)
5716 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5718 if(pic14_sameRegs(AOP(result), AOP(left))) {
5726 emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
5727 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5728 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5732 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5733 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5739 emitpcode(POC_MOVLW, popGetLit(0x0f));
5740 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5741 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5742 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5743 emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
5744 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5745 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5747 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5748 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5752 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5753 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5754 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5755 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5756 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5757 emitpcode(POC_ANDLW,popGetLit(0xc0));
5758 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5759 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5760 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5761 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5764 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5765 emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
5766 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5767 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5768 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5777 /* note, use a mov/add for the shift since the mov has a
5778 chance of getting optimized out */
5779 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5780 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5781 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5782 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5783 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5787 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5788 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5794 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5795 emitpcode(POC_ANDLW, popGetLit(0xF0));
5796 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5797 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5798 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5799 emitpcode(POC_ANDLW, popGetLit(0xF0));
5800 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5801 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5804 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5805 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5808 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5809 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5813 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5814 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5815 emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
5816 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5818 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5819 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5820 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5821 emitpcode(POC_ANDLW,popGetLit(0xc0));
5822 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5823 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5824 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5825 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5828 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5829 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5830 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5831 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5832 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5837 /*-----------------------------------------------------------------*/
5838 /* shiftR2Left2Result - shift right two bytes from left to result */
5839 /*-----------------------------------------------------------------*/
5840 static void shiftR2Left2Result (operand *left, int offl,
5841 operand *result, int offr,
5842 int shCount, int sign)
5846 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5847 if(pic14_sameRegs(AOP(result), AOP(left)) &&
5848 ((offl + MSB16) == offr)){
5850 /* don't crash result[offr] */
5851 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5852 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5854 movLeft2Result(left,offl, result, offr, 0);
5855 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5857 /* a:x >> shCount (x = lsb(result))*/
5859 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5861 //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5865 if(pic14_getDataSize(result) > 1)
5866 aopPut(AOP(result),"a",offr+MSB16);
5870 /*-----------------------------------------------------------------*/
5871 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
5872 /*-----------------------------------------------------------------*/
5873 static void shiftLLeftOrResult (operand *left, int offl,
5874 operand *result, int offr, int shCount)
5876 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5877 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5878 /* shift left accumulator */
5880 /* or with result */
5881 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5882 /* back to result */
5883 aopPut(AOP(result),"a",offr);
5886 /*-----------------------------------------------------------------*/
5887 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
5888 /*-----------------------------------------------------------------*/
5889 static void shiftRLeftOrResult (operand *left, int offl,
5890 operand *result, int offr, int shCount)
5892 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5893 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5894 /* shift right accumulator */
5896 /* or with result */
5897 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5898 /* back to result */
5899 aopPut(AOP(result),"a",offr);
5902 /*-----------------------------------------------------------------*/
5903 /* genlshOne - left shift a one byte quantity by known count */
5904 /*-----------------------------------------------------------------*/
5905 static void genlshOne (operand *result, operand *left, int shCount)
5907 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5908 shiftL1Left2Result(left, LSB, result, LSB, shCount);
5911 /*-----------------------------------------------------------------*/
5912 /* genlshTwo - left shift two bytes by known amount != 0 */
5913 /*-----------------------------------------------------------------*/
5914 static void genlshTwo (operand *result,operand *left, int shCount)
5918 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5919 size = pic14_getDataSize(result);
5921 /* if shCount >= 8 */
5927 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
5929 movLeft2Result(left, LSB, result, MSB16, 0);
5931 emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
5934 /* 1 <= shCount <= 7 */
5937 shiftL1Left2Result(left, LSB, result, LSB, shCount);
5939 shiftL2Left2Result(left, LSB, result, LSB, shCount);
5943 /*-----------------------------------------------------------------*/
5944 /* shiftLLong - shift left one long from left to result */
5945 /* offl = LSB or MSB16 */
5946 /*-----------------------------------------------------------------*/
5947 static void shiftLLong (operand *left, operand *result, int offr )
5950 int size = AOP_SIZE(result);
5952 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5953 if(size >= LSB+offr){
5954 l = aopGet(AOP(left),LSB,FALSE,FALSE);
5956 pic14_emitcode("add","a,acc");
5957 if (pic14_sameRegs(AOP(left),AOP(result)) &&
5958 size >= MSB16+offr && offr != LSB )
5959 pic14_emitcode("xch","a,%s",
5960 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
5962 aopPut(AOP(result),"a",LSB+offr);
5965 if(size >= MSB16+offr){
5966 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
5967 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
5970 pic14_emitcode("rlc","a");
5971 if (pic14_sameRegs(AOP(left),AOP(result)) &&
5972 size >= MSB24+offr && offr != LSB)
5973 pic14_emitcode("xch","a,%s",
5974 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
5976 aopPut(AOP(result),"a",MSB16+offr);
5979 if(size >= MSB24+offr){
5980 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
5981 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
5984 pic14_emitcode("rlc","a");
5985 if (pic14_sameRegs(AOP(left),AOP(result)) &&
5986 size >= MSB32+offr && offr != LSB )
5987 pic14_emitcode("xch","a,%s",
5988 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
5990 aopPut(AOP(result),"a",MSB24+offr);
5993 if(size > MSB32+offr){
5994 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
5995 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
5998 pic14_emitcode("rlc","a");
5999 aopPut(AOP(result),"a",MSB32+offr);
6002 aopPut(AOP(result),zero,LSB);
6005 /*-----------------------------------------------------------------*/
6006 /* genlshFour - shift four byte by a known amount != 0 */
6007 /*-----------------------------------------------------------------*/
6008 static void genlshFour (operand *result, operand *left, int shCount)
6012 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6013 size = AOP_SIZE(result);
6015 /* if shifting more that 3 bytes */
6016 if (shCount >= 24 ) {
6019 /* lowest order of left goes to the highest
6020 order of the destination */
6021 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6023 movLeft2Result(left, LSB, result, MSB32, 0);
6024 aopPut(AOP(result),zero,LSB);
6025 aopPut(AOP(result),zero,MSB16);
6026 aopPut(AOP(result),zero,MSB32);
6030 /* more than two bytes */
6031 else if ( shCount >= 16 ) {
6032 /* lower order two bytes goes to higher order two bytes */
6034 /* if some more remaining */
6036 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6038 movLeft2Result(left, MSB16, result, MSB32, 0);
6039 movLeft2Result(left, LSB, result, MSB24, 0);
6041 aopPut(AOP(result),zero,MSB16);
6042 aopPut(AOP(result),zero,LSB);
6046 /* if more than 1 byte */
6047 else if ( shCount >= 8 ) {
6048 /* lower order three bytes goes to higher order three bytes */
6052 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6054 movLeft2Result(left, LSB, result, MSB16, 0);
6056 else{ /* size = 4 */
6058 movLeft2Result(left, MSB24, result, MSB32, 0);
6059 movLeft2Result(left, MSB16, result, MSB24, 0);
6060 movLeft2Result(left, LSB, result, MSB16, 0);
6061 aopPut(AOP(result),zero,LSB);
6063 else if(shCount == 1)
6064 shiftLLong(left, result, MSB16);
6066 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6067 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6068 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6069 aopPut(AOP(result),zero,LSB);
6074 /* 1 <= shCount <= 7 */
6075 else if(shCount <= 2){
6076 shiftLLong(left, result, LSB);
6078 shiftLLong(result, result, LSB);
6080 /* 3 <= shCount <= 7, optimize */
6082 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6083 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6084 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6088 /*-----------------------------------------------------------------*/
6089 /* genLeftShiftLiteral - left shifting by known count */
6090 /*-----------------------------------------------------------------*/
6091 static void genLeftShiftLiteral (operand *left,
6096 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6099 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6100 freeAsmop(right,NULL,ic,TRUE);
6102 aopOp(left,ic,FALSE);
6103 aopOp(result,ic,FALSE);
6105 size = getSize(operandType(result));
6108 pic14_emitcode("; shift left ","result %d, left %d",size,
6112 /* I suppose that the left size >= result size */
6115 movLeft2Result(left, size, result, size, 0);
6119 else if(shCount >= (size * 8))
6121 aopPut(AOP(result),zero,size);
6125 genlshOne (result,left,shCount);
6130 genlshTwo (result,left,shCount);
6134 genlshFour (result,left,shCount);
6138 freeAsmop(left,NULL,ic,TRUE);
6139 freeAsmop(result,NULL,ic,TRUE);
6142 /*-----------------------------------------------------------------*/
6143 /* genLeftShift - generates code for left shifting */
6144 /*-----------------------------------------------------------------*/
6145 static void genLeftShift (iCode *ic)
6147 operand *left,*right, *result;
6150 symbol *tlbl , *tlbl1;
6152 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6154 right = IC_RIGHT(ic);
6156 result = IC_RESULT(ic);
6158 aopOp(right,ic,FALSE);
6160 /* if the shift count is known then do it
6161 as efficiently as possible */
6162 if (AOP_TYPE(right) == AOP_LIT) {
6163 genLeftShiftLiteral (left,right,result,ic);
6167 /* shift count is unknown then we have to form
6168 a loop get the loop count in B : Note: we take
6169 only the lower order byte since shifting
6170 more that 32 bits make no sense anyway, ( the
6171 largest size of an object can be only 32 bits ) */
6174 aopOp(left,ic,FALSE);
6175 aopOp(result,ic,FALSE);
6177 /* now move the left to the result if they are not the
6179 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6180 AOP_SIZE(result) > 1) {
6182 size = AOP_SIZE(result);
6185 l = aopGet(AOP(left),offset,FALSE,TRUE);
6186 if (*l == '@' && (IS_AOP_PREG(result))) {
6188 pic14_emitcode("mov","a,%s",l);
6189 aopPut(AOP(result),"a",offset);
6191 aopPut(AOP(result),l,offset);
6196 size = AOP_SIZE(result);
6198 /* if it is only one byte then */
6200 if(optimized_for_speed) {
6201 emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6202 emitpcode(POC_ANDLW, popGetLit(0xf0));
6203 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6204 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6205 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6206 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6207 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6208 emitpcode(POC_RLFW, popGet(AOP(result),0,FALSE,FALSE));
6209 emitpcode(POC_ANDLW, popGetLit(0xfe));
6210 emitpcode(POC_ADDFW, popGet(AOP(result),0,FALSE,FALSE));
6211 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6212 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6215 tlbl = newiTempLabel(NULL);
6216 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6217 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6218 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6221 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6222 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6223 emitpLabel(tlbl->key+100+labelOffset);
6224 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6225 emitpcode(POC_ADDLW, popGetLit(1));
6227 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6233 tlbl = newiTempLabel(NULL);
6235 tlbl1 = newiTempLabel(NULL);
6237 reAdjustPreg(AOP(result));
6239 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6240 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6241 l = aopGet(AOP(result),offset,FALSE,FALSE);
6243 pic14_emitcode("add","a,acc");
6244 aopPut(AOP(result),"a",offset++);
6246 l = aopGet(AOP(result),offset,FALSE,FALSE);
6248 pic14_emitcode("rlc","a");
6249 aopPut(AOP(result),"a",offset++);
6251 reAdjustPreg(AOP(result));
6253 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6254 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6256 freeAsmop (right,NULL,ic,TRUE);
6257 freeAsmop(left,NULL,ic,TRUE);
6258 freeAsmop(result,NULL,ic,TRUE);
6261 /*-----------------------------------------------------------------*/
6262 /* genrshOne - right shift a one byte quantity by known count */
6263 /*-----------------------------------------------------------------*/
6264 static void genrshOne (operand *result, operand *left,
6265 int shCount, int sign)
6267 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6268 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6271 /*-----------------------------------------------------------------*/
6272 /* genrshTwo - right shift two bytes by known amount != 0 */
6273 /*-----------------------------------------------------------------*/
6274 static void genrshTwo (operand *result,operand *left,
6275 int shCount, int sign)
6277 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6278 /* if shCount >= 8 */
6282 shiftR1Left2Result(left, MSB16, result, LSB,
6285 movLeft2Result(left, MSB16, result, LSB, sign);
6286 addSign(result, MSB16, sign);
6289 /* 1 <= shCount <= 7 */
6291 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6294 /*-----------------------------------------------------------------*/
6295 /* shiftRLong - shift right one long from left to result */
6296 /* offl = LSB or MSB16 */
6297 /*-----------------------------------------------------------------*/
6298 static void shiftRLong (operand *left, int offl,
6299 operand *result, int sign)
6301 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6303 pic14_emitcode("clr","c");
6304 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6306 pic14_emitcode("mov","c,acc.7");
6307 pic14_emitcode("rrc","a");
6308 aopPut(AOP(result),"a",MSB32-offl);
6310 /* add sign of "a" */
6311 addSign(result, MSB32, sign);
6313 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6314 pic14_emitcode("rrc","a");
6315 aopPut(AOP(result),"a",MSB24-offl);
6317 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6318 pic14_emitcode("rrc","a");
6319 aopPut(AOP(result),"a",MSB16-offl);
6322 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6323 pic14_emitcode("rrc","a");
6324 aopPut(AOP(result),"a",LSB);
6328 /*-----------------------------------------------------------------*/
6329 /* genrshFour - shift four byte by a known amount != 0 */
6330 /*-----------------------------------------------------------------*/
6331 static void genrshFour (operand *result, operand *left,
6332 int shCount, int sign)
6334 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6335 /* if shifting more that 3 bytes */
6336 if(shCount >= 24 ) {
6339 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6341 movLeft2Result(left, MSB32, result, LSB, sign);
6342 addSign(result, MSB16, sign);
6344 else if(shCount >= 16){
6347 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6349 movLeft2Result(left, MSB24, result, LSB, 0);
6350 movLeft2Result(left, MSB32, result, MSB16, sign);
6352 addSign(result, MSB24, sign);
6354 else if(shCount >= 8){
6357 shiftRLong(left, MSB16, result, sign);
6358 else if(shCount == 0){
6359 movLeft2Result(left, MSB16, result, LSB, 0);
6360 movLeft2Result(left, MSB24, result, MSB16, 0);
6361 movLeft2Result(left, MSB32, result, MSB24, sign);
6362 addSign(result, MSB32, sign);
6365 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6366 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6367 /* the last shift is signed */
6368 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6369 addSign(result, MSB32, sign);
6372 else{ /* 1 <= shCount <= 7 */
6374 shiftRLong(left, LSB, result, sign);
6376 shiftRLong(result, LSB, result, sign);
6379 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6380 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6381 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6386 /*-----------------------------------------------------------------*/
6387 /* genRightShiftLiteral - right shifting by known count */
6388 /*-----------------------------------------------------------------*/
6389 static void genRightShiftLiteral (operand *left,
6395 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6398 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6399 freeAsmop(right,NULL,ic,TRUE);
6401 aopOp(left,ic,FALSE);
6402 aopOp(result,ic,FALSE);
6405 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6409 size = pic14_getDataSize(left);
6410 /* test the LEFT size !!! */
6412 /* I suppose that the left size >= result size */
6414 size = pic14_getDataSize(result);
6416 movLeft2Result(left, size, result, size, 0);
6419 else if(shCount >= (size * 8)){
6421 /* get sign in acc.7 */
6422 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6423 addSign(result, LSB, sign);
6427 genrshOne (result,left,shCount,sign);
6431 genrshTwo (result,left,shCount,sign);
6435 genrshFour (result,left,shCount,sign);
6441 freeAsmop(left,NULL,ic,TRUE);
6442 freeAsmop(result,NULL,ic,TRUE);
6446 /*-----------------------------------------------------------------*/
6447 /* genSignedRightShift - right shift of signed number */
6448 /*-----------------------------------------------------------------*/
6449 static void genSignedRightShift (iCode *ic)
6451 operand *right, *left, *result;
6454 symbol *tlbl, *tlbl1 ;
6456 /* we do it the hard way put the shift count in b
6457 and loop thru preserving the sign */
6458 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6460 right = IC_RIGHT(ic);
6462 result = IC_RESULT(ic);
6464 aopOp(right,ic,FALSE);
6467 if ( AOP_TYPE(right) == AOP_LIT) {
6468 genRightShiftLiteral (left,right,result,ic,1);
6471 /* shift count is unknown then we have to form
6472 a loop get the loop count in B : Note: we take
6473 only the lower order byte since shifting
6474 more that 32 bits make no sense anyway, ( the
6475 largest size of an object can be only 32 bits ) */
6477 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6478 pic14_emitcode("inc","b");
6479 freeAsmop (right,NULL,ic,TRUE);
6480 aopOp(left,ic,FALSE);
6481 aopOp(result,ic,FALSE);
6483 /* now move the left to the result if they are not the
6485 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6486 AOP_SIZE(result) > 1) {
6488 size = AOP_SIZE(result);
6491 l = aopGet(AOP(left),offset,FALSE,TRUE);
6492 if (*l == '@' && IS_AOP_PREG(result)) {
6494 pic14_emitcode("mov","a,%s",l);
6495 aopPut(AOP(result),"a",offset);
6497 aopPut(AOP(result),l,offset);
6502 /* mov the highest order bit to OVR */
6503 tlbl = newiTempLabel(NULL);
6504 tlbl1= newiTempLabel(NULL);
6506 size = AOP_SIZE(result);
6508 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6509 pic14_emitcode("rlc","a");
6510 pic14_emitcode("mov","ov,c");
6511 /* if it is only one byte then */
6513 l = aopGet(AOP(left),0,FALSE,FALSE);
6515 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6516 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6517 pic14_emitcode("mov","c,ov");
6518 pic14_emitcode("rrc","a");
6519 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6520 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6521 aopPut(AOP(result),"a",0);
6525 reAdjustPreg(AOP(result));
6526 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6527 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6528 pic14_emitcode("mov","c,ov");
6530 l = aopGet(AOP(result),offset,FALSE,FALSE);
6532 pic14_emitcode("rrc","a");
6533 aopPut(AOP(result),"a",offset--);
6535 reAdjustPreg(AOP(result));
6536 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6537 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6540 freeAsmop(left,NULL,ic,TRUE);
6541 freeAsmop(result,NULL,ic,TRUE);
6544 /*-----------------------------------------------------------------*/
6545 /* genRightShift - generate code for right shifting */
6546 /*-----------------------------------------------------------------*/
6547 static void genRightShift (iCode *ic)
6549 operand *right, *left, *result;
6553 symbol *tlbl, *tlbl1 ;
6555 /* if signed then we do it the hard way preserve the
6556 sign bit moving it inwards */
6557 retype = getSpec(operandType(IC_RESULT(ic)));
6558 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6560 if (!SPEC_USIGN(retype)) {
6561 genSignedRightShift (ic);
6565 /* signed & unsigned types are treated the same : i.e. the
6566 signed is NOT propagated inwards : quoting from the
6567 ANSI - standard : "for E1 >> E2, is equivalent to division
6568 by 2**E2 if unsigned or if it has a non-negative value,
6569 otherwise the result is implementation defined ", MY definition
6570 is that the sign does not get propagated */
6572 right = IC_RIGHT(ic);
6574 result = IC_RESULT(ic);
6576 aopOp(right,ic,FALSE);
6578 /* if the shift count is known then do it
6579 as efficiently as possible */
6580 if (AOP_TYPE(right) == AOP_LIT) {
6581 genRightShiftLiteral (left,right,result,ic, 0);
6585 /* shift count is unknown then we have to form
6586 a loop get the loop count in B : Note: we take
6587 only the lower order byte since shifting
6588 more that 32 bits make no sense anyway, ( the
6589 largest size of an object can be only 32 bits ) */
6591 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6592 pic14_emitcode("inc","b");
6593 aopOp(left,ic,FALSE);
6594 aopOp(result,ic,FALSE);
6596 /* now move the left to the result if they are not the
6598 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6599 AOP_SIZE(result) > 1) {
6601 size = AOP_SIZE(result);
6604 l = aopGet(AOP(left),offset,FALSE,TRUE);
6605 if (*l == '@' && IS_AOP_PREG(result)) {
6607 pic14_emitcode("mov","a,%s",l);
6608 aopPut(AOP(result),"a",offset);
6610 aopPut(AOP(result),l,offset);
6615 tlbl = newiTempLabel(NULL);
6616 tlbl1= newiTempLabel(NULL);
6617 size = AOP_SIZE(result);
6620 /* if it is only one byte then */
6623 l = aopGet(AOP(left),0,FALSE,FALSE);
6625 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6626 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6628 pic14_emitcode("rrc","a");
6629 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6630 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6631 aopPut(AOP(result),"a",0);
6633 tlbl = newiTempLabel(NULL);
6634 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6635 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6636 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6639 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6640 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6641 emitpLabel(tlbl->key+100+labelOffset);
6642 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6643 emitpcode(POC_ADDLW, popGetLit(1));
6645 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6650 reAdjustPreg(AOP(result));
6651 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6652 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6655 l = aopGet(AOP(result),offset,FALSE,FALSE);
6657 pic14_emitcode("rrc","a");
6658 aopPut(AOP(result),"a",offset--);
6660 reAdjustPreg(AOP(result));
6662 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6663 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6666 freeAsmop(left,NULL,ic,TRUE);
6667 freeAsmop (right,NULL,ic,TRUE);
6668 freeAsmop(result,NULL,ic,TRUE);
6671 /*-----------------------------------------------------------------*/
6672 /* genUnpackBits - generates code for unpacking bits */
6673 /*-----------------------------------------------------------------*/
6674 static void genUnpackBits (operand *result, char *rname, int ptype)
6681 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6682 etype = getSpec(operandType(result));
6684 /* read the first byte */
6689 pic14_emitcode("mov","a,@%s",rname);
6693 pic14_emitcode("movx","a,@%s",rname);
6697 pic14_emitcode("movx","a,@dptr");
6701 pic14_emitcode("clr","a");
6702 pic14_emitcode("movc","a","@a+dptr");
6706 pic14_emitcode("lcall","__gptrget");
6710 /* if we have bitdisplacement then it fits */
6711 /* into this byte completely or if length is */
6712 /* less than a byte */
6713 if ((shCnt = SPEC_BSTR(etype)) ||
6714 (SPEC_BLEN(etype) <= 8)) {
6716 /* shift right acc */
6719 pic14_emitcode("anl","a,#0x%02x",
6720 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6721 aopPut(AOP(result),"a",offset);
6725 /* bit field did not fit in a byte */
6726 rlen = SPEC_BLEN(etype) - 8;
6727 aopPut(AOP(result),"a",offset++);
6734 pic14_emitcode("inc","%s",rname);
6735 pic14_emitcode("mov","a,@%s",rname);
6739 pic14_emitcode("inc","%s",rname);
6740 pic14_emitcode("movx","a,@%s",rname);
6744 pic14_emitcode("inc","dptr");
6745 pic14_emitcode("movx","a,@dptr");
6749 pic14_emitcode("clr","a");
6750 pic14_emitcode("inc","dptr");
6751 pic14_emitcode("movc","a","@a+dptr");
6755 pic14_emitcode("inc","dptr");
6756 pic14_emitcode("lcall","__gptrget");
6761 /* if we are done */
6765 aopPut(AOP(result),"a",offset++);
6770 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
6771 aopPut(AOP(result),"a",offset);
6778 /*-----------------------------------------------------------------*/
6779 /* genDataPointerGet - generates code when ptr offset is known */
6780 /*-----------------------------------------------------------------*/
6781 static void genDataPointerGet (operand *left,
6785 int size , offset = 0;
6788 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6791 /* optimization - most of the time, left and result are the same
6792 * address, but different types. for the pic code, we could omit
6796 aopOp(result,ic,TRUE);
6798 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
6800 size = AOP_SIZE(result);
6803 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
6807 freeAsmop(left,NULL,ic,TRUE);
6808 freeAsmop(result,NULL,ic,TRUE);
6811 /*-----------------------------------------------------------------*/
6812 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
6813 /*-----------------------------------------------------------------*/
6814 static void genNearPointerGet (operand *left,
6821 sym_link *rtype, *retype;
6822 sym_link *ltype = operandType(left);
6825 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6827 rtype = operandType(result);
6828 retype= getSpec(rtype);
6830 aopOp(left,ic,FALSE);
6832 /* if left is rematerialisable and
6833 result is not bit variable type and
6834 the left is pointer to data space i.e
6835 lower 128 bytes of space */
6836 if (AOP_TYPE(left) == AOP_IMMD &&
6837 !IS_BITVAR(retype) &&
6838 DCL_TYPE(ltype) == POINTER) {
6839 genDataPointerGet (left,result,ic);
6843 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6845 /* if the value is already in a pointer register
6846 then don't need anything more */
6847 if (!AOP_INPREG(AOP(left))) {
6848 /* otherwise get a free pointer register */
6849 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6851 preg = getFreePtr(ic,&aop,FALSE);
6852 pic14_emitcode("mov","%s,%s",
6854 aopGet(AOP(left),0,FALSE,TRUE));
6855 rname = preg->name ;
6857 rname = aopGet(AOP(left),0,FALSE,FALSE);
6859 freeAsmop(left,NULL,ic,TRUE);
6860 aopOp (result,ic,FALSE);
6862 /* if bitfield then unpack the bits */
6863 if (IS_BITVAR(retype))
6864 genUnpackBits (result,rname,POINTER);
6866 /* we have can just get the values */
6867 int size = AOP_SIZE(result);
6870 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6872 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
6874 pic14_emitcode("mov","a,@%s",rname);
6875 aopPut(AOP(result),"a",offset);
6877 sprintf(buffer,"@%s",rname);
6878 aopPut(AOP(result),buffer,offset);
6882 pic14_emitcode("inc","%s",rname);
6886 /* now some housekeeping stuff */
6888 /* we had to allocate for this iCode */
6889 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6890 freeAsmop(NULL,aop,ic,TRUE);
6892 /* we did not allocate which means left
6893 already in a pointer register, then
6894 if size > 0 && this could be used again
6895 we have to point it back to where it
6897 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6898 if (AOP_SIZE(result) > 1 &&
6899 !OP_SYMBOL(left)->remat &&
6900 ( OP_SYMBOL(left)->liveTo > ic->seq ||
6902 int size = AOP_SIZE(result) - 1;
6904 pic14_emitcode("dec","%s",rname);
6909 freeAsmop(result,NULL,ic,TRUE);
6913 /*-----------------------------------------------------------------*/
6914 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
6915 /*-----------------------------------------------------------------*/
6916 static void genPagedPointerGet (operand *left,
6923 sym_link *rtype, *retype;
6925 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6927 rtype = operandType(result);
6928 retype= getSpec(rtype);
6930 aopOp(left,ic,FALSE);
6932 /* if the value is already in a pointer register
6933 then don't need anything more */
6934 if (!AOP_INPREG(AOP(left))) {
6935 /* otherwise get a free pointer register */
6937 preg = getFreePtr(ic,&aop,FALSE);
6938 pic14_emitcode("mov","%s,%s",
6940 aopGet(AOP(left),0,FALSE,TRUE));
6941 rname = preg->name ;
6943 rname = aopGet(AOP(left),0,FALSE,FALSE);
6945 freeAsmop(left,NULL,ic,TRUE);
6946 aopOp (result,ic,FALSE);
6948 /* if bitfield then unpack the bits */
6949 if (IS_BITVAR(retype))
6950 genUnpackBits (result,rname,PPOINTER);
6952 /* we have can just get the values */
6953 int size = AOP_SIZE(result);
6958 pic14_emitcode("movx","a,@%s",rname);
6959 aopPut(AOP(result),"a",offset);
6964 pic14_emitcode("inc","%s",rname);
6968 /* now some housekeeping stuff */
6970 /* we had to allocate for this iCode */
6971 freeAsmop(NULL,aop,ic,TRUE);
6973 /* we did not allocate which means left
6974 already in a pointer register, then
6975 if size > 0 && this could be used again
6976 we have to point it back to where it
6978 if (AOP_SIZE(result) > 1 &&
6979 !OP_SYMBOL(left)->remat &&
6980 ( OP_SYMBOL(left)->liveTo > ic->seq ||
6982 int size = AOP_SIZE(result) - 1;
6984 pic14_emitcode("dec","%s",rname);
6989 freeAsmop(result,NULL,ic,TRUE);
6994 /*-----------------------------------------------------------------*/
6995 /* genFarPointerGet - gget value from far space */
6996 /*-----------------------------------------------------------------*/
6997 static void genFarPointerGet (operand *left,
6998 operand *result, iCode *ic)
7001 sym_link *retype = getSpec(operandType(result));
7003 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7005 aopOp(left,ic,FALSE);
7007 /* if the operand is already in dptr
7008 then we do nothing else we move the value to dptr */
7009 if (AOP_TYPE(left) != AOP_STR) {
7010 /* if this is remateriazable */
7011 if (AOP_TYPE(left) == AOP_IMMD)
7012 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7013 else { /* we need to get it byte by byte */
7014 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7015 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7016 if (options.model == MODEL_FLAT24)
7018 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7022 /* so dptr know contains the address */
7023 freeAsmop(left,NULL,ic,TRUE);
7024 aopOp(result,ic,FALSE);
7026 /* if bit then unpack */
7027 if (IS_BITVAR(retype))
7028 genUnpackBits(result,"dptr",FPOINTER);
7030 size = AOP_SIZE(result);
7034 pic14_emitcode("movx","a,@dptr");
7035 aopPut(AOP(result),"a",offset++);
7037 pic14_emitcode("inc","dptr");
7041 freeAsmop(result,NULL,ic,TRUE);
7044 /*-----------------------------------------------------------------*/
7045 /* pic14_emitcodePointerGet - gget value from code space */
7046 /*-----------------------------------------------------------------*/
7047 static void pic14_emitcodePointerGet (operand *left,
7048 operand *result, iCode *ic)
7051 sym_link *retype = getSpec(operandType(result));
7053 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7055 aopOp(left,ic,FALSE);
7057 /* if the operand is already in dptr
7058 then we do nothing else we move the value to dptr */
7059 if (AOP_TYPE(left) != AOP_STR) {
7060 /* if this is remateriazable */
7061 if (AOP_TYPE(left) == AOP_IMMD)
7062 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7063 else { /* we need to get it byte by byte */
7064 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7065 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7066 if (options.model == MODEL_FLAT24)
7068 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7072 /* so dptr know contains the address */
7073 freeAsmop(left,NULL,ic,TRUE);
7074 aopOp(result,ic,FALSE);
7076 /* if bit then unpack */
7077 if (IS_BITVAR(retype))
7078 genUnpackBits(result,"dptr",CPOINTER);
7080 size = AOP_SIZE(result);
7084 pic14_emitcode("clr","a");
7085 pic14_emitcode("movc","a,@a+dptr");
7086 aopPut(AOP(result),"a",offset++);
7088 pic14_emitcode("inc","dptr");
7092 freeAsmop(result,NULL,ic,TRUE);
7095 /*-----------------------------------------------------------------*/
7096 /* genGenPointerGet - gget value from generic pointer space */
7097 /*-----------------------------------------------------------------*/
7098 static void genGenPointerGet (operand *left,
7099 operand *result, iCode *ic)
7102 sym_link *retype = getSpec(operandType(result));
7104 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7105 aopOp(left,ic,FALSE);
7107 /* if the operand is already in dptr
7108 then we do nothing else we move the value to dptr */
7109 if (AOP_TYPE(left) != AOP_STR) {
7110 /* if this is remateriazable */
7111 if (AOP_TYPE(left) == AOP_IMMD) {
7112 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7113 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7115 else { /* we need to get it byte by byte */
7116 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7117 //emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
7118 //emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7119 pic14_emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
7120 pic14_emitcode("movwf","FSR");
7122 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7123 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7124 if (options.model == MODEL_FLAT24)
7126 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7127 pic14_emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
7131 pic14_emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
7136 /* so dptr know contains the address */
7137 freeAsmop(left,NULL,ic,TRUE);
7138 aopOp(result,ic,FALSE);
7140 /* if bit then unpack */
7141 if (IS_BITVAR(retype))
7142 genUnpackBits(result,"dptr",GPOINTER);
7144 size = AOP_SIZE(result);
7148 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7150 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7152 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7154 pic14_emitcode("movf","indf,w");
7155 pic14_emitcode("movwf","%s",
7156 aopGet(AOP(result),offset++,FALSE,FALSE));
7158 pic14_emitcode("incf","fsr,f");
7163 freeAsmop(result,NULL,ic,TRUE);
7166 /*-----------------------------------------------------------------*/
7167 /* genPointerGet - generate code for pointer get */
7168 /*-----------------------------------------------------------------*/
7169 static void genPointerGet (iCode *ic)
7171 operand *left, *result ;
7172 sym_link *type, *etype;
7175 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7178 result = IC_RESULT(ic) ;
7180 /* depending on the type of pointer we need to
7181 move it to the correct pointer register */
7182 type = operandType(left);
7183 etype = getSpec(type);
7184 /* if left is of type of pointer then it is simple */
7185 if (IS_PTR(type) && !IS_FUNC(type->next))
7186 p_type = DCL_TYPE(type);
7188 /* we have to go by the storage class */
7189 p_type = PTR_TYPE(SPEC_OCLS(etype));
7191 /* if (SPEC_OCLS(etype)->codesp ) { */
7192 /* p_type = CPOINTER ; */
7195 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7196 /* p_type = FPOINTER ; */
7198 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7199 /* p_type = PPOINTER; */
7201 /* if (SPEC_OCLS(etype) == idata ) */
7202 /* p_type = IPOINTER; */
7204 /* p_type = POINTER ; */
7207 /* now that we have the pointer type we assign
7208 the pointer values */
7213 genNearPointerGet (left,result,ic);
7217 genPagedPointerGet(left,result,ic);
7221 genFarPointerGet (left,result,ic);
7225 pic14_emitcodePointerGet (left,result,ic);
7229 genGenPointerGet (left,result,ic);
7235 /*-----------------------------------------------------------------*/
7236 /* genPackBits - generates code for packed bit storage */
7237 /*-----------------------------------------------------------------*/
7238 static void genPackBits (sym_link *etype ,
7240 char *rname, int p_type)
7248 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7249 blen = SPEC_BLEN(etype);
7250 bstr = SPEC_BSTR(etype);
7252 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7255 /* if the bit lenth is less than or */
7256 /* it exactly fits a byte then */
7257 if (SPEC_BLEN(etype) <= 8 ) {
7258 shCount = SPEC_BSTR(etype) ;
7260 /* shift left acc */
7263 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7268 pic14_emitcode ("mov","b,a");
7269 pic14_emitcode("mov","a,@%s",rname);
7273 pic14_emitcode ("mov","b,a");
7274 pic14_emitcode("movx","a,@dptr");
7278 pic14_emitcode ("push","b");
7279 pic14_emitcode ("push","acc");
7280 pic14_emitcode ("lcall","__gptrget");
7281 pic14_emitcode ("pop","b");
7285 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7286 ((unsigned char)(0xFF << (blen+bstr)) |
7287 (unsigned char)(0xFF >> (8-bstr)) ) );
7288 pic14_emitcode ("orl","a,b");
7289 if (p_type == GPOINTER)
7290 pic14_emitcode("pop","b");
7296 pic14_emitcode("mov","@%s,a",rname);
7300 pic14_emitcode("movx","@dptr,a");
7304 DEBUGpic14_emitcode(";lcall","__gptrput");
7309 if ( SPEC_BLEN(etype) <= 8 )
7312 pic14_emitcode("inc","%s",rname);
7313 rLen = SPEC_BLEN(etype) ;
7315 /* now generate for lengths greater than one byte */
7318 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7328 pic14_emitcode("mov","@%s,a",rname);
7330 pic14_emitcode("mov","@%s,%s",rname,l);
7335 pic14_emitcode("movx","@dptr,a");
7340 DEBUGpic14_emitcode(";lcall","__gptrput");
7343 pic14_emitcode ("inc","%s",rname);
7348 /* last last was not complete */
7350 /* save the byte & read byte */
7353 pic14_emitcode ("mov","b,a");
7354 pic14_emitcode("mov","a,@%s",rname);
7358 pic14_emitcode ("mov","b,a");
7359 pic14_emitcode("movx","a,@dptr");
7363 pic14_emitcode ("push","b");
7364 pic14_emitcode ("push","acc");
7365 pic14_emitcode ("lcall","__gptrget");
7366 pic14_emitcode ("pop","b");
7370 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7371 pic14_emitcode ("orl","a,b");
7374 if (p_type == GPOINTER)
7375 pic14_emitcode("pop","b");
7380 pic14_emitcode("mov","@%s,a",rname);
7384 pic14_emitcode("movx","@dptr,a");
7388 DEBUGpic14_emitcode(";lcall","__gptrput");
7392 /*-----------------------------------------------------------------*/
7393 /* genDataPointerSet - remat pointer to data space */
7394 /*-----------------------------------------------------------------*/
7395 static void genDataPointerSet(operand *right,
7399 int size, offset = 0 ;
7400 char *l, buffer[256];
7402 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7403 aopOp(right,ic,FALSE);
7405 l = aopGet(AOP(result),0,FALSE,TRUE);
7406 size = AOP_SIZE(right);
7407 // tsd, was l+1 - the underline `_' prefix was being stripped
7410 sprintf(buffer,"(%s + %d)",l,offset);
7412 sprintf(buffer,"%s",l);
7414 if (AOP_TYPE(right) == AOP_LIT) {
7415 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7416 lit = lit >> (8*offset);
7418 pic14_emitcode("movlw","%d",lit);
7419 pic14_emitcode("movwf","%s",buffer);
7421 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7422 emitpcode(POC_MOVWF, popRegFromString(buffer));
7425 pic14_emitcode("clrf","%s",buffer);
7426 emitpcode(POC_CLRF, popRegFromString(buffer));
7429 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7430 pic14_emitcode("movwf","%s",buffer);
7432 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7433 emitpcode(POC_MOVWF, popRegFromString(buffer));
7440 freeAsmop(right,NULL,ic,TRUE);
7441 freeAsmop(result,NULL,ic,TRUE);
7444 /*-----------------------------------------------------------------*/
7445 /* genNearPointerSet - pic14_emitcode for near pointer put */
7446 /*-----------------------------------------------------------------*/
7447 static void genNearPointerSet (operand *right,
7454 sym_link *ptype = operandType(result);
7457 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7458 retype= getSpec(operandType(right));
7460 aopOp(result,ic,FALSE);
7462 /* if the result is rematerializable &
7463 in data space & not a bit variable */
7464 if (AOP_TYPE(result) == AOP_IMMD &&
7465 DCL_TYPE(ptype) == POINTER &&
7466 !IS_BITVAR(retype)) {
7467 genDataPointerSet (right,result,ic);
7471 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7473 /* if the value is already in a pointer register
7474 then don't need anything more */
7475 if (!AOP_INPREG(AOP(result))) {
7476 /* otherwise get a free pointer register */
7477 //aop = newAsmop(0);
7478 //preg = getFreePtr(ic,&aop,FALSE);
7479 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7480 //pic14_emitcode("mov","%s,%s",
7482 // aopGet(AOP(result),0,FALSE,TRUE));
7483 //rname = preg->name ;
7484 pic14_emitcode("movwf","fsr");
7486 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7488 freeAsmop(result,NULL,ic,TRUE);
7489 aopOp (right,ic,FALSE);
7490 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7492 /* if bitfield then unpack the bits */
7493 if (IS_BITVAR(retype)) {
7494 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7495 "The programmer is obviously confused");
7496 //genPackBits (retype,right,rname,POINTER);
7500 /* we have can just get the values */
7501 int size = AOP_SIZE(right);
7504 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7506 l = aopGet(AOP(right),offset,FALSE,TRUE);
7509 //pic14_emitcode("mov","@%s,a",rname);
7510 pic14_emitcode("movf","indf,w ;1");
7513 if (AOP_TYPE(right) == AOP_LIT) {
7514 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7516 pic14_emitcode("movlw","%s",l);
7517 pic14_emitcode("movwf","indf ;2");
7519 pic14_emitcode("clrf","indf");
7521 pic14_emitcode("movf","%s,w",l);
7522 pic14_emitcode("movwf","indf ;2");
7524 //pic14_emitcode("mov","@%s,%s",rname,l);
7527 pic14_emitcode("incf","fsr,f ;3");
7528 //pic14_emitcode("inc","%s",rname);
7533 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7534 /* now some housekeeping stuff */
7536 /* we had to allocate for this iCode */
7537 freeAsmop(NULL,aop,ic,TRUE);
7539 /* we did not allocate which means left
7540 already in a pointer register, then
7541 if size > 0 && this could be used again
7542 we have to point it back to where it
7544 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7545 if (AOP_SIZE(right) > 1 &&
7546 !OP_SYMBOL(result)->remat &&
7547 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7549 int size = AOP_SIZE(right) - 1;
7551 pic14_emitcode("decf","fsr,f");
7552 //pic14_emitcode("dec","%s",rname);
7556 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7558 freeAsmop(right,NULL,ic,TRUE);
7563 /*-----------------------------------------------------------------*/
7564 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7565 /*-----------------------------------------------------------------*/
7566 static void genPagedPointerSet (operand *right,
7575 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7577 retype= getSpec(operandType(right));
7579 aopOp(result,ic,FALSE);
7581 /* if the value is already in a pointer register
7582 then don't need anything more */
7583 if (!AOP_INPREG(AOP(result))) {
7584 /* otherwise get a free pointer register */
7586 preg = getFreePtr(ic,&aop,FALSE);
7587 pic14_emitcode("mov","%s,%s",
7589 aopGet(AOP(result),0,FALSE,TRUE));
7590 rname = preg->name ;
7592 rname = aopGet(AOP(result),0,FALSE,FALSE);
7594 freeAsmop(result,NULL,ic,TRUE);
7595 aopOp (right,ic,FALSE);
7597 /* if bitfield then unpack the bits */
7598 if (IS_BITVAR(retype))
7599 genPackBits (retype,right,rname,PPOINTER);
7601 /* we have can just get the values */
7602 int size = AOP_SIZE(right);
7606 l = aopGet(AOP(right),offset,FALSE,TRUE);
7609 pic14_emitcode("movx","@%s,a",rname);
7612 pic14_emitcode("inc","%s",rname);
7618 /* now some housekeeping stuff */
7620 /* we had to allocate for this iCode */
7621 freeAsmop(NULL,aop,ic,TRUE);
7623 /* we did not allocate which means left
7624 already in a pointer register, then
7625 if size > 0 && this could be used again
7626 we have to point it back to where it
7628 if (AOP_SIZE(right) > 1 &&
7629 !OP_SYMBOL(result)->remat &&
7630 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7632 int size = AOP_SIZE(right) - 1;
7634 pic14_emitcode("dec","%s",rname);
7639 freeAsmop(right,NULL,ic,TRUE);
7644 /*-----------------------------------------------------------------*/
7645 /* genFarPointerSet - set value from far space */
7646 /*-----------------------------------------------------------------*/
7647 static void genFarPointerSet (operand *right,
7648 operand *result, iCode *ic)
7651 sym_link *retype = getSpec(operandType(right));
7653 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7654 aopOp(result,ic,FALSE);
7656 /* if the operand is already in dptr
7657 then we do nothing else we move the value to dptr */
7658 if (AOP_TYPE(result) != AOP_STR) {
7659 /* if this is remateriazable */
7660 if (AOP_TYPE(result) == AOP_IMMD)
7661 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7662 else { /* we need to get it byte by byte */
7663 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7664 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7665 if (options.model == MODEL_FLAT24)
7667 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7671 /* so dptr know contains the address */
7672 freeAsmop(result,NULL,ic,TRUE);
7673 aopOp(right,ic,FALSE);
7675 /* if bit then unpack */
7676 if (IS_BITVAR(retype))
7677 genPackBits(retype,right,"dptr",FPOINTER);
7679 size = AOP_SIZE(right);
7683 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7685 pic14_emitcode("movx","@dptr,a");
7687 pic14_emitcode("inc","dptr");
7691 freeAsmop(right,NULL,ic,TRUE);
7694 /*-----------------------------------------------------------------*/
7695 /* genGenPointerSet - set value from generic pointer space */
7696 /*-----------------------------------------------------------------*/
7697 static void genGenPointerSet (operand *right,
7698 operand *result, iCode *ic)
7701 sym_link *retype = getSpec(operandType(right));
7703 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7705 aopOp(result,ic,FALSE);
7707 /* if the operand is already in dptr
7708 then we do nothing else we move the value to dptr */
7709 if (AOP_TYPE(result) != AOP_STR) {
7710 /* if this is remateriazable */
7711 if (AOP_TYPE(result) == AOP_IMMD) {
7712 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7713 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7715 else { /* we need to get it byte by byte */
7716 char *l = aopGet(AOP(result),0,FALSE,FALSE);
7719 emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
7720 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7723 pic14_emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
7725 pic14_emitcode("movwf","INDF");
7728 /* so dptr know contains the address */
7729 freeAsmop(result,NULL,ic,TRUE);
7730 aopOp(right,ic,FALSE);
7732 /* if bit then unpack */
7733 if (IS_BITVAR(retype))
7734 genPackBits(retype,right,"dptr",GPOINTER);
7736 size = AOP_SIZE(right);
7740 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7742 pic14_emitcode("incf","fsr,f");
7743 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
7744 pic14_emitcode("movwf","indf");
7746 //DEBUGpic14_emitcode(";lcall","__gptrput");
7748 // pic14_emitcode("inc","dptr");
7752 freeAsmop(right,NULL,ic,TRUE);
7755 /*-----------------------------------------------------------------*/
7756 /* genPointerSet - stores the value into a pointer location */
7757 /*-----------------------------------------------------------------*/
7758 static void genPointerSet (iCode *ic)
7760 operand *right, *result ;
7761 sym_link *type, *etype;
7764 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7766 right = IC_RIGHT(ic);
7767 result = IC_RESULT(ic) ;
7769 /* depending on the type of pointer we need to
7770 move it to the correct pointer register */
7771 type = operandType(result);
7772 etype = getSpec(type);
7773 /* if left is of type of pointer then it is simple */
7774 if (IS_PTR(type) && !IS_FUNC(type->next)) {
7775 p_type = DCL_TYPE(type);
7778 /* we have to go by the storage class */
7779 p_type = PTR_TYPE(SPEC_OCLS(etype));
7781 /* if (SPEC_OCLS(etype)->codesp ) { */
7782 /* p_type = CPOINTER ; */
7785 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7786 /* p_type = FPOINTER ; */
7788 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7789 /* p_type = PPOINTER ; */
7791 /* if (SPEC_OCLS(etype) == idata ) */
7792 /* p_type = IPOINTER ; */
7794 /* p_type = POINTER ; */
7797 /* now that we have the pointer type we assign
7798 the pointer values */
7803 genNearPointerSet (right,result,ic);
7807 genPagedPointerSet (right,result,ic);
7811 genFarPointerSet (right,result,ic);
7815 genGenPointerSet (right,result,ic);
7821 /*-----------------------------------------------------------------*/
7822 /* genIfx - generate code for Ifx statement */
7823 /*-----------------------------------------------------------------*/
7824 static void genIfx (iCode *ic, iCode *popIc)
7826 operand *cond = IC_COND(ic);
7829 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7830 aopOp(cond,ic,FALSE);
7832 /* get the value into acc */
7833 if (AOP_TYPE(cond) != AOP_CRY)
7834 pic14_toBoolean(cond);
7837 /* the result is now in the accumulator */
7838 freeAsmop(cond,NULL,ic,TRUE);
7840 /* if there was something to be popped then do it */
7844 /* if the condition is a bit variable */
7845 if (isbit && IS_ITEMP(cond) &&
7847 genIfxJump(ic,SPIL_LOC(cond)->rname);
7848 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
7852 if (isbit && !IS_ITEMP(cond))
7853 DEBUGpic14_emitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
7855 DEBUGpic14_emitcode ("; isbit","a");
7858 if (isbit && !IS_ITEMP(cond))
7859 genIfxJump(ic,OP_SYMBOL(cond)->rname);
7866 /*-----------------------------------------------------------------*/
7867 /* genAddrOf - generates code for address of */
7868 /*-----------------------------------------------------------------*/
7869 static void genAddrOf (iCode *ic)
7871 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
7874 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7876 aopOp(IC_RESULT(ic),ic,FALSE);
7878 /* if the operand is on the stack then we
7879 need to get the stack offset of this
7882 /* if it has an offset then we need to compute
7885 pic14_emitcode("mov","a,_bp");
7886 pic14_emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
7887 aopPut(AOP(IC_RESULT(ic)),"a",0);
7889 /* we can just move _bp */
7890 aopPut(AOP(IC_RESULT(ic)),"_bp",0);
7892 /* fill the result with zero */
7893 size = AOP_SIZE(IC_RESULT(ic)) - 1;
7896 if (options.stack10bit && size < (FPTRSIZE - 1))
7899 "*** warning: pointer to stack var truncated.\n");
7906 if (options.stack10bit && offset == 2)
7908 aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
7912 aopPut(AOP(IC_RESULT(ic)),zero,offset++);
7919 /* object not on stack then we need the name */
7920 size = AOP_SIZE(IC_RESULT(ic));
7924 char s[SDCC_NAME_MAX];
7926 sprintf(s,"#(%s >> %d)",
7930 sprintf(s,"#%s",sym->rname);
7931 aopPut(AOP(IC_RESULT(ic)),s,offset++);
7935 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
7940 /*-----------------------------------------------------------------*/
7941 /* genFarFarAssign - assignment when both are in far space */
7942 /*-----------------------------------------------------------------*/
7943 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
7945 int size = AOP_SIZE(right);
7948 /* first push the right side on to the stack */
7950 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7952 pic14_emitcode ("push","acc");
7955 freeAsmop(right,NULL,ic,FALSE);
7956 /* now assign DPTR to result */
7957 aopOp(result,ic,FALSE);
7958 size = AOP_SIZE(result);
7960 pic14_emitcode ("pop","acc");
7961 aopPut(AOP(result),"a",--offset);
7963 freeAsmop(result,NULL,ic,FALSE);
7968 /*-----------------------------------------------------------------*/
7969 /* genAssign - generate code for assignment */
7970 /*-----------------------------------------------------------------*/
7971 static void genAssign (iCode *ic)
7973 operand *result, *right;
7975 unsigned long lit = 0L;
7977 result = IC_RESULT(ic);
7978 right = IC_RIGHT(ic) ;
7980 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7982 /* if they are the same */
7983 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
7986 aopOp(right,ic,FALSE);
7987 aopOp(result,ic,TRUE);
7989 /* if they are the same registers */
7990 if (pic14_sameRegs(AOP(right),AOP(result)))
7993 /* if the result is a bit */
7994 if (AOP_TYPE(result) == AOP_CRY) {
7996 /* if the right size is a literal then
7997 we know what the value is */
7998 if (AOP_TYPE(right) == AOP_LIT) {
8000 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8001 popGet(AOP(result),0,FALSE,FALSE));
8003 if (((int) operandLitValue(right)))
8004 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8005 AOP(result)->aopu.aop_dir,
8006 AOP(result)->aopu.aop_dir);
8008 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8009 AOP(result)->aopu.aop_dir,
8010 AOP(result)->aopu.aop_dir);
8014 /* the right is also a bit variable */
8015 if (AOP_TYPE(right) == AOP_CRY) {
8016 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8017 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8018 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8020 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8021 AOP(result)->aopu.aop_dir,
8022 AOP(result)->aopu.aop_dir);
8023 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8024 AOP(right)->aopu.aop_dir,
8025 AOP(right)->aopu.aop_dir);
8026 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8027 AOP(result)->aopu.aop_dir,
8028 AOP(result)->aopu.aop_dir);
8033 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8034 pic14_toBoolean(right);
8036 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8037 //aopPut(AOP(result),"a",0);
8041 /* bit variables done */
8043 size = AOP_SIZE(result);
8045 if(AOP_TYPE(right) == AOP_LIT)
8046 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8047 if((AOP_TYPE(result) != AOP_REG) &&
8048 (AOP_TYPE(right) == AOP_LIT) &&
8049 !IS_FLOAT(operandType(right)) &&
8053 if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) {
8054 //pic14_emitcode("clrf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8055 emitpcode(POC_CLRF,popGet(AOP(result),size,FALSE,FALSE));
8057 emitpcode(POC_MOVLW,popGet(AOP(right),size,FALSE,FALSE));
8058 emitpcode(POC_MOVWF,popGet(AOP(result),size,FALSE,FALSE));
8059 //pic14_emitcode("movlw","%s", aopGet(AOP(right),size,FALSE,FALSE));
8060 //pic14_emitcode("movwf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8065 if(AOP_TYPE(right) == AOP_LIT) {
8066 emitpcode(POC_MOVLW, popGet(AOP(right),offset,FALSE,FALSE));
8067 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8069 } else if (AOP_TYPE(right) == AOP_CRY) {
8070 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8072 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8073 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8076 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8077 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8080 //pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE));
8086 freeAsmop (right,NULL,ic,FALSE);
8087 freeAsmop (result,NULL,ic,TRUE);
8090 /*-----------------------------------------------------------------*/
8091 /* genJumpTab - genrates code for jump table */
8092 /*-----------------------------------------------------------------*/
8093 static void genJumpTab (iCode *ic)
8098 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8100 aopOp(IC_JTCOND(ic),ic,FALSE);
8101 /* get the condition into accumulator */
8102 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8104 /* multiply by three */
8105 pic14_emitcode("add","a,acc");
8106 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8108 jtab = newiTempLabel(NULL);
8109 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8110 pic14_emitcode("jmp","@a+dptr");
8111 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8113 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8114 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8116 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8117 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8118 emitpLabel(jtab->key+100+labelOffset);
8120 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8122 /* now generate the jump labels */
8123 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8124 jtab = setNextItem(IC_JTLABELS(ic))) {
8125 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8126 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8132 /*-----------------------------------------------------------------*/
8133 /* genMixedOperation - gen code for operators between mixed types */
8134 /*-----------------------------------------------------------------*/
8136 TSD - Written for the PIC port - but this unfortunately is buggy.
8137 This routine is good in that it is able to efficiently promote
8138 types to different (larger) sizes. Unfortunately, the temporary
8139 variables that are optimized out by this routine are sometimes
8140 used in other places. So until I know how to really parse the
8141 iCode tree, I'm going to not be using this routine :(.
8143 static int genMixedOperation (iCode *ic)
8146 operand *result = IC_RESULT(ic);
8147 sym_link *ctype = operandType(IC_LEFT(ic));
8148 operand *right = IC_RIGHT(ic);
8154 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8156 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8162 nextright = IC_RIGHT(nextic);
8163 nextleft = IC_LEFT(nextic);
8164 nextresult = IC_RESULT(nextic);
8166 aopOp(right,ic,FALSE);
8167 aopOp(result,ic,FALSE);
8168 aopOp(nextright, nextic, FALSE);
8169 aopOp(nextleft, nextic, FALSE);
8170 aopOp(nextresult, nextic, FALSE);
8172 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8178 pic14_emitcode(";remove right +","");
8180 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8186 pic14_emitcode(";remove left +","");
8190 big = AOP_SIZE(nextleft);
8191 small = AOP_SIZE(nextright);
8193 switch(nextic->op) {
8196 pic14_emitcode(";optimize a +","");
8197 /* if unsigned or not an integral type */
8198 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8199 pic14_emitcode(";add a bit to something","");
8202 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8204 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8205 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8206 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8208 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8216 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8217 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8218 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8221 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8223 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8224 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8225 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8226 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8227 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8230 pic14_emitcode("rlf","known_zero,w");
8237 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8238 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8239 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8241 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8251 freeAsmop(right,NULL,ic,TRUE);
8252 freeAsmop(result,NULL,ic,TRUE);
8253 freeAsmop(nextright,NULL,ic,TRUE);
8254 freeAsmop(nextleft,NULL,ic,TRUE);
8256 nextic->generated = 1;
8263 /*-----------------------------------------------------------------*/
8264 /* genCast - gen code for casting */
8265 /*-----------------------------------------------------------------*/
8266 static void genCast (iCode *ic)
8268 operand *result = IC_RESULT(ic);
8269 sym_link *ctype = operandType(IC_LEFT(ic));
8270 operand *right = IC_RIGHT(ic);
8273 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8274 /* if they are equivalent then do nothing */
8275 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8278 aopOp(right,ic,FALSE) ;
8279 aopOp(result,ic,FALSE);
8281 /* if the result is a bit */
8282 if (AOP_TYPE(result) == AOP_CRY) {
8283 /* if the right size is a literal then
8284 we know what the value is */
8285 if (AOP_TYPE(right) == AOP_LIT) {
8287 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8288 popGet(AOP(result),0,FALSE,FALSE));
8290 if (((int) operandLitValue(right)))
8291 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8292 AOP(result)->aopu.aop_dir,
8293 AOP(result)->aopu.aop_dir);
8295 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8296 AOP(result)->aopu.aop_dir,
8297 AOP(result)->aopu.aop_dir);
8302 /* the right is also a bit variable */
8303 if (AOP_TYPE(right) == AOP_CRY) {
8306 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8308 pic14_emitcode("clrc","");
8309 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8310 AOP(right)->aopu.aop_dir,
8311 AOP(right)->aopu.aop_dir);
8312 aopPut(AOP(result),"c",0);
8317 pic14_toBoolean(right);
8318 aopPut(AOP(result),"a",0);
8322 /* if they are the same size : or less */
8323 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8325 /* if they are in the same place */
8326 if (pic14_sameRegs(AOP(right),AOP(result)))
8329 /* if they in different places then copy */
8330 size = AOP_SIZE(result);
8334 aopGet(AOP(right),offset,FALSE,FALSE),
8342 /* if the result is of type pointer */
8343 if (IS_PTR(ctype)) {
8346 sym_link *type = operandType(right);
8347 sym_link *etype = getSpec(type);
8349 /* pointer to generic pointer */
8350 if (IS_GENPTR(ctype)) {
8354 p_type = DCL_TYPE(type);
8356 /* we have to go by the storage class */
8357 p_type = PTR_TYPE(SPEC_OCLS(etype));
8359 /* if (SPEC_OCLS(etype)->codesp ) */
8360 /* p_type = CPOINTER ; */
8362 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8363 /* p_type = FPOINTER ; */
8365 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8366 /* p_type = PPOINTER; */
8368 /* if (SPEC_OCLS(etype) == idata ) */
8369 /* p_type = IPOINTER ; */
8371 /* p_type = POINTER ; */
8374 /* the first two bytes are known */
8375 size = GPTRSIZE - 1;
8379 aopGet(AOP(right),offset,FALSE,FALSE),
8383 /* the last byte depending on type */
8400 /* this should never happen */
8401 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8402 "got unknown pointer type");
8405 aopPut(AOP(result),l, GPTRSIZE - 1);
8409 /* just copy the pointers */
8410 size = AOP_SIZE(result);
8414 aopGet(AOP(right),offset,FALSE,FALSE),
8422 if (AOP_TYPE(right) == AOP_CRY) {
8424 size = AOP_SIZE(right);
8426 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8427 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8428 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8430 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8431 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8432 AOP(right)->aopu.aop_dir,
8433 AOP(right)->aopu.aop_dir);
8434 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8436 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8437 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8442 /* so we now know that the size of destination is greater
8443 than the size of the source.
8444 Now, if the next iCode is an operator then we might be
8445 able to optimize the operation without performing a cast.
8447 if(genMixedOperation(ic))
8451 /* we move to result for the size of source */
8452 size = AOP_SIZE(right);
8455 pic14_emitcode(";","%d",__LINE__);
8457 aopGet(AOP(right),offset,FALSE,FALSE),
8462 /* now depending on the sign of the destination */
8463 size = AOP_SIZE(result) - AOP_SIZE(right);
8464 /* if unsigned or not an integral type */
8465 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8467 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8468 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8472 /* we need to extend the sign :{ */
8473 //char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,FALSE,FALSE);
8476 emitpcode(POC_CLRW, NULL);
8477 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8478 emitpcode(POC_MOVLW, popGetLit(0xff));
8480 pic14_emitcode("clrw","");
8481 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8482 AOP(right)->aopu.aop_dir,
8483 AOP(right)->aopu.aop_dir);
8484 pic14_emitcode("movlw","0xff");
8486 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8487 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8489 // aopPut(AOP(result),"a",offset++);
8494 /* we are done hurray !!!! */
8497 freeAsmop(right,NULL,ic,TRUE);
8498 freeAsmop(result,NULL,ic,TRUE);
8502 /*-----------------------------------------------------------------*/
8503 /* genDjnz - generate decrement & jump if not zero instrucion */
8504 /*-----------------------------------------------------------------*/
8505 static int genDjnz (iCode *ic, iCode *ifx)
8508 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8513 /* if the if condition has a false label
8514 then we cannot save */
8518 /* if the minus is not of the form
8520 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8521 !IS_OP_LITERAL(IC_RIGHT(ic)))
8524 if (operandLitValue(IC_RIGHT(ic)) != 1)
8527 /* if the size of this greater than one then no
8529 if (getSize(operandType(IC_RESULT(ic))) > 1)
8532 /* otherwise we can save BIG */
8533 lbl = newiTempLabel(NULL);
8534 lbl1= newiTempLabel(NULL);
8536 aopOp(IC_RESULT(ic),ic,FALSE);
8538 if (IS_AOP_PREG(IC_RESULT(ic))) {
8539 pic14_emitcode("dec","%s",
8540 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8541 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8542 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8546 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8547 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8549 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8550 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8553 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8554 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8555 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8556 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8559 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8564 /*-----------------------------------------------------------------*/
8565 /* genReceive - generate code for a receive iCode */
8566 /*-----------------------------------------------------------------*/
8567 static void genReceive (iCode *ic)
8569 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8571 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8572 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8573 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8575 int size = getSize(operandType(IC_RESULT(ic)));
8576 int offset = fReturnSizePic - size;
8578 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8579 fReturn[fReturnSizePic - offset - 1] : "acc"));
8582 aopOp(IC_RESULT(ic),ic,FALSE);
8583 size = AOP_SIZE(IC_RESULT(ic));
8586 pic14_emitcode ("pop","acc");
8587 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8592 aopOp(IC_RESULT(ic),ic,FALSE);
8594 assignResultValue(IC_RESULT(ic));
8597 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8600 /*-----------------------------------------------------------------*/
8601 /* genpic14Code - generate code for pic14 based controllers */
8602 /*-----------------------------------------------------------------*/
8604 * At this point, ralloc.c has gone through the iCode and attempted
8605 * to optimize in a way suitable for a PIC. Now we've got to generate
8606 * PIC instructions that correspond to the iCode.
8608 * Once the instructions are generated, we'll pass through both the
8609 * peep hole optimizer and the pCode optimizer.
8610 *-----------------------------------------------------------------*/
8612 void genpic14Code (iCode *lic)
8617 lineHead = lineCurr = NULL;
8619 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8622 /* if debug information required */
8623 /* if (options.debug && currFunc) { */
8625 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8627 if (IS_STATIC(currFunc->etype)) {
8628 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8629 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8631 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8632 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8638 for (ic = lic ; ic ; ic = ic->next ) {
8640 DEBUGpic14_emitcode(";ic","");
8641 if ( cln != ic->lineno ) {
8642 if ( options.debug ) {
8644 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8645 FileBaseName(ic->filename),ic->lineno,
8646 ic->level,ic->block);
8649 pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
8652 /* if the result is marked as
8653 spilt and rematerializable or code for
8654 this has already been generated then
8656 if (resultRemat(ic) || ic->generated )
8659 /* depending on the operation */
8678 /* IPOP happens only when trying to restore a
8679 spilt live range, if there is an ifx statement
8680 following this pop then the if statement might
8681 be using some of the registers being popped which
8682 would destory the contents of the register so
8683 we need to check for this condition and handle it */
8685 ic->next->op == IFX &&
8686 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8687 genIfx (ic->next,ic);
8705 genEndFunction (ic);
8725 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
8742 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
8746 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
8753 /* note these two are xlated by algebraic equivalence
8754 during parsing SDCC.y */
8755 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8756 "got '>=' or '<=' shouldn't have come here");
8760 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
8772 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
8776 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
8780 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
8807 case GET_VALUE_AT_ADDRESS:
8812 if (POINTER_SET(ic))
8839 addSet(&_G.sendSet,ic);
8848 /* now we are ready to call the
8849 peep hole optimizer */
8850 if (!options.nopeep) {
8851 printf("peep hole optimizing\n");
8852 peepHole (&lineHead);
8854 /* now do the actual printing */
8855 printLine (lineHead,codeOutFile);
8857 printf("printing pBlock\n\n");
8858 printpBlock(stdout,pb);