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);
310 /*-----------------------------------------------------------------*/
311 /* genPlusBits - generates code for addition of two bits */
312 /*-----------------------------------------------------------------*/
313 void genPlusBits (iCode *ic)
317 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
319 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
320 AopType(AOP_TYPE(IC_RESULT(ic))),
321 AopType(AOP_TYPE(IC_LEFT(ic))),
322 AopType(AOP_TYPE(IC_RIGHT(ic))));
324 The following block of code will add two bits.
325 Note that it'll even work if the destination is
326 the carry (C in the status register).
327 It won't work if the 'Z' bit is a source or destination.
330 /* If the result is stored in the accumulator (w) */
331 //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {}
332 switch(AOP_TYPE(IC_RESULT(ic))) {
334 emitpcode(POC_CLRW, NULL);
335 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
336 emitpcode(POC_XORLW, popGetLit(1));
337 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
338 emitpcode(POC_XORLW, popGetLit(1));
340 pic14_emitcode("clrw","");
341 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
342 AOP(IC_RIGHT(ic))->aopu.aop_dir,
343 AOP(IC_RIGHT(ic))->aopu.aop_dir);
344 pic14_emitcode("xorlw","1");
345 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
346 AOP(IC_LEFT(ic))->aopu.aop_dir,
347 AOP(IC_LEFT(ic))->aopu.aop_dir);
348 pic14_emitcode("xorlw","1");
351 emitpcode(POC_MOVLW, popGetLit(0));
352 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
353 emitpcode(POC_XORLW, popGetLit(1));
354 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
355 emitpcode(POC_XORLW, popGetLit(1));
356 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
359 if(pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic)))) {
366 if(pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic)))) {
367 DebugAop(AOP(IC_LEFT(ic)));
368 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),0));
369 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
370 emitpcode(POC_XORWF, popGet(AOP(IC_LEFT(ic)),0));
372 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
373 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
374 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
375 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
376 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
377 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
381 pic14_emitcode("movlw","(1 << (%s & 7))",
382 AOP(IC_RESULT(ic))->aopu.aop_dir,
383 AOP(IC_RESULT(ic))->aopu.aop_dir);
384 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
385 AOP(IC_RESULT(ic))->aopu.aop_dir,
386 AOP(IC_RESULT(ic))->aopu.aop_dir);
387 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
388 AOP(IC_RIGHT(ic))->aopu.aop_dir,
389 AOP(IC_RIGHT(ic))->aopu.aop_dir);
390 pic14_emitcode("xorwf","(%s >>3),f",
391 AOP(IC_RESULT(ic))->aopu.aop_dir);
392 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
393 AOP(IC_LEFT(ic))->aopu.aop_dir,
394 AOP(IC_LEFT(ic))->aopu.aop_dir);
395 pic14_emitcode("xorwf","(%s>>3),f",
396 AOP(IC_RESULT(ic))->aopu.aop_dir);
403 /* This is the original version of this code.
405 * This is being kept around for reference,
406 * because I am not entirely sure I got it right...
408 static void adjustArithmeticResult(iCode *ic)
410 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
411 AOP_SIZE(IC_LEFT(ic)) == 3 &&
412 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
413 aopPut(AOP(IC_RESULT(ic)),
414 aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
417 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
418 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
419 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
420 aopPut(AOP(IC_RESULT(ic)),
421 aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
424 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
425 AOP_SIZE(IC_LEFT(ic)) < 3 &&
426 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
427 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
428 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
430 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
431 aopPut(AOP(IC_RESULT(ic)),buffer,2);
435 /* This is the pure and virtuous version of this code.
436 * I'm pretty certain it's right, but not enough to toss the old
439 static void adjustArithmeticResult(iCode *ic)
441 if (opIsGptr(IC_RESULT(ic)) &&
442 opIsGptr(IC_LEFT(ic)) &&
443 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
445 aopPut(AOP(IC_RESULT(ic)),
446 aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
450 if (opIsGptr(IC_RESULT(ic)) &&
451 opIsGptr(IC_RIGHT(ic)) &&
452 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
454 aopPut(AOP(IC_RESULT(ic)),
455 aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
459 if (opIsGptr(IC_RESULT(ic)) &&
460 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
461 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
462 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
463 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
465 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
466 aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
471 /*-----------------------------------------------------------------*/
472 /* genAddlit - generates code for addition */
473 /*-----------------------------------------------------------------*/
474 static void genAddLit2byte (operand *result, int offr, int lit)
482 emitpcode(POC_INCF, popGet(AOP(result),offr));
485 emitpcode(POC_DECF, popGet(AOP(result),offr));
488 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
489 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
494 static void emitMOVWF(operand *reg, int offset)
500 if (AOP_TYPE(reg) == AOP_ACC) {
501 DEBUGpic14_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
505 emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
509 static void genAddLit (iCode *ic, int lit)
519 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
523 result = IC_RESULT(ic);
524 same = pic14_sameRegs(AOP(left), AOP(result));
525 size = pic14_getDataSize(result);
529 /* Handle special cases first */
531 genAddLit2byte (result, 0, lit);
534 int hi = 0xff & (lit >> 8);
541 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
546 emitpcode(POC_INCF, popGet(AOP(result),0));
548 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
551 emitpcode(POC_DECF, popGet(AOP(result),0));
552 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
553 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
557 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
558 emitpcode(POC_ADDWF,popGet(AOP(result),0));
560 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
568 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
571 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
574 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
575 emitpcode(POC_INCF, popGet(AOP(result),0));
577 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
579 case 0xff: /* 0x01ff */
580 emitpcode(POC_DECF, popGet(AOP(result),0));
581 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
582 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
583 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
588 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
592 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
595 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
596 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
598 /* case 0xff: * 0xffff *
599 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
600 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
601 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
605 emitpcode(POC_MOVLW,popGetLit(lo));
606 emitpcode(POC_ADDWF,popGet(AOP(result),0));
608 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
615 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
620 genAddLit2byte (result, MSB16, hi);
623 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
624 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
625 emitpcode(POC_MOVLW,popGetLit(hi));
626 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
628 /* case 0xff: * 0xHHff *
629 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
630 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
631 emitpcode(POC_MOVLW,popGetLit(hi));
632 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
634 */ default: /* 0xHHLL */
635 emitpcode(POC_MOVLW,popGetLit(lo));
636 emitpcode(POC_ADDWF, popGet(AOP(result),0));
637 emitpcode(POC_MOVLW,popGetLit(hi));
639 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
640 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
649 DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
652 lo = BYTEofLONG(lit,0);
660 emitpcode(POC_INCF, popGet(AOP(result),offset));
663 emitpcode(POC_RLFW, popGet(AOP(result),offset));
664 emitpcode(POC_ANDLW,popGetLit(1));
665 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
667 default: /* carry_info = 3 */
669 emitpcode(POC_INCF, popGet(AOP(result),offset));
675 emitpcode(POC_MOVLW,popGetLit(lo));
680 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
683 emitpcode(POC_MOVLW,popGetLit(lo));
688 emitpcode(POC_MOVLW,popGetLit(lo+1));
689 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
694 /* no carry info from previous step */
695 /* this means this is the first time to add */
700 emitpcode(POC_INCF, popGet(AOP(result),offset));
704 emitpcode(POC_MOVLW,popGetLit(lo));
705 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
707 carry_info = 3; /* Were adding only one byte and propogating the carry */
718 lo = BYTEofLONG(lit,0);
723 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
726 emitpcode(POC_MOVLW,popGetLit(lo));
727 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
730 emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
732 emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
734 emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
743 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
747 if(AOP_TYPE(left) == AOP_ACC) {
748 /* left addend is already in accumulator */
751 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
755 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
756 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
760 /* left addend is in a register */
763 emitpcode(POC_MOVFW, popGet(AOP(left),0));
764 emitMOVWF(result, 0);
765 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
769 emitpcode(POC_INCFW, popGet(AOP(left),0));
770 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
774 emitpcode(POC_DECFW, popGet(AOP(left),0));
775 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
779 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
780 emitpcode(POC_ADDFW, popGet(AOP(left),0));
781 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
789 /* left is not the accumulator */
791 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
792 emitpcode(POC_ADDFW, popGet(AOP(left),0));
794 emitpcode(POC_MOVFW, popGet(AOP(left),0));
795 /* We don't know the state of the carry bit at this point */
798 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
805 /* The ls byte of the lit must've been zero - that
806 means we don't have to deal with carry */
808 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
809 emitpcode(POC_ADDFW, popGet(AOP(left),offset));
810 emitpcode(POC_MOVWF, popGet(AOP(left),offset));
815 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
816 //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
817 emitMOVWF(result,offset);
818 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
820 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
821 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
825 emitpcode(POC_CLRF, popGet(AOP(result),offset));
826 emitpcode(POC_RLF, popGet(AOP(result),offset));
827 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
828 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
836 /*-----------------------------------------------------------------*/
837 /* genPlus - generates code for addition */
838 /*-----------------------------------------------------------------*/
839 void genPlus (iCode *ic)
841 int size, offset = 0;
843 /* special cases :- */
844 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
847 aopOp (IC_LEFT(ic),ic,FALSE);
848 aopOp (IC_RIGHT(ic),ic,FALSE);
849 aopOp (IC_RESULT(ic),ic,TRUE);
851 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
853 /* if literal, literal on the right or
854 if left requires ACC or right is already
857 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
858 operand *t = IC_RIGHT(ic);
859 IC_RIGHT(ic) = IC_LEFT(ic);
863 /* if both left & right are in bit space */
864 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
865 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
870 /* if left in bit space & right literal */
871 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
872 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
873 /* if result in bit space */
874 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
875 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
876 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
877 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
878 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
879 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
882 size = pic14_getDataSize(IC_RESULT(ic));
884 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
885 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
886 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
892 /* if I can do an increment instead
893 of add then GOOD for ME */
894 if (genPlusIncr (ic) == TRUE)
897 size = pic14_getDataSize(IC_RESULT(ic));
899 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
900 /* Add a literal to something else */
902 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
906 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
911 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
913 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
914 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
915 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
917 /* here we are adding a bit to a char or int */
919 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
921 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
922 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
924 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
925 AOP(IC_RIGHT(ic))->aopu.aop_dir,
926 AOP(IC_RIGHT(ic))->aopu.aop_dir);
927 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
930 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
931 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
932 emitpcode(POC_XORLW , popGetLit(1));
934 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
935 AOP(IC_RIGHT(ic))->aopu.aop_dir,
936 AOP(IC_RIGHT(ic))->aopu.aop_dir);
937 pic14_emitcode(" xorlw","1");
939 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
940 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
941 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
943 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
944 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
945 AOP(IC_RIGHT(ic))->aopu.aop_dir,
946 AOP(IC_RIGHT(ic))->aopu.aop_dir);
947 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
950 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
952 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
953 emitpcode(POC_ANDLW , popGetLit(1));
954 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
956 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
958 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
959 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
966 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
967 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
969 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
970 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
972 pic14_emitcode("clrz","");
974 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
975 AOP(IC_RIGHT(ic))->aopu.aop_dir,
976 AOP(IC_RIGHT(ic))->aopu.aop_dir);
977 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
981 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
982 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
983 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
984 //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
985 emitMOVWF(IC_RIGHT(ic),0);
987 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
988 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
989 AOP(IC_RIGHT(ic))->aopu.aop_dir,
990 AOP(IC_RIGHT(ic))->aopu.aop_dir);
991 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
992 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
998 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
999 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
1005 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1007 /* Add the first bytes */
1009 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1010 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
1011 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1014 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1015 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
1016 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1017 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1020 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1022 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1023 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1025 PIC_OPCODE poc = POC_ADDFW;
1027 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1028 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1029 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1031 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),0));
1032 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1033 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1038 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1043 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1044 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1045 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1046 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) {
1048 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1050 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1051 emitpcode(POC_ADDLW, popGetAddr(AOP(IC_LEFT(ic)),offset));
1052 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1057 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1059 emitpcode(POC_INCFSZW, popGet(AOP(IC_LEFT(ic)),offset));
1060 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
1065 PIC_OPCODE poc = POC_MOVFW;
1066 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1067 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1068 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1071 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1072 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset));
1073 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1075 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1077 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1078 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
1085 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1086 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1087 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1090 /* Need to extend result to higher bytes */
1091 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1093 /* First grab the carry from the lower bytes */
1094 if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1095 int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
1096 PIC_OPCODE poc = POC_MOVFW;
1097 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1098 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1099 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1101 while(leftsize-- > 0) {
1102 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset));
1103 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1105 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset));
1113 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1114 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
1118 if(sign && offset > 0 && offset < AOP_SIZE(IC_RESULT(ic))) {
1119 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1122 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1123 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1124 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1125 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1127 /* if chars or ints or being signed extended to longs: */
1129 emitpcode(POC_MOVLW, popGetLit(0));
1130 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1131 emitpcode(POC_MOVLW, popGetLit(0xff));
1139 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1141 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1148 //adjustArithmeticResult(ic);
1151 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1152 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1153 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1156 /*-----------------------------------------------------------------*/
1157 /* genMinusDec :- does subtraction with decrement if possible */
1158 /*-----------------------------------------------------------------*/
1159 bool genMinusDec (iCode *ic)
1161 unsigned int icount ;
1162 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1165 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1166 /* will try to generate an increment */
1167 /* if the right side is not a literal
1169 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1170 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1171 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1174 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1176 /* if the literal value of the right hand side
1177 is greater than 4 then it is not worth it */
1178 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1181 /* if decrement 16 bits in register */
1182 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1187 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1188 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1189 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1190 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1192 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1193 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1194 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1196 /* size is 3 or 4 */
1197 emitpcode(POC_MOVLW, popGetLit(0xff));
1198 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1200 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1202 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1204 pic14_emitcode("movlw","0xff");
1205 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1208 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1210 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1214 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1216 pic14_emitcode("skpnc","");
1218 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1227 /* if the sizes are greater than 1 then we cannot */
1228 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1229 AOP_SIZE(IC_LEFT(ic)) > 1 )
1232 /* we can if the aops of the left & result match or
1233 if they are in registers and the registers are the
1235 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1238 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1240 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1245 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1246 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1247 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1250 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1251 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1253 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1254 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1262 /*-----------------------------------------------------------------*/
1263 /* addSign - propogate sign bit to higher bytes */
1264 /*-----------------------------------------------------------------*/
1265 void addSign(operand *result, int offset, int sign)
1267 int size = (pic14_getDataSize(result) - offset);
1268 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1272 if(sign && offset) {
1275 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1276 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1277 emitpcode(POC_DECF, popGet(AOP(result),offset));
1280 emitpcode(POC_MOVLW, popGetLit(0));
1281 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1282 emitpcode(POC_MOVLW, popGetLit(0xff));
1284 emitpcode(POC_MOVWF, popGet(AOP(result),size));
1289 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1293 /*-----------------------------------------------------------------*/
1294 /* genMinusBits - generates code for subtraction of two bits */
1295 /*-----------------------------------------------------------------*/
1296 void genMinusBits (iCode *ic)
1298 symbol *lbl = newiTempLabel(NULL);
1300 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1301 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1302 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1303 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1304 pic14_emitcode("cpl","c");
1305 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1306 pic14_outBitC(IC_RESULT(ic));
1309 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1310 pic14_emitcode("subb","a,acc");
1311 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1312 pic14_emitcode("inc","a");
1313 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1314 aopPut(AOP(IC_RESULT(ic)),"a",0);
1315 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1319 /*-----------------------------------------------------------------*/
1320 /* genMinus - generates code for subtraction */
1321 /*-----------------------------------------------------------------*/
1322 void genMinus (iCode *ic)
1324 int size, offset = 0, same=0;
1325 unsigned long lit = 0L;
1328 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1329 aopOp (IC_LEFT(ic),ic,FALSE);
1330 aopOp (IC_RIGHT(ic),ic,FALSE);
1331 aopOp (IC_RESULT(ic),ic,TRUE);
1333 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1334 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1335 operand *t = IC_RIGHT(ic);
1336 IC_RIGHT(ic) = IC_LEFT(ic);
1340 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1341 AopType(AOP_TYPE(IC_RESULT(ic))),
1342 AopType(AOP_TYPE(IC_LEFT(ic))),
1343 AopType(AOP_TYPE(IC_RIGHT(ic))));
1345 /* special cases :- */
1346 /* if both left & right are in bit space */
1347 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1348 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1353 /* if I can do an decrement instead
1354 of subtract then GOOD for ME */
1355 // if (genMinusDec (ic) == TRUE)
1358 size = pic14_getDataSize(IC_RESULT(ic));
1359 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1361 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1362 /* Add a literal to something else */
1364 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1367 genAddLit ( ic, lit);
1370 /* add the first byte: */
1371 pic14_emitcode("movlw","0x%x", lit & 0xff);
1372 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1373 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1374 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1386 if((lit & 0xff) == 0xff) {
1387 emitpcode(POC_MOVLW, popGetLit(0xff));
1389 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1391 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1393 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1394 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1398 /* do the rlf known zero trick here */
1399 emitpcode(POC_MOVLW, popGetLit(1));
1401 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1406 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1409 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1410 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1411 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1413 /* here we are subtracting a bit from a char or int */
1415 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1417 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1418 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1420 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1421 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1422 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1423 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1426 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1427 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1428 emitpcode(POC_XORLW , popGetLit(1));
1429 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1430 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1432 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1434 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1435 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1437 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1438 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1441 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1443 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1445 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1446 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1450 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1451 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1452 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1453 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1458 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1459 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1460 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1463 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1465 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1468 emitpcode(POC_ANDLW , popGetLit(1));
1470 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1472 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1479 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1480 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1481 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1483 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1484 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1485 AopType(AOP_TYPE(IC_RESULT(ic))),
1486 AopType(AOP_TYPE(IC_LEFT(ic))),
1487 AopType(AOP_TYPE(IC_RIGHT(ic))));
1490 if( (size == 1) && ((lit & 0xff) == 0) ) {
1491 /* res = 0 - right */
1492 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1493 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1494 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1496 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1497 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1498 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1503 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1504 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1505 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1513 /* This is the last byte in a multibyte subtraction
1514 * There are a couple of tricks we can do by not worrying about
1515 * propogating the carry */
1517 /* 0xff - x == ~x */
1519 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1521 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1523 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1524 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1526 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1529 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1531 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1532 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1533 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1542 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1544 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1545 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1548 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1554 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1555 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1557 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1559 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1561 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1562 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1569 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1570 AopType(AOP_TYPE(IC_RESULT(ic))),
1571 AopType(AOP_TYPE(IC_LEFT(ic))),
1572 AopType(AOP_TYPE(IC_RIGHT(ic))));
1574 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1575 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1576 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1577 emitpcode(POC_SUBLW, popGetLit(0));
1578 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1581 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1582 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1583 emitpcode(POC_SUBLW, popGetLit(0));
1584 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1585 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1588 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1589 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1590 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1592 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1593 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1595 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1596 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1597 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1599 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1601 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1602 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1603 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1605 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1607 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1613 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1617 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1619 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1620 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1621 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) {
1625 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1627 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1628 emitpcode(lit?POC_SUBLW:POC_SUBFW, popGetAddr(AOP(IC_LEFT(ic)),offset));
1629 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1633 PIC_OPCODE poc = POC_MOVFW;
1634 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1635 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1636 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1639 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1640 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset));
1641 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1643 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1645 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1646 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1653 // adjustArithmeticResult(ic);
1656 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1657 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1658 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1660 /*-----------------------------------------------------------------*
1661 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1664 *-----------------------------------------------------------------*/
1665 void genUMult8XLit_16 (operand *left,
1668 pCodeOpReg *result_hi)
1673 unsigned int i,have_first_bit;
1678 if (AOP_TYPE(right) != AOP_LIT){
1679 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1685 result_hi = PCOR(popGet(AOP(result),1));
1688 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1690 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1692 same = pic14_sameRegs(AOP(left), AOP(result));
1697 emitpcode(POC_CLRF, popGet(AOP(left),0));
1700 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1701 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1704 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1705 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1706 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1709 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1710 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1711 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1712 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1715 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1716 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1717 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1718 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1721 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1722 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1723 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1724 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1725 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1728 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1729 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1730 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1731 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1732 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F
1735 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1736 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1737 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1738 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1739 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1742 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1743 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1744 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1745 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1746 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1747 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1750 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1751 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1752 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1753 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1754 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1755 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1758 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1759 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1760 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1761 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1762 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1763 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F
1766 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1767 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1768 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1769 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1770 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1771 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1772 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1775 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1776 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1777 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1778 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1779 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1780 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*F
1783 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1784 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1785 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1786 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1787 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1788 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F
1789 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F
1792 temp = popGetTempReg();
1794 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1797 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1798 emitpcode(POC_MOVWF, temp);
1799 emitpcode(POC_ANDLW, popGetLit(0xf0));
1800 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1801 emitpcode(POC_SWAPFW, temp);
1802 emitpcode(POC_SUBWF, popGet(AOP(left),0));
1803 popReleaseTempReg(temp);
1806 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1807 emitpcode(POC_ANDLW, popGetLit(0xf0));
1808 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1811 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1812 emitpcode(POC_ANDLW, popGetLit(0xf0));
1813 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1816 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1817 emitpcode(POC_RLFW, popGet(AOP(left),0));
1818 emitpcode(POC_ANDLW, popGetLit(0xe0));
1819 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1822 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1823 emitpcode(POC_RLF, popGet(AOP(left),0));
1824 emitpcode(POC_RLFW, popGet(AOP(left),0));
1825 emitpcode(POC_ANDLW, popGetLit(0xc0));
1826 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1829 emitpcode(POC_RRFW, popGet(AOP(left),0));
1830 emitpcode(POC_CLRF, popGet(AOP(left),0));
1831 emitpcode(POC_RRF, popGet(AOP(left),0));
1839 emitpcode(POC_CLRF, popGet(AOP(result),0));
1840 emitpcode(POC_CLRF, popCopyReg(result_hi));
1843 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1844 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1845 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1846 emitpcode(POC_ADDWF, popGet(AOP(result),0));
1847 emitpcode(POC_CLRF, popCopyReg(result_hi));
1848 emitpcode(POC_RLF, popCopyReg(result_hi));
1852 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1853 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1854 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1855 emitpcode(POC_CLRF, popCopyReg(result_hi));
1856 emitpcode(POC_BCF, popCopyReg(&pc_status));
1857 emitpcode(POC_RLF, popGet(AOP(result),0));
1858 emitpcode(POC_RLF, popCopyReg(result_hi));
1859 emitpcode(POC_RLF, popGet(AOP(result),0));
1860 emitpcode(POC_RLF, popCopyReg(result_hi));
1862 emitpcode(POC_RLF, popGet(AOP(result),0));
1863 emitpcode(POC_RLF, popCopyReg(result_hi));
1870 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1871 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1872 emitpcode(POC_CLRF, popGet(AOP(result),0));
1873 emitpcode(POC_CLRF, popCopyReg(result_hi));
1876 for(i=0; i<8; i++) {
1879 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1883 if(have_first_bit) {
1884 emitpcode(POC_RRF, popCopyReg(result_hi));
1885 emitpcode(POC_RRF, popGet(AOP(result),0));
1892 /*-----------------------------------------------------------------*
1893 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1896 *-----------------------------------------------------------------*/
1897 void genUMult8X8_16 (operand *left,
1900 pCodeOpReg *result_hi)
1909 result_hi = PCOR(popGet(AOP(result),1));
1912 if (AOP_TYPE(right) == AOP_LIT) {
1913 genUMult8XLit_16(left,right,result,result_hi);
1918 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1920 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1921 emitpcode(POC_CLRF, popGet(AOP(result),0));
1922 emitpcode(POC_CLRF, popCopyReg(result_hi));
1925 for(i=0; i<8; i++) {
1926 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1927 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1928 emitpcode(POC_RRF, popCopyReg(result_hi));
1929 emitpcode(POC_RRF, popGet(AOP(result),0));
1934 Here's another version that does the same thing and takes the
1935 same number of instructions. The one above is slightly better
1936 because the entry instructions have a higher probability of
1937 being optimized out.
1940 emitpcode(POC_CLRF, popCopyReg(result_hi));
1941 emitpcode(POC_RRFW, popGet(AOP(left),0));
1942 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1943 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1945 for(i=0; i<8; i++) {
1947 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1948 emitpcode(POC_RRF, popCopyReg(result_hi));
1949 emitpcode(POC_RRF, popGet(AOP(result),0));
1954 symbol *tlbl = newiTempLabel(NULL);
1958 pic14_emitcode(";","Looped 8 X 8 multiplication");
1960 emitpcode(POC_CLRF, popGet(AOP(result),0));
1961 emitpcode(POC_CLRF, popCopyReg(result_hi));
1963 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1965 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1967 temp = popGetTempReg();
1968 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1970 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1972 emitpLabel(tlbl->key);
1974 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1976 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1978 emitpcode(POC_RRF, popCopyReg(result_hi));
1979 emitpcode(POC_RRF, popGet(AOP(result),0));
1982 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1984 popReleaseTempReg(temp);
1989 /*-----------------------------------------------------------------*
1990 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1992 * this routine will call the unsigned multiply routine and then
1993 * post-fix the sign bit.
1994 *-----------------------------------------------------------------*/
1995 void genSMult8X8_16 (operand *left,
1998 pCodeOpReg *result_hi)
2003 result_hi = PCOR(popGet(AOP(result),1));
2006 genUMult8X8_16(left,right,result,result_hi);
2008 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
2009 emitpcode(POC_SUBWF, popCopyReg(result_hi));
2010 emitpcode(POC_MOVFW, popGet(AOP(left),0));
2011 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
2012 emitpcode(POC_SUBWF, popGet(AOP(result),1));
2016 /*-----------------------------------------------------------------*
2017 * genMult8X8_8 - multiplication of two 8-bit numbers
2019 * this routine will call the unsigned multiply 8X8=>16 routine and
2020 * then throw away the high byte of the result.
2022 *-----------------------------------------------------------------*/
2023 void genMult8X8_8 (operand *left,
2029 if (result && result->aop && result->aop->type==2 && result->aop->size>=1) {
2030 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. */
2032 result_hi = popGetTempReg();
2034 if (AOP_TYPE(right) == AOP_LIT)
2035 genUMult8XLit_16(left,right,result,PCOR(result_hi));
2037 genUMult8X8_16(left,right,result,PCOR(result_hi));
2039 popReleaseTempReg(result_hi);
2042 /*-----------------------------------------------------------------*/
2043 /* constMult - generates code for multiplication by a constant */
2044 /*-----------------------------------------------------------------*/
2045 void genMultConst(unsigned C)
2049 unsigned sr3; // Shift right 3
2055 Convert a string of 3 binary 1's in the lit into
2059 mask = 7 << ( (size*8) - 3);
2063 while(mask < (1<<size*8)) {
2065 if( (mask & lit) == lit) {
2068 /* We found 3 (or more) consecutive 1's */
2070 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2072 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2074 lit ^= consecutive_bits;
2078 sr3 |= (consecutive + lsb);