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);
526 if (size > pic14_getDataSize(left))
527 size = pic14_getDataSize(left);
531 /* Handle special cases first */
533 genAddLit2byte (result, 0, lit);
536 int hi = 0xff & (lit >> 8);
543 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
548 emitpcode(POC_INCF, popGet(AOP(result),0));
550 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
553 emitpcode(POC_DECF, popGet(AOP(result),0));
554 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
555 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
559 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
560 emitpcode(POC_ADDWF,popGet(AOP(result),0));
562 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
570 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
573 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
576 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
577 emitpcode(POC_INCF, popGet(AOP(result),0));
579 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
581 case 0xff: /* 0x01ff */
582 emitpcode(POC_DECF, popGet(AOP(result),0));
583 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
584 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
585 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
590 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
594 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
597 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
598 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
600 /* case 0xff: * 0xffff *
601 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
602 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
603 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
607 emitpcode(POC_MOVLW,popGetLit(lo));
608 emitpcode(POC_ADDWF,popGet(AOP(result),0));
610 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
617 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
622 genAddLit2byte (result, MSB16, hi);
625 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
626 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
627 emitpcode(POC_MOVLW,popGetLit(hi));
628 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
630 /* case 0xff: * 0xHHff *
631 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
632 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
633 emitpcode(POC_MOVLW,popGetLit(hi));
634 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
636 */ default: /* 0xHHLL */
637 emitpcode(POC_MOVLW,popGetLit(lo));
638 emitpcode(POC_ADDWF, popGet(AOP(result),0));
639 emitpcode(POC_MOVLW,popGetLit(hi));
641 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
642 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
651 DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
654 lo = BYTEofLONG(lit,0);
662 emitpcode(POC_INCF, popGet(AOP(result),offset));
665 emitpcode(POC_RLFW, popGet(AOP(result),offset));
666 emitpcode(POC_ANDLW,popGetLit(1));
667 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
669 default: /* carry_info = 3 */
671 emitpcode(POC_INCF, popGet(AOP(result),offset));
677 emitpcode(POC_MOVLW,popGetLit(lo));
682 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
685 emitpcode(POC_MOVLW,popGetLit(lo));
690 emitpcode(POC_MOVLW,popGetLit(lo+1));
691 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
696 /* no carry info from previous step */
697 /* this means this is the first time to add */
702 emitpcode(POC_INCF, popGet(AOP(result),offset));
706 emitpcode(POC_MOVLW,popGetLit(lo));
707 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
709 carry_info = 3; /* Were adding only one byte and propogating the carry */
720 lo = BYTEofLONG(lit,0);
725 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
728 emitpcode(POC_MOVLW,popGetLit(lo));
729 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
732 emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
734 emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
736 emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
745 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
749 if(AOP_TYPE(left) == AOP_ACC) {
750 /* left addend is already in accumulator */
753 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
757 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
758 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
762 /* left addend is in a register */
765 emitpcode(POC_MOVFW, popGet(AOP(left),0));
766 emitMOVWF(result, 0);
767 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
771 emitpcode(POC_INCFW, popGet(AOP(left),0));
772 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
776 emitpcode(POC_DECFW, popGet(AOP(left),0));
777 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
781 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
782 emitpcode(POC_ADDFW, popGet(AOP(left),0));
783 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
791 /* left is not the accumulator */
793 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
794 emitpcode(POC_ADDFW, popGet(AOP(left),0));
796 emitpcode(POC_MOVFW, popGet(AOP(left),0));
797 /* We don't know the state of the carry bit at this point */
800 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
807 /* The ls byte of the lit must've been zero - that
808 means we don't have to deal with carry */
810 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
811 emitpcode(POC_ADDFW, popGet(AOP(left),offset));
812 emitpcode(POC_MOVWF, popGet(AOP(left),offset));
817 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
818 //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
819 emitMOVWF(result,offset);
820 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
822 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
823 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
827 emitpcode(POC_CLRF, popGet(AOP(result),offset));
828 emitpcode(POC_RLF, popGet(AOP(result),offset));
829 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
830 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
837 size = pic14_getDataSize(result);
838 if (size > pic14_getDataSize(left))
839 size = pic14_getDataSize(left);
840 addSign(result, size, 0);
843 /*-----------------------------------------------------------------*/
844 /* genPlus - generates code for addition */
845 /*-----------------------------------------------------------------*/
846 void genPlus (iCode *ic)
848 int size, offset = 0;
850 /* special cases :- */
851 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
854 aopOp (IC_LEFT(ic),ic,FALSE);
855 aopOp (IC_RIGHT(ic),ic,FALSE);
856 aopOp (IC_RESULT(ic),ic,TRUE);
858 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
860 /* if literal, literal on the right or
861 if left requires ACC or right is already
864 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
865 operand *t = IC_RIGHT(ic);
866 IC_RIGHT(ic) = IC_LEFT(ic);
870 /* if both left & right are in bit space */
871 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
872 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
877 /* if left in bit space & right literal */
878 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
879 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
880 /* if result in bit space */
881 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
882 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
883 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
884 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
885 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
886 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
889 size = pic14_getDataSize(IC_RESULT(ic));
891 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
892 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
893 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
899 /* if I can do an increment instead
900 of add then GOOD for ME */
901 if (genPlusIncr (ic) == TRUE)
904 size = pic14_getDataSize(IC_RESULT(ic));
906 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
907 /* Add a literal to something else */
909 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
913 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
918 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
920 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
921 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
922 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
924 /* here we are adding a bit to a char or int */
926 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
928 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
929 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
931 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
932 AOP(IC_RIGHT(ic))->aopu.aop_dir,
933 AOP(IC_RIGHT(ic))->aopu.aop_dir);
934 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
937 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
938 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
939 emitpcode(POC_XORLW , popGetLit(1));
941 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
942 AOP(IC_RIGHT(ic))->aopu.aop_dir,
943 AOP(IC_RIGHT(ic))->aopu.aop_dir);
944 pic14_emitcode(" xorlw","1");
946 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
947 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
948 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
950 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
951 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
952 AOP(IC_RIGHT(ic))->aopu.aop_dir,
953 AOP(IC_RIGHT(ic))->aopu.aop_dir);
954 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
957 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
959 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
960 emitpcode(POC_ANDLW , popGetLit(1));
961 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
963 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
965 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
966 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
973 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
974 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
976 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
977 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
979 pic14_emitcode("clrz","");
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,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
988 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
989 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
990 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
991 //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
992 emitMOVWF(IC_RIGHT(ic),0);
994 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
995 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
996 AOP(IC_RIGHT(ic))->aopu.aop_dir,
997 AOP(IC_RIGHT(ic))->aopu.aop_dir);
998 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
999 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1005 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
1006 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
1012 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1014 /* Add the first bytes */
1016 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1017 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
1018 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1021 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1022 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
1023 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1024 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1027 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1029 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1030 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1032 PIC_OPCODE poc = POC_ADDFW;
1034 if (op_isLitLike (IC_LEFT (ic)))
1036 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),0,0));
1037 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1038 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1043 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1048 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1049 if (op_isLitLike (IC_LEFT(ic)))
1052 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1054 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1055 emitpcode(POC_ADDLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1056 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1061 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1063 emitpcode(POC_INCFSZW, popGet(AOP(IC_LEFT(ic)),offset));
1064 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
1069 PIC_OPCODE poc = POC_MOVFW;
1070 if (op_isLitLike (IC_LEFT(ic)))
1073 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1074 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1075 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1077 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1079 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1080 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
1087 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1088 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1089 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1092 /* Need to extend result to higher bytes */
1093 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1095 /* First grab the carry from the lower bytes */
1096 if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1097 int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
1098 PIC_OPCODE poc = POC_MOVFW;
1099 if (op_isLitLike (IC_LEFT(ic)))
1101 while(leftsize-- > 0) {
1102 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1104 emitpcode(POC_ADDLW, popGetLit(0x01));
1105 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1107 //emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset)); /* INCF does not update Carry! */
1115 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1116 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
1120 if(sign && offset > 0 && offset < AOP_SIZE(IC_RESULT(ic))) {
1121 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1124 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1125 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1126 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1127 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1129 /* if chars or ints or being signed extended to longs: */
1131 emitpcode(POC_MOVLW, popGetLit(0));
1132 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1133 emitpcode(POC_MOVLW, popGetLit(0xff));
1141 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1143 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1150 //adjustArithmeticResult(ic);
1153 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1154 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1155 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1158 /*-----------------------------------------------------------------*/
1159 /* genMinusDec :- does subtraction with decrement if possible */
1160 /*-----------------------------------------------------------------*/
1161 bool genMinusDec (iCode *ic)
1163 unsigned int icount ;
1164 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1167 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1168 /* will try to generate an increment */
1169 /* if the right side is not a literal
1171 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1172 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1173 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1176 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1178 /* if the literal value of the right hand side
1179 is greater than 4 then it is not worth it */
1180 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1183 /* if decrement 16 bits in register */
1184 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1189 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1190 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1191 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1192 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1194 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1195 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1196 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1198 /* size is 3 or 4 */
1199 emitpcode(POC_MOVLW, popGetLit(0xff));
1200 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1202 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1204 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1206 pic14_emitcode("movlw","0xff");
1207 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1210 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1212 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1216 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1218 pic14_emitcode("skpnc","");
1220 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1229 /* if the sizes are greater than 1 then we cannot */
1230 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1231 AOP_SIZE(IC_LEFT(ic)) > 1 )
1234 /* we can if the aops of the left & result match or
1235 if they are in registers and the registers are the
1237 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1240 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1242 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1247 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1248 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1249 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1252 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1253 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1255 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1256 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1264 /*-----------------------------------------------------------------*/
1265 /* addSign - propogate sign bit to higher bytes */
1266 /*-----------------------------------------------------------------*/
1267 void addSign(operand *result, int offset, int sign)
1269 int size = (pic14_getDataSize(result) - offset);
1270 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1274 if(sign && offset) {
1277 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1278 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1279 emitpcode(POC_DECF, popGet(AOP(result),offset));
1282 emitpcode(POC_MOVLW, popGetLit(0));
1283 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1284 emitpcode(POC_MOVLW, popGetLit(0xff));
1286 emitpcode(POC_MOVWF, popGet(AOP(result),offset+size));
1290 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1294 /*-----------------------------------------------------------------*/
1295 /* genMinusBits - generates code for subtraction of two bits */
1296 /*-----------------------------------------------------------------*/
1297 void genMinusBits (iCode *ic)
1299 symbol *lbl = newiTempLabel(NULL);
1301 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1302 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1303 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1304 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1305 pic14_emitcode("cpl","c");
1306 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1307 pic14_outBitC(IC_RESULT(ic));
1310 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1311 pic14_emitcode("subb","a,acc");
1312 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1313 pic14_emitcode("inc","a");
1314 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1315 aopPut(AOP(IC_RESULT(ic)),"a",0);
1316 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1320 /*-----------------------------------------------------------------*/
1321 /* genMinus - generates code for subtraction */
1322 /*-----------------------------------------------------------------*/
1323 void genMinus (iCode *ic)
1325 int size, offset = 0, same=0;
1326 unsigned long lit = 0L;
1329 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1330 aopOp (IC_LEFT(ic),ic,FALSE);
1331 aopOp (IC_RIGHT(ic),ic,FALSE);
1332 aopOp (IC_RESULT(ic),ic,TRUE);
1334 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1335 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1336 operand *t = IC_RIGHT(ic);
1337 IC_RIGHT(ic) = IC_LEFT(ic);
1341 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1342 AopType(AOP_TYPE(IC_RESULT(ic))),
1343 AopType(AOP_TYPE(IC_LEFT(ic))),
1344 AopType(AOP_TYPE(IC_RIGHT(ic))));
1346 /* special cases :- */
1347 /* if both left & right are in bit space */
1348 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1349 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1354 /* if I can do an decrement instead
1355 of subtract then GOOD for ME */
1356 // if (genMinusDec (ic) == TRUE)
1359 size = pic14_getDataSize(IC_RESULT(ic));
1360 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1362 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1363 /* Add a literal to something else */
1365 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1368 genAddLit ( ic, lit);
1371 /* add the first byte: */
1372 pic14_emitcode("movlw","0x%x", lit & 0xff);
1373 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1374 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1375 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1387 if((lit & 0xff) == 0xff) {
1388 emitpcode(POC_MOVLW, popGetLit(0xff));
1390 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1392 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1394 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1395 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1399 /* do the rlf known zero trick here */
1400 emitpcode(POC_MOVLW, popGetLit(1));
1402 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1407 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1410 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1411 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1412 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1414 /* here we are subtracting a bit from a char or int */
1416 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1418 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1419 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1421 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1422 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1423 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1424 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1427 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1428 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1429 emitpcode(POC_XORLW , popGetLit(1));
1430 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1431 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1433 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1435 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1436 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1438 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1439 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1442 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1444 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1446 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1447 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1451 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1452 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1453 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1454 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1459 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1460 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1461 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1464 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1466 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1469 emitpcode(POC_ANDLW , popGetLit(1));
1471 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1473 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1480 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1481 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1482 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1484 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1485 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1486 AopType(AOP_TYPE(IC_RESULT(ic))),
1487 AopType(AOP_TYPE(IC_LEFT(ic))),
1488 AopType(AOP_TYPE(IC_RIGHT(ic))));
1491 if( (size == 1) && ((lit & 0xff) == 0) ) {
1492 /* res = 0 - right */
1493 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1494 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1495 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1497 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1498 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1499 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1504 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1505 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1506 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1514 /* This is the last byte in a multibyte subtraction
1515 * There are a couple of tricks we can do by not worrying about
1516 * propogating the carry */
1518 /* 0xff - x == ~x */
1520 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1522 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1524 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1525 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1527 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1530 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1532 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1533 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1534 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1543 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1545 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1546 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1549 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1555 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1556 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1558 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1560 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1562 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1563 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1570 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1571 AopType(AOP_TYPE(IC_RESULT(ic))),
1572 AopType(AOP_TYPE(IC_LEFT(ic))),
1573 AopType(AOP_TYPE(IC_RIGHT(ic))));
1575 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1576 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1577 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1578 emitpcode(POC_SUBLW, popGetLit(0));
1579 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1582 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1583 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1584 emitpcode(POC_SUBLW, popGetLit(0));
1585 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1586 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1589 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1590 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1591 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1593 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1594 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1596 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1597 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1598 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1600 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1602 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1603 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1604 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1606 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1608 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1614 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1618 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1620 if (op_isLitLike (IC_LEFT(ic)))
1623 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1625 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1626 emitpcode(lit?POC_SUBLW:POC_SUBFW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1627 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1631 PIC_OPCODE poc = POC_MOVFW;
1632 if (op_isLitLike (IC_LEFT(ic)))
1635 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1636 emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
1637 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1639 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1641 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1642 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1649 // adjustArithmeticResult(ic);
1652 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1653 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1654 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1656 /*-----------------------------------------------------------------*
1657 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1660 *-----------------------------------------------------------------*/
1661 void genUMult8XLit_16 (operand *left,
1664 pCodeOpReg *result_hi)
1669 unsigned int i,have_first_bit;
1674 if (AOP_TYPE(right) != AOP_LIT){
1675 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1681 result_hi = PCOR(popGet(AOP(result),1));
1684 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1686 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1688 same = pic14_sameRegs(AOP(left), AOP(result));
1693 emitpcode(POC_CLRF, popGet(AOP(left),0));
1696 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1697 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1700 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1701 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1702 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1705 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1706 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1707 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1708 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1711 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1712 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1713 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1714 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1717 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1718 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1719 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1720 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1721 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1724 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1725 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1726 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1727 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1728 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F
1731 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1732 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1733 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1734 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1735 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1738 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1739 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1740 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1741 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1742 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1743 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1746 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1747 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1748 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1749 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1750 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1751 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1754 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1755 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1756 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1757 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1758 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1759 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F
1762 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1763 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1764 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1765 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1766 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1767 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1768 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1771 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1772 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1773 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1774 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1775 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1776 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*F
1779 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1780 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1781 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1782 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1783 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1784 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F
1785 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F
1788 temp = popGetTempReg();
1790 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1793 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1794 emitpcode(POC_MOVWF, temp);
1795 emitpcode(POC_ANDLW, popGetLit(0xf0));
1796 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1797 emitpcode(POC_SWAPFW, temp);
1798 emitpcode(POC_SUBWF, popGet(AOP(left),0));
1799 popReleaseTempReg(temp);
1802 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1803 emitpcode(POC_ANDLW, popGetLit(0xf0));
1804 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1807 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1808 emitpcode(POC_ANDLW, popGetLit(0xf0));
1809 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1812 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1813 emitpcode(POC_RLFW, popGet(AOP(left),0));
1814 emitpcode(POC_ANDLW, popGetLit(0xe0));
1815 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1818 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1819 emitpcode(POC_RLF, popGet(AOP(left),0));
1820 emitpcode(POC_RLFW, popGet(AOP(left),0));
1821 emitpcode(POC_ANDLW, popGetLit(0xc0));
1822 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1825 emitpcode(POC_RRFW, popGet(AOP(left),0));
1826 emitpcode(POC_CLRF, popGet(AOP(left),0));
1827 emitpcode(POC_RRF, popGet(AOP(left),0));
1835 emitpcode(POC_CLRF, popGet(AOP(result),0));
1836 emitpcode(POC_CLRF, popCopyReg(result_hi));
1839 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1840 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1841 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1842 emitpcode(POC_ADDWF, popGet(AOP(result),0));
1843 emitpcode(POC_CLRF, popCopyReg(result_hi));
1844 emitpcode(POC_RLF, popCopyReg(result_hi));
1848 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1849 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1850 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1851 emitpcode(POC_CLRF, popCopyReg(result_hi));
1852 emitpcode(POC_BCF, popCopyReg(&pc_status));
1853 emitpcode(POC_RLF, popGet(AOP(result),0));
1854 emitpcode(POC_RLF, popCopyReg(result_hi));
1855 emitpcode(POC_RLF, popGet(AOP(result),0));
1856 emitpcode(POC_RLF, popCopyReg(result_hi));
1858 emitpcode(POC_RLF, popGet(AOP(result),0));
1859 emitpcode(POC_RLF, popCopyReg(result_hi));
1866 if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
1867 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1868 emitpcode(POC_CLRF, popGet(AOP(result),0));
1869 emitpcode(POC_CLRF, popCopyReg(result_hi));
1872 for(i=0; i<8; i++) {
1875 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1879 if(have_first_bit) {
1880 emitpcode(POC_RRF, popCopyReg(result_hi));
1881 emitpcode(POC_RRF, popGet(AOP(result),0));
1888 /*-----------------------------------------------------------------*
1889 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1892 *-----------------------------------------------------------------*/
1893 void genUMult8X8_16 (operand *left,
1896 pCodeOpReg *result_hi)
1905 result_hi = PCOR(popGet(AOP(result),1));
1908 if (AOP_TYPE(right) == AOP_LIT) {
1909 genUMult8XLit_16(left,right,result,result_hi);
1914 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1916 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1917 emitpcode(POC_CLRF, popGet(AOP(result),0));
1918 emitpcode(POC_CLRF, popCopyReg(result_hi));
1921 for(i=0; i<8; i++) {
1922 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1923 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1924 emitpcode(POC_RRF, popCopyReg(result_hi));
1925 emitpcode(POC_RRF, popGet(AOP(result),0));
1930 Here's another version that does the same thing and takes the
1931 same number of instructions. The one above is slightly better
1932 because the entry instructions have a higher probability of
1933 being optimized out.
1936 emitpcode(POC_CLRF, popCopyReg(result_hi));
1937 emitpcode(POC_RRFW, popGet(AOP(left),0));
1938 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1939 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1941 for(i=0; i<8; i++) {
1943 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1944 emitpcode(POC_RRF, popCopyReg(result_hi));
1945 emitpcode(POC_RRF, popGet(AOP(result),0));
1950 symbol *tlbl = newiTempLabel(NULL);
1954 pic14_emitcode(";","Looped 8 X 8 multiplication");
1956 emitpcode(POC_CLRF, popGet(AOP(result),0));
1957 emitpcode(POC_CLRF, popCopyReg(result_hi));
1959 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1961 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1963 temp = popGetTempReg();
1964 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1966 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1968 emitpLabel(tlbl->key);
1970 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1972 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1974 emitpcode(POC_RRF, popCopyReg(result_hi));
1975 emitpcode(POC_RRF, popGet(AOP(result),0));
1978 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1980 popReleaseTempReg(temp);
1985 /*-----------------------------------------------------------------*
1986 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1988 * this routine will call the unsigned multiply routine and then
1989 * post-fix the sign bit.
1990 *-----------------------------------------------------------------*/
1991 void genSMult8X8_16 (operand *left,
1994 pCodeOpReg *result_hi)
1999 result_hi = PCOR(popGet(AOP(result),1));
2002 genUMult8X8_16(left,right,result,result_hi);
2004 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
2005 emitpcode(POC_SUBWF, popCopyReg(result_hi));
2006 emitpcode(POC_MOVFW, popGet(AOP(left),0));
2007 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
2008 emitpcode(POC_SUBWF, popGet(AOP(result),1));
2012 /*-----------------------------------------------------------------*
2013 * genMult8X8_8 - multiplication of two 8-bit numbers
2015 * this routine will call the unsigned multiply 8X8=>16 routine and
2016 * then throw away the high byte of the result.
2018 *-----------------------------------------------------------------*/
2019 void genMult8X8_8 (operand *left,
2025 if (result && result->aop && result->aop->type==2 && result->aop->size>=1) {
2026 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. */
2028 result_hi = popGetTempReg();
2030 if (AOP_TYPE(right) == AOP_LIT)
2031 genUMult8XLit_16(left,right,result,PCOR(result_hi));
2033 genUMult8X8_16(left,right,result,PCOR(result_hi));
2035 popReleaseTempReg(result_hi);
2038 /*-----------------------------------------------------------------*/
2039 /* constMult - generates code for multiplication by a constant */
2040 /*-----------------------------------------------------------------*/
2041 void genMultConst(unsigned C)
2045 unsigned sr3; // Shift right 3
2051 Convert a string of 3 binary 1's in the lit into
2055 mask = 7 << ( (size*8) - 3);
2059 while(mask < (1<<size*8)) {
2061 if( (mask & lit) == lit) {
2064 /* We found 3 (or more) consecutive 1's */
2066 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2068 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2070 lit ^= consecutive_bits;
2074 sr3 |= (consecutive + lsb);