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));
204 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
205 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
206 AopType(AOP_TYPE(IC_RESULT(ic))),
207 AopType(AOP_TYPE(IC_LEFT(ic))),
208 AopType(AOP_TYPE(IC_RIGHT(ic))));
210 /* will try to generate an increment */
211 /* if the right side is not a literal
213 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
216 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
217 /* if the literal value of the right hand side
218 is greater than 1 then it is faster to add */
219 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
222 /* if increment 16 bits in register */
223 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
228 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB));
229 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
233 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
234 //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
240 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
241 /* if left is in accumulator - probably a bit operation*/
242 if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
243 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
245 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
246 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
247 AOP(IC_RESULT(ic))->aopu.aop_dir,
248 AOP(IC_RESULT(ic))->aopu.aop_dir);
250 emitpcode(POC_XORLW,popGetLit(1));
251 //pic14_emitcode("xorlw","1");
253 emitpcode(POC_ANDLW,popGetLit(1));
254 //pic14_emitcode("andlw","1");
257 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
258 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
259 AOP(IC_RESULT(ic))->aopu.aop_dir,
260 AOP(IC_RESULT(ic))->aopu.aop_dir);
267 /* if the sizes are greater than 1 then we cannot */
268 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
269 AOP_SIZE(IC_LEFT(ic)) > 1 )
272 /* If we are incrementing the same register by two: */
274 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
277 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
278 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
283 DEBUGpic14_emitcode ("; ","couldn't increment ");
288 /*-----------------------------------------------------------------*/
289 /* pic14_outBitAcc - output a bit in acc */
290 /*-----------------------------------------------------------------*/
291 void pic14_outBitAcc(operand *result)
293 symbol *tlbl = newiTempLabel(NULL);
294 /* if the result is a bit */
295 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
297 if (AOP_TYPE(result) == AOP_CRY){
298 aopPut(AOP(result),"a",0);
301 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
302 pic14_emitcode("mov","a,#01");
303 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
304 pic14_outAcc(result);
308 /*-----------------------------------------------------------------*/
309 /* genPlusBits - generates code for addition of two bits */
310 /*-----------------------------------------------------------------*/
311 void genPlusBits (iCode *ic)
314 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
316 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
317 AopType(AOP_TYPE(IC_RESULT(ic))),
318 AopType(AOP_TYPE(IC_LEFT(ic))),
319 AopType(AOP_TYPE(IC_RIGHT(ic))));
321 The following block of code will add two bits.
322 Note that it'll even work if the destination is
323 the carry (C in the status register).
324 It won't work if the 'Z' bit is a source or destination.
327 /* If the result is stored in the accumulator (w) */
328 //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
329 switch(AOP_TYPE(IC_RESULT(ic))) {
331 emitpcode(POC_CLRW, NULL);
332 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
333 emitpcode(POC_XORLW, popGetLit(1));
334 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
335 emitpcode(POC_XORLW, popGetLit(1));
337 pic14_emitcode("clrw","");
338 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
339 AOP(IC_RIGHT(ic))->aopu.aop_dir,
340 AOP(IC_RIGHT(ic))->aopu.aop_dir);
341 pic14_emitcode("xorlw","1");
342 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
343 AOP(IC_LEFT(ic))->aopu.aop_dir,
344 AOP(IC_LEFT(ic))->aopu.aop_dir);
345 pic14_emitcode("xorlw","1");
348 emitpcode(POC_MOVLW, popGetLit(0));
349 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
350 emitpcode(POC_XORLW, popGetLit(1));
351 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
352 emitpcode(POC_XORLW, popGetLit(1));
353 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
356 if(pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic)))) {
363 if(pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic)))) {
364 DebugAop(AOP(IC_LEFT(ic)));
365 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),0));
366 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
367 emitpcode(POC_XORWF, popGet(AOP(IC_LEFT(ic)),0));
369 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
370 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
371 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
372 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
373 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
374 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
378 pic14_emitcode("movlw","(1 << (%s & 7))",
379 AOP(IC_RESULT(ic))->aopu.aop_dir,
380 AOP(IC_RESULT(ic))->aopu.aop_dir);
381 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
382 AOP(IC_RESULT(ic))->aopu.aop_dir,
383 AOP(IC_RESULT(ic))->aopu.aop_dir);
384 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
385 AOP(IC_RIGHT(ic))->aopu.aop_dir,
386 AOP(IC_RIGHT(ic))->aopu.aop_dir);
387 pic14_emitcode("xorwf","(%s >>3),f",
388 AOP(IC_RESULT(ic))->aopu.aop_dir);
389 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
390 AOP(IC_LEFT(ic))->aopu.aop_dir,
391 AOP(IC_LEFT(ic))->aopu.aop_dir);
392 pic14_emitcode("xorwf","(%s>>3),f",
393 AOP(IC_RESULT(ic))->aopu.aop_dir);
400 /* This is the original version of this code.
402 * This is being kept around for reference,
403 * because I am not entirely sure I got it right...
405 static void adjustArithmeticResult(iCode *ic)
407 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
408 AOP_SIZE(IC_LEFT(ic)) == 3 &&
409 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
410 aopPut(AOP(IC_RESULT(ic)),
411 aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
414 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
415 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
416 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
417 aopPut(AOP(IC_RESULT(ic)),
418 aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
421 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
422 AOP_SIZE(IC_LEFT(ic)) < 3 &&
423 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
424 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
425 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
427 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
428 aopPut(AOP(IC_RESULT(ic)),buffer,2);
432 /* This is the pure and virtuous version of this code.
433 * I'm pretty certain it's right, but not enough to toss the old
436 static void adjustArithmeticResult(iCode *ic)
438 if (opIsGptr(IC_RESULT(ic)) &&
439 opIsGptr(IC_LEFT(ic)) &&
440 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
442 aopPut(AOP(IC_RESULT(ic)),
443 aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
447 if (opIsGptr(IC_RESULT(ic)) &&
448 opIsGptr(IC_RIGHT(ic)) &&
449 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
451 aopPut(AOP(IC_RESULT(ic)),
452 aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
456 if (opIsGptr(IC_RESULT(ic)) &&
457 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
458 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
459 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
460 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
462 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
463 aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
468 /*-----------------------------------------------------------------*/
469 /* genAddlit - generates code for addition */
470 /*-----------------------------------------------------------------*/
471 static void genAddLit2byte (operand *result, int offr, int lit)
478 emitpcode(POC_INCF, popGet(AOP(result),offr));
481 emitpcode(POC_DECF, popGet(AOP(result),offr));
484 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
485 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
490 static void emitMOVWF(operand *reg, int offset)
495 if (AOP_TYPE(reg) == AOP_ACC) {
496 DEBUGpic14_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
500 emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
504 static void genAddLit (iCode *ic, int lit)
513 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
517 result = IC_RESULT(ic);
518 same = pic14_sameRegs(AOP(left), AOP(result));
519 size = pic14_getDataSize(result);
523 /* Handle special cases first */
525 genAddLit2byte (result, 0, lit);
528 int hi = 0xff & (lit >> 8);
535 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
540 emitpcode(POC_INCF, popGet(AOP(result),0));
542 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
545 emitpcode(POC_DECF, popGet(AOP(result),0));
546 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
547 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
551 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
552 emitpcode(POC_ADDWF,popGet(AOP(result),0));
554 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
562 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
565 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
568 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
569 emitpcode(POC_INCF, popGet(AOP(result),0));
571 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
573 case 0xff: /* 0x01ff */
574 emitpcode(POC_DECF, popGet(AOP(result),0));
575 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
576 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
577 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
582 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
586 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
589 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
590 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
592 /* case 0xff: * 0xffff *
593 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
594 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
595 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
599 emitpcode(POC_MOVLW,popGetLit(lo));
600 emitpcode(POC_ADDWF,popGet(AOP(result),0));
602 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
609 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
614 genAddLit2byte (result, MSB16, hi);
617 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
618 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
619 emitpcode(POC_MOVLW,popGetLit(hi));
620 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
622 /* case 0xff: * 0xHHff *
623 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
624 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
625 emitpcode(POC_MOVLW,popGetLit(hi));
626 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
628 */ default: /* 0xHHLL */
629 emitpcode(POC_MOVLW,popGetLit(lo));
630 emitpcode(POC_ADDWF, popGet(AOP(result),0));
631 emitpcode(POC_MOVLW,popGetLit(hi));
633 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
634 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
643 DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
646 lo = BYTEofLONG(lit,0);
654 emitpcode(POC_INCF, popGet(AOP(result),offset));
657 emitpcode(POC_RLFW, popGet(AOP(result),offset));
658 emitpcode(POC_ANDLW,popGetLit(1));
659 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
661 default: /* carry_info = 3 */
663 emitpcode(POC_INCF, popGet(AOP(result),offset));
669 emitpcode(POC_MOVLW,popGetLit(lo));
674 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
677 emitpcode(POC_MOVLW,popGetLit(lo));
682 emitpcode(POC_MOVLW,popGetLit(lo+1));
683 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
688 /* no carry info from previous step */
689 /* this means this is the first time to add */
694 emitpcode(POC_INCF, popGet(AOP(result),offset));
698 emitpcode(POC_MOVLW,popGetLit(lo));
699 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
701 carry_info = 3; /* Were adding only one byte and propogating the carry */
712 lo = BYTEofLONG(lit,0);
717 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
720 emitpcode(POC_MOVLW,popGetLit(lo));
721 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
724 emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
726 emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
728 emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
738 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
742 if(AOP_TYPE(left) == AOP_ACC) {
743 /* left addend is already in accumulator */
746 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
750 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
751 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
755 /* left addend is in a register */
758 emitpcode(POC_MOVFW, popGet(AOP(left),0));
759 emitMOVWF(result, 0);
760 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
764 emitpcode(POC_INCFW, popGet(AOP(left),0));
765 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
769 emitpcode(POC_DECFW, popGet(AOP(left),0));
770 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
774 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
775 emitpcode(POC_ADDFW, popGet(AOP(left),0));
776 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
784 /* left is not the accumulator */
786 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
787 emitpcode(POC_ADDFW, popGet(AOP(left),0));
789 emitpcode(POC_MOVFW, popGet(AOP(left),0));
790 /* We don't know the state of the carry bit at this point */
793 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
800 /* The ls byte of the lit must've been zero - that
801 means we don't have to deal with carry */
803 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
804 emitpcode(POC_ADDFW, popGet(AOP(left),offset));
805 emitpcode(POC_MOVWF, popGet(AOP(left),offset));
810 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
811 //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
812 emitMOVWF(result,offset);
813 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
815 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
816 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
820 emitpcode(POC_CLRF, popGet(AOP(result),offset));
821 emitpcode(POC_RLF, popGet(AOP(result),offset));
822 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
823 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
831 /*-----------------------------------------------------------------*/
832 /* genPlus - generates code for addition */
833 /*-----------------------------------------------------------------*/
834 void genPlus (iCode *ic)
836 int size, offset = 0;
838 /* special cases :- */
839 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
841 aopOp (IC_LEFT(ic),ic,FALSE);
842 aopOp (IC_RIGHT(ic),ic,FALSE);
843 aopOp (IC_RESULT(ic),ic,TRUE);
845 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
847 /* if literal, literal on the right or
848 if left requires ACC or right is already
851 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
852 operand *t = IC_RIGHT(ic);
853 IC_RIGHT(ic) = IC_LEFT(ic);
857 /* if both left & right are in bit space */
858 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
859 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
864 /* if left in bit space & right literal */
865 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
866 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
867 /* if result in bit space */
868 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
869 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
870 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
871 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
872 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
873 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
876 size = pic14_getDataSize(IC_RESULT(ic));
878 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
879 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
880 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
886 /* if I can do an increment instead
887 of add then GOOD for ME */
888 if (genPlusIncr (ic) == TRUE)
891 size = pic14_getDataSize(IC_RESULT(ic));
893 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
894 /* Add a literal to something else */
896 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
900 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
905 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
907 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
908 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
909 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
911 /* here we are adding a bit to a char or int */
913 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
915 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
916 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
918 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
919 AOP(IC_RIGHT(ic))->aopu.aop_dir,
920 AOP(IC_RIGHT(ic))->aopu.aop_dir);
921 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
924 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
925 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
926 emitpcode(POC_XORLW , popGetLit(1));
928 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
929 AOP(IC_RIGHT(ic))->aopu.aop_dir,
930 AOP(IC_RIGHT(ic))->aopu.aop_dir);
931 pic14_emitcode(" xorlw","1");
933 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
934 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
935 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
937 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
938 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
939 AOP(IC_RIGHT(ic))->aopu.aop_dir,
940 AOP(IC_RIGHT(ic))->aopu.aop_dir);
941 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
944 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
946 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
947 emitpcode(POC_ANDLW , popGetLit(1));
948 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
950 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
952 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
953 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
960 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
961 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
963 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
964 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
966 pic14_emitcode("clrz","");
968 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
969 AOP(IC_RIGHT(ic))->aopu.aop_dir,
970 AOP(IC_RIGHT(ic))->aopu.aop_dir);
971 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
975 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
976 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
977 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
978 //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
979 emitMOVWF(IC_RIGHT(ic),0);
981 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
982 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
983 AOP(IC_RIGHT(ic))->aopu.aop_dir,
984 AOP(IC_RIGHT(ic))->aopu.aop_dir);
985 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
986 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
992 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
993 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
999 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1001 /* Add the first bytes */
1003 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1004 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
1005 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1008 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1009 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
1010 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1011 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1014 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1016 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1017 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1019 PIC_OPCODE poc = POC_ADDFW;
1021 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1022 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1023 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1025 emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0));
1026 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1027 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1032 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1037 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1038 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1039 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1040 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) {
1042 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1044 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1045 emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),offset));
1046 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1051 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1053 emitpcode(POC_INCFSZW, popGet(AOP(IC_LEFT(ic)),offset));
1054 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
1059 PIC_OPCODE poc = POC_MOVFW;
1060 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1061 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1062 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1065 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1066 emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset));
1067 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1069 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1071 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1072 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
1079 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1080 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1081 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1084 /* Need to extend result to higher bytes */
1085 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1087 /* First grab the carry from the lower bytes */
1088 if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1089 int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
1090 PIC_OPCODE poc = POC_MOVFW;
1091 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1092 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1093 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1095 while(leftsize-- > 0) {
1096 emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset));
1097 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1099 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset));
1107 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1108 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
1113 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1116 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1117 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1118 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1119 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1121 /* if chars or ints or being signed extended to longs: */
1123 emitpcode(POC_MOVLW, popGetLit(0));
1124 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1125 emitpcode(POC_MOVLW, popGetLit(0xff));
1133 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1135 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1142 //adjustArithmeticResult(ic);
1145 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1146 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1147 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1150 /*-----------------------------------------------------------------*/
1151 /* genMinusDec :- does subtraction with decrement if possible */
1152 /*-----------------------------------------------------------------*/
1153 bool genMinusDec (iCode *ic)
1155 unsigned int icount ;
1156 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1158 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1159 /* will try to generate an increment */
1160 /* if the right side is not a literal
1162 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1163 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1164 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1167 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1169 /* if the literal value of the right hand side
1170 is greater than 4 then it is not worth it */
1171 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1174 /* if decrement 16 bits in register */
1175 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1180 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1181 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1182 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1183 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1185 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1186 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1187 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1189 /* size is 3 or 4 */
1190 emitpcode(POC_MOVLW, popGetLit(0xff));
1191 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1193 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1195 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1197 pic14_emitcode("movlw","0xff");
1198 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1201 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1203 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1207 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1209 pic14_emitcode("skpnc","");
1211 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1220 /* if the sizes are greater than 1 then we cannot */
1221 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1222 AOP_SIZE(IC_LEFT(ic)) > 1 )
1225 /* we can if the aops of the left & result match or
1226 if they are in registers and the registers are the
1228 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1231 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1233 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1238 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1239 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1240 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1243 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1244 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1246 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1247 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1255 /*-----------------------------------------------------------------*/
1256 /* addSign - propogate sign bit to higher bytes */
1257 /*-----------------------------------------------------------------*/
1258 void addSign(operand *result, int offset, int sign)
1260 int size = (pic14_getDataSize(result) - offset);
1261 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1264 if(sign && offset) {
1267 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1268 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1269 emitpcode(POC_DECF, popGet(AOP(result),offset));
1272 emitpcode(POC_MOVLW, popGetLit(0));
1273 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1274 emitpcode(POC_MOVLW, popGetLit(0xff));
1276 emitpcode(POC_MOVWF, popGet(AOP(result),size));
1281 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1285 /*-----------------------------------------------------------------*/
1286 /* genMinusBits - generates code for subtraction of two bits */
1287 /*-----------------------------------------------------------------*/
1288 void genMinusBits (iCode *ic)
1290 symbol *lbl = newiTempLabel(NULL);
1291 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1292 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1293 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1294 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1295 pic14_emitcode("cpl","c");
1296 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1297 pic14_outBitC(IC_RESULT(ic));
1300 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1301 pic14_emitcode("subb","a,acc");
1302 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1303 pic14_emitcode("inc","a");
1304 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1305 aopPut(AOP(IC_RESULT(ic)),"a",0);
1306 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1310 /*-----------------------------------------------------------------*/
1311 /* genMinus - generates code for subtraction */
1312 /*-----------------------------------------------------------------*/
1313 void genMinus (iCode *ic)
1315 int size, offset = 0, same=0;
1316 unsigned long lit = 0L;
1318 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1319 aopOp (IC_LEFT(ic),ic,FALSE);
1320 aopOp (IC_RIGHT(ic),ic,FALSE);
1321 aopOp (IC_RESULT(ic),ic,TRUE);
1323 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1324 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1325 operand *t = IC_RIGHT(ic);
1326 IC_RIGHT(ic) = IC_LEFT(ic);
1330 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1331 AopType(AOP_TYPE(IC_RESULT(ic))),
1332 AopType(AOP_TYPE(IC_LEFT(ic))),
1333 AopType(AOP_TYPE(IC_RIGHT(ic))));
1335 /* special cases :- */
1336 /* if both left & right are in bit space */
1337 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1338 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1343 /* if I can do an decrement instead
1344 of subtract then GOOD for ME */
1345 // if (genMinusDec (ic) == TRUE)
1348 size = pic14_getDataSize(IC_RESULT(ic));
1349 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1351 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1352 /* Add a literal to something else */
1354 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1357 genAddLit ( ic, lit);
1360 /* add the first byte: */
1361 pic14_emitcode("movlw","0x%x", lit & 0xff);
1362 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1363 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1364 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1376 if((lit & 0xff) == 0xff) {
1377 emitpcode(POC_MOVLW, popGetLit(0xff));
1379 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1381 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1383 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1384 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1388 /* do the rlf known zero trick here */
1389 emitpcode(POC_MOVLW, popGetLit(1));
1391 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1396 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1399 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1400 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1401 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1403 /* here we are subtracting a bit from a char or int */
1405 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1407 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1408 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1410 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1411 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1412 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1413 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1416 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1417 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1418 emitpcode(POC_XORLW , popGetLit(1));
1419 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1420 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1422 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1424 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1425 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1427 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1428 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1431 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1433 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1435 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1436 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1440 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1441 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1442 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1443 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1448 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1449 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1450 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1453 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1455 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1458 emitpcode(POC_ANDLW , popGetLit(1));
1460 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1462 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1469 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1470 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1471 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1473 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1474 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1475 AopType(AOP_TYPE(IC_RESULT(ic))),
1476 AopType(AOP_TYPE(IC_LEFT(ic))),
1477 AopType(AOP_TYPE(IC_RIGHT(ic))));
1480 if( (size == 1) && ((lit & 0xff) == 0) ) {
1481 /* res = 0 - right */
1482 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1483 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1484 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1486 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1487 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1488 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1493 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1494 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1495 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1503 /* This is the last byte in a multibyte subtraction
1504 * There are a couple of tricks we can do by not worrying about
1505 * propogating the carry */
1507 /* 0xff - x == ~x */
1509 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1511 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1513 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1514 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1516 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1519 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1521 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1522 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1523 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1532 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1534 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1535 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1538 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1544 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1545 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1547 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1549 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1551 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1552 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1559 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1560 AopType(AOP_TYPE(IC_RESULT(ic))),
1561 AopType(AOP_TYPE(IC_LEFT(ic))),
1562 AopType(AOP_TYPE(IC_RIGHT(ic))));
1564 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1565 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1566 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1567 emitpcode(POC_SUBLW, popGetLit(0));
1568 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1571 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1572 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1573 emitpcode(POC_SUBLW, popGetLit(0));
1574 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1575 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1578 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1579 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1580 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1582 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1583 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1585 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1586 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1587 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1589 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1591 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1592 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1593 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1595 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1597 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1603 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1607 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1608 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1609 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1610 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) {
1612 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1614 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1615 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),offset));
1616 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1621 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1623 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1624 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),offset));
1625 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1630 PIC_OPCODE poc = POC_MOVFW;
1631 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1632 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1633 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1636 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1637 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1638 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1640 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1642 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1643 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1650 // adjustArithmeticResult(ic);
1653 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1654 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1655 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1657 /*-----------------------------------------------------------------*
1658 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1661 *-----------------------------------------------------------------*/
1662 void genUMult8XLit_16 (operand *left,
1665 pCodeOpReg *result_hi)
1670 unsigned int i,have_first_bit;
1674 if (AOP_TYPE(right) != AOP_LIT){
1675 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1681 result_hi = PCOR(popGet(AOP(result),1));
1684 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1686 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1688 same = pic14_sameRegs(AOP(left), AOP(result));
1693 emitpcode(POC_CLRF, popGet(AOP(left),0));
1696 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1697 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1700 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1701 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1702 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1705 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1706 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1707 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1708 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1711 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1712 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1713 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1714 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1717 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1718 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1719 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1720 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1721 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1724 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1725 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1726 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1727 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1728 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F
1731 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1732 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1733 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1734 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1735 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1738 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1739 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1740 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1741 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1742 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1743 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1746 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1747 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1748 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1749 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1750 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1751 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1754 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1755 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1756 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1757 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1758 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1759 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F
1762 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1763 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1764 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1765 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1766 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1767 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1768 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1771 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1772 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1773 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1774 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1775 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1776 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*F
1779 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1780 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1781 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1782 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1783 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1784 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F
1785 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F
1788 temp = popGetTempReg();
1790 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1793 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1794 emitpcode(POC_MOVWF, temp);
1795 emitpcode(POC_ANDLW, popGetLit(0xf0));
1796 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1797 emitpcode(POC_SWAPFW, temp);
1798 emitpcode(POC_SUBWF, popGet(AOP(left),0));
1799 popReleaseTempReg(temp);
1802 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1803 emitpcode(POC_ANDLW, popGetLit(0xf0));
1804 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1807 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1808 emitpcode(POC_ANDLW, popGetLit(0xf0));
1809 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1812 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1813 emitpcode(POC_RLFW, popGet(AOP(left),0));
1814 emitpcode(POC_ANDLW, popGetLit(0xe0));
1815 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1818 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1819 emitpcode(POC_RLF, popGet(AOP(left),0));
1820 emitpcode(POC_RLFW, popGet(AOP(left),0));
1821 emitpcode(POC_ANDLW, popGetLit(0xc0));
1822 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1825 emitpcode(POC_RRFW, popGet(AOP(left),0));
1826 emitpcode(POC_CLRF, popGet(AOP(left),0));
1827 emitpcode(POC_RRF, popGet(AOP(left),0));
1835 emitpcode(POC_CLRF, popGet(AOP(result),0));
1836 emitpcode(POC_CLRF, popCopyReg(result_hi));
1839 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1840 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1841 emitpcode(POC_ADDWF, popGet(AOP(result),0));
1842 emitpcode(POC_CLRF, popCopyReg(result_hi));
1843 emitpcode(POC_RLF, popCopyReg(result_hi));
1849 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1850 emitpcode(POC_CLRF, popGet(AOP(result),0));
1851 emitpcode(POC_CLRF, popCopyReg(result_hi));
1854 for(i=0; i<8; i++) {
1857 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1861 if(have_first_bit) {
1862 emitpcode(POC_RRF, popCopyReg(result_hi));
1863 emitpcode(POC_RRF, popGet(AOP(result),0));
1871 /*-----------------------------------------------------------------*
1872 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1875 *-----------------------------------------------------------------*/
1876 void genUMult8X8_16 (operand *left,
1879 pCodeOpReg *result_hi)
1887 result_hi = PCOR(popGet(AOP(result),1));
1890 if (AOP_TYPE(right) == AOP_LIT) {
1891 genUMult8XLit_16(left,right,result,result_hi);
1896 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1898 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1899 emitpcode(POC_CLRF, popGet(AOP(result),0));
1900 emitpcode(POC_CLRF, popCopyReg(result_hi));
1903 for(i=0; i<8; i++) {
1904 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1905 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1906 emitpcode(POC_RRF, popCopyReg(result_hi));
1907 emitpcode(POC_RRF, popGet(AOP(result),0));
1912 Here's another version that does the same thing and takes the
1913 same number of instructions. The one above is slightly better
1914 because the entry instructions have a higher probability of
1915 being optimized out.
1918 emitpcode(POC_CLRF, popCopyReg(result_hi));
1919 emitpcode(POC_RRFW, popGet(AOP(left),0));
1920 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1921 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1923 for(i=0; i<8; i++) {
1925 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1926 emitpcode(POC_RRF, popCopyReg(result_hi));
1927 emitpcode(POC_RRF, popGet(AOP(result),0));
1932 symbol *tlbl = newiTempLabel(NULL);
1936 pic14_emitcode(";","Looped 8 X 8 multiplication");
1938 emitpcode(POC_CLRF, popGet(AOP(result),0));
1939 emitpcode(POC_CLRF, popCopyReg(result_hi));
1941 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1943 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1945 temp = popGetTempReg();
1946 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1948 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1950 emitpLabel(tlbl->key);
1952 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1954 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1956 emitpcode(POC_RRF, popCopyReg(result_hi));
1957 emitpcode(POC_RRF, popGet(AOP(result),0));
1960 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1962 popReleaseTempReg(temp);
1967 /*-----------------------------------------------------------------*
1968 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1970 * this routine will call the unsigned multiply routine and then
1971 * post-fix the sign bit.
1972 *-----------------------------------------------------------------*/
1973 void genSMult8X8_16 (operand *left,
1976 pCodeOpReg *result_hi)
1980 result_hi = PCOR(popGet(AOP(result),1));
1983 genUMult8X8_16(left,right,result,result_hi);
1985 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1986 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1987 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1988 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1989 emitpcode(POC_SUBWF, popGet(AOP(result),1));
1993 /*-----------------------------------------------------------------*
1994 * genMult8X8_8 - multiplication of two 8-bit numbers
1996 * this routine will call the unsigned multiply 8X8=>16 routine and
1997 * then throw away the high byte of the result.
1999 *-----------------------------------------------------------------*/
2000 void genMult8X8_8 (operand *left,
2004 pCodeOp *result_hi = popGetTempReg();
2006 if (AOP_TYPE(right) == AOP_LIT)
2007 genUMult8XLit_16(left,right,result,PCOR(result_hi));
2009 genUMult8X8_16(left,right,result,PCOR(result_hi));
2011 popReleaseTempReg(result_hi);
2014 /*-----------------------------------------------------------------*/
2015 /* constMult - generates code for multiplication by a constant */
2016 /*-----------------------------------------------------------------*/
2017 void genMultConst(unsigned C)
2021 unsigned sr3; // Shift right 3
2027 Convert a string of 3 binary 1's in the lit into
2031 mask = 7 << ( (size*8) - 3);
2035 while(mask < (1<<size*8)) {
2037 if( (mask & lit) == lit) {
2040 /* We found 3 (or more) consecutive 1's */
2042 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2044 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2046 lit ^= consecutive_bits;
2050 sr3 |= (consecutive + lsb);