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));
737 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
741 if(AOP_TYPE(left) == AOP_ACC) {
742 /* left addend is already in accumulator */
745 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
749 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
750 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
754 /* left addend is in a register */
757 emitpcode(POC_MOVFW, popGet(AOP(left),0));
758 emitMOVWF(result, 0);
759 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
763 emitpcode(POC_INCFW, popGet(AOP(left),0));
764 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
768 emitpcode(POC_DECFW, popGet(AOP(left),0));
769 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
773 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
774 emitpcode(POC_ADDFW, popGet(AOP(left),0));
775 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
783 /* left is not the accumulator */
785 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
786 emitpcode(POC_ADDFW, popGet(AOP(left),0));
788 emitpcode(POC_MOVFW, popGet(AOP(left),0));
789 /* We don't know the state of the carry bit at this point */
792 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
799 /* The ls byte of the lit must've been zero - that
800 means we don't have to deal with carry */
802 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
803 emitpcode(POC_ADDFW, popGet(AOP(left),offset));
804 emitpcode(POC_MOVWF, popGet(AOP(left),offset));
809 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
810 //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
811 emitMOVWF(result,offset);
812 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
814 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
815 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
819 emitpcode(POC_CLRF, popGet(AOP(result),offset));
820 emitpcode(POC_RLF, popGet(AOP(result),offset));
821 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
822 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
830 /*-----------------------------------------------------------------*/
831 /* genPlus - generates code for addition */
832 /*-----------------------------------------------------------------*/
833 void genPlus (iCode *ic)
835 int size, offset = 0;
837 /* special cases :- */
838 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
840 aopOp (IC_LEFT(ic),ic,FALSE);
841 aopOp (IC_RIGHT(ic),ic,FALSE);
842 aopOp (IC_RESULT(ic),ic,TRUE);
844 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
846 /* if literal, literal on the right or
847 if left requires ACC or right is already
850 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
851 operand *t = IC_RIGHT(ic);
852 IC_RIGHT(ic) = IC_LEFT(ic);
856 /* if both left & right are in bit space */
857 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
858 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
863 /* if left in bit space & right literal */
864 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
865 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
866 /* if result in bit space */
867 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
868 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
869 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
870 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
871 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
872 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
875 size = pic14_getDataSize(IC_RESULT(ic));
877 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
878 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
879 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
885 /* if I can do an increment instead
886 of add then GOOD for ME */
887 if (genPlusIncr (ic) == TRUE)
890 size = pic14_getDataSize(IC_RESULT(ic));
892 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
893 /* Add a literal to something else */
895 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
899 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
904 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
906 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
907 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
908 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
910 /* here we are adding a bit to a char or int */
912 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
914 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
915 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
917 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
918 AOP(IC_RIGHT(ic))->aopu.aop_dir,
919 AOP(IC_RIGHT(ic))->aopu.aop_dir);
920 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
923 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
924 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
925 emitpcode(POC_XORLW , popGetLit(1));
927 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
928 AOP(IC_RIGHT(ic))->aopu.aop_dir,
929 AOP(IC_RIGHT(ic))->aopu.aop_dir);
930 pic14_emitcode(" xorlw","1");
932 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
933 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
934 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
936 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
937 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
938 AOP(IC_RIGHT(ic))->aopu.aop_dir,
939 AOP(IC_RIGHT(ic))->aopu.aop_dir);
940 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
943 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
945 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
946 emitpcode(POC_ANDLW , popGetLit(1));
947 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
949 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
951 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
952 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
959 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
960 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
962 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
963 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
965 pic14_emitcode("clrz","");
967 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
968 AOP(IC_RIGHT(ic))->aopu.aop_dir,
969 AOP(IC_RIGHT(ic))->aopu.aop_dir);
970 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
974 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
975 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
976 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
977 //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
978 emitMOVWF(IC_RIGHT(ic),0);
980 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
981 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
982 AOP(IC_RIGHT(ic))->aopu.aop_dir,
983 AOP(IC_RIGHT(ic))->aopu.aop_dir);
984 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
985 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
991 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
992 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
998 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1000 /* Add the first bytes */
1002 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1003 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
1004 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1007 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1008 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
1009 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1010 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1013 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1015 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1016 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1018 PIC_OPCODE poc = POC_ADDFW;
1020 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1021 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1022 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1024 emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0));
1025 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1026 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1031 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1036 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1037 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1038 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1039 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) {
1041 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1043 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1044 emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),offset));
1045 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1050 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1052 emitpcode(POC_INCFSZW, popGet(AOP(IC_LEFT(ic)),offset));
1053 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
1058 PIC_OPCODE poc = POC_MOVFW;
1059 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1060 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1061 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1064 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1065 emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset));
1066 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1068 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1070 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1071 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
1078 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1079 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1080 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1083 /* Need to extend result to higher bytes */
1084 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1086 /* First grab the carry from the lower bytes */
1087 if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1088 int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
1089 PIC_OPCODE poc = POC_MOVFW;
1090 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1091 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1092 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1094 while(leftsize-- > 0) {
1095 emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset));
1096 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1098 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset));
1106 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1107 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
1112 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1115 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1116 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1117 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1118 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1120 /* if chars or ints or being signed extended to longs: */
1122 emitpcode(POC_MOVLW, popGetLit(0));
1123 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1124 emitpcode(POC_MOVLW, popGetLit(0xff));
1132 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1134 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1141 //adjustArithmeticResult(ic);
1144 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1145 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1146 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1149 /*-----------------------------------------------------------------*/
1150 /* genMinusDec :- does subtraction with decrement if possible */
1151 /*-----------------------------------------------------------------*/
1152 bool genMinusDec (iCode *ic)
1154 unsigned int icount ;
1155 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1157 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1158 /* will try to generate an increment */
1159 /* if the right side is not a literal
1161 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1162 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1163 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1166 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1168 /* if the literal value of the right hand side
1169 is greater than 4 then it is not worth it */
1170 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1173 /* if decrement 16 bits in register */
1174 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1179 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1180 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1181 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1182 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1184 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1185 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1186 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1188 /* size is 3 or 4 */
1189 emitpcode(POC_MOVLW, popGetLit(0xff));
1190 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1192 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1194 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1196 pic14_emitcode("movlw","0xff");
1197 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1200 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1202 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1206 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1208 pic14_emitcode("skpnc","");
1210 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1219 /* if the sizes are greater than 1 then we cannot */
1220 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1221 AOP_SIZE(IC_LEFT(ic)) > 1 )
1224 /* we can if the aops of the left & result match or
1225 if they are in registers and the registers are the
1227 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1230 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1232 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1237 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1238 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1239 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1242 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1243 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1245 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1246 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1254 /*-----------------------------------------------------------------*/
1255 /* addSign - propogate sign bit to higher bytes */
1256 /*-----------------------------------------------------------------*/
1257 void addSign(operand *result, int offset, int sign)
1259 int size = (pic14_getDataSize(result) - offset);
1260 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1263 if(sign && offset) {
1266 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1267 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1268 emitpcode(POC_DECF, popGet(AOP(result),offset));
1271 emitpcode(POC_MOVLW, popGetLit(0));
1272 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1273 emitpcode(POC_MOVLW, popGetLit(0xff));
1275 emitpcode(POC_MOVWF, popGet(AOP(result),size));
1280 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1284 /*-----------------------------------------------------------------*/
1285 /* genMinusBits - generates code for subtraction of two bits */
1286 /*-----------------------------------------------------------------*/
1287 void genMinusBits (iCode *ic)
1289 symbol *lbl = newiTempLabel(NULL);
1290 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1291 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1292 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1293 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1294 pic14_emitcode("cpl","c");
1295 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1296 pic14_outBitC(IC_RESULT(ic));
1299 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1300 pic14_emitcode("subb","a,acc");
1301 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1302 pic14_emitcode("inc","a");
1303 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1304 aopPut(AOP(IC_RESULT(ic)),"a",0);
1305 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1309 /*-----------------------------------------------------------------*/
1310 /* genMinus - generates code for subtraction */
1311 /*-----------------------------------------------------------------*/
1312 void genMinus (iCode *ic)
1314 int size, offset = 0, same=0;
1315 unsigned long lit = 0L;
1317 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1318 aopOp (IC_LEFT(ic),ic,FALSE);
1319 aopOp (IC_RIGHT(ic),ic,FALSE);
1320 aopOp (IC_RESULT(ic),ic,TRUE);
1322 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1323 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1324 operand *t = IC_RIGHT(ic);
1325 IC_RIGHT(ic) = IC_LEFT(ic);
1329 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1330 AopType(AOP_TYPE(IC_RESULT(ic))),
1331 AopType(AOP_TYPE(IC_LEFT(ic))),
1332 AopType(AOP_TYPE(IC_RIGHT(ic))));
1334 /* special cases :- */
1335 /* if both left & right are in bit space */
1336 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1337 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1342 /* if I can do an decrement instead
1343 of subtract then GOOD for ME */
1344 // if (genMinusDec (ic) == TRUE)
1347 size = pic14_getDataSize(IC_RESULT(ic));
1348 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1350 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1351 /* Add a literal to something else */
1353 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1356 genAddLit ( ic, lit);
1359 /* add the first byte: */
1360 pic14_emitcode("movlw","0x%x", lit & 0xff);
1361 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1362 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1363 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1375 if((lit & 0xff) == 0xff) {
1376 emitpcode(POC_MOVLW, popGetLit(0xff));
1378 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1380 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1382 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1383 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1387 /* do the rlf known zero trick here */
1388 emitpcode(POC_MOVLW, popGetLit(1));
1390 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1395 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1398 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1399 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1400 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1402 /* here we are subtracting a bit from a char or int */
1404 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1406 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1407 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1409 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1410 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1411 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1412 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1415 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1416 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1417 emitpcode(POC_XORLW , popGetLit(1));
1418 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1419 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1421 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1423 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1424 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1426 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1427 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1430 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1432 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1434 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1435 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1439 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1440 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1441 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1442 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1447 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1448 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1449 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1452 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1454 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1457 emitpcode(POC_ANDLW , popGetLit(1));
1459 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1461 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1468 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1469 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1470 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1472 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1473 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1474 AopType(AOP_TYPE(IC_RESULT(ic))),
1475 AopType(AOP_TYPE(IC_LEFT(ic))),
1476 AopType(AOP_TYPE(IC_RIGHT(ic))));
1479 if( (size == 1) && ((lit & 0xff) == 0) ) {
1480 /* res = 0 - right */
1481 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1482 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1483 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1485 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1486 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1487 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1492 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1493 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1494 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1502 /* This is the last byte in a multibyte subtraction
1503 * There are a couple of tricks we can do by not worrying about
1504 * propogating the carry */
1506 /* 0xff - x == ~x */
1508 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1510 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1512 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1513 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1515 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1518 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1520 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1521 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1522 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1531 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1533 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1534 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1537 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1543 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1544 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1546 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1548 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1550 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1551 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1558 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1559 AopType(AOP_TYPE(IC_RESULT(ic))),
1560 AopType(AOP_TYPE(IC_LEFT(ic))),
1561 AopType(AOP_TYPE(IC_RIGHT(ic))));
1563 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1564 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1565 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1566 emitpcode(POC_SUBLW, popGetLit(0));
1567 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1570 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1571 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1572 emitpcode(POC_SUBLW, popGetLit(0));
1573 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1574 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1577 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1578 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1579 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1581 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1582 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1584 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1585 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1586 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1588 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1590 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1591 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1592 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1594 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1596 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1602 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1606 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))) {
1614 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1616 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1617 emitpcode(lit?POC_SUBLW:POC_SUBFW, popGet(AOP(IC_LEFT(ic)),offset));
1618 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1622 PIC_OPCODE poc = POC_MOVFW;
1623 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1624 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1625 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1628 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1629 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
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;
1666 if (AOP_TYPE(right) != AOP_LIT){
1667 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1673 result_hi = PCOR(popGet(AOP(result),1));
1676 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1678 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1680 same = pic14_sameRegs(AOP(left), AOP(result));
1685 emitpcode(POC_CLRF, popGet(AOP(left),0));
1688 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1689 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1692 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1693 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1694 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1697 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1698 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1699 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1700 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1703 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1704 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1705 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1706 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1709 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1710 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1711 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1712 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1713 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1716 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1717 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1718 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1719 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1720 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F
1723 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1724 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1725 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1726 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1727 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1730 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1731 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1732 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1733 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1734 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1735 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1738 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1739 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1740 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1741 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1742 emitpcode(POC_MOVFW, 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_ADDFW, popGet(AOP(left),0)); // W = 5*F
1750 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1751 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F
1754 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1755 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1756 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1757 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1758 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1759 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1760 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1763 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1764 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1765 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1766 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1767 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1768 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*F
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_ADDFW, popGet(AOP(left),0)); // W = 8*F
1776 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F
1777 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F
1780 temp = popGetTempReg();
1782 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1785 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1786 emitpcode(POC_MOVWF, temp);
1787 emitpcode(POC_ANDLW, popGetLit(0xf0));
1788 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1789 emitpcode(POC_SWAPFW, temp);
1790 emitpcode(POC_SUBWF, popGet(AOP(left),0));
1791 popReleaseTempReg(temp);
1794 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1795 emitpcode(POC_ANDLW, popGetLit(0xf0));
1796 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1799 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1800 emitpcode(POC_ANDLW, popGetLit(0xf0));
1801 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1804 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1805 emitpcode(POC_RLFW, popGet(AOP(left),0));
1806 emitpcode(POC_ANDLW, popGetLit(0xe0));
1807 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1810 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1811 emitpcode(POC_RLF, popGet(AOP(left),0));
1812 emitpcode(POC_RLFW, popGet(AOP(left),0));
1813 emitpcode(POC_ANDLW, popGetLit(0xc0));
1814 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1817 emitpcode(POC_RRFW, popGet(AOP(left),0));
1818 emitpcode(POC_CLRF, popGet(AOP(left),0));
1819 emitpcode(POC_RRF, popGet(AOP(left),0));
1827 emitpcode(POC_CLRF, popGet(AOP(result),0));
1828 emitpcode(POC_CLRF, popCopyReg(result_hi));
1831 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1832 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1833 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1834 emitpcode(POC_ADDWF, popGet(AOP(result),0));
1835 emitpcode(POC_CLRF, popCopyReg(result_hi));
1836 emitpcode(POC_RLF, popCopyReg(result_hi));
1840 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1841 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1842 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1843 emitpcode(POC_CLRF, popCopyReg(result_hi));
1844 emitpcode(POC_BCF, popCopyReg(&pc_status));
1845 emitpcode(POC_RLF, popGet(AOP(result),0));
1846 emitpcode(POC_RLF, popCopyReg(result_hi));
1847 emitpcode(POC_RLF, popGet(AOP(result),0));
1848 emitpcode(POC_RLF, popCopyReg(result_hi));
1850 emitpcode(POC_RLF, popGet(AOP(result),0));
1851 emitpcode(POC_RLF, popCopyReg(result_hi));
1858 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1859 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1860 emitpcode(POC_CLRF, popGet(AOP(result),0));
1861 emitpcode(POC_CLRF, popCopyReg(result_hi));
1864 for(i=0; i<8; i++) {
1867 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1871 if(have_first_bit) {
1872 emitpcode(POC_RRF, popCopyReg(result_hi));
1873 emitpcode(POC_RRF, popGet(AOP(result),0));
1880 /*-----------------------------------------------------------------*
1881 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1884 *-----------------------------------------------------------------*/
1885 void genUMult8X8_16 (operand *left,
1888 pCodeOpReg *result_hi)
1896 result_hi = PCOR(popGet(AOP(result),1));
1899 if (AOP_TYPE(right) == AOP_LIT) {
1900 genUMult8XLit_16(left,right,result,result_hi);
1905 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1907 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1908 emitpcode(POC_CLRF, popGet(AOP(result),0));
1909 emitpcode(POC_CLRF, popCopyReg(result_hi));
1912 for(i=0; i<8; i++) {
1913 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1914 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1915 emitpcode(POC_RRF, popCopyReg(result_hi));
1916 emitpcode(POC_RRF, popGet(AOP(result),0));
1921 Here's another version that does the same thing and takes the
1922 same number of instructions. The one above is slightly better
1923 because the entry instructions have a higher probability of
1924 being optimized out.
1927 emitpcode(POC_CLRF, popCopyReg(result_hi));
1928 emitpcode(POC_RRFW, popGet(AOP(left),0));
1929 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1930 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1932 for(i=0; i<8; i++) {
1934 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1935 emitpcode(POC_RRF, popCopyReg(result_hi));
1936 emitpcode(POC_RRF, popGet(AOP(result),0));
1941 symbol *tlbl = newiTempLabel(NULL);
1945 pic14_emitcode(";","Looped 8 X 8 multiplication");
1947 emitpcode(POC_CLRF, popGet(AOP(result),0));
1948 emitpcode(POC_CLRF, popCopyReg(result_hi));
1950 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1952 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1954 temp = popGetTempReg();
1955 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1957 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1959 emitpLabel(tlbl->key);
1961 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1963 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1965 emitpcode(POC_RRF, popCopyReg(result_hi));
1966 emitpcode(POC_RRF, popGet(AOP(result),0));
1969 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1971 popReleaseTempReg(temp);
1976 /*-----------------------------------------------------------------*
1977 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1979 * this routine will call the unsigned multiply routine and then
1980 * post-fix the sign bit.
1981 *-----------------------------------------------------------------*/
1982 void genSMult8X8_16 (operand *left,
1985 pCodeOpReg *result_hi)
1989 result_hi = PCOR(popGet(AOP(result),1));
1992 genUMult8X8_16(left,right,result,result_hi);
1994 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1995 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1996 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1997 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1998 emitpcode(POC_SUBWF, popGet(AOP(result),1));
2002 /*-----------------------------------------------------------------*
2003 * genMult8X8_8 - multiplication of two 8-bit numbers
2005 * this routine will call the unsigned multiply 8X8=>16 routine and
2006 * then throw away the high byte of the result.
2008 *-----------------------------------------------------------------*/
2009 void genMult8X8_8 (operand *left,
2014 if (result && result->aop && result->aop->type==2 && result->aop->size>=1) {
2015 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. */
2017 result_hi = popGetTempReg();
2019 if (AOP_TYPE(right) == AOP_LIT)
2020 genUMult8XLit_16(left,right,result,PCOR(result_hi));
2022 genUMult8X8_16(left,right,result,PCOR(result_hi));
2024 popReleaseTempReg(result_hi);
2027 /*-----------------------------------------------------------------*/
2028 /* constMult - generates code for multiplication by a constant */
2029 /*-----------------------------------------------------------------*/
2030 void genMultConst(unsigned C)
2034 unsigned sr3; // Shift right 3
2040 Convert a string of 3 binary 1's in the lit into
2044 mask = 7 << ( (size*8) - 3);
2048 while(mask < (1<<size*8)) {
2050 if( (mask & lit) == lit) {
2053 /* We found 3 (or more) consecutive 1's */
2055 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2057 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2059 lit ^= consecutive_bits;
2063 sr3 |= (consecutive + lsb);