1 /*-------------------------------------------------------------------------
2 genarith.c - source file for code generation - arithmetic
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 #if defined(_MSC_VER) && (_MSC_VER < 1300)
40 #define __FUNCTION__ __FILE__
44 #include "SDCCpeeph.h"
50 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
51 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result);
53 const char *AopType(short type)
100 void DebugAop(asmop *aop)
104 printf("%s\n",AopType(aop->type));
105 printf(" current offset: %d\n",aop->coff);
106 printf(" size: %d\n",aop->size);
110 printf(" name: %s\n",aop->aopu.aop_lit->name);
113 printf(" name: %s\n",aop->aopu.aop_reg[0]->name);
117 printf(" name: %s\n",aop->aopu.aop_dir);
124 printf("not supported\n");
127 printf(" Stack offset: %d\n",aop->aopu.aop_stk);
130 printf(" immediate: %s\n",aop->aopu.aop_immd);
133 printf(" aop_str[0]: %s\n",aop->aopu.aop_str[0]);
136 //printpCode(stdout,aop->aopu.pcop);
141 const char *pCodeOpType( pCodeOp *pcop)
160 case PO_GPR_REGISTER:
161 return "PO_GPR_REGISTER";
163 return "PO_GPR_POINTER";
167 return "PO_GPR_TEMP";
168 case PO_SFR_REGISTER:
169 return "PO_SFR_REGISTER";
177 return "PO_IMMEDIATE";
193 return "BAD PO_TYPE";
196 /*-----------------------------------------------------------------*/
197 /* genPlusIncr :- does addition with increment if possible */
198 /*-----------------------------------------------------------------*/
199 bool genPlusIncr (iCode *ic)
201 unsigned int icount ;
202 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
205 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
206 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
207 AopType(AOP_TYPE(IC_RESULT(ic))),
208 AopType(AOP_TYPE(IC_LEFT(ic))),
209 AopType(AOP_TYPE(IC_RIGHT(ic))));
211 /* will try to generate an increment */
212 /* if the right side is not a literal
214 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
217 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
218 /* if the literal value of the right hand side
219 is greater than 1 then it is faster to add */
220 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
223 /* if increment 16 bits in register */
224 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
229 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB));
230 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
234 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
235 //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
241 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
242 /* if left is in accumulator - probably a bit operation*/
243 if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
244 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
246 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
247 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
248 AOP(IC_RESULT(ic))->aopu.aop_dir,
249 AOP(IC_RESULT(ic))->aopu.aop_dir);
251 emitpcode(POC_XORLW,popGetLit(1));
252 //pic14_emitcode("xorlw","1");
254 emitpcode(POC_ANDLW,popGetLit(1));
255 //pic14_emitcode("andlw","1");
258 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
259 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
260 AOP(IC_RESULT(ic))->aopu.aop_dir,
261 AOP(IC_RESULT(ic))->aopu.aop_dir);
268 /* if the sizes are greater than 1 then we cannot */
269 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
270 AOP_SIZE(IC_LEFT(ic)) > 1 )
273 /* If we are incrementing the same register by two: */
275 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
278 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
279 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
284 DEBUGpic14_emitcode ("; ","couldn't increment ");
289 /*-----------------------------------------------------------------*/
290 /* pic14_outBitAcc - output a bit in acc */
291 /*-----------------------------------------------------------------*/
292 void pic14_outBitAcc(operand *result)
294 symbol *tlbl = newiTempLabel(NULL);
295 /* if the result is a bit */
297 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
299 if (AOP_TYPE(result) == AOP_CRY){
300 aopPut(AOP(result),"a",0);
303 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
304 pic14_emitcode("mov","a,#01");
305 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
306 pic14_outAcc(result);
311 /* This is the original version of this code.
313 * This is being kept around for reference,
314 * because I am not entirely sure I got it right...
316 static void adjustArithmeticResult(iCode *ic)
318 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
319 AOP_SIZE(IC_LEFT(ic)) == 3 &&
320 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
321 aopPut(AOP(IC_RESULT(ic)),
322 aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
325 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
326 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
327 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
328 aopPut(AOP(IC_RESULT(ic)),
329 aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
332 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
333 AOP_SIZE(IC_LEFT(ic)) < 3 &&
334 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
335 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
336 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
338 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
339 aopPut(AOP(IC_RESULT(ic)),buffer,2);
343 /* This is the pure and virtuous version of this code.
344 * I'm pretty certain it's right, but not enough to toss the old
347 static void adjustArithmeticResult(iCode *ic)
349 if (opIsGptr(IC_RESULT(ic)) &&
350 opIsGptr(IC_LEFT(ic)) &&
351 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
353 aopPut(AOP(IC_RESULT(ic)),
354 aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
358 if (opIsGptr(IC_RESULT(ic)) &&
359 opIsGptr(IC_RIGHT(ic)) &&
360 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
362 aopPut(AOP(IC_RESULT(ic)),
363 aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
367 if (opIsGptr(IC_RESULT(ic)) &&
368 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
369 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
370 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
371 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
373 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
374 aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
379 /*-----------------------------------------------------------------*/
380 /* genAddlit - generates code for addition */
381 /*-----------------------------------------------------------------*/
382 static void genAddLit2byte (operand *result, int offr, int lit)
390 emitpcode(POC_INCF, popGet(AOP(result),offr));
393 emitpcode(POC_DECF, popGet(AOP(result),offr));
396 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
397 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
402 static void emitMOVWF(operand *reg, int offset)
408 if (AOP_TYPE(reg) == AOP_ACC) {
409 DEBUGpic14_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
413 emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
417 static void genAddLit (iCode *ic, int lit)
427 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
431 result = IC_RESULT(ic);
432 same = pic14_sameRegs(AOP(left), AOP(result));
433 size = pic14_getDataSize(result);
434 if (size > pic14_getDataSize(left))
435 size = pic14_getDataSize(left);
439 /* Handle special cases first */
441 genAddLit2byte (result, 0, lit);
444 int hi = 0xff & (lit >> 8);
451 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
456 emitpcode(POC_INCF, popGet(AOP(result),0));
458 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
461 emitpcode(POC_DECF, popGet(AOP(result),0));
462 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
463 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
467 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
468 emitpcode(POC_ADDWF,popGet(AOP(result),0));
470 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
478 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
481 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
484 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
485 emitpcode(POC_INCF, popGet(AOP(result),0));
487 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
489 case 0xff: /* 0x01ff */
490 emitpcode(POC_DECF, popGet(AOP(result),0));
491 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
492 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
493 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
498 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
502 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
505 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
506 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
508 /* case 0xff: * 0xffff *
509 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
510 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
511 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
515 emitpcode(POC_MOVLW,popGetLit(lo));
516 emitpcode(POC_ADDWF,popGet(AOP(result),0));
518 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
525 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
530 genAddLit2byte (result, MSB16, hi);
533 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
534 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
535 emitpcode(POC_MOVLW,popGetLit(hi));
536 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
538 /* case 0xff: * 0xHHff *
539 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
540 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
541 emitpcode(POC_MOVLW,popGetLit(hi));
542 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
544 */ default: /* 0xHHLL */
545 emitpcode(POC_MOVLW,popGetLit(lo));
546 emitpcode(POC_ADDWF, popGet(AOP(result),0));
547 emitpcode(POC_MOVLW,popGetLit(hi));
549 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
550 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
559 DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
562 lo = BYTEofLONG(lit,0);
570 emitpcode(POC_INCF, popGet(AOP(result),offset));
573 emitpcode(POC_RLFW, popGet(AOP(result),offset));
574 emitpcode(POC_ANDLW,popGetLit(1));
575 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
577 default: /* carry_info = 3 */
579 emitpcode(POC_INCF, popGet(AOP(result),offset));
585 emitpcode(POC_MOVLW,popGetLit(lo));
590 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
593 emitpcode(POC_MOVLW,popGetLit(lo));
598 emitpcode(POC_MOVLW,popGetLit(lo+1));
599 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
604 /* no carry info from previous step */
605 /* this means this is the first time to add */
610 emitpcode(POC_INCF, popGet(AOP(result),offset));
614 emitpcode(POC_MOVLW,popGetLit(lo));
615 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
617 carry_info = 3; /* Were adding only one byte and propogating the carry */
628 lo = BYTEofLONG(lit,0);
633 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
636 emitpcode(POC_MOVLW,popGetLit(lo));
637 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
640 emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
642 emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
644 emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
653 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
657 if(AOP_TYPE(left) == AOP_ACC) {
658 /* left addend is already in accumulator */
661 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
665 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
666 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
670 /* left addend is in a register */
673 emitpcode(POC_MOVFW, popGet(AOP(left),0));
674 emitMOVWF(result, 0);
675 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
679 emitpcode(POC_INCFW, popGet(AOP(left),0));
680 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
684 emitpcode(POC_DECFW, popGet(AOP(left),0));
685 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
689 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
690 emitpcode(POC_ADDFW, popGet(AOP(left),0));
691 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
699 /* left is not the accumulator */
701 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
702 emitpcode(POC_ADDFW, popGet(AOP(left),0));
704 emitpcode(POC_MOVFW, popGet(AOP(left),0));
705 /* We don't know the state of the carry bit at this point */
708 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
715 /* The ls byte of the lit must've been zero - that
716 means we don't have to deal with carry */
718 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
719 emitpcode(POC_ADDFW, popGet(AOP(left),offset));
720 emitpcode(POC_MOVWF, popGet(AOP(left),offset));
725 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
726 //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
727 emitMOVWF(result,offset);
728 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
730 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
731 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
735 emitpcode(POC_CLRF, popGet(AOP(result),offset));
736 emitpcode(POC_RLF, popGet(AOP(result),offset));
737 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
738 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
745 size = pic14_getDataSize(result);
746 if (size > pic14_getDataSize(left))
747 size = pic14_getDataSize(left);
748 addSign(result, size, 0);
751 /*-----------------------------------------------------------------*/
752 /* genPlus - generates code for addition */
753 /*-----------------------------------------------------------------*/
754 void genPlus (iCode *ic)
756 int size, offset = 0;
758 /* special cases :- */
759 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
762 aopOp (IC_LEFT(ic),ic,FALSE);
763 aopOp (IC_RIGHT(ic),ic,FALSE);
764 aopOp (IC_RESULT(ic),ic,TRUE);
766 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
768 /* if literal, literal on the right or
769 if left requires ACC or right is already
772 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
773 operand *t = IC_RIGHT(ic);
774 IC_RIGHT(ic) = IC_LEFT(ic);
778 /* if left in bit space & right literal */
779 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
780 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
781 /* if result in bit space */
782 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
783 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
784 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
785 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
786 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
787 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
790 size = pic14_getDataSize(IC_RESULT(ic));
792 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
793 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
794 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
800 /* if I can do an increment instead
801 of add then GOOD for ME */
802 if (genPlusIncr (ic) == TRUE)
805 size = pic14_getDataSize(IC_RESULT(ic));
807 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
808 /* Add a literal to something else */
810 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
814 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
819 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
821 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
822 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
823 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
825 /* here we are adding a bit to a char or int */
827 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
829 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
830 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
832 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
833 AOP(IC_RIGHT(ic))->aopu.aop_dir,
834 AOP(IC_RIGHT(ic))->aopu.aop_dir);
835 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
838 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
839 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
840 emitpcode(POC_XORLW , popGetLit(1));
842 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
843 AOP(IC_RIGHT(ic))->aopu.aop_dir,
844 AOP(IC_RIGHT(ic))->aopu.aop_dir);
845 pic14_emitcode(" xorlw","1");
847 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
848 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
849 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
851 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
852 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
853 AOP(IC_RIGHT(ic))->aopu.aop_dir,
854 AOP(IC_RIGHT(ic))->aopu.aop_dir);
855 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
858 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
860 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
861 emitpcode(POC_ANDLW , popGetLit(1));
862 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
864 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
866 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
867 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
874 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
875 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
877 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
878 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
880 pic14_emitcode("clrz","");
882 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
883 AOP(IC_RIGHT(ic))->aopu.aop_dir,
884 AOP(IC_RIGHT(ic))->aopu.aop_dir);
885 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
889 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
890 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
891 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
892 //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
893 emitMOVWF(IC_RIGHT(ic),0);
895 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
896 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
897 AOP(IC_RIGHT(ic))->aopu.aop_dir,
898 AOP(IC_RIGHT(ic))->aopu.aop_dir);
899 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
900 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
906 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
907 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
913 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
915 /* Add the first bytes */
917 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
918 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
919 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
922 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
923 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
924 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
925 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
928 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
930 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
931 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
933 PIC_OPCODE poc = POC_ADDFW;
935 if (op_isLitLike (IC_LEFT (ic)))
937 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),0,0));
938 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
939 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
944 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
949 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
950 if (op_isLitLike (IC_LEFT(ic)))
953 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
955 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
956 emitpcode(POC_ADDLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
957 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
962 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
964 emitpcode(POC_INCFSZW, popGet(AOP(IC_LEFT(ic)),offset));
965 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
970 PIC_OPCODE poc = POC_MOVFW;
971 if (op_isLitLike (IC_LEFT(ic)))
974 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
975 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
976 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
978 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
980 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
981 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
988 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
989 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
990 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
993 /* Need to extend result to higher bytes */
994 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
996 /* First grab the carry from the lower bytes */
997 if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
998 int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
999 PIC_OPCODE poc = POC_MOVFW;
1000 if (op_isLitLike (IC_LEFT(ic)))
1002 while(leftsize-- > 0) {
1003 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1005 emitpcode(POC_ADDLW, popGetLit(0x01));
1006 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1008 //emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset)); /* INCF does not update Carry! */
1016 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1017 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
1021 if(sign && offset > 0 && offset < AOP_SIZE(IC_RESULT(ic))) {
1022 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1025 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1026 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1027 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1028 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1030 /* if chars or ints or being signed extended to longs: */
1032 emitpcode(POC_MOVLW, popGetLit(0));
1033 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1034 emitpcode(POC_MOVLW, popGetLit(0xff));
1042 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1044 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1051 //adjustArithmeticResult(ic);
1054 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1055 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1056 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1059 /*-----------------------------------------------------------------*/
1060 /* genMinusDec :- does subtraction with decrement if possible */
1061 /*-----------------------------------------------------------------*/
1062 bool genMinusDec (iCode *ic)
1064 unsigned int icount ;
1065 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1068 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1069 /* will try to generate an increment */
1070 /* if the right side is not a literal
1072 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1073 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1074 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1077 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1079 /* if the literal value of the right hand side
1080 is greater than 4 then it is not worth it */
1081 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1084 /* if decrement 16 bits in register */
1085 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1090 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1091 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1092 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1093 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1095 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1096 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1097 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1099 /* size is 3 or 4 */
1100 emitpcode(POC_MOVLW, popGetLit(0xff));
1101 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1103 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1105 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1107 pic14_emitcode("movlw","0xff");
1108 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1111 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1113 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1117 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1119 pic14_emitcode("skpnc","");
1121 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1130 /* if the sizes are greater than 1 then we cannot */
1131 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1132 AOP_SIZE(IC_LEFT(ic)) > 1 )
1135 /* we can if the aops of the left & result match or
1136 if they are in registers and the registers are the
1138 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1141 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1143 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1148 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1149 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1150 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1153 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1154 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1156 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1157 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1165 /*-----------------------------------------------------------------*/
1166 /* addSign - propogate sign bit to higher bytes */
1167 /*-----------------------------------------------------------------*/
1168 void addSign(operand *result, int offset, int sign)
1170 int size = (pic14_getDataSize(result) - offset);
1171 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1175 if(sign && offset) {
1178 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1179 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1180 emitpcode(POC_DECF, popGet(AOP(result),offset));
1183 emitpcode(POC_MOVLW, popGetLit(0));
1184 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1185 emitpcode(POC_MOVLW, popGetLit(0xff));
1187 emitpcode(POC_MOVWF, popGet(AOP(result),offset+size));
1191 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1195 /*-----------------------------------------------------------------*/
1196 /* genMinus - generates code for subtraction */
1197 /*-----------------------------------------------------------------*/
1198 void genMinus (iCode *ic)
1200 int size, offset = 0, same=0;
1201 unsigned long lit = 0L;
1204 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1205 aopOp (IC_LEFT(ic),ic,FALSE);
1206 aopOp (IC_RIGHT(ic),ic,FALSE);
1207 aopOp (IC_RESULT(ic),ic,TRUE);
1209 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1210 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1211 operand *t = IC_RIGHT(ic);
1212 IC_RIGHT(ic) = IC_LEFT(ic);
1216 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1217 AopType(AOP_TYPE(IC_RESULT(ic))),
1218 AopType(AOP_TYPE(IC_LEFT(ic))),
1219 AopType(AOP_TYPE(IC_RIGHT(ic))));
1221 /* if I can do an decrement instead
1222 of subtract then GOOD for ME */
1223 // if (genMinusDec (ic) == TRUE)
1226 size = pic14_getDataSize(IC_RESULT(ic));
1227 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1229 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1230 /* Add a literal to something else */
1232 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1235 genAddLit ( ic, lit);
1238 /* add the first byte: */
1239 pic14_emitcode("movlw","0x%x", lit & 0xff);
1240 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1241 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1242 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1254 if((lit & 0xff) == 0xff) {
1255 emitpcode(POC_MOVLW, popGetLit(0xff));
1257 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1259 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1261 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1262 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1266 /* do the rlf known zero trick here */
1267 emitpcode(POC_MOVLW, popGetLit(1));
1269 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1274 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1277 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1278 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1279 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1281 /* here we are subtracting a bit from a char or int */
1283 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1285 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1286 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1288 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1289 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1290 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1291 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1294 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1295 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1296 emitpcode(POC_XORLW , popGetLit(1));
1297 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1298 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1300 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1302 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1303 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1305 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1306 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1309 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1311 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1313 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1314 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1318 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1319 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1320 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1321 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1326 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1327 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1328 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1331 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1333 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1336 emitpcode(POC_ANDLW , popGetLit(1));
1338 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1340 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1347 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1348 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1349 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1351 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1352 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1353 AopType(AOP_TYPE(IC_RESULT(ic))),
1354 AopType(AOP_TYPE(IC_LEFT(ic))),
1355 AopType(AOP_TYPE(IC_RIGHT(ic))));
1358 if( (size == 1) && ((lit & 0xff) == 0) ) {
1359 /* res = 0 - right */
1360 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1361 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1362 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1364 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1365 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1366 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1371 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1372 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1373 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1381 /* This is the last byte in a multibyte subtraction
1382 * There are a couple of tricks we can do by not worrying about
1383 * propogating the carry */
1385 /* 0xff - x == ~x */
1387 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1389 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1391 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1392 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1394 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1397 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1399 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1400 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1401 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1410 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1412 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1413 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1416 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1422 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1423 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1425 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1427 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1429 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1430 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1437 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1438 AopType(AOP_TYPE(IC_RESULT(ic))),
1439 AopType(AOP_TYPE(IC_LEFT(ic))),
1440 AopType(AOP_TYPE(IC_RIGHT(ic))));
1442 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1443 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1444 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1445 emitpcode(POC_SUBLW, popGetLit(0));
1446 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1449 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1450 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1451 emitpcode(POC_SUBLW, popGetLit(0));
1452 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1453 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1456 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1457 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1458 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1460 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1461 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1463 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1464 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1465 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1467 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1469 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1470 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1471 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1473 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1475 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1481 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1485 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1487 if (op_isLitLike (IC_LEFT(ic)))
1490 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1492 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1493 emitpcode(lit?POC_SUBLW:POC_SUBFW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1494 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1498 PIC_OPCODE poc = POC_MOVFW;
1499 if (op_isLitLike (IC_LEFT(ic)))
1502 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1503 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1504 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1506 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1508 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1509 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1516 // adjustArithmeticResult(ic);
1519 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1520 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1521 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1523 /*-----------------------------------------------------------------*
1524 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1527 *-----------------------------------------------------------------*/
1528 void genUMult8XLit_16 (operand *left,
1531 pCodeOpReg *result_hi)
1536 unsigned int i,have_first_bit;
1541 if (AOP_TYPE(right) != AOP_LIT){
1542 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1548 result_hi = PCOR(popGet(AOP(result),1));
1551 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1553 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1555 same = pic14_sameRegs(AOP(left), AOP(result));
1560 emitpcode(POC_CLRF, popGet(AOP(left),0));
1563 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1564 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1567 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1568 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1569 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1572 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1573 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1574 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1575 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1578 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1579 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1580 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1581 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1584 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1585 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1586 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1587 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1588 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1591 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1592 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1593 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1594 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1595 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F
1598 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1599 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1600 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1601 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1602 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1605 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1606 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1607 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1608 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1609 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1610 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1613 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1614 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1615 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1616 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1617 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1618 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1621 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1622 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1623 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1624 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1625 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1626 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F
1629 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1630 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1631 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1632 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1633 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1634 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1635 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1638 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1639 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1640 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1641 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1642 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1643 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*F
1646 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1647 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1648 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1649 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1650 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1651 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F
1652 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F
1655 temp = popGetTempReg();
1657 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1660 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1661 emitpcode(POC_MOVWF, temp);
1662 emitpcode(POC_ANDLW, popGetLit(0xf0));
1663 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1664 emitpcode(POC_SWAPFW, temp);
1665 emitpcode(POC_SUBWF, popGet(AOP(left),0));
1666 popReleaseTempReg(temp);
1669 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1670 emitpcode(POC_ANDLW, popGetLit(0xf0));
1671 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1674 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1675 emitpcode(POC_ANDLW, popGetLit(0xf0));
1676 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1679 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1680 emitpcode(POC_RLFW, popGet(AOP(left),0));
1681 emitpcode(POC_ANDLW, popGetLit(0xe0));
1682 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1685 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1686 emitpcode(POC_RLF, popGet(AOP(left),0));
1687 emitpcode(POC_RLFW, popGet(AOP(left),0));
1688 emitpcode(POC_ANDLW, popGetLit(0xc0));
1689 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1692 emitpcode(POC_RRFW, popGet(AOP(left),0));
1693 emitpcode(POC_CLRF, popGet(AOP(left),0));
1694 emitpcode(POC_RRF, popGet(AOP(left),0));
1702 emitpcode(POC_CLRF, popGet(AOP(result),0));
1703 emitpcode(POC_CLRF, popCopyReg(result_hi));
1706 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1707 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1708 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1709 emitpcode(POC_ADDWF, popGet(AOP(result),0));
1710 emitpcode(POC_CLRF, popCopyReg(result_hi));
1711 emitpcode(POC_RLF, popCopyReg(result_hi));
1715 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1716 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1717 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1718 emitpcode(POC_CLRF, popCopyReg(result_hi));
1719 emitpcode(POC_BCF, popCopyReg(&pc_status));
1720 emitpcode(POC_RLF, popGet(AOP(result),0));
1721 emitpcode(POC_RLF, popCopyReg(result_hi));
1722 emitpcode(POC_RLF, popGet(AOP(result),0));
1723 emitpcode(POC_RLF, popCopyReg(result_hi));
1725 emitpcode(POC_RLF, popGet(AOP(result),0));
1726 emitpcode(POC_RLF, popCopyReg(result_hi));
1733 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1734 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1735 emitpcode(POC_CLRF, popGet(AOP(result),0));
1736 emitpcode(POC_CLRF, popCopyReg(result_hi));
1739 for(i=0; i<8; i++) {
1742 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1746 if(have_first_bit) {
1747 emitpcode(POC_RRF, popCopyReg(result_hi));
1748 emitpcode(POC_RRF, popGet(AOP(result),0));
1755 /*-----------------------------------------------------------------*
1756 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1759 *-----------------------------------------------------------------*/
1760 void genUMult8X8_16 (operand *left,
1763 pCodeOpReg *result_hi)
1772 result_hi = PCOR(popGet(AOP(result),1));
1775 if (AOP_TYPE(right) == AOP_LIT) {
1776 genUMult8XLit_16(left,right,result,result_hi);
1781 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1783 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1784 emitpcode(POC_CLRF, popGet(AOP(result),0));
1785 emitpcode(POC_CLRF, popCopyReg(result_hi));
1788 for(i=0; i<8; i++) {
1789 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1790 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1791 emitpcode(POC_RRF, popCopyReg(result_hi));
1792 emitpcode(POC_RRF, popGet(AOP(result),0));
1797 Here's another version that does the same thing and takes the
1798 same number of instructions. The one above is slightly better
1799 because the entry instructions have a higher probability of
1800 being optimized out.
1803 emitpcode(POC_CLRF, popCopyReg(result_hi));
1804 emitpcode(POC_RRFW, popGet(AOP(left),0));
1805 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1806 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1808 for(i=0; i<8; i++) {
1810 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1811 emitpcode(POC_RRF, popCopyReg(result_hi));
1812 emitpcode(POC_RRF, popGet(AOP(result),0));
1817 symbol *tlbl = newiTempLabel(NULL);
1821 pic14_emitcode(";","Looped 8 X 8 multiplication");
1823 emitpcode(POC_CLRF, popGet(AOP(result),0));
1824 emitpcode(POC_CLRF, popCopyReg(result_hi));
1826 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1828 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1830 temp = popGetTempReg();
1831 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1833 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1835 emitpLabel(tlbl->key);
1837 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1839 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1841 emitpcode(POC_RRF, popCopyReg(result_hi));
1842 emitpcode(POC_RRF, popGet(AOP(result),0));
1845 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1847 popReleaseTempReg(temp);
1852 /*-----------------------------------------------------------------*
1853 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1855 * this routine will call the unsigned multiply routine and then
1856 * post-fix the sign bit.
1857 *-----------------------------------------------------------------*/
1858 void genSMult8X8_16 (operand *left,
1861 pCodeOpReg *result_hi)
1866 result_hi = PCOR(popGet(AOP(result),1));
1869 genUMult8X8_16(left,right,result,result_hi);
1871 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1872 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1873 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1874 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1875 emitpcode(POC_SUBWF, popGet(AOP(result),1));
1879 /*-----------------------------------------------------------------*
1880 * genMult8X8_8 - multiplication of two 8-bit numbers
1882 * this routine will call the unsigned multiply 8X8=>16 routine and
1883 * then throw away the high byte of the result.
1885 *-----------------------------------------------------------------*/
1886 void genMult8X8_8 (operand *left,
1892 if (result && result->aop && result->aop->type==2 && result->aop->size>=1) {
1893 result->aop->aopu.aop_reg[0]->isFree = 0; /* Sometimes (ie part of last instruction in a blk) the result reg is pre marked as free, which mean on the next line popGetTempReg() will return this reg instead of allocating a new one. */
1895 result_hi = popGetTempReg();
1897 if (AOP_TYPE(right) == AOP_LIT)
1898 genUMult8XLit_16(left,right,result,PCOR(result_hi));
1900 genUMult8X8_16(left,right,result,PCOR(result_hi));
1902 popReleaseTempReg(result_hi);
1905 /*-----------------------------------------------------------------*/
1906 /* constMult - generates code for multiplication by a constant */
1907 /*-----------------------------------------------------------------*/
1908 void genMultConst(unsigned C)
1912 unsigned sr3; // Shift right 3
1918 Convert a string of 3 binary 1's in the lit into
1922 mask = 7 << ( (size*8) - 3);
1926 while(mask < (1<<size*8)) {
1928 if( (mask & lit) == lit) {
1931 /* We found 3 (or more) consecutive 1's */
1933 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1935 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1937 lit ^= consecutive_bits;
1941 sr3 |= (consecutive + lsb);