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))) && (offl == offr);
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(0x0f));
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(0x0f));
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),offl,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
5583 /*-----------------------------------------------------------------*/
5584 /* AccAXRsh - right shift a:x known count (0..7) */
5585 /*-----------------------------------------------------------------*/
5586 static void AccAXRsh (char *x, int shCount)
5588 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5594 AccAXRrl1(x); // 0->a:x
5598 AccAXRrl1(x); // 0->a:x
5600 AccAXRrl1(x); // 0->a:x
5604 case 5 : // AAAAABBB:CCCCCDDD = a:x
5605 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5606 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5607 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5608 pic14_emitcode("anl","a,#0x%02x",
5609 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5610 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5611 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5612 pic14_emitcode("anl","a,#0x%02x",
5613 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5614 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5615 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5616 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5618 case 6 : // AABBBBBB:CCDDDDDD
5619 pic14_emitcode("mov","c,acc.7");
5620 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5621 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5622 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5623 pic14_emitcode("anl","a,#0x%02x",
5624 SRMask[shCount]); // 000000AA:BBBBBBCC
5626 case 7 : // ABBBBBBB:CDDDDDDD
5627 pic14_emitcode("mov","c,acc.7"); // c = A
5628 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5629 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5630 pic14_emitcode("anl","a,#0x%02x",
5631 SRMask[shCount]); // 0000000A:BBBBBBBC
5638 /*-----------------------------------------------------------------*/
5639 /* AccAXRshS - right shift signed a:x known count (0..7) */
5640 /*-----------------------------------------------------------------*/
5641 static void AccAXRshS (char *x, int shCount)
5644 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5649 pic14_emitcode("mov","c,acc.7");
5650 AccAXRrl1(x); // s->a:x
5653 pic14_emitcode("mov","c,acc.7");
5654 AccAXRrl1(x); // s->a:x
5655 pic14_emitcode("mov","c,acc.7");
5656 AccAXRrl1(x); // s->a:x
5660 case 5 : // AAAAABBB:CCCCCDDD = a:x
5661 tlbl = newiTempLabel(NULL);
5662 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
5663 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5664 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5665 pic14_emitcode("anl","a,#0x%02x",
5666 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5667 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5668 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5669 pic14_emitcode("anl","a,#0x%02x",
5670 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5671 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5672 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5673 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
5674 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5675 pic14_emitcode("orl","a,#0x%02x",
5676 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5677 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5678 break; // SSSSAAAA:BBBCCCCC
5679 case 6 : // AABBBBBB:CCDDDDDD
5680 tlbl = newiTempLabel(NULL);
5681 pic14_emitcode("mov","c,acc.7");
5682 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5683 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5684 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5685 pic14_emitcode("anl","a,#0x%02x",
5686 SRMask[shCount]); // 000000AA:BBBBBBCC
5687 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5688 pic14_emitcode("orl","a,#0x%02x",
5689 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
5690 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5692 case 7 : // ABBBBBBB:CDDDDDDD
5693 tlbl = newiTempLabel(NULL);
5694 pic14_emitcode("mov","c,acc.7"); // c = A
5695 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5696 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5697 pic14_emitcode("anl","a,#0x%02x",
5698 SRMask[shCount]); // 0000000A:BBBBBBBC
5699 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5700 pic14_emitcode("orl","a,#0x%02x",
5701 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
5702 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5709 /*-----------------------------------------------------------------*/
5710 /* shiftL2Left2Result - shift left two bytes from left to result */
5711 /*-----------------------------------------------------------------*/
5712 static void shiftL2Left2Result (operand *left, int offl,
5713 operand *result, int offr, int shCount)
5717 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5719 if(pic14_sameRegs(AOP(result), AOP(left))) {
5727 emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
5728 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5729 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5733 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5734 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5740 emitpcode(POC_MOVLW, popGetLit(0x0f));
5741 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5742 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5743 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5744 emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
5745 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5746 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5748 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5749 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5753 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5754 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5755 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5756 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5757 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5758 emitpcode(POC_ANDLW,popGetLit(0xc0));
5759 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5760 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5761 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5762 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5765 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5766 emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
5767 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5768 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5769 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5779 /* note, use a mov/add for the shift since the mov has a
5780 chance of getting optimized out */
5781 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5782 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5783 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5784 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5785 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5789 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5790 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5796 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5797 emitpcode(POC_ANDLW, popGetLit(0xF0));
5798 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5799 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5800 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5801 emitpcode(POC_ANDLW, popGetLit(0xF0));
5802 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5803 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5807 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5808 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5812 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5813 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5814 emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
5815 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5817 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5818 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5819 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5820 emitpcode(POC_ANDLW,popGetLit(0xc0));
5821 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5822 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5823 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5824 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5827 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5828 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5829 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5830 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5831 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5836 /*-----------------------------------------------------------------*/
5837 /* shiftR2Left2Result - shift right two bytes from left to result */
5838 /*-----------------------------------------------------------------*/
5839 static void shiftR2Left2Result (operand *left, int offl,
5840 operand *result, int offr,
5841 int shCount, int sign)
5845 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5846 same = pic14_sameRegs(AOP(result), AOP(left));
5848 if(same && ((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);
5871 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5872 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5875 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5876 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5877 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5878 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5883 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5884 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5891 emitpcode(POC_MOVLW, popGetLit(0xf0));
5892 emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
5893 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5895 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5896 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5897 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5898 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5900 emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
5901 emitpcode(POC_ANDLW, popGetLit(0x0f));
5902 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5904 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5905 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5906 emitpcode(POC_ANDLW, popGetLit(0xf0));
5907 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5908 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5912 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5913 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5921 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5922 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5924 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5925 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5926 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5927 emitpcode(POC_ANDLW,popGetLit(0x03));
5928 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5929 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5930 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5931 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5933 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5934 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5935 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
5936 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5937 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5938 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5939 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5940 emitpcode(POC_ANDLW,popGetLit(0x03));
5941 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5946 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5947 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5948 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5949 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5950 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5955 /*-----------------------------------------------------------------*/
5956 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
5957 /*-----------------------------------------------------------------*/
5958 static void shiftLLeftOrResult (operand *left, int offl,
5959 operand *result, int offr, int shCount)
5961 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5962 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5963 /* shift left accumulator */
5965 /* or with result */
5966 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5967 /* back to result */
5968 aopPut(AOP(result),"a",offr);
5971 /*-----------------------------------------------------------------*/
5972 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
5973 /*-----------------------------------------------------------------*/
5974 static void shiftRLeftOrResult (operand *left, int offl,
5975 operand *result, int offr, int shCount)
5977 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5978 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5979 /* shift right accumulator */
5981 /* or with result */
5982 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5983 /* back to result */
5984 aopPut(AOP(result),"a",offr);
5987 /*-----------------------------------------------------------------*/
5988 /* genlshOne - left shift a one byte quantity by known count */
5989 /*-----------------------------------------------------------------*/
5990 static void genlshOne (operand *result, operand *left, int shCount)
5992 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5993 shiftL1Left2Result(left, LSB, result, LSB, shCount);
5996 /*-----------------------------------------------------------------*/
5997 /* genlshTwo - left shift two bytes by known amount != 0 */
5998 /*-----------------------------------------------------------------*/
5999 static void genlshTwo (operand *result,operand *left, int shCount)
6003 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6004 size = pic14_getDataSize(result);
6006 /* if shCount >= 8 */
6012 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6014 movLeft2Result(left, LSB, result, MSB16, 0);
6016 emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6019 /* 1 <= shCount <= 7 */
6022 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6024 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6028 /*-----------------------------------------------------------------*/
6029 /* shiftLLong - shift left one long from left to result */
6030 /* offl = LSB or MSB16 */
6031 /*-----------------------------------------------------------------*/
6032 static void shiftLLong (operand *left, operand *result, int offr )
6035 int size = AOP_SIZE(result);
6037 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6038 if(size >= LSB+offr){
6039 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6041 pic14_emitcode("add","a,acc");
6042 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6043 size >= MSB16+offr && offr != LSB )
6044 pic14_emitcode("xch","a,%s",
6045 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6047 aopPut(AOP(result),"a",LSB+offr);
6050 if(size >= MSB16+offr){
6051 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6052 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6055 pic14_emitcode("rlc","a");
6056 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6057 size >= MSB24+offr && offr != LSB)
6058 pic14_emitcode("xch","a,%s",
6059 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6061 aopPut(AOP(result),"a",MSB16+offr);
6064 if(size >= MSB24+offr){
6065 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6066 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6069 pic14_emitcode("rlc","a");
6070 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6071 size >= MSB32+offr && offr != LSB )
6072 pic14_emitcode("xch","a,%s",
6073 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6075 aopPut(AOP(result),"a",MSB24+offr);
6078 if(size > MSB32+offr){
6079 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6080 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6083 pic14_emitcode("rlc","a");
6084 aopPut(AOP(result),"a",MSB32+offr);
6087 aopPut(AOP(result),zero,LSB);
6090 /*-----------------------------------------------------------------*/
6091 /* genlshFour - shift four byte by a known amount != 0 */
6092 /*-----------------------------------------------------------------*/
6093 static void genlshFour (operand *result, operand *left, int shCount)
6097 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6098 size = AOP_SIZE(result);
6100 /* if shifting more that 3 bytes */
6101 if (shCount >= 24 ) {
6104 /* lowest order of left goes to the highest
6105 order of the destination */
6106 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6108 movLeft2Result(left, LSB, result, MSB32, 0);
6109 aopPut(AOP(result),zero,LSB);
6110 aopPut(AOP(result),zero,MSB16);
6111 aopPut(AOP(result),zero,MSB32);
6115 /* more than two bytes */
6116 else if ( shCount >= 16 ) {
6117 /* lower order two bytes goes to higher order two bytes */
6119 /* if some more remaining */
6121 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6123 movLeft2Result(left, MSB16, result, MSB32, 0);
6124 movLeft2Result(left, LSB, result, MSB24, 0);
6126 aopPut(AOP(result),zero,MSB16);
6127 aopPut(AOP(result),zero,LSB);
6131 /* if more than 1 byte */
6132 else if ( shCount >= 8 ) {
6133 /* lower order three bytes goes to higher order three bytes */
6137 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6139 movLeft2Result(left, LSB, result, MSB16, 0);
6141 else{ /* size = 4 */
6143 movLeft2Result(left, MSB24, result, MSB32, 0);
6144 movLeft2Result(left, MSB16, result, MSB24, 0);
6145 movLeft2Result(left, LSB, result, MSB16, 0);
6146 aopPut(AOP(result),zero,LSB);
6148 else if(shCount == 1)
6149 shiftLLong(left, result, MSB16);
6151 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6152 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6153 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6154 aopPut(AOP(result),zero,LSB);
6159 /* 1 <= shCount <= 7 */
6160 else if(shCount <= 2){
6161 shiftLLong(left, result, LSB);
6163 shiftLLong(result, result, LSB);
6165 /* 3 <= shCount <= 7, optimize */
6167 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6168 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6169 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6173 /*-----------------------------------------------------------------*/
6174 /* genLeftShiftLiteral - left shifting by known count */
6175 /*-----------------------------------------------------------------*/
6176 static void genLeftShiftLiteral (operand *left,
6181 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6184 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6185 freeAsmop(right,NULL,ic,TRUE);
6187 aopOp(left,ic,FALSE);
6188 aopOp(result,ic,FALSE);
6190 size = getSize(operandType(result));
6193 pic14_emitcode("; shift left ","result %d, left %d",size,
6197 /* I suppose that the left size >= result size */
6200 movLeft2Result(left, size, result, size, 0);
6204 else if(shCount >= (size * 8))
6206 aopPut(AOP(result),zero,size);
6210 genlshOne (result,left,shCount);
6215 genlshTwo (result,left,shCount);
6219 genlshFour (result,left,shCount);
6223 freeAsmop(left,NULL,ic,TRUE);
6224 freeAsmop(result,NULL,ic,TRUE);
6227 /*-----------------------------------------------------------------*/
6228 /* genLeftShift - generates code for left shifting */
6229 /*-----------------------------------------------------------------*/
6230 static void genLeftShift (iCode *ic)
6232 operand *left,*right, *result;
6235 symbol *tlbl , *tlbl1;
6237 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6239 right = IC_RIGHT(ic);
6241 result = IC_RESULT(ic);
6243 aopOp(right,ic,FALSE);
6245 /* if the shift count is known then do it
6246 as efficiently as possible */
6247 if (AOP_TYPE(right) == AOP_LIT) {
6248 genLeftShiftLiteral (left,right,result,ic);
6252 /* shift count is unknown then we have to form
6253 a loop get the loop count in B : Note: we take
6254 only the lower order byte since shifting
6255 more that 32 bits make no sense anyway, ( the
6256 largest size of an object can be only 32 bits ) */
6259 aopOp(left,ic,FALSE);
6260 aopOp(result,ic,FALSE);
6262 /* now move the left to the result if they are not the
6264 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6265 AOP_SIZE(result) > 1) {
6267 size = AOP_SIZE(result);
6270 l = aopGet(AOP(left),offset,FALSE,TRUE);
6271 if (*l == '@' && (IS_AOP_PREG(result))) {
6273 pic14_emitcode("mov","a,%s",l);
6274 aopPut(AOP(result),"a",offset);
6276 aopPut(AOP(result),l,offset);
6281 size = AOP_SIZE(result);
6283 /* if it is only one byte then */
6285 if(optimized_for_speed) {
6286 emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6287 emitpcode(POC_ANDLW, popGetLit(0xf0));
6288 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6289 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6290 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6291 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6292 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6293 emitpcode(POC_RLFW, popGet(AOP(result),0,FALSE,FALSE));
6294 emitpcode(POC_ANDLW, popGetLit(0xfe));
6295 emitpcode(POC_ADDFW, popGet(AOP(result),0,FALSE,FALSE));
6296 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6297 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6300 tlbl = newiTempLabel(NULL);
6301 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6302 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6303 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6306 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6307 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6308 emitpLabel(tlbl->key+100+labelOffset);
6309 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6310 emitpcode(POC_ADDLW, popGetLit(1));
6312 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6318 tlbl = newiTempLabel(NULL);
6320 tlbl1 = newiTempLabel(NULL);
6322 reAdjustPreg(AOP(result));
6324 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6325 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6326 l = aopGet(AOP(result),offset,FALSE,FALSE);
6328 pic14_emitcode("add","a,acc");
6329 aopPut(AOP(result),"a",offset++);
6331 l = aopGet(AOP(result),offset,FALSE,FALSE);
6333 pic14_emitcode("rlc","a");
6334 aopPut(AOP(result),"a",offset++);
6336 reAdjustPreg(AOP(result));
6338 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6339 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6341 freeAsmop (right,NULL,ic,TRUE);
6342 freeAsmop(left,NULL,ic,TRUE);
6343 freeAsmop(result,NULL,ic,TRUE);
6346 /*-----------------------------------------------------------------*/
6347 /* genrshOne - right shift a one byte quantity by known count */
6348 /*-----------------------------------------------------------------*/
6349 static void genrshOne (operand *result, operand *left,
6350 int shCount, int sign)
6352 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6353 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6356 /*-----------------------------------------------------------------*/
6357 /* genrshTwo - right shift two bytes by known amount != 0 */
6358 /*-----------------------------------------------------------------*/
6359 static void genrshTwo (operand *result,operand *left,
6360 int shCount, int sign)
6362 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6363 /* if shCount >= 8 */
6367 shiftR1Left2Result(left, MSB16, result, LSB,
6370 movLeft2Result(left, MSB16, result, LSB, sign);
6372 addSign(result, MSB16, sign);
6374 emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6378 /* 1 <= shCount <= 7 */
6380 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6383 /*-----------------------------------------------------------------*/
6384 /* shiftRLong - shift right one long from left to result */
6385 /* offl = LSB or MSB16 */
6386 /*-----------------------------------------------------------------*/
6387 static void shiftRLong (operand *left, int offl,
6388 operand *result, int sign)
6390 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6392 pic14_emitcode("clr","c");
6393 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6395 pic14_emitcode("mov","c,acc.7");
6396 pic14_emitcode("rrc","a");
6397 aopPut(AOP(result),"a",MSB32-offl);
6399 /* add sign of "a" */
6400 addSign(result, MSB32, sign);
6402 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6403 pic14_emitcode("rrc","a");
6404 aopPut(AOP(result),"a",MSB24-offl);
6406 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6407 pic14_emitcode("rrc","a");
6408 aopPut(AOP(result),"a",MSB16-offl);
6411 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6412 pic14_emitcode("rrc","a");
6413 aopPut(AOP(result),"a",LSB);
6417 /*-----------------------------------------------------------------*/
6418 /* genrshFour - shift four byte by a known amount != 0 */
6419 /*-----------------------------------------------------------------*/
6420 static void genrshFour (operand *result, operand *left,
6421 int shCount, int sign)
6423 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6424 /* if shifting more that 3 bytes */
6425 if(shCount >= 24 ) {
6428 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6430 movLeft2Result(left, MSB32, result, LSB, sign);
6431 addSign(result, MSB16, sign);
6433 else if(shCount >= 16){
6436 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6438 movLeft2Result(left, MSB24, result, LSB, 0);
6439 movLeft2Result(left, MSB32, result, MSB16, sign);
6441 addSign(result, MSB24, sign);
6443 else if(shCount >= 8){
6446 shiftRLong(left, MSB16, result, sign);
6447 else if(shCount == 0){
6448 movLeft2Result(left, MSB16, result, LSB, 0);
6449 movLeft2Result(left, MSB24, result, MSB16, 0);
6450 movLeft2Result(left, MSB32, result, MSB24, sign);
6451 addSign(result, MSB32, sign);
6454 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6455 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6456 /* the last shift is signed */
6457 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6458 addSign(result, MSB32, sign);
6461 else{ /* 1 <= shCount <= 7 */
6463 shiftRLong(left, LSB, result, sign);
6465 shiftRLong(result, LSB, result, sign);
6468 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6469 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6470 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6475 /*-----------------------------------------------------------------*/
6476 /* genRightShiftLiteral - right shifting by known count */
6477 /*-----------------------------------------------------------------*/
6478 static void genRightShiftLiteral (operand *left,
6484 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6487 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6488 freeAsmop(right,NULL,ic,TRUE);
6490 aopOp(left,ic,FALSE);
6491 aopOp(result,ic,FALSE);
6494 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6498 size = pic14_getDataSize(left);
6499 /* test the LEFT size !!! */
6501 /* I suppose that the left size >= result size */
6503 size = pic14_getDataSize(result);
6505 movLeft2Result(left, size, result, size, 0);
6508 else if(shCount >= (size * 8)){
6510 /* get sign in acc.7 */
6511 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6512 addSign(result, LSB, sign);
6516 genrshOne (result,left,shCount,sign);
6520 genrshTwo (result,left,shCount,sign);
6524 genrshFour (result,left,shCount,sign);
6530 freeAsmop(left,NULL,ic,TRUE);
6531 freeAsmop(result,NULL,ic,TRUE);
6535 /*-----------------------------------------------------------------*/
6536 /* genSignedRightShift - right shift of signed number */
6537 /*-----------------------------------------------------------------*/
6538 static void genSignedRightShift (iCode *ic)
6540 operand *right, *left, *result;
6543 symbol *tlbl, *tlbl1 ;
6545 /* we do it the hard way put the shift count in b
6546 and loop thru preserving the sign */
6547 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6549 right = IC_RIGHT(ic);
6551 result = IC_RESULT(ic);
6553 aopOp(right,ic,FALSE);
6556 if ( AOP_TYPE(right) == AOP_LIT) {
6557 genRightShiftLiteral (left,right,result,ic,1);
6560 /* shift count is unknown then we have to form
6561 a loop get the loop count in B : Note: we take
6562 only the lower order byte since shifting
6563 more that 32 bits make no sense anyway, ( the
6564 largest size of an object can be only 32 bits ) */
6566 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6567 pic14_emitcode("inc","b");
6568 freeAsmop (right,NULL,ic,TRUE);
6569 aopOp(left,ic,FALSE);
6570 aopOp(result,ic,FALSE);
6572 /* now move the left to the result if they are not the
6574 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6575 AOP_SIZE(result) > 1) {
6577 size = AOP_SIZE(result);
6580 l = aopGet(AOP(left),offset,FALSE,TRUE);
6581 if (*l == '@' && IS_AOP_PREG(result)) {
6583 pic14_emitcode("mov","a,%s",l);
6584 aopPut(AOP(result),"a",offset);
6586 aopPut(AOP(result),l,offset);
6591 /* mov the highest order bit to OVR */
6592 tlbl = newiTempLabel(NULL);
6593 tlbl1= newiTempLabel(NULL);
6595 size = AOP_SIZE(result);
6597 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6598 pic14_emitcode("rlc","a");
6599 pic14_emitcode("mov","ov,c");
6600 /* if it is only one byte then */
6602 l = aopGet(AOP(left),0,FALSE,FALSE);
6604 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6605 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6606 pic14_emitcode("mov","c,ov");
6607 pic14_emitcode("rrc","a");
6608 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6609 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6610 aopPut(AOP(result),"a",0);
6614 reAdjustPreg(AOP(result));
6615 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6616 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6617 pic14_emitcode("mov","c,ov");
6619 l = aopGet(AOP(result),offset,FALSE,FALSE);
6621 pic14_emitcode("rrc","a");
6622 aopPut(AOP(result),"a",offset--);
6624 reAdjustPreg(AOP(result));
6625 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6626 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6629 freeAsmop(left,NULL,ic,TRUE);
6630 freeAsmop(result,NULL,ic,TRUE);
6633 /*-----------------------------------------------------------------*/
6634 /* genRightShift - generate code for right shifting */
6635 /*-----------------------------------------------------------------*/
6636 static void genRightShift (iCode *ic)
6638 operand *right, *left, *result;
6642 symbol *tlbl, *tlbl1 ;
6644 /* if signed then we do it the hard way preserve the
6645 sign bit moving it inwards */
6646 retype = getSpec(operandType(IC_RESULT(ic)));
6647 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6649 if (!SPEC_USIGN(retype)) {
6650 genSignedRightShift (ic);
6654 /* signed & unsigned types are treated the same : i.e. the
6655 signed is NOT propagated inwards : quoting from the
6656 ANSI - standard : "for E1 >> E2, is equivalent to division
6657 by 2**E2 if unsigned or if it has a non-negative value,
6658 otherwise the result is implementation defined ", MY definition
6659 is that the sign does not get propagated */
6661 right = IC_RIGHT(ic);
6663 result = IC_RESULT(ic);
6665 aopOp(right,ic,FALSE);
6667 /* if the shift count is known then do it
6668 as efficiently as possible */
6669 if (AOP_TYPE(right) == AOP_LIT) {
6670 genRightShiftLiteral (left,right,result,ic, 0);
6674 /* shift count is unknown then we have to form
6675 a loop get the loop count in B : Note: we take
6676 only the lower order byte since shifting
6677 more that 32 bits make no sense anyway, ( the
6678 largest size of an object can be only 32 bits ) */
6680 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6681 pic14_emitcode("inc","b");
6682 aopOp(left,ic,FALSE);
6683 aopOp(result,ic,FALSE);
6685 /* now move the left to the result if they are not the
6687 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6688 AOP_SIZE(result) > 1) {
6690 size = AOP_SIZE(result);
6693 l = aopGet(AOP(left),offset,FALSE,TRUE);
6694 if (*l == '@' && IS_AOP_PREG(result)) {
6696 pic14_emitcode("mov","a,%s",l);
6697 aopPut(AOP(result),"a",offset);
6699 aopPut(AOP(result),l,offset);
6704 tlbl = newiTempLabel(NULL);
6705 tlbl1= newiTempLabel(NULL);
6706 size = AOP_SIZE(result);
6709 /* if it is only one byte then */
6712 l = aopGet(AOP(left),0,FALSE,FALSE);
6714 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6715 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6717 pic14_emitcode("rrc","a");
6718 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6719 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6720 aopPut(AOP(result),"a",0);
6722 tlbl = newiTempLabel(NULL);
6723 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6724 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6725 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6728 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6729 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6730 emitpLabel(tlbl->key+100+labelOffset);
6731 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6732 emitpcode(POC_ADDLW, popGetLit(1));
6734 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6739 reAdjustPreg(AOP(result));
6740 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6741 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6744 l = aopGet(AOP(result),offset,FALSE,FALSE);
6746 pic14_emitcode("rrc","a");
6747 aopPut(AOP(result),"a",offset--);
6749 reAdjustPreg(AOP(result));
6751 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6752 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6755 freeAsmop(left,NULL,ic,TRUE);
6756 freeAsmop (right,NULL,ic,TRUE);
6757 freeAsmop(result,NULL,ic,TRUE);
6760 /*-----------------------------------------------------------------*/
6761 /* genUnpackBits - generates code for unpacking bits */
6762 /*-----------------------------------------------------------------*/
6763 static void genUnpackBits (operand *result, char *rname, int ptype)
6770 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6771 etype = getSpec(operandType(result));
6773 /* read the first byte */
6778 pic14_emitcode("mov","a,@%s",rname);
6782 pic14_emitcode("movx","a,@%s",rname);
6786 pic14_emitcode("movx","a,@dptr");
6790 pic14_emitcode("clr","a");
6791 pic14_emitcode("movc","a","@a+dptr");
6795 pic14_emitcode("lcall","__gptrget");
6799 /* if we have bitdisplacement then it fits */
6800 /* into this byte completely or if length is */
6801 /* less than a byte */
6802 if ((shCnt = SPEC_BSTR(etype)) ||
6803 (SPEC_BLEN(etype) <= 8)) {
6805 /* shift right acc */
6808 pic14_emitcode("anl","a,#0x%02x",
6809 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6810 aopPut(AOP(result),"a",offset);
6814 /* bit field did not fit in a byte */
6815 rlen = SPEC_BLEN(etype) - 8;
6816 aopPut(AOP(result),"a",offset++);
6823 pic14_emitcode("inc","%s",rname);
6824 pic14_emitcode("mov","a,@%s",rname);
6828 pic14_emitcode("inc","%s",rname);
6829 pic14_emitcode("movx","a,@%s",rname);
6833 pic14_emitcode("inc","dptr");
6834 pic14_emitcode("movx","a,@dptr");
6838 pic14_emitcode("clr","a");
6839 pic14_emitcode("inc","dptr");
6840 pic14_emitcode("movc","a","@a+dptr");
6844 pic14_emitcode("inc","dptr");
6845 pic14_emitcode("lcall","__gptrget");
6850 /* if we are done */
6854 aopPut(AOP(result),"a",offset++);
6859 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
6860 aopPut(AOP(result),"a",offset);
6867 /*-----------------------------------------------------------------*/
6868 /* genDataPointerGet - generates code when ptr offset is known */
6869 /*-----------------------------------------------------------------*/
6870 static void genDataPointerGet (operand *left,
6874 int size , offset = 0;
6877 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6880 /* optimization - most of the time, left and result are the same
6881 * address, but different types. for the pic code, we could omit
6885 aopOp(result,ic,TRUE);
6887 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
6889 size = AOP_SIZE(result);
6892 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
6896 freeAsmop(left,NULL,ic,TRUE);
6897 freeAsmop(result,NULL,ic,TRUE);
6900 /*-----------------------------------------------------------------*/
6901 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
6902 /*-----------------------------------------------------------------*/
6903 static void genNearPointerGet (operand *left,
6910 sym_link *rtype, *retype;
6911 sym_link *ltype = operandType(left);
6914 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6916 rtype = operandType(result);
6917 retype= getSpec(rtype);
6919 aopOp(left,ic,FALSE);
6921 /* if left is rematerialisable and
6922 result is not bit variable type and
6923 the left is pointer to data space i.e
6924 lower 128 bytes of space */
6925 if (AOP_TYPE(left) == AOP_IMMD &&
6926 !IS_BITVAR(retype) &&
6927 DCL_TYPE(ltype) == POINTER) {
6928 genDataPointerGet (left,result,ic);
6932 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6934 /* if the value is already in a pointer register
6935 then don't need anything more */
6936 if (!AOP_INPREG(AOP(left))) {
6937 /* otherwise get a free pointer register */
6938 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6940 preg = getFreePtr(ic,&aop,FALSE);
6941 pic14_emitcode("mov","%s,%s",
6943 aopGet(AOP(left),0,FALSE,TRUE));
6944 rname = preg->name ;
6946 rname = aopGet(AOP(left),0,FALSE,FALSE);
6948 freeAsmop(left,NULL,ic,TRUE);
6949 aopOp (result,ic,FALSE);
6951 /* if bitfield then unpack the bits */
6952 if (IS_BITVAR(retype))
6953 genUnpackBits (result,rname,POINTER);
6955 /* we have can just get the values */
6956 int size = AOP_SIZE(result);
6959 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6961 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
6963 pic14_emitcode("mov","a,@%s",rname);
6964 aopPut(AOP(result),"a",offset);
6966 sprintf(buffer,"@%s",rname);
6967 aopPut(AOP(result),buffer,offset);
6971 pic14_emitcode("inc","%s",rname);
6975 /* now some housekeeping stuff */
6977 /* we had to allocate for this iCode */
6978 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6979 freeAsmop(NULL,aop,ic,TRUE);
6981 /* we did not allocate which means left
6982 already in a pointer register, then
6983 if size > 0 && this could be used again
6984 we have to point it back to where it
6986 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6987 if (AOP_SIZE(result) > 1 &&
6988 !OP_SYMBOL(left)->remat &&
6989 ( OP_SYMBOL(left)->liveTo > ic->seq ||
6991 int size = AOP_SIZE(result) - 1;
6993 pic14_emitcode("dec","%s",rname);
6998 freeAsmop(result,NULL,ic,TRUE);
7002 /*-----------------------------------------------------------------*/
7003 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7004 /*-----------------------------------------------------------------*/
7005 static void genPagedPointerGet (operand *left,
7012 sym_link *rtype, *retype;
7014 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7016 rtype = operandType(result);
7017 retype= getSpec(rtype);
7019 aopOp(left,ic,FALSE);
7021 /* if the value is already in a pointer register
7022 then don't need anything more */
7023 if (!AOP_INPREG(AOP(left))) {
7024 /* otherwise get a free pointer register */
7026 preg = getFreePtr(ic,&aop,FALSE);
7027 pic14_emitcode("mov","%s,%s",
7029 aopGet(AOP(left),0,FALSE,TRUE));
7030 rname = preg->name ;
7032 rname = aopGet(AOP(left),0,FALSE,FALSE);
7034 freeAsmop(left,NULL,ic,TRUE);
7035 aopOp (result,ic,FALSE);
7037 /* if bitfield then unpack the bits */
7038 if (IS_BITVAR(retype))
7039 genUnpackBits (result,rname,PPOINTER);
7041 /* we have can just get the values */
7042 int size = AOP_SIZE(result);
7047 pic14_emitcode("movx","a,@%s",rname);
7048 aopPut(AOP(result),"a",offset);
7053 pic14_emitcode("inc","%s",rname);
7057 /* now some housekeeping stuff */
7059 /* we had to allocate for this iCode */
7060 freeAsmop(NULL,aop,ic,TRUE);
7062 /* we did not allocate which means left
7063 already in a pointer register, then
7064 if size > 0 && this could be used again
7065 we have to point it back to where it
7067 if (AOP_SIZE(result) > 1 &&
7068 !OP_SYMBOL(left)->remat &&
7069 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7071 int size = AOP_SIZE(result) - 1;
7073 pic14_emitcode("dec","%s",rname);
7078 freeAsmop(result,NULL,ic,TRUE);
7083 /*-----------------------------------------------------------------*/
7084 /* genFarPointerGet - gget value from far space */
7085 /*-----------------------------------------------------------------*/
7086 static void genFarPointerGet (operand *left,
7087 operand *result, iCode *ic)
7090 sym_link *retype = getSpec(operandType(result));
7092 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7094 aopOp(left,ic,FALSE);
7096 /* if the operand is already in dptr
7097 then we do nothing else we move the value to dptr */
7098 if (AOP_TYPE(left) != AOP_STR) {
7099 /* if this is remateriazable */
7100 if (AOP_TYPE(left) == AOP_IMMD)
7101 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7102 else { /* we need to get it byte by byte */
7103 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7104 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7105 if (options.model == MODEL_FLAT24)
7107 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7111 /* so dptr know contains the address */
7112 freeAsmop(left,NULL,ic,TRUE);
7113 aopOp(result,ic,FALSE);
7115 /* if bit then unpack */
7116 if (IS_BITVAR(retype))
7117 genUnpackBits(result,"dptr",FPOINTER);
7119 size = AOP_SIZE(result);
7123 pic14_emitcode("movx","a,@dptr");
7124 aopPut(AOP(result),"a",offset++);
7126 pic14_emitcode("inc","dptr");
7130 freeAsmop(result,NULL,ic,TRUE);
7133 /*-----------------------------------------------------------------*/
7134 /* pic14_emitcodePointerGet - gget value from code space */
7135 /*-----------------------------------------------------------------*/
7136 static void pic14_emitcodePointerGet (operand *left,
7137 operand *result, iCode *ic)
7140 sym_link *retype = getSpec(operandType(result));
7142 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7144 aopOp(left,ic,FALSE);
7146 /* if the operand is already in dptr
7147 then we do nothing else we move the value to dptr */
7148 if (AOP_TYPE(left) != AOP_STR) {
7149 /* if this is remateriazable */
7150 if (AOP_TYPE(left) == AOP_IMMD)
7151 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7152 else { /* we need to get it byte by byte */
7153 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7154 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7155 if (options.model == MODEL_FLAT24)
7157 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7161 /* so dptr know contains the address */
7162 freeAsmop(left,NULL,ic,TRUE);
7163 aopOp(result,ic,FALSE);
7165 /* if bit then unpack */
7166 if (IS_BITVAR(retype))
7167 genUnpackBits(result,"dptr",CPOINTER);
7169 size = AOP_SIZE(result);
7173 pic14_emitcode("clr","a");
7174 pic14_emitcode("movc","a,@a+dptr");
7175 aopPut(AOP(result),"a",offset++);
7177 pic14_emitcode("inc","dptr");
7181 freeAsmop(result,NULL,ic,TRUE);
7184 /*-----------------------------------------------------------------*/
7185 /* genGenPointerGet - gget value from generic pointer space */
7186 /*-----------------------------------------------------------------*/
7187 static void genGenPointerGet (operand *left,
7188 operand *result, iCode *ic)
7191 sym_link *retype = getSpec(operandType(result));
7193 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7194 aopOp(left,ic,FALSE);
7196 /* if the operand is already in dptr
7197 then we do nothing else we move the value to dptr */
7198 if (AOP_TYPE(left) != AOP_STR) {
7199 /* if this is remateriazable */
7200 if (AOP_TYPE(left) == AOP_IMMD) {
7201 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7202 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7204 else { /* we need to get it byte by byte */
7205 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7206 //emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
7207 //emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7208 pic14_emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
7209 pic14_emitcode("movwf","FSR");
7211 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7212 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7213 if (options.model == MODEL_FLAT24)
7215 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7216 pic14_emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
7220 pic14_emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
7225 /* so dptr know contains the address */
7226 freeAsmop(left,NULL,ic,TRUE);
7227 aopOp(result,ic,FALSE);
7229 /* if bit then unpack */
7230 if (IS_BITVAR(retype))
7231 genUnpackBits(result,"dptr",GPOINTER);
7233 size = AOP_SIZE(result);
7237 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7239 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7241 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7243 pic14_emitcode("movf","indf,w");
7244 pic14_emitcode("movwf","%s",
7245 aopGet(AOP(result),offset++,FALSE,FALSE));
7247 pic14_emitcode("incf","fsr,f");
7252 freeAsmop(result,NULL,ic,TRUE);
7255 /*-----------------------------------------------------------------*/
7256 /* genPointerGet - generate code for pointer get */
7257 /*-----------------------------------------------------------------*/
7258 static void genPointerGet (iCode *ic)
7260 operand *left, *result ;
7261 sym_link *type, *etype;
7264 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7267 result = IC_RESULT(ic) ;
7269 /* depending on the type of pointer we need to
7270 move it to the correct pointer register */
7271 type = operandType(left);
7272 etype = getSpec(type);
7273 /* if left is of type of pointer then it is simple */
7274 if (IS_PTR(type) && !IS_FUNC(type->next))
7275 p_type = DCL_TYPE(type);
7277 /* we have to go by the storage class */
7278 p_type = PTR_TYPE(SPEC_OCLS(etype));
7280 /* if (SPEC_OCLS(etype)->codesp ) { */
7281 /* p_type = CPOINTER ; */
7284 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7285 /* p_type = FPOINTER ; */
7287 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7288 /* p_type = PPOINTER; */
7290 /* if (SPEC_OCLS(etype) == idata ) */
7291 /* p_type = IPOINTER; */
7293 /* p_type = POINTER ; */
7296 /* now that we have the pointer type we assign
7297 the pointer values */
7302 genNearPointerGet (left,result,ic);
7306 genPagedPointerGet(left,result,ic);
7310 genFarPointerGet (left,result,ic);
7314 pic14_emitcodePointerGet (left,result,ic);
7318 genGenPointerGet (left,result,ic);
7324 /*-----------------------------------------------------------------*/
7325 /* genPackBits - generates code for packed bit storage */
7326 /*-----------------------------------------------------------------*/
7327 static void genPackBits (sym_link *etype ,
7329 char *rname, int p_type)
7337 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7338 blen = SPEC_BLEN(etype);
7339 bstr = SPEC_BSTR(etype);
7341 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7344 /* if the bit lenth is less than or */
7345 /* it exactly fits a byte then */
7346 if (SPEC_BLEN(etype) <= 8 ) {
7347 shCount = SPEC_BSTR(etype) ;
7349 /* shift left acc */
7352 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7357 pic14_emitcode ("mov","b,a");
7358 pic14_emitcode("mov","a,@%s",rname);
7362 pic14_emitcode ("mov","b,a");
7363 pic14_emitcode("movx","a,@dptr");
7367 pic14_emitcode ("push","b");
7368 pic14_emitcode ("push","acc");
7369 pic14_emitcode ("lcall","__gptrget");
7370 pic14_emitcode ("pop","b");
7374 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7375 ((unsigned char)(0xFF << (blen+bstr)) |
7376 (unsigned char)(0xFF >> (8-bstr)) ) );
7377 pic14_emitcode ("orl","a,b");
7378 if (p_type == GPOINTER)
7379 pic14_emitcode("pop","b");
7385 pic14_emitcode("mov","@%s,a",rname);
7389 pic14_emitcode("movx","@dptr,a");
7393 DEBUGpic14_emitcode(";lcall","__gptrput");
7398 if ( SPEC_BLEN(etype) <= 8 )
7401 pic14_emitcode("inc","%s",rname);
7402 rLen = SPEC_BLEN(etype) ;
7404 /* now generate for lengths greater than one byte */
7407 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7417 pic14_emitcode("mov","@%s,a",rname);
7419 pic14_emitcode("mov","@%s,%s",rname,l);
7424 pic14_emitcode("movx","@dptr,a");
7429 DEBUGpic14_emitcode(";lcall","__gptrput");
7432 pic14_emitcode ("inc","%s",rname);
7437 /* last last was not complete */
7439 /* save the byte & read byte */
7442 pic14_emitcode ("mov","b,a");
7443 pic14_emitcode("mov","a,@%s",rname);
7447 pic14_emitcode ("mov","b,a");
7448 pic14_emitcode("movx","a,@dptr");
7452 pic14_emitcode ("push","b");
7453 pic14_emitcode ("push","acc");
7454 pic14_emitcode ("lcall","__gptrget");
7455 pic14_emitcode ("pop","b");
7459 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7460 pic14_emitcode ("orl","a,b");
7463 if (p_type == GPOINTER)
7464 pic14_emitcode("pop","b");
7469 pic14_emitcode("mov","@%s,a",rname);
7473 pic14_emitcode("movx","@dptr,a");
7477 DEBUGpic14_emitcode(";lcall","__gptrput");
7481 /*-----------------------------------------------------------------*/
7482 /* genDataPointerSet - remat pointer to data space */
7483 /*-----------------------------------------------------------------*/
7484 static void genDataPointerSet(operand *right,
7488 int size, offset = 0 ;
7489 char *l, buffer[256];
7491 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7492 aopOp(right,ic,FALSE);
7494 l = aopGet(AOP(result),0,FALSE,TRUE);
7495 size = AOP_SIZE(right);
7496 // tsd, was l+1 - the underline `_' prefix was being stripped
7499 sprintf(buffer,"(%s + %d)",l,offset);
7501 sprintf(buffer,"%s",l);
7503 if (AOP_TYPE(right) == AOP_LIT) {
7504 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7505 lit = lit >> (8*offset);
7507 pic14_emitcode("movlw","%d",lit);
7508 pic14_emitcode("movwf","%s",buffer);
7510 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7511 emitpcode(POC_MOVWF, popRegFromString(buffer));
7514 pic14_emitcode("clrf","%s",buffer);
7515 emitpcode(POC_CLRF, popRegFromString(buffer));
7518 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7519 pic14_emitcode("movwf","%s",buffer);
7521 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7522 emitpcode(POC_MOVWF, popRegFromString(buffer));
7529 freeAsmop(right,NULL,ic,TRUE);
7530 freeAsmop(result,NULL,ic,TRUE);
7533 /*-----------------------------------------------------------------*/
7534 /* genNearPointerSet - pic14_emitcode for near pointer put */
7535 /*-----------------------------------------------------------------*/
7536 static void genNearPointerSet (operand *right,
7543 sym_link *ptype = operandType(result);
7546 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7547 retype= getSpec(operandType(right));
7549 aopOp(result,ic,FALSE);
7551 /* if the result is rematerializable &
7552 in data space & not a bit variable */
7553 if (AOP_TYPE(result) == AOP_IMMD &&
7554 DCL_TYPE(ptype) == POINTER &&
7555 !IS_BITVAR(retype)) {
7556 genDataPointerSet (right,result,ic);
7560 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7562 /* if the value is already in a pointer register
7563 then don't need anything more */
7564 if (!AOP_INPREG(AOP(result))) {
7565 /* otherwise get a free pointer register */
7566 //aop = newAsmop(0);
7567 //preg = getFreePtr(ic,&aop,FALSE);
7568 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7569 //pic14_emitcode("mov","%s,%s",
7571 // aopGet(AOP(result),0,FALSE,TRUE));
7572 //rname = preg->name ;
7573 pic14_emitcode("movwf","fsr");
7575 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7577 freeAsmop(result,NULL,ic,TRUE);
7578 aopOp (right,ic,FALSE);
7579 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7581 /* if bitfield then unpack the bits */
7582 if (IS_BITVAR(retype)) {
7583 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7584 "The programmer is obviously confused");
7585 //genPackBits (retype,right,rname,POINTER);
7589 /* we have can just get the values */
7590 int size = AOP_SIZE(right);
7593 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7595 l = aopGet(AOP(right),offset,FALSE,TRUE);
7598 //pic14_emitcode("mov","@%s,a",rname);
7599 pic14_emitcode("movf","indf,w ;1");
7602 if (AOP_TYPE(right) == AOP_LIT) {
7603 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7605 pic14_emitcode("movlw","%s",l);
7606 pic14_emitcode("movwf","indf ;2");
7608 pic14_emitcode("clrf","indf");
7610 pic14_emitcode("movf","%s,w",l);
7611 pic14_emitcode("movwf","indf ;2");
7613 //pic14_emitcode("mov","@%s,%s",rname,l);
7616 pic14_emitcode("incf","fsr,f ;3");
7617 //pic14_emitcode("inc","%s",rname);
7622 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7623 /* now some housekeeping stuff */
7625 /* we had to allocate for this iCode */
7626 freeAsmop(NULL,aop,ic,TRUE);
7628 /* we did not allocate which means left
7629 already in a pointer register, then
7630 if size > 0 && this could be used again
7631 we have to point it back to where it
7633 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7634 if (AOP_SIZE(right) > 1 &&
7635 !OP_SYMBOL(result)->remat &&
7636 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7638 int size = AOP_SIZE(right) - 1;
7640 pic14_emitcode("decf","fsr,f");
7641 //pic14_emitcode("dec","%s",rname);
7645 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7647 freeAsmop(right,NULL,ic,TRUE);
7652 /*-----------------------------------------------------------------*/
7653 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7654 /*-----------------------------------------------------------------*/
7655 static void genPagedPointerSet (operand *right,
7664 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7666 retype= getSpec(operandType(right));
7668 aopOp(result,ic,FALSE);
7670 /* if the value is already in a pointer register
7671 then don't need anything more */
7672 if (!AOP_INPREG(AOP(result))) {
7673 /* otherwise get a free pointer register */
7675 preg = getFreePtr(ic,&aop,FALSE);
7676 pic14_emitcode("mov","%s,%s",
7678 aopGet(AOP(result),0,FALSE,TRUE));
7679 rname = preg->name ;
7681 rname = aopGet(AOP(result),0,FALSE,FALSE);
7683 freeAsmop(result,NULL,ic,TRUE);
7684 aopOp (right,ic,FALSE);
7686 /* if bitfield then unpack the bits */
7687 if (IS_BITVAR(retype))
7688 genPackBits (retype,right,rname,PPOINTER);
7690 /* we have can just get the values */
7691 int size = AOP_SIZE(right);
7695 l = aopGet(AOP(right),offset,FALSE,TRUE);
7698 pic14_emitcode("movx","@%s,a",rname);
7701 pic14_emitcode("inc","%s",rname);
7707 /* now some housekeeping stuff */
7709 /* we had to allocate for this iCode */
7710 freeAsmop(NULL,aop,ic,TRUE);
7712 /* we did not allocate which means left
7713 already in a pointer register, then
7714 if size > 0 && this could be used again
7715 we have to point it back to where it
7717 if (AOP_SIZE(right) > 1 &&
7718 !OP_SYMBOL(result)->remat &&
7719 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7721 int size = AOP_SIZE(right) - 1;
7723 pic14_emitcode("dec","%s",rname);
7728 freeAsmop(right,NULL,ic,TRUE);
7733 /*-----------------------------------------------------------------*/
7734 /* genFarPointerSet - set value from far space */
7735 /*-----------------------------------------------------------------*/
7736 static void genFarPointerSet (operand *right,
7737 operand *result, iCode *ic)
7740 sym_link *retype = getSpec(operandType(right));
7742 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7743 aopOp(result,ic,FALSE);
7745 /* if the operand is already in dptr
7746 then we do nothing else we move the value to dptr */
7747 if (AOP_TYPE(result) != AOP_STR) {
7748 /* if this is remateriazable */
7749 if (AOP_TYPE(result) == AOP_IMMD)
7750 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7751 else { /* we need to get it byte by byte */
7752 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7753 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7754 if (options.model == MODEL_FLAT24)
7756 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7760 /* so dptr know contains the address */
7761 freeAsmop(result,NULL,ic,TRUE);
7762 aopOp(right,ic,FALSE);
7764 /* if bit then unpack */
7765 if (IS_BITVAR(retype))
7766 genPackBits(retype,right,"dptr",FPOINTER);
7768 size = AOP_SIZE(right);
7772 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7774 pic14_emitcode("movx","@dptr,a");
7776 pic14_emitcode("inc","dptr");
7780 freeAsmop(right,NULL,ic,TRUE);
7783 /*-----------------------------------------------------------------*/
7784 /* genGenPointerSet - set value from generic pointer space */
7785 /*-----------------------------------------------------------------*/
7786 static void genGenPointerSet (operand *right,
7787 operand *result, iCode *ic)
7790 sym_link *retype = getSpec(operandType(right));
7792 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7794 aopOp(result,ic,FALSE);
7796 /* if the operand is already in dptr
7797 then we do nothing else we move the value to dptr */
7798 if (AOP_TYPE(result) != AOP_STR) {
7799 /* if this is remateriazable */
7800 if (AOP_TYPE(result) == AOP_IMMD) {
7801 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7802 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7804 else { /* we need to get it byte by byte */
7805 char *l = aopGet(AOP(result),0,FALSE,FALSE);
7808 emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
7809 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7812 pic14_emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
7814 pic14_emitcode("movwf","INDF");
7817 /* so dptr know contains the address */
7818 freeAsmop(result,NULL,ic,TRUE);
7819 aopOp(right,ic,FALSE);
7821 /* if bit then unpack */
7822 if (IS_BITVAR(retype))
7823 genPackBits(retype,right,"dptr",GPOINTER);
7825 size = AOP_SIZE(right);
7829 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7831 pic14_emitcode("incf","fsr,f");
7832 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
7833 pic14_emitcode("movwf","indf");
7835 //DEBUGpic14_emitcode(";lcall","__gptrput");
7837 // pic14_emitcode("inc","dptr");
7841 freeAsmop(right,NULL,ic,TRUE);
7844 /*-----------------------------------------------------------------*/
7845 /* genPointerSet - stores the value into a pointer location */
7846 /*-----------------------------------------------------------------*/
7847 static void genPointerSet (iCode *ic)
7849 operand *right, *result ;
7850 sym_link *type, *etype;
7853 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7855 right = IC_RIGHT(ic);
7856 result = IC_RESULT(ic) ;
7858 /* depending on the type of pointer we need to
7859 move it to the correct pointer register */
7860 type = operandType(result);
7861 etype = getSpec(type);
7862 /* if left is of type of pointer then it is simple */
7863 if (IS_PTR(type) && !IS_FUNC(type->next)) {
7864 p_type = DCL_TYPE(type);
7867 /* we have to go by the storage class */
7868 p_type = PTR_TYPE(SPEC_OCLS(etype));
7870 /* if (SPEC_OCLS(etype)->codesp ) { */
7871 /* p_type = CPOINTER ; */
7874 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7875 /* p_type = FPOINTER ; */
7877 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7878 /* p_type = PPOINTER ; */
7880 /* if (SPEC_OCLS(etype) == idata ) */
7881 /* p_type = IPOINTER ; */
7883 /* p_type = POINTER ; */
7886 /* now that we have the pointer type we assign
7887 the pointer values */
7892 genNearPointerSet (right,result,ic);
7896 genPagedPointerSet (right,result,ic);
7900 genFarPointerSet (right,result,ic);
7904 genGenPointerSet (right,result,ic);
7910 /*-----------------------------------------------------------------*/
7911 /* genIfx - generate code for Ifx statement */
7912 /*-----------------------------------------------------------------*/
7913 static void genIfx (iCode *ic, iCode *popIc)
7915 operand *cond = IC_COND(ic);
7918 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7919 aopOp(cond,ic,FALSE);
7921 /* get the value into acc */
7922 if (AOP_TYPE(cond) != AOP_CRY)
7923 pic14_toBoolean(cond);
7926 /* the result is now in the accumulator */
7927 freeAsmop(cond,NULL,ic,TRUE);
7929 /* if there was something to be popped then do it */
7933 /* if the condition is a bit variable */
7934 if (isbit && IS_ITEMP(cond) &&
7936 genIfxJump(ic,SPIL_LOC(cond)->rname);
7937 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
7941 if (isbit && !IS_ITEMP(cond))
7942 DEBUGpic14_emitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
7944 DEBUGpic14_emitcode ("; isbit","a");
7947 if (isbit && !IS_ITEMP(cond))
7948 genIfxJump(ic,OP_SYMBOL(cond)->rname);
7955 /*-----------------------------------------------------------------*/
7956 /* genAddrOf - generates code for address of */
7957 /*-----------------------------------------------------------------*/
7958 static void genAddrOf (iCode *ic)
7960 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
7963 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7965 aopOp(IC_RESULT(ic),ic,FALSE);
7967 /* if the operand is on the stack then we
7968 need to get the stack offset of this
7971 /* if it has an offset then we need to compute
7974 pic14_emitcode("mov","a,_bp");
7975 pic14_emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
7976 aopPut(AOP(IC_RESULT(ic)),"a",0);
7978 /* we can just move _bp */
7979 aopPut(AOP(IC_RESULT(ic)),"_bp",0);
7981 /* fill the result with zero */
7982 size = AOP_SIZE(IC_RESULT(ic)) - 1;
7985 if (options.stack10bit && size < (FPTRSIZE - 1))
7988 "*** warning: pointer to stack var truncated.\n");
7995 if (options.stack10bit && offset == 2)
7997 aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
8001 aopPut(AOP(IC_RESULT(ic)),zero,offset++);
8008 /* object not on stack then we need the name */
8009 size = AOP_SIZE(IC_RESULT(ic));
8013 char s[SDCC_NAME_MAX];
8015 sprintf(s,"#(%s >> %d)",
8019 sprintf(s,"#%s",sym->rname);
8020 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8024 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8029 /*-----------------------------------------------------------------*/
8030 /* genFarFarAssign - assignment when both are in far space */
8031 /*-----------------------------------------------------------------*/
8032 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8034 int size = AOP_SIZE(right);
8037 /* first push the right side on to the stack */
8039 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8041 pic14_emitcode ("push","acc");
8044 freeAsmop(right,NULL,ic,FALSE);
8045 /* now assign DPTR to result */
8046 aopOp(result,ic,FALSE);
8047 size = AOP_SIZE(result);
8049 pic14_emitcode ("pop","acc");
8050 aopPut(AOP(result),"a",--offset);
8052 freeAsmop(result,NULL,ic,FALSE);
8057 /*-----------------------------------------------------------------*/
8058 /* genAssign - generate code for assignment */
8059 /*-----------------------------------------------------------------*/
8060 static void genAssign (iCode *ic)
8062 operand *result, *right;
8064 unsigned long lit = 0L;
8066 result = IC_RESULT(ic);
8067 right = IC_RIGHT(ic) ;
8069 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8071 /* if they are the same */
8072 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8075 aopOp(right,ic,FALSE);
8076 aopOp(result,ic,TRUE);
8078 /* if they are the same registers */
8079 if (pic14_sameRegs(AOP(right),AOP(result)))
8082 /* if the result is a bit */
8083 if (AOP_TYPE(result) == AOP_CRY) {
8085 /* if the right size is a literal then
8086 we know what the value is */
8087 if (AOP_TYPE(right) == AOP_LIT) {
8089 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8090 popGet(AOP(result),0,FALSE,FALSE));
8092 if (((int) operandLitValue(right)))
8093 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8094 AOP(result)->aopu.aop_dir,
8095 AOP(result)->aopu.aop_dir);
8097 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8098 AOP(result)->aopu.aop_dir,
8099 AOP(result)->aopu.aop_dir);
8103 /* the right is also a bit variable */
8104 if (AOP_TYPE(right) == AOP_CRY) {
8105 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8106 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8107 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8109 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8110 AOP(result)->aopu.aop_dir,
8111 AOP(result)->aopu.aop_dir);
8112 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8113 AOP(right)->aopu.aop_dir,
8114 AOP(right)->aopu.aop_dir);
8115 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8116 AOP(result)->aopu.aop_dir,
8117 AOP(result)->aopu.aop_dir);
8122 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8123 pic14_toBoolean(right);
8125 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8126 //aopPut(AOP(result),"a",0);
8130 /* bit variables done */
8132 size = AOP_SIZE(result);
8134 if(AOP_TYPE(right) == AOP_LIT)
8135 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8136 if((AOP_TYPE(result) != AOP_REG) &&
8137 (AOP_TYPE(right) == AOP_LIT) &&
8138 !IS_FLOAT(operandType(right)) &&
8142 if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) {
8143 //pic14_emitcode("clrf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8144 emitpcode(POC_CLRF,popGet(AOP(result),size,FALSE,FALSE));
8146 emitpcode(POC_MOVLW,popGet(AOP(right),size,FALSE,FALSE));
8147 emitpcode(POC_MOVWF,popGet(AOP(result),size,FALSE,FALSE));
8148 //pic14_emitcode("movlw","%s", aopGet(AOP(right),size,FALSE,FALSE));
8149 //pic14_emitcode("movwf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8154 if(AOP_TYPE(right) == AOP_LIT) {
8155 emitpcode(POC_MOVLW, popGet(AOP(right),offset,FALSE,FALSE));
8156 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8158 } else if (AOP_TYPE(right) == AOP_CRY) {
8159 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8161 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8162 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8165 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8166 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8169 //pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE));
8175 freeAsmop (right,NULL,ic,FALSE);
8176 freeAsmop (result,NULL,ic,TRUE);
8179 /*-----------------------------------------------------------------*/
8180 /* genJumpTab - genrates code for jump table */
8181 /*-----------------------------------------------------------------*/
8182 static void genJumpTab (iCode *ic)
8187 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8189 aopOp(IC_JTCOND(ic),ic,FALSE);
8190 /* get the condition into accumulator */
8191 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8193 /* multiply by three */
8194 pic14_emitcode("add","a,acc");
8195 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8197 jtab = newiTempLabel(NULL);
8198 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8199 pic14_emitcode("jmp","@a+dptr");
8200 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8202 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8203 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8205 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8206 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8207 emitpLabel(jtab->key+100+labelOffset);
8209 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8211 /* now generate the jump labels */
8212 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8213 jtab = setNextItem(IC_JTLABELS(ic))) {
8214 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8215 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8221 /*-----------------------------------------------------------------*/
8222 /* genMixedOperation - gen code for operators between mixed types */
8223 /*-----------------------------------------------------------------*/
8225 TSD - Written for the PIC port - but this unfortunately is buggy.
8226 This routine is good in that it is able to efficiently promote
8227 types to different (larger) sizes. Unfortunately, the temporary
8228 variables that are optimized out by this routine are sometimes
8229 used in other places. So until I know how to really parse the
8230 iCode tree, I'm going to not be using this routine :(.
8232 static int genMixedOperation (iCode *ic)
8235 operand *result = IC_RESULT(ic);
8236 sym_link *ctype = operandType(IC_LEFT(ic));
8237 operand *right = IC_RIGHT(ic);
8243 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8245 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8251 nextright = IC_RIGHT(nextic);
8252 nextleft = IC_LEFT(nextic);
8253 nextresult = IC_RESULT(nextic);
8255 aopOp(right,ic,FALSE);
8256 aopOp(result,ic,FALSE);
8257 aopOp(nextright, nextic, FALSE);
8258 aopOp(nextleft, nextic, FALSE);
8259 aopOp(nextresult, nextic, FALSE);
8261 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8267 pic14_emitcode(";remove right +","");
8269 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8275 pic14_emitcode(";remove left +","");
8279 big = AOP_SIZE(nextleft);
8280 small = AOP_SIZE(nextright);
8282 switch(nextic->op) {
8285 pic14_emitcode(";optimize a +","");
8286 /* if unsigned or not an integral type */
8287 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8288 pic14_emitcode(";add a bit to something","");
8291 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8293 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8294 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8295 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8297 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8305 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8306 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8307 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8310 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8312 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8313 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8314 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8315 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8316 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8319 pic14_emitcode("rlf","known_zero,w");
8326 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8327 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8328 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8330 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8340 freeAsmop(right,NULL,ic,TRUE);
8341 freeAsmop(result,NULL,ic,TRUE);
8342 freeAsmop(nextright,NULL,ic,TRUE);
8343 freeAsmop(nextleft,NULL,ic,TRUE);
8345 nextic->generated = 1;
8352 /*-----------------------------------------------------------------*/
8353 /* genCast - gen code for casting */
8354 /*-----------------------------------------------------------------*/
8355 static void genCast (iCode *ic)
8357 operand *result = IC_RESULT(ic);
8358 sym_link *ctype = operandType(IC_LEFT(ic));
8359 operand *right = IC_RIGHT(ic);
8362 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8363 /* if they are equivalent then do nothing */
8364 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8367 aopOp(right,ic,FALSE) ;
8368 aopOp(result,ic,FALSE);
8370 /* if the result is a bit */
8371 if (AOP_TYPE(result) == AOP_CRY) {
8372 /* if the right size is a literal then
8373 we know what the value is */
8374 if (AOP_TYPE(right) == AOP_LIT) {
8376 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8377 popGet(AOP(result),0,FALSE,FALSE));
8379 if (((int) operandLitValue(right)))
8380 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8381 AOP(result)->aopu.aop_dir,
8382 AOP(result)->aopu.aop_dir);
8384 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8385 AOP(result)->aopu.aop_dir,
8386 AOP(result)->aopu.aop_dir);
8391 /* the right is also a bit variable */
8392 if (AOP_TYPE(right) == AOP_CRY) {
8395 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8397 pic14_emitcode("clrc","");
8398 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8399 AOP(right)->aopu.aop_dir,
8400 AOP(right)->aopu.aop_dir);
8401 aopPut(AOP(result),"c",0);
8406 pic14_toBoolean(right);
8407 aopPut(AOP(result),"a",0);
8411 /* if they are the same size : or less */
8412 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8414 /* if they are in the same place */
8415 if (pic14_sameRegs(AOP(right),AOP(result)))
8418 /* if they in different places then copy */
8419 size = AOP_SIZE(result);
8423 aopGet(AOP(right),offset,FALSE,FALSE),
8431 /* if the result is of type pointer */
8432 if (IS_PTR(ctype)) {
8435 sym_link *type = operandType(right);
8436 sym_link *etype = getSpec(type);
8438 /* pointer to generic pointer */
8439 if (IS_GENPTR(ctype)) {
8443 p_type = DCL_TYPE(type);
8445 /* we have to go by the storage class */
8446 p_type = PTR_TYPE(SPEC_OCLS(etype));
8448 /* if (SPEC_OCLS(etype)->codesp ) */
8449 /* p_type = CPOINTER ; */
8451 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8452 /* p_type = FPOINTER ; */
8454 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8455 /* p_type = PPOINTER; */
8457 /* if (SPEC_OCLS(etype) == idata ) */
8458 /* p_type = IPOINTER ; */
8460 /* p_type = POINTER ; */
8463 /* the first two bytes are known */
8464 size = GPTRSIZE - 1;
8468 aopGet(AOP(right),offset,FALSE,FALSE),
8472 /* the last byte depending on type */
8489 /* this should never happen */
8490 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8491 "got unknown pointer type");
8494 aopPut(AOP(result),l, GPTRSIZE - 1);
8498 /* just copy the pointers */
8499 size = AOP_SIZE(result);
8503 aopGet(AOP(right),offset,FALSE,FALSE),
8511 if (AOP_TYPE(right) == AOP_CRY) {
8513 size = AOP_SIZE(right);
8515 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8516 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8517 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8519 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8520 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8521 AOP(right)->aopu.aop_dir,
8522 AOP(right)->aopu.aop_dir);
8523 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8525 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8526 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8531 /* so we now know that the size of destination is greater
8532 than the size of the source.
8533 Now, if the next iCode is an operator then we might be
8534 able to optimize the operation without performing a cast.
8536 if(genMixedOperation(ic))
8540 /* we move to result for the size of source */
8541 size = AOP_SIZE(right);
8544 pic14_emitcode(";","%d",__LINE__);
8546 aopGet(AOP(right),offset,FALSE,FALSE),
8551 /* now depending on the sign of the destination */
8552 size = AOP_SIZE(result) - AOP_SIZE(right);
8553 /* if unsigned or not an integral type */
8554 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8556 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8557 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8561 /* we need to extend the sign :{ */
8562 //char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,FALSE,FALSE);
8565 emitpcode(POC_CLRW, NULL);
8566 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8567 emitpcode(POC_MOVLW, popGetLit(0xff));
8569 pic14_emitcode("clrw","");
8570 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8571 AOP(right)->aopu.aop_dir,
8572 AOP(right)->aopu.aop_dir);
8573 pic14_emitcode("movlw","0xff");
8575 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8576 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8578 // aopPut(AOP(result),"a",offset++);
8583 /* we are done hurray !!!! */
8586 freeAsmop(right,NULL,ic,TRUE);
8587 freeAsmop(result,NULL,ic,TRUE);
8591 /*-----------------------------------------------------------------*/
8592 /* genDjnz - generate decrement & jump if not zero instrucion */
8593 /*-----------------------------------------------------------------*/
8594 static int genDjnz (iCode *ic, iCode *ifx)
8597 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8602 /* if the if condition has a false label
8603 then we cannot save */
8607 /* if the minus is not of the form
8609 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8610 !IS_OP_LITERAL(IC_RIGHT(ic)))
8613 if (operandLitValue(IC_RIGHT(ic)) != 1)
8616 /* if the size of this greater than one then no
8618 if (getSize(operandType(IC_RESULT(ic))) > 1)
8621 /* otherwise we can save BIG */
8622 lbl = newiTempLabel(NULL);
8623 lbl1= newiTempLabel(NULL);
8625 aopOp(IC_RESULT(ic),ic,FALSE);
8627 if (IS_AOP_PREG(IC_RESULT(ic))) {
8628 pic14_emitcode("dec","%s",
8629 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8630 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8631 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8635 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8636 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8638 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8639 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8642 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8643 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8644 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8645 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8648 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8653 /*-----------------------------------------------------------------*/
8654 /* genReceive - generate code for a receive iCode */
8655 /*-----------------------------------------------------------------*/
8656 static void genReceive (iCode *ic)
8658 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8660 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8661 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8662 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8664 int size = getSize(operandType(IC_RESULT(ic)));
8665 int offset = fReturnSizePic - size;
8667 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8668 fReturn[fReturnSizePic - offset - 1] : "acc"));
8671 aopOp(IC_RESULT(ic),ic,FALSE);
8672 size = AOP_SIZE(IC_RESULT(ic));
8675 pic14_emitcode ("pop","acc");
8676 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8681 aopOp(IC_RESULT(ic),ic,FALSE);
8683 assignResultValue(IC_RESULT(ic));
8686 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8689 /*-----------------------------------------------------------------*/
8690 /* genpic14Code - generate code for pic14 based controllers */
8691 /*-----------------------------------------------------------------*/
8693 * At this point, ralloc.c has gone through the iCode and attempted
8694 * to optimize in a way suitable for a PIC. Now we've got to generate
8695 * PIC instructions that correspond to the iCode.
8697 * Once the instructions are generated, we'll pass through both the
8698 * peep hole optimizer and the pCode optimizer.
8699 *-----------------------------------------------------------------*/
8701 void genpic14Code (iCode *lic)
8706 lineHead = lineCurr = NULL;
8708 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8711 /* if debug information required */
8712 /* if (options.debug && currFunc) { */
8714 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8716 if (IS_STATIC(currFunc->etype)) {
8717 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8718 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8720 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8721 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8727 for (ic = lic ; ic ; ic = ic->next ) {
8729 DEBUGpic14_emitcode(";ic","");
8730 if ( cln != ic->lineno ) {
8731 if ( options.debug ) {
8733 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8734 FileBaseName(ic->filename),ic->lineno,
8735 ic->level,ic->block);
8738 pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
8741 /* if the result is marked as
8742 spilt and rematerializable or code for
8743 this has already been generated then
8745 if (resultRemat(ic) || ic->generated )
8748 /* depending on the operation */
8767 /* IPOP happens only when trying to restore a
8768 spilt live range, if there is an ifx statement
8769 following this pop then the if statement might
8770 be using some of the registers being popped which
8771 would destory the contents of the register so
8772 we need to check for this condition and handle it */
8774 ic->next->op == IFX &&
8775 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8776 genIfx (ic->next,ic);
8794 genEndFunction (ic);
8814 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
8831 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
8835 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
8842 /* note these two are xlated by algebraic equivalence
8843 during parsing SDCC.y */
8844 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8845 "got '>=' or '<=' shouldn't have come here");
8849 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
8861 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
8865 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
8869 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
8896 case GET_VALUE_AT_ADDRESS:
8901 if (POINTER_SET(ic))
8928 addSet(&_G.sendSet,ic);
8937 /* now we are ready to call the
8938 peep hole optimizer */
8939 if (!options.nopeep) {
8940 printf("peep hole optimizing\n");
8941 peepHole (&lineHead);
8943 /* now do the actual printing */
8944 printLine (lineHead,codeOutFile);
8946 printf("printing pBlock\n\n");
8947 printpBlock(stdout,pb);