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 const char *pCodeOpType( pCodeOp *pcop)
119 case PO_GPR_REGISTER:
120 return "PO_GPR_REGISTER";
122 return "PO_GPR_POINTER";
126 return "PO_GPR_TEMP";
127 case PO_SFR_REGISTER:
128 return "PO_SFR_REGISTER";
136 return "PO_IMMEDIATE";
152 return "BAD PO_TYPE";
155 /*-----------------------------------------------------------------*/
156 /* genPlusIncr :- does addition with increment if possible */
157 /*-----------------------------------------------------------------*/
158 bool genPlusIncr (iCode *ic)
160 unsigned int icount ;
161 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
163 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
164 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
165 AopType(AOP_TYPE(IC_RESULT(ic))),
166 AopType(AOP_TYPE(IC_LEFT(ic))),
167 AopType(AOP_TYPE(IC_RIGHT(ic))));
169 /* will try to generate an increment */
170 /* if the right side is not a literal
172 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
175 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
176 /* if the literal value of the right hand side
177 is greater than 1 then it is faster to add */
178 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
181 /* if increment 16 bits in register */
182 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
187 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB));
188 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
192 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
193 //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
199 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
200 /* if left is in accumulator - probably a bit operation*/
201 if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
202 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
204 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
205 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
206 AOP(IC_RESULT(ic))->aopu.aop_dir,
207 AOP(IC_RESULT(ic))->aopu.aop_dir);
209 emitpcode(POC_XORLW,popGetLit(1));
210 //pic14_emitcode("xorlw","1");
212 emitpcode(POC_ANDLW,popGetLit(1));
213 //pic14_emitcode("andlw","1");
216 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
217 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
218 AOP(IC_RESULT(ic))->aopu.aop_dir,
219 AOP(IC_RESULT(ic))->aopu.aop_dir);
226 /* if the sizes are greater than 1 then we cannot */
227 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
228 AOP_SIZE(IC_LEFT(ic)) > 1 )
231 /* If we are incrementing the same register by two: */
233 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
236 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
237 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
242 DEBUGpic14_emitcode ("; ","couldn't increment ");
247 /*-----------------------------------------------------------------*/
248 /* pic14_outBitAcc - output a bit in acc */
249 /*-----------------------------------------------------------------*/
250 void pic14_outBitAcc(operand *result)
252 symbol *tlbl = newiTempLabel(NULL);
253 /* if the result is a bit */
254 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
256 if (AOP_TYPE(result) == AOP_CRY){
257 aopPut(AOP(result),"a",0);
260 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
261 pic14_emitcode("mov","a,#01");
262 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
263 pic14_outAcc(result);
267 /*-----------------------------------------------------------------*/
268 /* genPlusBits - generates code for addition of two bits */
269 /*-----------------------------------------------------------------*/
270 void genPlusBits (iCode *ic)
273 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
275 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
276 AopType(AOP_TYPE(IC_RESULT(ic))),
277 AopType(AOP_TYPE(IC_LEFT(ic))),
278 AopType(AOP_TYPE(IC_RIGHT(ic))));
280 The following block of code will add two bits.
281 Note that it'll even work if the destination is
282 the carry (C in the status register).
283 It won't work if the 'Z' bit is a source or destination.
286 /* If the result is stored in the accumulator (w) */
287 //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
288 switch(AOP_TYPE(IC_RESULT(ic))) {
290 emitpcode(POC_CLRW, NULL);
291 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
292 emitpcode(POC_XORLW, popGetLit(1));
293 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
294 emitpcode(POC_XORLW, popGetLit(1));
296 pic14_emitcode("clrw","");
297 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
298 AOP(IC_RIGHT(ic))->aopu.aop_dir,
299 AOP(IC_RIGHT(ic))->aopu.aop_dir);
300 pic14_emitcode("xorlw","1");
301 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
302 AOP(IC_LEFT(ic))->aopu.aop_dir,
303 AOP(IC_LEFT(ic))->aopu.aop_dir);
304 pic14_emitcode("xorlw","1");
307 emitpcode(POC_MOVLW, popGetLit(0));
308 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
309 emitpcode(POC_XORLW, popGetLit(1));
310 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
311 emitpcode(POC_XORLW, popGetLit(1));
312 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
315 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
316 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
317 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
318 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
319 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
320 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
322 pic14_emitcode("movlw","(1 << (%s & 7))",
323 AOP(IC_RESULT(ic))->aopu.aop_dir,
324 AOP(IC_RESULT(ic))->aopu.aop_dir);
325 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
326 AOP(IC_RESULT(ic))->aopu.aop_dir,
327 AOP(IC_RESULT(ic))->aopu.aop_dir);
328 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
329 AOP(IC_RIGHT(ic))->aopu.aop_dir,
330 AOP(IC_RIGHT(ic))->aopu.aop_dir);
331 pic14_emitcode("xorwf","(%s >>3),f",
332 AOP(IC_RESULT(ic))->aopu.aop_dir);
333 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
334 AOP(IC_LEFT(ic))->aopu.aop_dir,
335 AOP(IC_LEFT(ic))->aopu.aop_dir);
336 pic14_emitcode("xorwf","(%s>>3),f",
337 AOP(IC_RESULT(ic))->aopu.aop_dir);
344 /* This is the original version of this code.
346 * This is being kept around for reference,
347 * because I am not entirely sure I got it right...
349 static void adjustArithmeticResult(iCode *ic)
351 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
352 AOP_SIZE(IC_LEFT(ic)) == 3 &&
353 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
354 aopPut(AOP(IC_RESULT(ic)),
355 aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
358 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
359 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
360 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
361 aopPut(AOP(IC_RESULT(ic)),
362 aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
365 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
366 AOP_SIZE(IC_LEFT(ic)) < 3 &&
367 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
368 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
369 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
371 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
372 aopPut(AOP(IC_RESULT(ic)),buffer,2);
376 /* This is the pure and virtuous version of this code.
377 * I'm pretty certain it's right, but not enough to toss the old
380 static void adjustArithmeticResult(iCode *ic)
382 if (opIsGptr(IC_RESULT(ic)) &&
383 opIsGptr(IC_LEFT(ic)) &&
384 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
386 aopPut(AOP(IC_RESULT(ic)),
387 aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
391 if (opIsGptr(IC_RESULT(ic)) &&
392 opIsGptr(IC_RIGHT(ic)) &&
393 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
395 aopPut(AOP(IC_RESULT(ic)),
396 aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
400 if (opIsGptr(IC_RESULT(ic)) &&
401 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
402 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
403 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
404 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
406 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
407 aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
412 /*-----------------------------------------------------------------*/
413 /* genAddlit - generates code for addition */
414 /*-----------------------------------------------------------------*/
415 static void genAddLit2byte (operand *result, int offr, int lit)
422 emitpcode(POC_INCF, popGet(AOP(result),offr));
425 emitpcode(POC_DECF, popGet(AOP(result),offr));
428 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
429 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
434 static void emitMOVWF(operand *reg, int offset)
439 if (AOP_TYPE(reg) == AOP_ACC) {
440 DEBUGpic14_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
444 emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
448 static void genAddLit (iCode *ic, int lit)
457 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
461 result = IC_RESULT(ic);
462 same = pic14_sameRegs(AOP(left), AOP(result));
463 size = pic14_getDataSize(result);
467 /* Handle special cases first */
469 genAddLit2byte (result, 0, lit);
472 int hi = 0xff & (lit >> 8);
479 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
484 emitpcode(POC_INCF, popGet(AOP(result),0));
486 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
489 emitpcode(POC_DECF, popGet(AOP(result),0));
490 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
491 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
495 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
496 emitpcode(POC_ADDWF,popGet(AOP(result),0));
498 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
506 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
509 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
512 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
513 emitpcode(POC_INCF, popGet(AOP(result),0));
515 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
517 case 0xff: /* 0x01ff */
518 emitpcode(POC_DECF, popGet(AOP(result),0));
519 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
520 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
521 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
526 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
530 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
533 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
534 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
536 /* case 0xff: * 0xffff *
537 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
538 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
539 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
543 emitpcode(POC_MOVLW,popGetLit(lo));
544 emitpcode(POC_ADDWF,popGet(AOP(result),0));
546 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
553 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
558 genAddLit2byte (result, MSB16, hi);
561 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
562 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
563 emitpcode(POC_MOVLW,popGetLit(hi));
564 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
566 /* case 0xff: * 0xHHff *
567 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
568 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
569 emitpcode(POC_MOVLW,popGetLit(hi));
570 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
572 */ default: /* 0xHHLL */
573 emitpcode(POC_MOVLW,popGetLit(lo));
574 emitpcode(POC_ADDWF, popGet(AOP(result),0));
575 emitpcode(POC_MOVLW,popGetLit(hi));
577 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
578 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
587 DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
590 lo = BYTEofLONG(lit,0);
598 emitpcode(POC_INCF, popGet(AOP(result),offset));
601 emitpcode(POC_RLFW, popGet(AOP(result),offset));
602 emitpcode(POC_ANDLW,popGetLit(1));
603 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
605 default: /* carry_info = 3 */
607 emitpcode(POC_INCF, popGet(AOP(result),offset));
613 emitpcode(POC_MOVLW,popGetLit(lo));
618 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
621 emitpcode(POC_MOVLW,popGetLit(lo));
626 emitpcode(POC_MOVLW,popGetLit(lo+1));
627 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
632 /* no carry info from previous step */
633 /* this means this is the first time to add */
638 emitpcode(POC_INCF, popGet(AOP(result),offset));
642 emitpcode(POC_MOVLW,popGetLit(lo));
643 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
645 carry_info = 3; /* Were adding only one byte and propogating the carry */
656 lo = BYTEofLONG(lit,0);
661 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
664 emitpcode(POC_MOVLW,popGetLit(lo));
665 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
668 emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
670 emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
672 emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
682 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
686 if(AOP_TYPE(left) == AOP_ACC) {
687 /* left addend is already in accumulator */
690 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
694 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
695 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
699 /* left addend is in a register */
702 emitpcode(POC_MOVFW, popGet(AOP(left),0));
703 emitMOVWF(result, 0);
704 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
708 emitpcode(POC_INCFW, popGet(AOP(left),0));
709 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
713 emitpcode(POC_DECFW, popGet(AOP(left),0));
714 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
718 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
719 emitpcode(POC_ADDFW, popGet(AOP(left),0));
720 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
728 /* left is not the accumulator */
730 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
731 emitpcode(POC_ADDFW, popGet(AOP(left),0));
733 emitpcode(POC_MOVFW, popGet(AOP(left),0));
734 /* We don't know the state of the carry bit at this point */
737 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
744 /* The ls byte of the lit must've been zero - that
745 means we don't have to deal with carry */
747 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
748 emitpcode(POC_ADDFW, popGet(AOP(left),offset));
749 emitpcode(POC_MOVWF, popGet(AOP(left),offset));
754 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
755 //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
756 emitMOVWF(result,offset);
757 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
759 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
760 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
764 emitpcode(POC_CLRF, popGet(AOP(result),offset));
765 emitpcode(POC_RLF, popGet(AOP(result),offset));
766 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
767 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
775 /*-----------------------------------------------------------------*/
776 /* genPlus - generates code for addition */
777 /*-----------------------------------------------------------------*/
778 void genPlus (iCode *ic)
780 int size, offset = 0;
782 /* special cases :- */
783 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
785 aopOp (IC_LEFT(ic),ic,FALSE);
786 aopOp (IC_RIGHT(ic),ic,FALSE);
787 aopOp (IC_RESULT(ic),ic,TRUE);
789 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
791 /* if literal, literal on the right or
792 if left requires ACC or right is already
795 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
796 operand *t = IC_RIGHT(ic);
797 IC_RIGHT(ic) = IC_LEFT(ic);
801 /* if both left & right are in bit space */
802 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
803 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
808 /* if left in bit space & right literal */
809 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
810 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
811 /* if result in bit space */
812 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
813 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
814 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
815 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
816 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
817 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
820 size = pic14_getDataSize(IC_RESULT(ic));
822 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
823 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
824 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
830 /* if I can do an increment instead
831 of add then GOOD for ME */
832 if (genPlusIncr (ic) == TRUE)
835 size = pic14_getDataSize(IC_RESULT(ic));
837 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
838 /* Add a literal to something else */
840 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
844 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
849 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
851 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
852 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
853 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
855 /* here we are adding a bit to a char or int */
857 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
859 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
860 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
862 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
863 AOP(IC_RIGHT(ic))->aopu.aop_dir,
864 AOP(IC_RIGHT(ic))->aopu.aop_dir);
865 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
868 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
869 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
870 emitpcode(POC_XORLW , popGetLit(1));
872 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
873 AOP(IC_RIGHT(ic))->aopu.aop_dir,
874 AOP(IC_RIGHT(ic))->aopu.aop_dir);
875 pic14_emitcode(" xorlw","1");
877 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
878 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
879 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
881 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
882 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
883 AOP(IC_RIGHT(ic))->aopu.aop_dir,
884 AOP(IC_RIGHT(ic))->aopu.aop_dir);
885 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
888 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
890 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
891 emitpcode(POC_ANDLW , popGetLit(1));
892 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
894 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
896 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
897 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
904 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
905 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
907 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
908 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
910 pic14_emitcode("clrz","");
912 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
913 AOP(IC_RIGHT(ic))->aopu.aop_dir,
914 AOP(IC_RIGHT(ic))->aopu.aop_dir);
915 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
919 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
920 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
921 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
922 //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
923 emitMOVWF(IC_RIGHT(ic),0);
925 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
926 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
927 AOP(IC_RIGHT(ic))->aopu.aop_dir,
928 AOP(IC_RIGHT(ic))->aopu.aop_dir);
929 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
930 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
936 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
937 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
943 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
945 /* Add the first bytes */
947 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
948 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
949 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
952 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
953 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
954 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
955 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
958 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
960 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
961 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
963 PIC_OPCODE poc = POC_ADDFW;
965 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
966 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
967 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
969 emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0));
970 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
971 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
976 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
981 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
982 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
983 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
984 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) {
986 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
988 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
989 emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),offset));
990 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
995 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
997 emitpcode(POC_INCFSZW, popGet(AOP(IC_LEFT(ic)),offset));
998 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
1003 PIC_OPCODE poc = POC_MOVFW;
1004 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1005 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1006 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1009 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1010 emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset));
1011 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1013 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1015 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1016 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
1023 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1024 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1025 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1028 /* Need to extend result to higher bytes */
1029 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1031 /* First grab the carry from the lower bytes */
1032 if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1033 int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
1034 PIC_OPCODE poc = POC_MOVFW;
1035 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1036 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1037 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1039 while(leftsize-- > 0) {
1040 emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset));
1041 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1043 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset));
1051 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1052 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
1057 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1060 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1061 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1062 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1063 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1065 /* if chars or ints or being signed extended to longs: */
1067 emitpcode(POC_MOVLW, popGetLit(0));
1068 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1069 emitpcode(POC_MOVLW, popGetLit(0xff));
1077 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1079 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1086 //adjustArithmeticResult(ic);
1089 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1090 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1091 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1094 /*-----------------------------------------------------------------*/
1095 /* genMinusDec :- does subtraction with decrement if possible */
1096 /*-----------------------------------------------------------------*/
1097 bool genMinusDec (iCode *ic)
1099 unsigned int icount ;
1100 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1102 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1103 /* will try to generate an increment */
1104 /* if the right side is not a literal
1106 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1107 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1108 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1111 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1113 /* if the literal value of the right hand side
1114 is greater than 4 then it is not worth it */
1115 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1118 /* if decrement 16 bits in register */
1119 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1124 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1125 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1126 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1127 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1129 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1130 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1131 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1133 /* size is 3 or 4 */
1134 emitpcode(POC_MOVLW, popGetLit(0xff));
1135 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1137 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1139 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1141 pic14_emitcode("movlw","0xff");
1142 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1145 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1147 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1151 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1153 pic14_emitcode("skpnc","");
1155 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1164 /* if the sizes are greater than 1 then we cannot */
1165 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1166 AOP_SIZE(IC_LEFT(ic)) > 1 )
1169 /* we can if the aops of the left & result match or
1170 if they are in registers and the registers are the
1172 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1175 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1177 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1182 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1183 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1184 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1187 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1188 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1190 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1191 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1199 /*-----------------------------------------------------------------*/
1200 /* addSign - propogate sign bit to higher bytes */
1201 /*-----------------------------------------------------------------*/
1202 void addSign(operand *result, int offset, int sign)
1204 int size = (pic14_getDataSize(result) - offset);
1205 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1208 if(sign && offset) {
1211 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1212 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1213 emitpcode(POC_DECF, popGet(AOP(result),offset));
1216 emitpcode(POC_MOVLW, popGetLit(0));
1217 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1218 emitpcode(POC_MOVLW, popGetLit(0xff));
1220 emitpcode(POC_MOVWF, popGet(AOP(result),size));
1225 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1229 /*-----------------------------------------------------------------*/
1230 /* genMinusBits - generates code for subtraction of two bits */
1231 /*-----------------------------------------------------------------*/
1232 void genMinusBits (iCode *ic)
1234 symbol *lbl = newiTempLabel(NULL);
1235 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1236 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1237 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1238 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1239 pic14_emitcode("cpl","c");
1240 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1241 pic14_outBitC(IC_RESULT(ic));
1244 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1245 pic14_emitcode("subb","a,acc");
1246 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1247 pic14_emitcode("inc","a");
1248 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1249 aopPut(AOP(IC_RESULT(ic)),"a",0);
1250 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1254 /*-----------------------------------------------------------------*/
1255 /* genMinus - generates code for subtraction */
1256 /*-----------------------------------------------------------------*/
1257 void genMinus (iCode *ic)
1259 int size, offset = 0, same=0;
1260 unsigned long lit = 0L;
1262 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1263 aopOp (IC_LEFT(ic),ic,FALSE);
1264 aopOp (IC_RIGHT(ic),ic,FALSE);
1265 aopOp (IC_RESULT(ic),ic,TRUE);
1267 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1268 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1269 operand *t = IC_RIGHT(ic);
1270 IC_RIGHT(ic) = IC_LEFT(ic);
1274 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1275 AopType(AOP_TYPE(IC_RESULT(ic))),
1276 AopType(AOP_TYPE(IC_LEFT(ic))),
1277 AopType(AOP_TYPE(IC_RIGHT(ic))));
1279 /* special cases :- */
1280 /* if both left & right are in bit space */
1281 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1282 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1287 /* if I can do an decrement instead
1288 of subtract then GOOD for ME */
1289 // if (genMinusDec (ic) == TRUE)
1292 size = pic14_getDataSize(IC_RESULT(ic));
1293 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1295 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1296 /* Add a literal to something else */
1298 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1301 genAddLit ( ic, lit);
1304 /* add the first byte: */
1305 pic14_emitcode("movlw","0x%x", lit & 0xff);
1306 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1307 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1308 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1320 if((lit & 0xff) == 0xff) {
1321 emitpcode(POC_MOVLW, popGetLit(0xff));
1323 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1325 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1327 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1328 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1332 /* do the rlf known zero trick here */
1333 emitpcode(POC_MOVLW, popGetLit(1));
1335 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1340 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1343 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1344 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1345 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1347 /* here we are subtracting a bit from a char or int */
1349 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1351 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1352 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1354 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1355 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1356 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1357 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1360 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1361 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1362 emitpcode(POC_XORLW , popGetLit(1));
1363 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1364 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1366 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1368 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1369 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1371 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1372 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1375 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1377 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1379 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1380 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1384 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1385 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1386 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1387 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1392 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1393 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1394 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1397 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1399 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1402 emitpcode(POC_ANDLW , popGetLit(1));
1404 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1406 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1413 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1414 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1415 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1417 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1418 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1419 AopType(AOP_TYPE(IC_RESULT(ic))),
1420 AopType(AOP_TYPE(IC_LEFT(ic))),
1421 AopType(AOP_TYPE(IC_RIGHT(ic))));
1424 if( (size == 1) && ((lit & 0xff) == 0) ) {
1425 /* res = 0 - right */
1426 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1427 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1428 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1430 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1431 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1432 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1437 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1438 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1439 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1447 /* This is the last byte in a multibyte subtraction
1448 * There are a couple of tricks we can do by not worrying about
1449 * propogating the carry */
1451 /* 0xff - x == ~x */
1453 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1455 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1457 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1458 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1460 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1463 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1465 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1466 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1467 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1476 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1478 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1479 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1482 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1488 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1489 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1491 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1493 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1495 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1496 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1503 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1504 AopType(AOP_TYPE(IC_RESULT(ic))),
1505 AopType(AOP_TYPE(IC_LEFT(ic))),
1506 AopType(AOP_TYPE(IC_RIGHT(ic))));
1508 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1509 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1510 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1511 emitpcode(POC_SUBLW, popGetLit(0));
1512 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1515 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1516 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1517 emitpcode(POC_SUBLW, popGetLit(0));
1518 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1519 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1522 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1523 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1524 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1526 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1527 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1529 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1530 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1531 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1533 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1535 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1536 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1537 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1539 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1541 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1547 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1551 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1552 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1553 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1554 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) {
1556 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1558 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1559 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),offset));
1560 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1565 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1567 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1568 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),offset));
1569 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1574 PIC_OPCODE poc = POC_MOVFW;
1575 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
1576 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
1577 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
1580 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1581 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1582 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1584 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1586 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1587 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1594 // adjustArithmeticResult(ic);
1597 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1598 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1599 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1601 /*-----------------------------------------------------------------*
1602 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1605 *-----------------------------------------------------------------*/
1606 void genUMult8XLit_16 (operand *left,
1609 pCodeOpReg *result_hi)
1614 unsigned int i,have_first_bit;
1618 if (AOP_TYPE(right) != AOP_LIT){
1619 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1625 result_hi = PCOR(popGet(AOP(result),1));
1628 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1630 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1632 same = pic14_sameRegs(AOP(left), AOP(result));
1637 emitpcode(POC_CLRF, popGet(AOP(left),0));
1640 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1641 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1644 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1645 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1646 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1649 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1650 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1651 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1652 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1655 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1656 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1657 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1658 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1661 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1662 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1663 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1664 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1665 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1668 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1669 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1670 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1671 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1672 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F
1675 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1676 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1677 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1678 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1679 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1682 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1683 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1684 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1685 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1686 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1687 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1690 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1691 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1692 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1693 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1694 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1695 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1698 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1699 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1700 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1701 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1702 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1703 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F
1706 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1707 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1708 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1709 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1710 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1711 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1712 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1715 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1716 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1717 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1718 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1719 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1720 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*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_ADDFW, popGet(AOP(left),0)); // W = 8*F
1728 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F
1729 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F
1732 temp = popGetTempReg();
1734 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1737 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1738 emitpcode(POC_MOVWF, temp);
1739 emitpcode(POC_ANDLW, popGetLit(0xf0));
1740 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1741 emitpcode(POC_SWAPFW, temp);
1742 emitpcode(POC_SUBWF, popGet(AOP(left),0));
1743 popReleaseTempReg(temp);
1746 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1747 emitpcode(POC_ANDLW, popGetLit(0xf0));
1748 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1751 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1752 emitpcode(POC_ANDLW, popGetLit(0xf0));
1753 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1756 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1757 emitpcode(POC_RLFW, popGet(AOP(left),0));
1758 emitpcode(POC_ANDLW, popGetLit(0xe0));
1759 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1762 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1763 emitpcode(POC_RLF, popGet(AOP(left),0));
1764 emitpcode(POC_RLFW, popGet(AOP(left),0));
1765 emitpcode(POC_ANDLW, popGetLit(0xc0));
1766 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1769 emitpcode(POC_RRFW, popGet(AOP(left),0));
1770 emitpcode(POC_CLRF, popGet(AOP(left),0));
1771 emitpcode(POC_RRF, popGet(AOP(left),0));
1779 emitpcode(POC_CLRF, popGet(AOP(result),0));
1780 emitpcode(POC_CLRF, popCopyReg(result_hi));
1783 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1784 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1785 emitpcode(POC_ADDWF, popGet(AOP(result),0));
1786 emitpcode(POC_CLRF, popCopyReg(result_hi));
1787 emitpcode(POC_RLF, popCopyReg(result_hi));
1793 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1794 emitpcode(POC_CLRF, popGet(AOP(result),0));
1795 emitpcode(POC_CLRF, popCopyReg(result_hi));
1798 for(i=0; i<8; i++) {
1801 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1805 if(have_first_bit) {
1806 emitpcode(POC_RRF, popCopyReg(result_hi));
1807 emitpcode(POC_RRF, popGet(AOP(result),0));
1815 /*-----------------------------------------------------------------*
1816 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1819 *-----------------------------------------------------------------*/
1820 void genUMult8X8_16 (operand *left,
1823 pCodeOpReg *result_hi)
1831 result_hi = PCOR(popGet(AOP(result),1));
1834 if (AOP_TYPE(right) == AOP_LIT) {
1835 genUMult8XLit_16(left,right,result,result_hi);
1840 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1842 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1843 emitpcode(POC_CLRF, popGet(AOP(result),0));
1844 emitpcode(POC_CLRF, popCopyReg(result_hi));
1847 for(i=0; i<8; i++) {
1848 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1849 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1850 emitpcode(POC_RRF, popCopyReg(result_hi));
1851 emitpcode(POC_RRF, popGet(AOP(result),0));
1856 Here's another version that does the same thing and takes the
1857 same number of instructions. The one above is slightly better
1858 because the entry instructions have a higher probability of
1859 being optimized out.
1862 emitpcode(POC_CLRF, popCopyReg(result_hi));
1863 emitpcode(POC_RRFW, popGet(AOP(left),0));
1864 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1865 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1867 for(i=0; i<8; i++) {
1869 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1870 emitpcode(POC_RRF, popCopyReg(result_hi));
1871 emitpcode(POC_RRF, popGet(AOP(result),0));
1876 symbol *tlbl = newiTempLabel(NULL);
1880 pic14_emitcode(";","Looped 8 X 8 multiplication");
1882 emitpcode(POC_CLRF, popGet(AOP(result),0));
1883 emitpcode(POC_CLRF, popCopyReg(result_hi));
1885 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1887 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1889 temp = popGetTempReg();
1890 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1892 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1894 emitpLabel(tlbl->key);
1896 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1898 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1900 emitpcode(POC_RRF, popCopyReg(result_hi));
1901 emitpcode(POC_RRF, popGet(AOP(result),0));
1904 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1906 popReleaseTempReg(temp);
1911 /*-----------------------------------------------------------------*
1912 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1914 * this routine will call the unsigned multiply routine and then
1915 * post-fix the sign bit.
1916 *-----------------------------------------------------------------*/
1917 void genSMult8X8_16 (operand *left,
1920 pCodeOpReg *result_hi)
1924 result_hi = PCOR(popGet(AOP(result),1));
1927 genUMult8X8_16(left,right,result,result_hi);
1929 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1930 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1931 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1932 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1933 emitpcode(POC_SUBWF, popGet(AOP(result),1));
1937 /*-----------------------------------------------------------------*
1938 * genMult8X8_8 - multiplication of two 8-bit numbers
1940 * this routine will call the unsigned multiply 8X8=>16 routine and
1941 * then throw away the high byte of the result.
1943 *-----------------------------------------------------------------*/
1944 void genMult8X8_8 (operand *left,
1948 pCodeOp *result_hi = popGetTempReg();
1950 if (AOP_TYPE(right) == AOP_LIT)
1951 genUMult8XLit_16(left,right,result,PCOR(result_hi));
1953 genUMult8X8_16(left,right,result,PCOR(result_hi));
1955 popReleaseTempReg(result_hi);
1958 /*-----------------------------------------------------------------*/
1959 /* constMult - generates code for multiplication by a constant */
1960 /*-----------------------------------------------------------------*/
1961 void genMultConst(unsigned C)
1965 unsigned sr3; // Shift right 3
1971 Convert a string of 3 binary 1's in the lit into
1975 mask = 7 << ( (size*8) - 3);
1979 while(mask < (1<<size*8)) {
1981 if( (mask & lit) == lit) {
1984 /* We found 3 (or more) consecutive 1's */
1986 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1988 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1990 lit ^= consecutive_bits;
1994 sr3 |= (consecutive + lsb);