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
5582 /*-----------------------------------------------------------------*/
5583 /* AccAXRsh - right shift a:x known count (0..7) */
5584 /*-----------------------------------------------------------------*/
5585 static void AccAXRsh (char *x, int shCount)
5587 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5593 AccAXRrl1(x); // 0->a:x
5597 AccAXRrl1(x); // 0->a:x
5599 AccAXRrl1(x); // 0->a:x
5603 case 5 : // AAAAABBB:CCCCCDDD = a:x
5604 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5605 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5606 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5607 pic14_emitcode("anl","a,#0x%02x",
5608 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5609 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5610 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5611 pic14_emitcode("anl","a,#0x%02x",
5612 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5613 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5614 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5615 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5617 case 6 : // AABBBBBB:CCDDDDDD
5618 pic14_emitcode("mov","c,acc.7");
5619 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5620 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5621 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5622 pic14_emitcode("anl","a,#0x%02x",
5623 SRMask[shCount]); // 000000AA:BBBBBBCC
5625 case 7 : // ABBBBBBB:CDDDDDDD
5626 pic14_emitcode("mov","c,acc.7"); // c = A
5627 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5628 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5629 pic14_emitcode("anl","a,#0x%02x",
5630 SRMask[shCount]); // 0000000A:BBBBBBBC
5637 /*-----------------------------------------------------------------*/
5638 /* AccAXRshS - right shift signed a:x known count (0..7) */
5639 /*-----------------------------------------------------------------*/
5640 static void AccAXRshS (char *x, int shCount)
5643 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5648 pic14_emitcode("mov","c,acc.7");
5649 AccAXRrl1(x); // s->a:x
5652 pic14_emitcode("mov","c,acc.7");
5653 AccAXRrl1(x); // s->a:x
5654 pic14_emitcode("mov","c,acc.7");
5655 AccAXRrl1(x); // s->a:x
5659 case 5 : // AAAAABBB:CCCCCDDD = a:x
5660 tlbl = newiTempLabel(NULL);
5661 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
5662 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5663 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5664 pic14_emitcode("anl","a,#0x%02x",
5665 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5666 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5667 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5668 pic14_emitcode("anl","a,#0x%02x",
5669 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5670 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5671 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5672 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
5673 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5674 pic14_emitcode("orl","a,#0x%02x",
5675 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5676 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5677 break; // SSSSAAAA:BBBCCCCC
5678 case 6 : // AABBBBBB:CCDDDDDD
5679 tlbl = newiTempLabel(NULL);
5680 pic14_emitcode("mov","c,acc.7");
5681 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5682 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5683 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5684 pic14_emitcode("anl","a,#0x%02x",
5685 SRMask[shCount]); // 000000AA:BBBBBBCC
5686 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5687 pic14_emitcode("orl","a,#0x%02x",
5688 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
5689 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5691 case 7 : // ABBBBBBB:CDDDDDDD
5692 tlbl = newiTempLabel(NULL);
5693 pic14_emitcode("mov","c,acc.7"); // c = A
5694 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5695 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5696 pic14_emitcode("anl","a,#0x%02x",
5697 SRMask[shCount]); // 0000000A:BBBBBBBC
5698 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5699 pic14_emitcode("orl","a,#0x%02x",
5700 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
5701 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5708 /*-----------------------------------------------------------------*/
5709 /* shiftL2Left2Result - shift left two bytes from left to result */
5710 /*-----------------------------------------------------------------*/
5711 static void shiftL2Left2Result (operand *left, int offl,
5712 operand *result, int offr, int shCount)
5716 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5718 if(pic14_sameRegs(AOP(result), AOP(left))) {
5726 emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
5727 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5728 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5732 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5733 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5739 emitpcode(POC_MOVLW, popGetLit(0x0f));
5740 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5741 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5742 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5743 emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
5744 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5745 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5747 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5748 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5752 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5753 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5754 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5755 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5756 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5757 emitpcode(POC_ANDLW,popGetLit(0xc0));
5758 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5759 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5760 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5761 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5764 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5765 emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
5766 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5767 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5768 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5778 /* note, use a mov/add for the shift since the mov has a
5779 chance of getting optimized out */
5780 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5781 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5782 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5783 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5784 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5788 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5789 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5795 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5796 emitpcode(POC_ANDLW, popGetLit(0xF0));
5797 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5798 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5799 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5800 emitpcode(POC_ANDLW, popGetLit(0xF0));
5801 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
5802 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5806 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5807 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5811 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5812 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5813 emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
5814 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5816 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5817 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5818 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5819 emitpcode(POC_ANDLW,popGetLit(0xc0));
5820 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5821 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
5822 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
5823 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5826 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5827 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5828 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5829 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5830 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5835 /*-----------------------------------------------------------------*/
5836 /* shiftR2Left2Result - shift right two bytes from left to result */
5837 /*-----------------------------------------------------------------*/
5838 static void shiftR2Left2Result (operand *left, int offl,
5839 operand *result, int offr,
5840 int shCount, int sign)
5844 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5845 same = pic14_sameRegs(AOP(result), AOP(left));
5847 if(same && ((offl + MSB16) == offr)){
5849 /* don't crash result[offr] */
5850 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5851 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5853 movLeft2Result(left,offl, result, offr, 0);
5854 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5856 /* a:x >> shCount (x = lsb(result))*/
5858 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5860 //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5870 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5871 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5874 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5875 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5876 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5877 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5882 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5883 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
5890 emitpcode(POC_MOVLW, popGetLit(0xf0));
5891 emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
5892 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5894 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5895 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5896 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5897 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5899 emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
5900 emitpcode(POC_ANDLW, popGetLit(0x0f));
5901 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5903 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5904 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5905 emitpcode(POC_ANDLW, popGetLit(0xf0));
5906 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5907 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
5911 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5912 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5920 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5921 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5923 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5924 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5925 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5926 emitpcode(POC_ANDLW,popGetLit(0x03));
5927 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5928 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5929 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5930 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5932 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5933 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5934 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
5935 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5936 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5937 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5938 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5939 emitpcode(POC_ANDLW,popGetLit(0x03));
5940 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5945 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5946 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
5947 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5948 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5949 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
5954 /*-----------------------------------------------------------------*/
5955 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
5956 /*-----------------------------------------------------------------*/
5957 static void shiftLLeftOrResult (operand *left, int offl,
5958 operand *result, int offr, int shCount)
5960 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5961 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5962 /* shift left accumulator */
5964 /* or with result */
5965 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5966 /* back to result */
5967 aopPut(AOP(result),"a",offr);
5970 /*-----------------------------------------------------------------*/
5971 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
5972 /*-----------------------------------------------------------------*/
5973 static void shiftRLeftOrResult (operand *left, int offl,
5974 operand *result, int offr, int shCount)
5976 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5977 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5978 /* shift right accumulator */
5980 /* or with result */
5981 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5982 /* back to result */
5983 aopPut(AOP(result),"a",offr);
5986 /*-----------------------------------------------------------------*/
5987 /* genlshOne - left shift a one byte quantity by known count */
5988 /*-----------------------------------------------------------------*/
5989 static void genlshOne (operand *result, operand *left, int shCount)
5991 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5992 shiftL1Left2Result(left, LSB, result, LSB, shCount);
5995 /*-----------------------------------------------------------------*/
5996 /* genlshTwo - left shift two bytes by known amount != 0 */
5997 /*-----------------------------------------------------------------*/
5998 static void genlshTwo (operand *result,operand *left, int shCount)
6002 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6003 size = pic14_getDataSize(result);
6005 /* if shCount >= 8 */
6011 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6013 movLeft2Result(left, LSB, result, MSB16, 0);
6015 emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6018 /* 1 <= shCount <= 7 */
6021 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6023 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6027 /*-----------------------------------------------------------------*/
6028 /* shiftLLong - shift left one long from left to result */
6029 /* offl = LSB or MSB16 */
6030 /*-----------------------------------------------------------------*/
6031 static void shiftLLong (operand *left, operand *result, int offr )
6034 int size = AOP_SIZE(result);
6036 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6037 if(size >= LSB+offr){
6038 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6040 pic14_emitcode("add","a,acc");
6041 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6042 size >= MSB16+offr && offr != LSB )
6043 pic14_emitcode("xch","a,%s",
6044 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6046 aopPut(AOP(result),"a",LSB+offr);
6049 if(size >= MSB16+offr){
6050 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6051 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6054 pic14_emitcode("rlc","a");
6055 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6056 size >= MSB24+offr && offr != LSB)
6057 pic14_emitcode("xch","a,%s",
6058 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6060 aopPut(AOP(result),"a",MSB16+offr);
6063 if(size >= MSB24+offr){
6064 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6065 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6068 pic14_emitcode("rlc","a");
6069 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6070 size >= MSB32+offr && offr != LSB )
6071 pic14_emitcode("xch","a,%s",
6072 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6074 aopPut(AOP(result),"a",MSB24+offr);
6077 if(size > MSB32+offr){
6078 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6079 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6082 pic14_emitcode("rlc","a");
6083 aopPut(AOP(result),"a",MSB32+offr);
6086 aopPut(AOP(result),zero,LSB);
6089 /*-----------------------------------------------------------------*/
6090 /* genlshFour - shift four byte by a known amount != 0 */
6091 /*-----------------------------------------------------------------*/
6092 static void genlshFour (operand *result, operand *left, int shCount)
6096 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6097 size = AOP_SIZE(result);
6099 /* if shifting more that 3 bytes */
6100 if (shCount >= 24 ) {
6103 /* lowest order of left goes to the highest
6104 order of the destination */
6105 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6107 movLeft2Result(left, LSB, result, MSB32, 0);
6108 aopPut(AOP(result),zero,LSB);
6109 aopPut(AOP(result),zero,MSB16);
6110 aopPut(AOP(result),zero,MSB32);
6114 /* more than two bytes */
6115 else if ( shCount >= 16 ) {
6116 /* lower order two bytes goes to higher order two bytes */
6118 /* if some more remaining */
6120 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6122 movLeft2Result(left, MSB16, result, MSB32, 0);
6123 movLeft2Result(left, LSB, result, MSB24, 0);
6125 aopPut(AOP(result),zero,MSB16);
6126 aopPut(AOP(result),zero,LSB);
6130 /* if more than 1 byte */
6131 else if ( shCount >= 8 ) {
6132 /* lower order three bytes goes to higher order three bytes */
6136 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6138 movLeft2Result(left, LSB, result, MSB16, 0);
6140 else{ /* size = 4 */
6142 movLeft2Result(left, MSB24, result, MSB32, 0);
6143 movLeft2Result(left, MSB16, result, MSB24, 0);
6144 movLeft2Result(left, LSB, result, MSB16, 0);
6145 aopPut(AOP(result),zero,LSB);
6147 else if(shCount == 1)
6148 shiftLLong(left, result, MSB16);
6150 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6151 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6152 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6153 aopPut(AOP(result),zero,LSB);
6158 /* 1 <= shCount <= 7 */
6159 else if(shCount <= 2){
6160 shiftLLong(left, result, LSB);
6162 shiftLLong(result, result, LSB);
6164 /* 3 <= shCount <= 7, optimize */
6166 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6167 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6168 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6172 /*-----------------------------------------------------------------*/
6173 /* genLeftShiftLiteral - left shifting by known count */
6174 /*-----------------------------------------------------------------*/
6175 static void genLeftShiftLiteral (operand *left,
6180 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6183 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6184 freeAsmop(right,NULL,ic,TRUE);
6186 aopOp(left,ic,FALSE);
6187 aopOp(result,ic,FALSE);
6189 size = getSize(operandType(result));
6192 pic14_emitcode("; shift left ","result %d, left %d",size,
6196 /* I suppose that the left size >= result size */
6199 movLeft2Result(left, size, result, size, 0);
6203 else if(shCount >= (size * 8))
6205 aopPut(AOP(result),zero,size);
6209 genlshOne (result,left,shCount);
6214 genlshTwo (result,left,shCount);
6218 genlshFour (result,left,shCount);
6222 freeAsmop(left,NULL,ic,TRUE);
6223 freeAsmop(result,NULL,ic,TRUE);
6226 /*-----------------------------------------------------------------*/
6227 /* genLeftShift - generates code for left shifting */
6228 /*-----------------------------------------------------------------*/
6229 static void genLeftShift (iCode *ic)
6231 operand *left,*right, *result;
6234 symbol *tlbl , *tlbl1;
6236 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6238 right = IC_RIGHT(ic);
6240 result = IC_RESULT(ic);
6242 aopOp(right,ic,FALSE);
6244 /* if the shift count is known then do it
6245 as efficiently as possible */
6246 if (AOP_TYPE(right) == AOP_LIT) {
6247 genLeftShiftLiteral (left,right,result,ic);
6251 /* shift count is unknown then we have to form
6252 a loop get the loop count in B : Note: we take
6253 only the lower order byte since shifting
6254 more that 32 bits make no sense anyway, ( the
6255 largest size of an object can be only 32 bits ) */
6258 aopOp(left,ic,FALSE);
6259 aopOp(result,ic,FALSE);
6261 /* now move the left to the result if they are not the
6263 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6264 AOP_SIZE(result) > 1) {
6266 size = AOP_SIZE(result);
6269 l = aopGet(AOP(left),offset,FALSE,TRUE);
6270 if (*l == '@' && (IS_AOP_PREG(result))) {
6272 pic14_emitcode("mov","a,%s",l);
6273 aopPut(AOP(result),"a",offset);
6275 aopPut(AOP(result),l,offset);
6280 size = AOP_SIZE(result);
6282 /* if it is only one byte then */
6284 if(optimized_for_speed) {
6285 emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6286 emitpcode(POC_ANDLW, popGetLit(0xf0));
6287 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6288 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6289 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6290 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6291 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6292 emitpcode(POC_RLFW, popGet(AOP(result),0,FALSE,FALSE));
6293 emitpcode(POC_ANDLW, popGetLit(0xfe));
6294 emitpcode(POC_ADDFW, popGet(AOP(result),0,FALSE,FALSE));
6295 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6296 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6299 tlbl = newiTempLabel(NULL);
6300 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6301 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6302 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6305 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6306 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6307 emitpLabel(tlbl->key+100+labelOffset);
6308 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6309 emitpcode(POC_ADDLW, popGetLit(1));
6311 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6317 tlbl = newiTempLabel(NULL);
6319 tlbl1 = newiTempLabel(NULL);
6321 reAdjustPreg(AOP(result));
6323 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6324 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6325 l = aopGet(AOP(result),offset,FALSE,FALSE);
6327 pic14_emitcode("add","a,acc");
6328 aopPut(AOP(result),"a",offset++);
6330 l = aopGet(AOP(result),offset,FALSE,FALSE);
6332 pic14_emitcode("rlc","a");
6333 aopPut(AOP(result),"a",offset++);
6335 reAdjustPreg(AOP(result));
6337 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6338 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6340 freeAsmop (right,NULL,ic,TRUE);
6341 freeAsmop(left,NULL,ic,TRUE);
6342 freeAsmop(result,NULL,ic,TRUE);
6345 /*-----------------------------------------------------------------*/
6346 /* genrshOne - right shift a one byte quantity by known count */
6347 /*-----------------------------------------------------------------*/
6348 static void genrshOne (operand *result, operand *left,
6349 int shCount, int sign)
6351 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6352 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6355 /*-----------------------------------------------------------------*/
6356 /* genrshTwo - right shift two bytes by known amount != 0 */
6357 /*-----------------------------------------------------------------*/
6358 static void genrshTwo (operand *result,operand *left,
6359 int shCount, int sign)
6361 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6362 /* if shCount >= 8 */
6366 shiftR1Left2Result(left, MSB16, result, LSB,
6369 movLeft2Result(left, MSB16, result, LSB, sign);
6371 addSign(result, MSB16, sign);
6373 emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6377 /* 1 <= shCount <= 7 */
6379 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6382 /*-----------------------------------------------------------------*/
6383 /* shiftRLong - shift right one long from left to result */
6384 /* offl = LSB or MSB16 */
6385 /*-----------------------------------------------------------------*/
6386 static void shiftRLong (operand *left, int offl,
6387 operand *result, int sign)
6389 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6391 pic14_emitcode("clr","c");
6392 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6394 pic14_emitcode("mov","c,acc.7");
6395 pic14_emitcode("rrc","a");
6396 aopPut(AOP(result),"a",MSB32-offl);
6398 /* add sign of "a" */
6399 addSign(result, MSB32, sign);
6401 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6402 pic14_emitcode("rrc","a");
6403 aopPut(AOP(result),"a",MSB24-offl);
6405 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6406 pic14_emitcode("rrc","a");
6407 aopPut(AOP(result),"a",MSB16-offl);
6410 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6411 pic14_emitcode("rrc","a");
6412 aopPut(AOP(result),"a",LSB);
6416 /*-----------------------------------------------------------------*/
6417 /* genrshFour - shift four byte by a known amount != 0 */
6418 /*-----------------------------------------------------------------*/
6419 static void genrshFour (operand *result, operand *left,
6420 int shCount, int sign)
6422 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6423 /* if shifting more that 3 bytes */
6424 if(shCount >= 24 ) {
6427 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6429 movLeft2Result(left, MSB32, result, LSB, sign);
6430 addSign(result, MSB16, sign);
6432 else if(shCount >= 16){
6435 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6437 movLeft2Result(left, MSB24, result, LSB, 0);
6438 movLeft2Result(left, MSB32, result, MSB16, sign);
6440 addSign(result, MSB24, sign);
6442 else if(shCount >= 8){
6445 shiftRLong(left, MSB16, result, sign);
6446 else if(shCount == 0){
6447 movLeft2Result(left, MSB16, result, LSB, 0);
6448 movLeft2Result(left, MSB24, result, MSB16, 0);
6449 movLeft2Result(left, MSB32, result, MSB24, sign);
6450 addSign(result, MSB32, sign);
6453 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6454 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6455 /* the last shift is signed */
6456 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6457 addSign(result, MSB32, sign);
6460 else{ /* 1 <= shCount <= 7 */
6462 shiftRLong(left, LSB, result, sign);
6464 shiftRLong(result, LSB, result, sign);
6467 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6468 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6469 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6474 /*-----------------------------------------------------------------*/
6475 /* genRightShiftLiteral - right shifting by known count */
6476 /*-----------------------------------------------------------------*/
6477 static void genRightShiftLiteral (operand *left,
6483 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6486 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6487 freeAsmop(right,NULL,ic,TRUE);
6489 aopOp(left,ic,FALSE);
6490 aopOp(result,ic,FALSE);
6493 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6497 size = pic14_getDataSize(left);
6498 /* test the LEFT size !!! */
6500 /* I suppose that the left size >= result size */
6502 size = pic14_getDataSize(result);
6504 movLeft2Result(left, size, result, size, 0);
6507 else if(shCount >= (size * 8)){
6509 /* get sign in acc.7 */
6510 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6511 addSign(result, LSB, sign);
6515 genrshOne (result,left,shCount,sign);
6519 genrshTwo (result,left,shCount,sign);
6523 genrshFour (result,left,shCount,sign);
6529 freeAsmop(left,NULL,ic,TRUE);
6530 freeAsmop(result,NULL,ic,TRUE);
6534 /*-----------------------------------------------------------------*/
6535 /* genSignedRightShift - right shift of signed number */
6536 /*-----------------------------------------------------------------*/
6537 static void genSignedRightShift (iCode *ic)
6539 operand *right, *left, *result;
6542 symbol *tlbl, *tlbl1 ;
6544 /* we do it the hard way put the shift count in b
6545 and loop thru preserving the sign */
6546 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6548 right = IC_RIGHT(ic);
6550 result = IC_RESULT(ic);
6552 aopOp(right,ic,FALSE);
6555 if ( AOP_TYPE(right) == AOP_LIT) {
6556 genRightShiftLiteral (left,right,result,ic,1);
6559 /* shift count is unknown then we have to form
6560 a loop get the loop count in B : Note: we take
6561 only the lower order byte since shifting
6562 more that 32 bits make no sense anyway, ( the
6563 largest size of an object can be only 32 bits ) */
6565 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6566 pic14_emitcode("inc","b");
6567 freeAsmop (right,NULL,ic,TRUE);
6568 aopOp(left,ic,FALSE);
6569 aopOp(result,ic,FALSE);
6571 /* now move the left to the result if they are not the
6573 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6574 AOP_SIZE(result) > 1) {
6576 size = AOP_SIZE(result);
6579 l = aopGet(AOP(left),offset,FALSE,TRUE);
6580 if (*l == '@' && IS_AOP_PREG(result)) {
6582 pic14_emitcode("mov","a,%s",l);
6583 aopPut(AOP(result),"a",offset);
6585 aopPut(AOP(result),l,offset);
6590 /* mov the highest order bit to OVR */
6591 tlbl = newiTempLabel(NULL);
6592 tlbl1= newiTempLabel(NULL);
6594 size = AOP_SIZE(result);
6596 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6597 pic14_emitcode("rlc","a");
6598 pic14_emitcode("mov","ov,c");
6599 /* if it is only one byte then */
6601 l = aopGet(AOP(left),0,FALSE,FALSE);
6603 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6604 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6605 pic14_emitcode("mov","c,ov");
6606 pic14_emitcode("rrc","a");
6607 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6608 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6609 aopPut(AOP(result),"a",0);
6613 reAdjustPreg(AOP(result));
6614 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6615 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6616 pic14_emitcode("mov","c,ov");
6618 l = aopGet(AOP(result),offset,FALSE,FALSE);
6620 pic14_emitcode("rrc","a");
6621 aopPut(AOP(result),"a",offset--);
6623 reAdjustPreg(AOP(result));
6624 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6625 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6628 freeAsmop(left,NULL,ic,TRUE);
6629 freeAsmop(result,NULL,ic,TRUE);
6632 /*-----------------------------------------------------------------*/
6633 /* genRightShift - generate code for right shifting */
6634 /*-----------------------------------------------------------------*/
6635 static void genRightShift (iCode *ic)
6637 operand *right, *left, *result;
6641 symbol *tlbl, *tlbl1 ;
6643 /* if signed then we do it the hard way preserve the
6644 sign bit moving it inwards */
6645 retype = getSpec(operandType(IC_RESULT(ic)));
6646 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6648 if (!SPEC_USIGN(retype)) {
6649 genSignedRightShift (ic);
6653 /* signed & unsigned types are treated the same : i.e. the
6654 signed is NOT propagated inwards : quoting from the
6655 ANSI - standard : "for E1 >> E2, is equivalent to division
6656 by 2**E2 if unsigned or if it has a non-negative value,
6657 otherwise the result is implementation defined ", MY definition
6658 is that the sign does not get propagated */
6660 right = IC_RIGHT(ic);
6662 result = IC_RESULT(ic);
6664 aopOp(right,ic,FALSE);
6666 /* if the shift count is known then do it
6667 as efficiently as possible */
6668 if (AOP_TYPE(right) == AOP_LIT) {
6669 genRightShiftLiteral (left,right,result,ic, 0);
6673 /* shift count is unknown then we have to form
6674 a loop get the loop count in B : Note: we take
6675 only the lower order byte since shifting
6676 more that 32 bits make no sense anyway, ( the
6677 largest size of an object can be only 32 bits ) */
6679 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6680 pic14_emitcode("inc","b");
6681 aopOp(left,ic,FALSE);
6682 aopOp(result,ic,FALSE);
6684 /* now move the left to the result if they are not the
6686 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6687 AOP_SIZE(result) > 1) {
6689 size = AOP_SIZE(result);
6692 l = aopGet(AOP(left),offset,FALSE,TRUE);
6693 if (*l == '@' && IS_AOP_PREG(result)) {
6695 pic14_emitcode("mov","a,%s",l);
6696 aopPut(AOP(result),"a",offset);
6698 aopPut(AOP(result),l,offset);
6703 tlbl = newiTempLabel(NULL);
6704 tlbl1= newiTempLabel(NULL);
6705 size = AOP_SIZE(result);
6708 /* if it is only one byte then */
6711 l = aopGet(AOP(left),0,FALSE,FALSE);
6713 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6714 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6716 pic14_emitcode("rrc","a");
6717 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6718 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6719 aopPut(AOP(result),"a",0);
6721 tlbl = newiTempLabel(NULL);
6722 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6723 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6724 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6727 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6728 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6729 emitpLabel(tlbl->key+100+labelOffset);
6730 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6731 emitpcode(POC_ADDLW, popGetLit(1));
6733 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6738 reAdjustPreg(AOP(result));
6739 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6740 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6743 l = aopGet(AOP(result),offset,FALSE,FALSE);
6745 pic14_emitcode("rrc","a");
6746 aopPut(AOP(result),"a",offset--);
6748 reAdjustPreg(AOP(result));
6750 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6751 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6754 freeAsmop(left,NULL,ic,TRUE);
6755 freeAsmop (right,NULL,ic,TRUE);
6756 freeAsmop(result,NULL,ic,TRUE);
6759 /*-----------------------------------------------------------------*/
6760 /* genUnpackBits - generates code for unpacking bits */
6761 /*-----------------------------------------------------------------*/
6762 static void genUnpackBits (operand *result, char *rname, int ptype)
6769 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6770 etype = getSpec(operandType(result));
6772 /* read the first byte */
6777 pic14_emitcode("mov","a,@%s",rname);
6781 pic14_emitcode("movx","a,@%s",rname);
6785 pic14_emitcode("movx","a,@dptr");
6789 pic14_emitcode("clr","a");
6790 pic14_emitcode("movc","a","@a+dptr");
6794 pic14_emitcode("lcall","__gptrget");
6798 /* if we have bitdisplacement then it fits */
6799 /* into this byte completely or if length is */
6800 /* less than a byte */
6801 if ((shCnt = SPEC_BSTR(etype)) ||
6802 (SPEC_BLEN(etype) <= 8)) {
6804 /* shift right acc */
6807 pic14_emitcode("anl","a,#0x%02x",
6808 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6809 aopPut(AOP(result),"a",offset);
6813 /* bit field did not fit in a byte */
6814 rlen = SPEC_BLEN(etype) - 8;
6815 aopPut(AOP(result),"a",offset++);
6822 pic14_emitcode("inc","%s",rname);
6823 pic14_emitcode("mov","a,@%s",rname);
6827 pic14_emitcode("inc","%s",rname);
6828 pic14_emitcode("movx","a,@%s",rname);
6832 pic14_emitcode("inc","dptr");
6833 pic14_emitcode("movx","a,@dptr");
6837 pic14_emitcode("clr","a");
6838 pic14_emitcode("inc","dptr");
6839 pic14_emitcode("movc","a","@a+dptr");
6843 pic14_emitcode("inc","dptr");
6844 pic14_emitcode("lcall","__gptrget");
6849 /* if we are done */
6853 aopPut(AOP(result),"a",offset++);
6858 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
6859 aopPut(AOP(result),"a",offset);
6866 /*-----------------------------------------------------------------*/
6867 /* genDataPointerGet - generates code when ptr offset is known */
6868 /*-----------------------------------------------------------------*/
6869 static void genDataPointerGet (operand *left,
6873 int size , offset = 0;
6876 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6879 /* optimization - most of the time, left and result are the same
6880 * address, but different types. for the pic code, we could omit
6884 aopOp(result,ic,TRUE);
6886 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
6888 size = AOP_SIZE(result);
6891 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
6895 freeAsmop(left,NULL,ic,TRUE);
6896 freeAsmop(result,NULL,ic,TRUE);
6899 /*-----------------------------------------------------------------*/
6900 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
6901 /*-----------------------------------------------------------------*/
6902 static void genNearPointerGet (operand *left,
6909 sym_link *rtype, *retype;
6910 sym_link *ltype = operandType(left);
6913 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6915 rtype = operandType(result);
6916 retype= getSpec(rtype);
6918 aopOp(left,ic,FALSE);
6920 /* if left is rematerialisable and
6921 result is not bit variable type and
6922 the left is pointer to data space i.e
6923 lower 128 bytes of space */
6924 if (AOP_TYPE(left) == AOP_IMMD &&
6925 !IS_BITVAR(retype) &&
6926 DCL_TYPE(ltype) == POINTER) {
6927 genDataPointerGet (left,result,ic);
6931 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6933 /* if the value is already in a pointer register
6934 then don't need anything more */
6935 if (!AOP_INPREG(AOP(left))) {
6936 /* otherwise get a free pointer register */
6937 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6939 preg = getFreePtr(ic,&aop,FALSE);
6940 pic14_emitcode("mov","%s,%s",
6942 aopGet(AOP(left),0,FALSE,TRUE));
6943 rname = preg->name ;
6945 rname = aopGet(AOP(left),0,FALSE,FALSE);
6947 freeAsmop(left,NULL,ic,TRUE);
6948 aopOp (result,ic,FALSE);
6950 /* if bitfield then unpack the bits */
6951 if (IS_BITVAR(retype))
6952 genUnpackBits (result,rname,POINTER);
6954 /* we have can just get the values */
6955 int size = AOP_SIZE(result);
6958 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6960 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
6962 pic14_emitcode("mov","a,@%s",rname);
6963 aopPut(AOP(result),"a",offset);
6965 sprintf(buffer,"@%s",rname);
6966 aopPut(AOP(result),buffer,offset);
6970 pic14_emitcode("inc","%s",rname);
6974 /* now some housekeeping stuff */
6976 /* we had to allocate for this iCode */
6977 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6978 freeAsmop(NULL,aop,ic,TRUE);
6980 /* we did not allocate which means left
6981 already in a pointer register, then
6982 if size > 0 && this could be used again
6983 we have to point it back to where it
6985 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6986 if (AOP_SIZE(result) > 1 &&
6987 !OP_SYMBOL(left)->remat &&
6988 ( OP_SYMBOL(left)->liveTo > ic->seq ||
6990 int size = AOP_SIZE(result) - 1;
6992 pic14_emitcode("dec","%s",rname);
6997 freeAsmop(result,NULL,ic,TRUE);
7001 /*-----------------------------------------------------------------*/
7002 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7003 /*-----------------------------------------------------------------*/
7004 static void genPagedPointerGet (operand *left,
7011 sym_link *rtype, *retype;
7013 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7015 rtype = operandType(result);
7016 retype= getSpec(rtype);
7018 aopOp(left,ic,FALSE);
7020 /* if the value is already in a pointer register
7021 then don't need anything more */
7022 if (!AOP_INPREG(AOP(left))) {
7023 /* otherwise get a free pointer register */
7025 preg = getFreePtr(ic,&aop,FALSE);
7026 pic14_emitcode("mov","%s,%s",
7028 aopGet(AOP(left),0,FALSE,TRUE));
7029 rname = preg->name ;
7031 rname = aopGet(AOP(left),0,FALSE,FALSE);
7033 freeAsmop(left,NULL,ic,TRUE);
7034 aopOp (result,ic,FALSE);
7036 /* if bitfield then unpack the bits */
7037 if (IS_BITVAR(retype))
7038 genUnpackBits (result,rname,PPOINTER);
7040 /* we have can just get the values */
7041 int size = AOP_SIZE(result);
7046 pic14_emitcode("movx","a,@%s",rname);
7047 aopPut(AOP(result),"a",offset);
7052 pic14_emitcode("inc","%s",rname);
7056 /* now some housekeeping stuff */
7058 /* we had to allocate for this iCode */
7059 freeAsmop(NULL,aop,ic,TRUE);
7061 /* we did not allocate which means left
7062 already in a pointer register, then
7063 if size > 0 && this could be used again
7064 we have to point it back to where it
7066 if (AOP_SIZE(result) > 1 &&
7067 !OP_SYMBOL(left)->remat &&
7068 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7070 int size = AOP_SIZE(result) - 1;
7072 pic14_emitcode("dec","%s",rname);
7077 freeAsmop(result,NULL,ic,TRUE);
7082 /*-----------------------------------------------------------------*/
7083 /* genFarPointerGet - gget value from far space */
7084 /*-----------------------------------------------------------------*/
7085 static void genFarPointerGet (operand *left,
7086 operand *result, iCode *ic)
7089 sym_link *retype = getSpec(operandType(result));
7091 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7093 aopOp(left,ic,FALSE);
7095 /* if the operand is already in dptr
7096 then we do nothing else we move the value to dptr */
7097 if (AOP_TYPE(left) != AOP_STR) {
7098 /* if this is remateriazable */
7099 if (AOP_TYPE(left) == AOP_IMMD)
7100 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7101 else { /* we need to get it byte by byte */
7102 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7103 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7104 if (options.model == MODEL_FLAT24)
7106 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7110 /* so dptr know contains the address */
7111 freeAsmop(left,NULL,ic,TRUE);
7112 aopOp(result,ic,FALSE);
7114 /* if bit then unpack */
7115 if (IS_BITVAR(retype))
7116 genUnpackBits(result,"dptr",FPOINTER);
7118 size = AOP_SIZE(result);
7122 pic14_emitcode("movx","a,@dptr");
7123 aopPut(AOP(result),"a",offset++);
7125 pic14_emitcode("inc","dptr");
7129 freeAsmop(result,NULL,ic,TRUE);
7132 /*-----------------------------------------------------------------*/
7133 /* pic14_emitcodePointerGet - gget value from code space */
7134 /*-----------------------------------------------------------------*/
7135 static void pic14_emitcodePointerGet (operand *left,
7136 operand *result, iCode *ic)
7139 sym_link *retype = getSpec(operandType(result));
7141 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7143 aopOp(left,ic,FALSE);
7145 /* if the operand is already in dptr
7146 then we do nothing else we move the value to dptr */
7147 if (AOP_TYPE(left) != AOP_STR) {
7148 /* if this is remateriazable */
7149 if (AOP_TYPE(left) == AOP_IMMD)
7150 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7151 else { /* we need to get it byte by byte */
7152 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7153 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7154 if (options.model == MODEL_FLAT24)
7156 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7160 /* so dptr know contains the address */
7161 freeAsmop(left,NULL,ic,TRUE);
7162 aopOp(result,ic,FALSE);
7164 /* if bit then unpack */
7165 if (IS_BITVAR(retype))
7166 genUnpackBits(result,"dptr",CPOINTER);
7168 size = AOP_SIZE(result);
7172 pic14_emitcode("clr","a");
7173 pic14_emitcode("movc","a,@a+dptr");
7174 aopPut(AOP(result),"a",offset++);
7176 pic14_emitcode("inc","dptr");
7180 freeAsmop(result,NULL,ic,TRUE);
7183 /*-----------------------------------------------------------------*/
7184 /* genGenPointerGet - gget value from generic pointer space */
7185 /*-----------------------------------------------------------------*/
7186 static void genGenPointerGet (operand *left,
7187 operand *result, iCode *ic)
7190 sym_link *retype = getSpec(operandType(result));
7192 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7193 aopOp(left,ic,FALSE);
7195 /* if the operand is already in dptr
7196 then we do nothing else we move the value to dptr */
7197 if (AOP_TYPE(left) != AOP_STR) {
7198 /* if this is remateriazable */
7199 if (AOP_TYPE(left) == AOP_IMMD) {
7200 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7201 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7203 else { /* we need to get it byte by byte */
7204 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7205 //emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
7206 //emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7207 pic14_emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
7208 pic14_emitcode("movwf","FSR");
7210 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7211 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7212 if (options.model == MODEL_FLAT24)
7214 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7215 pic14_emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
7219 pic14_emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
7224 /* so dptr know contains the address */
7225 freeAsmop(left,NULL,ic,TRUE);
7226 aopOp(result,ic,FALSE);
7228 /* if bit then unpack */
7229 if (IS_BITVAR(retype))
7230 genUnpackBits(result,"dptr",GPOINTER);
7232 size = AOP_SIZE(result);
7236 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7238 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7240 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7242 pic14_emitcode("movf","indf,w");
7243 pic14_emitcode("movwf","%s",
7244 aopGet(AOP(result),offset++,FALSE,FALSE));
7246 pic14_emitcode("incf","fsr,f");
7251 freeAsmop(result,NULL,ic,TRUE);
7254 /*-----------------------------------------------------------------*/
7255 /* genPointerGet - generate code for pointer get */
7256 /*-----------------------------------------------------------------*/
7257 static void genPointerGet (iCode *ic)
7259 operand *left, *result ;
7260 sym_link *type, *etype;
7263 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7266 result = IC_RESULT(ic) ;
7268 /* depending on the type of pointer we need to
7269 move it to the correct pointer register */
7270 type = operandType(left);
7271 etype = getSpec(type);
7272 /* if left is of type of pointer then it is simple */
7273 if (IS_PTR(type) && !IS_FUNC(type->next))
7274 p_type = DCL_TYPE(type);
7276 /* we have to go by the storage class */
7277 p_type = PTR_TYPE(SPEC_OCLS(etype));
7279 /* if (SPEC_OCLS(etype)->codesp ) { */
7280 /* p_type = CPOINTER ; */
7283 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7284 /* p_type = FPOINTER ; */
7286 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7287 /* p_type = PPOINTER; */
7289 /* if (SPEC_OCLS(etype) == idata ) */
7290 /* p_type = IPOINTER; */
7292 /* p_type = POINTER ; */
7295 /* now that we have the pointer type we assign
7296 the pointer values */
7301 genNearPointerGet (left,result,ic);
7305 genPagedPointerGet(left,result,ic);
7309 genFarPointerGet (left,result,ic);
7313 pic14_emitcodePointerGet (left,result,ic);
7317 genGenPointerGet (left,result,ic);
7323 /*-----------------------------------------------------------------*/
7324 /* genPackBits - generates code for packed bit storage */
7325 /*-----------------------------------------------------------------*/
7326 static void genPackBits (sym_link *etype ,
7328 char *rname, int p_type)
7336 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7337 blen = SPEC_BLEN(etype);
7338 bstr = SPEC_BSTR(etype);
7340 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7343 /* if the bit lenth is less than or */
7344 /* it exactly fits a byte then */
7345 if (SPEC_BLEN(etype) <= 8 ) {
7346 shCount = SPEC_BSTR(etype) ;
7348 /* shift left acc */
7351 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7356 pic14_emitcode ("mov","b,a");
7357 pic14_emitcode("mov","a,@%s",rname);
7361 pic14_emitcode ("mov","b,a");
7362 pic14_emitcode("movx","a,@dptr");
7366 pic14_emitcode ("push","b");
7367 pic14_emitcode ("push","acc");
7368 pic14_emitcode ("lcall","__gptrget");
7369 pic14_emitcode ("pop","b");
7373 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7374 ((unsigned char)(0xFF << (blen+bstr)) |
7375 (unsigned char)(0xFF >> (8-bstr)) ) );
7376 pic14_emitcode ("orl","a,b");
7377 if (p_type == GPOINTER)
7378 pic14_emitcode("pop","b");
7384 pic14_emitcode("mov","@%s,a",rname);
7388 pic14_emitcode("movx","@dptr,a");
7392 DEBUGpic14_emitcode(";lcall","__gptrput");
7397 if ( SPEC_BLEN(etype) <= 8 )
7400 pic14_emitcode("inc","%s",rname);
7401 rLen = SPEC_BLEN(etype) ;
7403 /* now generate for lengths greater than one byte */
7406 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7416 pic14_emitcode("mov","@%s,a",rname);
7418 pic14_emitcode("mov","@%s,%s",rname,l);
7423 pic14_emitcode("movx","@dptr,a");
7428 DEBUGpic14_emitcode(";lcall","__gptrput");
7431 pic14_emitcode ("inc","%s",rname);
7436 /* last last was not complete */
7438 /* save the byte & read byte */
7441 pic14_emitcode ("mov","b,a");
7442 pic14_emitcode("mov","a,@%s",rname);
7446 pic14_emitcode ("mov","b,a");
7447 pic14_emitcode("movx","a,@dptr");
7451 pic14_emitcode ("push","b");
7452 pic14_emitcode ("push","acc");
7453 pic14_emitcode ("lcall","__gptrget");
7454 pic14_emitcode ("pop","b");
7458 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7459 pic14_emitcode ("orl","a,b");
7462 if (p_type == GPOINTER)
7463 pic14_emitcode("pop","b");
7468 pic14_emitcode("mov","@%s,a",rname);
7472 pic14_emitcode("movx","@dptr,a");
7476 DEBUGpic14_emitcode(";lcall","__gptrput");
7480 /*-----------------------------------------------------------------*/
7481 /* genDataPointerSet - remat pointer to data space */
7482 /*-----------------------------------------------------------------*/
7483 static void genDataPointerSet(operand *right,
7487 int size, offset = 0 ;
7488 char *l, buffer[256];
7490 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7491 aopOp(right,ic,FALSE);
7493 l = aopGet(AOP(result),0,FALSE,TRUE);
7494 size = AOP_SIZE(right);
7495 // tsd, was l+1 - the underline `_' prefix was being stripped
7498 sprintf(buffer,"(%s + %d)",l,offset);
7500 sprintf(buffer,"%s",l);
7502 if (AOP_TYPE(right) == AOP_LIT) {
7503 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7504 lit = lit >> (8*offset);
7506 pic14_emitcode("movlw","%d",lit);
7507 pic14_emitcode("movwf","%s",buffer);
7509 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7510 emitpcode(POC_MOVWF, popRegFromString(buffer));
7513 pic14_emitcode("clrf","%s",buffer);
7514 emitpcode(POC_CLRF, popRegFromString(buffer));
7517 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7518 pic14_emitcode("movwf","%s",buffer);
7520 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7521 emitpcode(POC_MOVWF, popRegFromString(buffer));
7528 freeAsmop(right,NULL,ic,TRUE);
7529 freeAsmop(result,NULL,ic,TRUE);
7532 /*-----------------------------------------------------------------*/
7533 /* genNearPointerSet - pic14_emitcode for near pointer put */
7534 /*-----------------------------------------------------------------*/
7535 static void genNearPointerSet (operand *right,
7542 sym_link *ptype = operandType(result);
7545 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7546 retype= getSpec(operandType(right));
7548 aopOp(result,ic,FALSE);
7550 /* if the result is rematerializable &
7551 in data space & not a bit variable */
7552 if (AOP_TYPE(result) == AOP_IMMD &&
7553 DCL_TYPE(ptype) == POINTER &&
7554 !IS_BITVAR(retype)) {
7555 genDataPointerSet (right,result,ic);
7559 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7561 /* if the value is already in a pointer register
7562 then don't need anything more */
7563 if (!AOP_INPREG(AOP(result))) {
7564 /* otherwise get a free pointer register */
7565 //aop = newAsmop(0);
7566 //preg = getFreePtr(ic,&aop,FALSE);
7567 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7568 //pic14_emitcode("mov","%s,%s",
7570 // aopGet(AOP(result),0,FALSE,TRUE));
7571 //rname = preg->name ;
7572 pic14_emitcode("movwf","fsr");
7574 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7576 freeAsmop(result,NULL,ic,TRUE);
7577 aopOp (right,ic,FALSE);
7578 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7580 /* if bitfield then unpack the bits */
7581 if (IS_BITVAR(retype)) {
7582 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7583 "The programmer is obviously confused");
7584 //genPackBits (retype,right,rname,POINTER);
7588 /* we have can just get the values */
7589 int size = AOP_SIZE(right);
7592 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7594 l = aopGet(AOP(right),offset,FALSE,TRUE);
7597 //pic14_emitcode("mov","@%s,a",rname);
7598 pic14_emitcode("movf","indf,w ;1");
7601 if (AOP_TYPE(right) == AOP_LIT) {
7602 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7604 pic14_emitcode("movlw","%s",l);
7605 pic14_emitcode("movwf","indf ;2");
7607 pic14_emitcode("clrf","indf");
7609 pic14_emitcode("movf","%s,w",l);
7610 pic14_emitcode("movwf","indf ;2");
7612 //pic14_emitcode("mov","@%s,%s",rname,l);
7615 pic14_emitcode("incf","fsr,f ;3");
7616 //pic14_emitcode("inc","%s",rname);
7621 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7622 /* now some housekeeping stuff */
7624 /* we had to allocate for this iCode */
7625 freeAsmop(NULL,aop,ic,TRUE);
7627 /* we did not allocate which means left
7628 already in a pointer register, then
7629 if size > 0 && this could be used again
7630 we have to point it back to where it
7632 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7633 if (AOP_SIZE(right) > 1 &&
7634 !OP_SYMBOL(result)->remat &&
7635 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7637 int size = AOP_SIZE(right) - 1;
7639 pic14_emitcode("decf","fsr,f");
7640 //pic14_emitcode("dec","%s",rname);
7644 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7646 freeAsmop(right,NULL,ic,TRUE);
7651 /*-----------------------------------------------------------------*/
7652 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7653 /*-----------------------------------------------------------------*/
7654 static void genPagedPointerSet (operand *right,
7663 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7665 retype= getSpec(operandType(right));
7667 aopOp(result,ic,FALSE);
7669 /* if the value is already in a pointer register
7670 then don't need anything more */
7671 if (!AOP_INPREG(AOP(result))) {
7672 /* otherwise get a free pointer register */
7674 preg = getFreePtr(ic,&aop,FALSE);
7675 pic14_emitcode("mov","%s,%s",
7677 aopGet(AOP(result),0,FALSE,TRUE));
7678 rname = preg->name ;
7680 rname = aopGet(AOP(result),0,FALSE,FALSE);
7682 freeAsmop(result,NULL,ic,TRUE);
7683 aopOp (right,ic,FALSE);
7685 /* if bitfield then unpack the bits */
7686 if (IS_BITVAR(retype))
7687 genPackBits (retype,right,rname,PPOINTER);
7689 /* we have can just get the values */
7690 int size = AOP_SIZE(right);
7694 l = aopGet(AOP(right),offset,FALSE,TRUE);
7697 pic14_emitcode("movx","@%s,a",rname);
7700 pic14_emitcode("inc","%s",rname);
7706 /* now some housekeeping stuff */
7708 /* we had to allocate for this iCode */
7709 freeAsmop(NULL,aop,ic,TRUE);
7711 /* we did not allocate which means left
7712 already in a pointer register, then
7713 if size > 0 && this could be used again
7714 we have to point it back to where it
7716 if (AOP_SIZE(right) > 1 &&
7717 !OP_SYMBOL(result)->remat &&
7718 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7720 int size = AOP_SIZE(right) - 1;
7722 pic14_emitcode("dec","%s",rname);
7727 freeAsmop(right,NULL,ic,TRUE);
7732 /*-----------------------------------------------------------------*/
7733 /* genFarPointerSet - set value from far space */
7734 /*-----------------------------------------------------------------*/
7735 static void genFarPointerSet (operand *right,
7736 operand *result, iCode *ic)
7739 sym_link *retype = getSpec(operandType(right));
7741 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7742 aopOp(result,ic,FALSE);
7744 /* if the operand is already in dptr
7745 then we do nothing else we move the value to dptr */
7746 if (AOP_TYPE(result) != AOP_STR) {
7747 /* if this is remateriazable */
7748 if (AOP_TYPE(result) == AOP_IMMD)
7749 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7750 else { /* we need to get it byte by byte */
7751 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7752 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7753 if (options.model == MODEL_FLAT24)
7755 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7759 /* so dptr know contains the address */
7760 freeAsmop(result,NULL,ic,TRUE);
7761 aopOp(right,ic,FALSE);
7763 /* if bit then unpack */
7764 if (IS_BITVAR(retype))
7765 genPackBits(retype,right,"dptr",FPOINTER);
7767 size = AOP_SIZE(right);
7771 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7773 pic14_emitcode("movx","@dptr,a");
7775 pic14_emitcode("inc","dptr");
7779 freeAsmop(right,NULL,ic,TRUE);
7782 /*-----------------------------------------------------------------*/
7783 /* genGenPointerSet - set value from generic pointer space */
7784 /*-----------------------------------------------------------------*/
7785 static void genGenPointerSet (operand *right,
7786 operand *result, iCode *ic)
7789 sym_link *retype = getSpec(operandType(right));
7791 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7793 aopOp(result,ic,FALSE);
7795 /* if the operand is already in dptr
7796 then we do nothing else we move the value to dptr */
7797 if (AOP_TYPE(result) != AOP_STR) {
7798 /* if this is remateriazable */
7799 if (AOP_TYPE(result) == AOP_IMMD) {
7800 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7801 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7803 else { /* we need to get it byte by byte */
7804 char *l = aopGet(AOP(result),0,FALSE,FALSE);
7807 emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
7808 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7811 pic14_emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
7813 pic14_emitcode("movwf","INDF");
7816 /* so dptr know contains the address */
7817 freeAsmop(result,NULL,ic,TRUE);
7818 aopOp(right,ic,FALSE);
7820 /* if bit then unpack */
7821 if (IS_BITVAR(retype))
7822 genPackBits(retype,right,"dptr",GPOINTER);
7824 size = AOP_SIZE(right);
7828 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7830 pic14_emitcode("incf","fsr,f");
7831 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
7832 pic14_emitcode("movwf","indf");
7834 //DEBUGpic14_emitcode(";lcall","__gptrput");
7836 // pic14_emitcode("inc","dptr");
7840 freeAsmop(right,NULL,ic,TRUE);
7843 /*-----------------------------------------------------------------*/
7844 /* genPointerSet - stores the value into a pointer location */
7845 /*-----------------------------------------------------------------*/
7846 static void genPointerSet (iCode *ic)
7848 operand *right, *result ;
7849 sym_link *type, *etype;
7852 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7854 right = IC_RIGHT(ic);
7855 result = IC_RESULT(ic) ;
7857 /* depending on the type of pointer we need to
7858 move it to the correct pointer register */
7859 type = operandType(result);
7860 etype = getSpec(type);
7861 /* if left is of type of pointer then it is simple */
7862 if (IS_PTR(type) && !IS_FUNC(type->next)) {
7863 p_type = DCL_TYPE(type);
7866 /* we have to go by the storage class */
7867 p_type = PTR_TYPE(SPEC_OCLS(etype));
7869 /* if (SPEC_OCLS(etype)->codesp ) { */
7870 /* p_type = CPOINTER ; */
7873 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7874 /* p_type = FPOINTER ; */
7876 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7877 /* p_type = PPOINTER ; */
7879 /* if (SPEC_OCLS(etype) == idata ) */
7880 /* p_type = IPOINTER ; */
7882 /* p_type = POINTER ; */
7885 /* now that we have the pointer type we assign
7886 the pointer values */
7891 genNearPointerSet (right,result,ic);
7895 genPagedPointerSet (right,result,ic);
7899 genFarPointerSet (right,result,ic);
7903 genGenPointerSet (right,result,ic);
7909 /*-----------------------------------------------------------------*/
7910 /* genIfx - generate code for Ifx statement */
7911 /*-----------------------------------------------------------------*/
7912 static void genIfx (iCode *ic, iCode *popIc)
7914 operand *cond = IC_COND(ic);
7917 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7918 aopOp(cond,ic,FALSE);
7920 /* get the value into acc */
7921 if (AOP_TYPE(cond) != AOP_CRY)
7922 pic14_toBoolean(cond);
7925 /* the result is now in the accumulator */
7926 freeAsmop(cond,NULL,ic,TRUE);
7928 /* if there was something to be popped then do it */
7932 /* if the condition is a bit variable */
7933 if (isbit && IS_ITEMP(cond) &&
7935 genIfxJump(ic,SPIL_LOC(cond)->rname);
7936 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
7940 if (isbit && !IS_ITEMP(cond))
7941 DEBUGpic14_emitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
7943 DEBUGpic14_emitcode ("; isbit","a");
7946 if (isbit && !IS_ITEMP(cond))
7947 genIfxJump(ic,OP_SYMBOL(cond)->rname);
7954 /*-----------------------------------------------------------------*/
7955 /* genAddrOf - generates code for address of */
7956 /*-----------------------------------------------------------------*/
7957 static void genAddrOf (iCode *ic)
7959 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
7962 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7964 aopOp(IC_RESULT(ic),ic,FALSE);
7966 /* if the operand is on the stack then we
7967 need to get the stack offset of this
7970 /* if it has an offset then we need to compute
7973 pic14_emitcode("mov","a,_bp");
7974 pic14_emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
7975 aopPut(AOP(IC_RESULT(ic)),"a",0);
7977 /* we can just move _bp */
7978 aopPut(AOP(IC_RESULT(ic)),"_bp",0);
7980 /* fill the result with zero */
7981 size = AOP_SIZE(IC_RESULT(ic)) - 1;
7984 if (options.stack10bit && size < (FPTRSIZE - 1))
7987 "*** warning: pointer to stack var truncated.\n");
7994 if (options.stack10bit && offset == 2)
7996 aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
8000 aopPut(AOP(IC_RESULT(ic)),zero,offset++);
8007 /* object not on stack then we need the name */
8008 size = AOP_SIZE(IC_RESULT(ic));
8012 char s[SDCC_NAME_MAX];
8014 sprintf(s,"#(%s >> %d)",
8018 sprintf(s,"#%s",sym->rname);
8019 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8023 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8028 /*-----------------------------------------------------------------*/
8029 /* genFarFarAssign - assignment when both are in far space */
8030 /*-----------------------------------------------------------------*/
8031 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8033 int size = AOP_SIZE(right);
8036 /* first push the right side on to the stack */
8038 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8040 pic14_emitcode ("push","acc");
8043 freeAsmop(right,NULL,ic,FALSE);
8044 /* now assign DPTR to result */
8045 aopOp(result,ic,FALSE);
8046 size = AOP_SIZE(result);
8048 pic14_emitcode ("pop","acc");
8049 aopPut(AOP(result),"a",--offset);
8051 freeAsmop(result,NULL,ic,FALSE);
8056 /*-----------------------------------------------------------------*/
8057 /* genAssign - generate code for assignment */
8058 /*-----------------------------------------------------------------*/
8059 static void genAssign (iCode *ic)
8061 operand *result, *right;
8063 unsigned long lit = 0L;
8065 result = IC_RESULT(ic);
8066 right = IC_RIGHT(ic) ;
8068 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8070 /* if they are the same */
8071 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8074 aopOp(right,ic,FALSE);
8075 aopOp(result,ic,TRUE);
8077 /* if they are the same registers */
8078 if (pic14_sameRegs(AOP(right),AOP(result)))
8081 /* if the result is a bit */
8082 if (AOP_TYPE(result) == AOP_CRY) {
8084 /* if the right size is a literal then
8085 we know what the value is */
8086 if (AOP_TYPE(right) == AOP_LIT) {
8088 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8089 popGet(AOP(result),0,FALSE,FALSE));
8091 if (((int) operandLitValue(right)))
8092 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8093 AOP(result)->aopu.aop_dir,
8094 AOP(result)->aopu.aop_dir);
8096 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8097 AOP(result)->aopu.aop_dir,
8098 AOP(result)->aopu.aop_dir);
8102 /* the right is also a bit variable */
8103 if (AOP_TYPE(right) == AOP_CRY) {
8104 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8105 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8106 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8108 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8109 AOP(result)->aopu.aop_dir,
8110 AOP(result)->aopu.aop_dir);
8111 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8112 AOP(right)->aopu.aop_dir,
8113 AOP(right)->aopu.aop_dir);
8114 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8115 AOP(result)->aopu.aop_dir,
8116 AOP(result)->aopu.aop_dir);
8121 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8122 pic14_toBoolean(right);
8124 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8125 //aopPut(AOP(result),"a",0);
8129 /* bit variables done */
8131 size = AOP_SIZE(result);
8133 if(AOP_TYPE(right) == AOP_LIT)
8134 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8135 if((AOP_TYPE(result) != AOP_REG) &&
8136 (AOP_TYPE(right) == AOP_LIT) &&
8137 !IS_FLOAT(operandType(right)) &&
8141 if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) {
8142 //pic14_emitcode("clrf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8143 emitpcode(POC_CLRF,popGet(AOP(result),size,FALSE,FALSE));
8145 emitpcode(POC_MOVLW,popGet(AOP(right),size,FALSE,FALSE));
8146 emitpcode(POC_MOVWF,popGet(AOP(result),size,FALSE,FALSE));
8147 //pic14_emitcode("movlw","%s", aopGet(AOP(right),size,FALSE,FALSE));
8148 //pic14_emitcode("movwf","%s", aopGet(AOP(result),size,FALSE,FALSE));
8153 if(AOP_TYPE(right) == AOP_LIT) {
8154 emitpcode(POC_MOVLW, popGet(AOP(right),offset,FALSE,FALSE));
8155 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8157 } else if (AOP_TYPE(right) == AOP_CRY) {
8158 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8160 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8161 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8164 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8165 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8168 //pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE));
8174 freeAsmop (right,NULL,ic,FALSE);
8175 freeAsmop (result,NULL,ic,TRUE);
8178 /*-----------------------------------------------------------------*/
8179 /* genJumpTab - genrates code for jump table */
8180 /*-----------------------------------------------------------------*/
8181 static void genJumpTab (iCode *ic)
8186 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8188 aopOp(IC_JTCOND(ic),ic,FALSE);
8189 /* get the condition into accumulator */
8190 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8192 /* multiply by three */
8193 pic14_emitcode("add","a,acc");
8194 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8196 jtab = newiTempLabel(NULL);
8197 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8198 pic14_emitcode("jmp","@a+dptr");
8199 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8201 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8202 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8204 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8205 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8206 emitpLabel(jtab->key+100+labelOffset);
8208 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8210 /* now generate the jump labels */
8211 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8212 jtab = setNextItem(IC_JTLABELS(ic))) {
8213 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8214 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8220 /*-----------------------------------------------------------------*/
8221 /* genMixedOperation - gen code for operators between mixed types */
8222 /*-----------------------------------------------------------------*/
8224 TSD - Written for the PIC port - but this unfortunately is buggy.
8225 This routine is good in that it is able to efficiently promote
8226 types to different (larger) sizes. Unfortunately, the temporary
8227 variables that are optimized out by this routine are sometimes
8228 used in other places. So until I know how to really parse the
8229 iCode tree, I'm going to not be using this routine :(.
8231 static int genMixedOperation (iCode *ic)
8234 operand *result = IC_RESULT(ic);
8235 sym_link *ctype = operandType(IC_LEFT(ic));
8236 operand *right = IC_RIGHT(ic);
8242 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8244 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8250 nextright = IC_RIGHT(nextic);
8251 nextleft = IC_LEFT(nextic);
8252 nextresult = IC_RESULT(nextic);
8254 aopOp(right,ic,FALSE);
8255 aopOp(result,ic,FALSE);
8256 aopOp(nextright, nextic, FALSE);
8257 aopOp(nextleft, nextic, FALSE);
8258 aopOp(nextresult, nextic, FALSE);
8260 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8266 pic14_emitcode(";remove right +","");
8268 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8274 pic14_emitcode(";remove left +","");
8278 big = AOP_SIZE(nextleft);
8279 small = AOP_SIZE(nextright);
8281 switch(nextic->op) {
8284 pic14_emitcode(";optimize a +","");
8285 /* if unsigned or not an integral type */
8286 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8287 pic14_emitcode(";add a bit to something","");
8290 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8292 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8293 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8294 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8296 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8304 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8305 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8306 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8309 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8311 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8312 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8313 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8314 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8315 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8318 pic14_emitcode("rlf","known_zero,w");
8325 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8326 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8327 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8329 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8339 freeAsmop(right,NULL,ic,TRUE);
8340 freeAsmop(result,NULL,ic,TRUE);
8341 freeAsmop(nextright,NULL,ic,TRUE);
8342 freeAsmop(nextleft,NULL,ic,TRUE);
8344 nextic->generated = 1;
8351 /*-----------------------------------------------------------------*/
8352 /* genCast - gen code for casting */
8353 /*-----------------------------------------------------------------*/
8354 static void genCast (iCode *ic)
8356 operand *result = IC_RESULT(ic);
8357 sym_link *ctype = operandType(IC_LEFT(ic));
8358 operand *right = IC_RIGHT(ic);
8361 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8362 /* if they are equivalent then do nothing */
8363 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8366 aopOp(right,ic,FALSE) ;
8367 aopOp(result,ic,FALSE);
8369 /* if the result is a bit */
8370 if (AOP_TYPE(result) == AOP_CRY) {
8371 /* if the right size is a literal then
8372 we know what the value is */
8373 if (AOP_TYPE(right) == AOP_LIT) {
8375 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8376 popGet(AOP(result),0,FALSE,FALSE));
8378 if (((int) operandLitValue(right)))
8379 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8380 AOP(result)->aopu.aop_dir,
8381 AOP(result)->aopu.aop_dir);
8383 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8384 AOP(result)->aopu.aop_dir,
8385 AOP(result)->aopu.aop_dir);
8390 /* the right is also a bit variable */
8391 if (AOP_TYPE(right) == AOP_CRY) {
8394 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8396 pic14_emitcode("clrc","");
8397 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8398 AOP(right)->aopu.aop_dir,
8399 AOP(right)->aopu.aop_dir);
8400 aopPut(AOP(result),"c",0);
8405 pic14_toBoolean(right);
8406 aopPut(AOP(result),"a",0);
8410 /* if they are the same size : or less */
8411 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8413 /* if they are in the same place */
8414 if (pic14_sameRegs(AOP(right),AOP(result)))
8417 /* if they in different places then copy */
8418 size = AOP_SIZE(result);
8422 aopGet(AOP(right),offset,FALSE,FALSE),
8430 /* if the result is of type pointer */
8431 if (IS_PTR(ctype)) {
8434 sym_link *type = operandType(right);
8435 sym_link *etype = getSpec(type);
8437 /* pointer to generic pointer */
8438 if (IS_GENPTR(ctype)) {
8442 p_type = DCL_TYPE(type);
8444 /* we have to go by the storage class */
8445 p_type = PTR_TYPE(SPEC_OCLS(etype));
8447 /* if (SPEC_OCLS(etype)->codesp ) */
8448 /* p_type = CPOINTER ; */
8450 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8451 /* p_type = FPOINTER ; */
8453 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8454 /* p_type = PPOINTER; */
8456 /* if (SPEC_OCLS(etype) == idata ) */
8457 /* p_type = IPOINTER ; */
8459 /* p_type = POINTER ; */
8462 /* the first two bytes are known */
8463 size = GPTRSIZE - 1;
8467 aopGet(AOP(right),offset,FALSE,FALSE),
8471 /* the last byte depending on type */
8488 /* this should never happen */
8489 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8490 "got unknown pointer type");
8493 aopPut(AOP(result),l, GPTRSIZE - 1);
8497 /* just copy the pointers */
8498 size = AOP_SIZE(result);
8502 aopGet(AOP(right),offset,FALSE,FALSE),
8510 if (AOP_TYPE(right) == AOP_CRY) {
8512 size = AOP_SIZE(right);
8514 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8515 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8516 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8518 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8519 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8520 AOP(right)->aopu.aop_dir,
8521 AOP(right)->aopu.aop_dir);
8522 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8524 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8525 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8530 /* so we now know that the size of destination is greater
8531 than the size of the source.
8532 Now, if the next iCode is an operator then we might be
8533 able to optimize the operation without performing a cast.
8535 if(genMixedOperation(ic))
8539 /* we move to result for the size of source */
8540 size = AOP_SIZE(right);
8543 pic14_emitcode(";","%d",__LINE__);
8545 aopGet(AOP(right),offset,FALSE,FALSE),
8550 /* now depending on the sign of the destination */
8551 size = AOP_SIZE(result) - AOP_SIZE(right);
8552 /* if unsigned or not an integral type */
8553 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8555 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8556 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8560 /* we need to extend the sign :{ */
8561 //char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,FALSE,FALSE);
8564 emitpcode(POC_CLRW, NULL);
8565 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8566 emitpcode(POC_MOVLW, popGetLit(0xff));
8568 pic14_emitcode("clrw","");
8569 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8570 AOP(right)->aopu.aop_dir,
8571 AOP(right)->aopu.aop_dir);
8572 pic14_emitcode("movlw","0xff");
8574 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8575 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8577 // aopPut(AOP(result),"a",offset++);
8582 /* we are done hurray !!!! */
8585 freeAsmop(right,NULL,ic,TRUE);
8586 freeAsmop(result,NULL,ic,TRUE);
8590 /*-----------------------------------------------------------------*/
8591 /* genDjnz - generate decrement & jump if not zero instrucion */
8592 /*-----------------------------------------------------------------*/
8593 static int genDjnz (iCode *ic, iCode *ifx)
8596 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8601 /* if the if condition has a false label
8602 then we cannot save */
8606 /* if the minus is not of the form
8608 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8609 !IS_OP_LITERAL(IC_RIGHT(ic)))
8612 if (operandLitValue(IC_RIGHT(ic)) != 1)
8615 /* if the size of this greater than one then no
8617 if (getSize(operandType(IC_RESULT(ic))) > 1)
8620 /* otherwise we can save BIG */
8621 lbl = newiTempLabel(NULL);
8622 lbl1= newiTempLabel(NULL);
8624 aopOp(IC_RESULT(ic),ic,FALSE);
8626 if (IS_AOP_PREG(IC_RESULT(ic))) {
8627 pic14_emitcode("dec","%s",
8628 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8629 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8630 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8634 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8635 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8637 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8638 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8641 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8642 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8643 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8644 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8647 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8652 /*-----------------------------------------------------------------*/
8653 /* genReceive - generate code for a receive iCode */
8654 /*-----------------------------------------------------------------*/
8655 static void genReceive (iCode *ic)
8657 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8659 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8660 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8661 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8663 int size = getSize(operandType(IC_RESULT(ic)));
8664 int offset = fReturnSizePic - size;
8666 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8667 fReturn[fReturnSizePic - offset - 1] : "acc"));
8670 aopOp(IC_RESULT(ic),ic,FALSE);
8671 size = AOP_SIZE(IC_RESULT(ic));
8674 pic14_emitcode ("pop","acc");
8675 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8680 aopOp(IC_RESULT(ic),ic,FALSE);
8682 assignResultValue(IC_RESULT(ic));
8685 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8688 /*-----------------------------------------------------------------*/
8689 /* genpic14Code - generate code for pic14 based controllers */
8690 /*-----------------------------------------------------------------*/
8692 * At this point, ralloc.c has gone through the iCode and attempted
8693 * to optimize in a way suitable for a PIC. Now we've got to generate
8694 * PIC instructions that correspond to the iCode.
8696 * Once the instructions are generated, we'll pass through both the
8697 * peep hole optimizer and the pCode optimizer.
8698 *-----------------------------------------------------------------*/
8700 void genpic14Code (iCode *lic)
8705 lineHead = lineCurr = NULL;
8707 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8710 /* if debug information required */
8711 /* if (options.debug && currFunc) { */
8713 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8715 if (IS_STATIC(currFunc->etype)) {
8716 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8717 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8719 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8720 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8726 for (ic = lic ; ic ; ic = ic->next ) {
8728 DEBUGpic14_emitcode(";ic","");
8729 if ( cln != ic->lineno ) {
8730 if ( options.debug ) {
8732 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8733 FileBaseName(ic->filename),ic->lineno,
8734 ic->level,ic->block);
8737 pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
8740 /* if the result is marked as
8741 spilt and rematerializable or code for
8742 this has already been generated then
8744 if (resultRemat(ic) || ic->generated )
8747 /* depending on the operation */
8766 /* IPOP happens only when trying to restore a
8767 spilt live range, if there is an ifx statement
8768 following this pop then the if statement might
8769 be using some of the registers being popped which
8770 would destory the contents of the register so
8771 we need to check for this condition and handle it */
8773 ic->next->op == IFX &&
8774 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8775 genIfx (ic->next,ic);
8793 genEndFunction (ic);
8813 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
8830 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
8834 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
8841 /* note these two are xlated by algebraic equivalence
8842 during parsing SDCC.y */
8843 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8844 "got '>=' or '<=' shouldn't have come here");
8848 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
8860 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
8864 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
8868 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
8895 case GET_VALUE_AT_ADDRESS:
8900 if (POINTER_SET(ic))
8927 addSet(&_G.sendSet,ic);
8936 /* now we are ready to call the
8937 peep hole optimizer */
8938 if (!options.nopeep) {
8939 printf("peep hole optimizing\n");
8940 peepHole (&lineHead);
8942 /* now do the actual printing */
8943 printLine (lineHead,codeOutFile);
8945 printf("printing pBlock\n\n");
8946 printpBlock(stdout,pb);