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 (op_isLitLike (IC_LEFT (ic)))
1029 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),0,0));
1030 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1031 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1036 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1041 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1042 if (op_isLitLike (IC_LEFT(ic)))
1045 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1047 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1048 emitpcode(POC_ADDLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1049 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1054 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1056 emitpcode(POC_INCFSZW, popGet(AOP(IC_LEFT(ic)),offset));
1057 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
1062 PIC_OPCODE poc = POC_MOVFW;
1063 if (op_isLitLike (IC_LEFT(ic)))
1066 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1067 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1068 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1070 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1072 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1073 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
1080 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1081 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1082 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1085 /* Need to extend result to higher bytes */
1086 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1088 /* First grab the carry from the lower bytes */
1089 if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1090 int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
1091 PIC_OPCODE poc = POC_MOVFW;
1092 if (op_isLitLike (IC_LEFT(ic)))
1094 while(leftsize-- > 0) {
1095 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1097 emitpcode(POC_ADDLW, popGetLit(0x01));
1098 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1100 //emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset)); /* INCF does not update Carry! */
1108 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1109 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
1113 if(sign && offset > 0 && offset < AOP_SIZE(IC_RESULT(ic))) {
1114 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1117 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1118 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1119 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1120 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1122 /* if chars or ints or being signed extended to longs: */
1124 emitpcode(POC_MOVLW, popGetLit(0));
1125 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1126 emitpcode(POC_MOVLW, popGetLit(0xff));
1134 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1136 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1143 //adjustArithmeticResult(ic);
1146 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1147 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1148 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1151 /*-----------------------------------------------------------------*/
1152 /* genMinusDec :- does subtraction with decrement if possible */
1153 /*-----------------------------------------------------------------*/
1154 bool genMinusDec (iCode *ic)
1156 unsigned int icount ;
1157 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1161 /* will try to generate an increment */
1162 /* if the right side is not a literal
1164 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1165 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1166 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1169 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1171 /* if the literal value of the right hand side
1172 is greater than 4 then it is not worth it */
1173 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1176 /* if decrement 16 bits in register */
1177 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1182 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1183 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1184 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1185 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1187 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1188 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1189 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1191 /* size is 3 or 4 */
1192 emitpcode(POC_MOVLW, popGetLit(0xff));
1193 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1195 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1197 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1199 pic14_emitcode("movlw","0xff");
1200 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1203 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1205 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1209 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1211 pic14_emitcode("skpnc","");
1213 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1222 /* if the sizes are greater than 1 then we cannot */
1223 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1224 AOP_SIZE(IC_LEFT(ic)) > 1 )
1227 /* we can if the aops of the left & result match or
1228 if they are in registers and the registers are the
1230 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1233 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1235 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1240 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1241 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1242 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1245 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1246 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1248 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1249 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1257 /*-----------------------------------------------------------------*/
1258 /* addSign - propogate sign bit to higher bytes */
1259 /*-----------------------------------------------------------------*/
1260 void addSign(operand *result, int offset, int sign)
1262 int size = (pic14_getDataSize(result) - offset);
1263 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1267 if(sign && offset) {
1270 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1271 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1272 emitpcode(POC_DECF, popGet(AOP(result),offset));
1275 emitpcode(POC_MOVLW, popGetLit(0));
1276 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1277 emitpcode(POC_MOVLW, popGetLit(0xff));
1279 emitpcode(POC_MOVWF, popGet(AOP(result),offset+size));
1283 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1287 /*-----------------------------------------------------------------*/
1288 /* genMinusBits - generates code for subtraction of two bits */
1289 /*-----------------------------------------------------------------*/
1290 void genMinusBits (iCode *ic)
1292 symbol *lbl = newiTempLabel(NULL);
1294 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1295 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1296 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1297 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1298 pic14_emitcode("cpl","c");
1299 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1300 pic14_outBitC(IC_RESULT(ic));
1303 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1304 pic14_emitcode("subb","a,acc");
1305 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1306 pic14_emitcode("inc","a");
1307 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1308 aopPut(AOP(IC_RESULT(ic)),"a",0);
1309 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1313 /*-----------------------------------------------------------------*/
1314 /* genMinus - generates code for subtraction */
1315 /*-----------------------------------------------------------------*/
1316 void genMinus (iCode *ic)
1318 int size, offset = 0, same=0;
1319 unsigned long lit = 0L;
1322 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1323 aopOp (IC_LEFT(ic),ic,FALSE);
1324 aopOp (IC_RIGHT(ic),ic,FALSE);
1325 aopOp (IC_RESULT(ic),ic,TRUE);
1327 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1328 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1329 operand *t = IC_RIGHT(ic);
1330 IC_RIGHT(ic) = IC_LEFT(ic);
1334 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1335 AopType(AOP_TYPE(IC_RESULT(ic))),
1336 AopType(AOP_TYPE(IC_LEFT(ic))),
1337 AopType(AOP_TYPE(IC_RIGHT(ic))));
1339 /* special cases :- */
1340 /* if both left & right are in bit space */
1341 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1342 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1347 /* if I can do an decrement instead
1348 of subtract then GOOD for ME */
1349 // if (genMinusDec (ic) == TRUE)
1352 size = pic14_getDataSize(IC_RESULT(ic));
1353 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1355 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1356 /* Add a literal to something else */
1358 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1361 genAddLit ( ic, lit);
1364 /* add the first byte: */
1365 pic14_emitcode("movlw","0x%x", lit & 0xff);
1366 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1367 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1368 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1380 if((lit & 0xff) == 0xff) {
1381 emitpcode(POC_MOVLW, popGetLit(0xff));
1383 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1385 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1387 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1388 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1392 /* do the rlf known zero trick here */
1393 emitpcode(POC_MOVLW, popGetLit(1));
1395 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1400 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1403 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1404 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1405 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1407 /* here we are subtracting a bit from a char or int */
1409 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1411 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1412 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1414 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1415 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1416 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1417 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1420 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1421 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1422 emitpcode(POC_XORLW , popGetLit(1));
1423 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1424 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1426 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1428 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1429 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1431 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1432 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1435 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1437 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1439 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1440 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1444 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1445 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1446 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1447 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1452 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1453 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1454 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1457 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1459 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1462 emitpcode(POC_ANDLW , popGetLit(1));
1464 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1466 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1473 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1474 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1475 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1477 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1478 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1479 AopType(AOP_TYPE(IC_RESULT(ic))),
1480 AopType(AOP_TYPE(IC_LEFT(ic))),
1481 AopType(AOP_TYPE(IC_RIGHT(ic))));
1484 if( (size == 1) && ((lit & 0xff) == 0) ) {
1485 /* res = 0 - right */
1486 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1487 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1488 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1490 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1491 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1492 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1497 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1498 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1499 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1507 /* This is the last byte in a multibyte subtraction
1508 * There are a couple of tricks we can do by not worrying about
1509 * propogating the carry */
1511 /* 0xff - x == ~x */
1513 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1515 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1517 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1518 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1520 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1523 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1525 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1526 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1527 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1536 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1538 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1539 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1542 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1548 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1549 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1551 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1553 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1555 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1556 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1563 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1564 AopType(AOP_TYPE(IC_RESULT(ic))),
1565 AopType(AOP_TYPE(IC_LEFT(ic))),
1566 AopType(AOP_TYPE(IC_RIGHT(ic))));
1568 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1569 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1570 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1571 emitpcode(POC_SUBLW, popGetLit(0));
1572 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1575 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1576 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1577 emitpcode(POC_SUBLW, popGetLit(0));
1578 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1579 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1582 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1583 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1584 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1586 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1587 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1589 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1590 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1591 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1593 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1595 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1596 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1597 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1599 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1601 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1607 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1611 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1613 if (op_isLitLike (IC_LEFT(ic)))
1616 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1618 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1619 emitpcode(lit?POC_SUBLW:POC_SUBFW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1620 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1624 PIC_OPCODE poc = POC_MOVFW;
1625 if (op_isLitLike (IC_LEFT(ic)))
1628 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1629 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1630 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1632 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1634 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1635 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1642 // adjustArithmeticResult(ic);
1645 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1646 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1647 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1649 /*-----------------------------------------------------------------*
1650 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1653 *-----------------------------------------------------------------*/
1654 void genUMult8XLit_16 (operand *left,
1657 pCodeOpReg *result_hi)
1662 unsigned int i,have_first_bit;
1667 if (AOP_TYPE(right) != AOP_LIT){
1668 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1674 result_hi = PCOR(popGet(AOP(result),1));
1677 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1679 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1681 same = pic14_sameRegs(AOP(left), AOP(result));
1686 emitpcode(POC_CLRF, popGet(AOP(left),0));
1689 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1690 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1693 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1694 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1695 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1698 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1699 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1700 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1701 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1704 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1705 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1706 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1707 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1710 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1711 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1712 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1713 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1714 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1717 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1718 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1719 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1720 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1721 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F
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_ADDFW, popGet(AOP(left),0)); // W = 5*F
1728 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1731 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1732 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1733 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1734 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1735 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1736 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1739 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1740 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1741 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1742 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1743 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1744 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1747 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1748 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1749 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1750 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1751 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1752 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F
1755 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1756 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1757 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1758 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1759 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1760 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1761 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1764 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1765 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1766 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1767 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1768 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1769 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*F
1772 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1773 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1774 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1775 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1776 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1777 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F
1778 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F
1781 temp = popGetTempReg();
1783 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1786 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1787 emitpcode(POC_MOVWF, temp);
1788 emitpcode(POC_ANDLW, popGetLit(0xf0));
1789 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1790 emitpcode(POC_SWAPFW, temp);
1791 emitpcode(POC_SUBWF, popGet(AOP(left),0));
1792 popReleaseTempReg(temp);
1795 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1796 emitpcode(POC_ANDLW, popGetLit(0xf0));
1797 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1800 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1801 emitpcode(POC_ANDLW, popGetLit(0xf0));
1802 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1805 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1806 emitpcode(POC_RLFW, popGet(AOP(left),0));
1807 emitpcode(POC_ANDLW, popGetLit(0xe0));
1808 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1811 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1812 emitpcode(POC_RLF, popGet(AOP(left),0));
1813 emitpcode(POC_RLFW, popGet(AOP(left),0));
1814 emitpcode(POC_ANDLW, popGetLit(0xc0));
1815 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1818 emitpcode(POC_RRFW, popGet(AOP(left),0));
1819 emitpcode(POC_CLRF, popGet(AOP(left),0));
1820 emitpcode(POC_RRF, popGet(AOP(left),0));
1828 emitpcode(POC_CLRF, popGet(AOP(result),0));
1829 emitpcode(POC_CLRF, popCopyReg(result_hi));
1832 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1833 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1834 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1835 emitpcode(POC_ADDWF, popGet(AOP(result),0));
1836 emitpcode(POC_CLRF, popCopyReg(result_hi));
1837 emitpcode(POC_RLF, popCopyReg(result_hi));
1841 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1842 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1843 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1844 emitpcode(POC_CLRF, popCopyReg(result_hi));
1845 emitpcode(POC_BCF, popCopyReg(&pc_status));
1846 emitpcode(POC_RLF, popGet(AOP(result),0));
1847 emitpcode(POC_RLF, popCopyReg(result_hi));
1848 emitpcode(POC_RLF, popGet(AOP(result),0));
1849 emitpcode(POC_RLF, popCopyReg(result_hi));
1851 emitpcode(POC_RLF, popGet(AOP(result),0));
1852 emitpcode(POC_RLF, popCopyReg(result_hi));
1859 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1860 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1861 emitpcode(POC_CLRF, popGet(AOP(result),0));
1862 emitpcode(POC_CLRF, popCopyReg(result_hi));
1865 for(i=0; i<8; i++) {
1868 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1872 if(have_first_bit) {
1873 emitpcode(POC_RRF, popCopyReg(result_hi));
1874 emitpcode(POC_RRF, popGet(AOP(result),0));
1881 /*-----------------------------------------------------------------*
1882 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1885 *-----------------------------------------------------------------*/
1886 void genUMult8X8_16 (operand *left,
1889 pCodeOpReg *result_hi)
1898 result_hi = PCOR(popGet(AOP(result),1));
1901 if (AOP_TYPE(right) == AOP_LIT) {
1902 genUMult8XLit_16(left,right,result,result_hi);
1907 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1909 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1910 emitpcode(POC_CLRF, popGet(AOP(result),0));
1911 emitpcode(POC_CLRF, popCopyReg(result_hi));
1914 for(i=0; i<8; i++) {
1915 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1916 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1917 emitpcode(POC_RRF, popCopyReg(result_hi));
1918 emitpcode(POC_RRF, popGet(AOP(result),0));
1923 Here's another version that does the same thing and takes the
1924 same number of instructions. The one above is slightly better
1925 because the entry instructions have a higher probability of
1926 being optimized out.
1929 emitpcode(POC_CLRF, popCopyReg(result_hi));
1930 emitpcode(POC_RRFW, popGet(AOP(left),0));
1931 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1932 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1934 for(i=0; i<8; i++) {
1936 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1937 emitpcode(POC_RRF, popCopyReg(result_hi));
1938 emitpcode(POC_RRF, popGet(AOP(result),0));
1943 symbol *tlbl = newiTempLabel(NULL);
1947 pic14_emitcode(";","Looped 8 X 8 multiplication");
1949 emitpcode(POC_CLRF, popGet(AOP(result),0));
1950 emitpcode(POC_CLRF, popCopyReg(result_hi));
1952 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1954 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1956 temp = popGetTempReg();
1957 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1959 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1961 emitpLabel(tlbl->key);
1963 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1965 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1967 emitpcode(POC_RRF, popCopyReg(result_hi));
1968 emitpcode(POC_RRF, popGet(AOP(result),0));
1971 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1973 popReleaseTempReg(temp);
1978 /*-----------------------------------------------------------------*
1979 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1981 * this routine will call the unsigned multiply routine and then
1982 * post-fix the sign bit.
1983 *-----------------------------------------------------------------*/
1984 void genSMult8X8_16 (operand *left,
1987 pCodeOpReg *result_hi)
1992 result_hi = PCOR(popGet(AOP(result),1));
1995 genUMult8X8_16(left,right,result,result_hi);
1997 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1998 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1999 emitpcode(POC_MOVFW, popGet(AOP(left),0));
2000 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
2001 emitpcode(POC_SUBWF, popGet(AOP(result),1));
2005 /*-----------------------------------------------------------------*
2006 * genMult8X8_8 - multiplication of two 8-bit numbers
2008 * this routine will call the unsigned multiply 8X8=>16 routine and
2009 * then throw away the high byte of the result.
2011 *-----------------------------------------------------------------*/
2012 void genMult8X8_8 (operand *left,
2018 if (result && result->aop && result->aop->type==2 && result->aop->size>=1) {
2019 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. */
2021 result_hi = popGetTempReg();
2023 if (AOP_TYPE(right) == AOP_LIT)
2024 genUMult8XLit_16(left,right,result,PCOR(result_hi));
2026 genUMult8X8_16(left,right,result,PCOR(result_hi));
2028 popReleaseTempReg(result_hi);
2031 /*-----------------------------------------------------------------*/
2032 /* constMult - generates code for multiplication by a constant */
2033 /*-----------------------------------------------------------------*/
2034 void genMultConst(unsigned C)
2038 unsigned sr3; // Shift right 3
2044 Convert a string of 3 binary 1's in the lit into
2048 mask = 7 << ( (size*8) - 3);
2052 while(mask < (1<<size*8)) {
2054 if( (mask & lit) == lit) {
2057 /* We found 3 (or more) consecutive 1's */
2059 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2061 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2063 lit ^= consecutive_bits;
2067 sr3 |= (consecutive + lsb);