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_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
982 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
983 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
985 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
986 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
989 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
991 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
992 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
995 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
997 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
998 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1006 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1007 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1008 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1011 /* Need to extend result to higher bytes */
1012 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1014 /* First grab the carry from the lower bytes */
1015 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1016 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
1020 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1023 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1024 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1025 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1026 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1028 /* if chars or ints or being signed extended to longs: */
1030 emitpcode(POC_MOVLW, popGetLit(0));
1031 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1032 emitpcode(POC_MOVLW, popGetLit(0xff));
1040 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1042 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1049 //adjustArithmeticResult(ic);
1052 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1053 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1054 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1057 /*-----------------------------------------------------------------*/
1058 /* genMinusDec :- does subtraction with decrement if possible */
1059 /*-----------------------------------------------------------------*/
1060 bool genMinusDec (iCode *ic)
1062 unsigned int icount ;
1063 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1065 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1066 /* will try to generate an increment */
1067 /* if the right side is not a literal
1069 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1070 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1071 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1074 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1076 /* if the literal value of the right hand side
1077 is greater than 4 then it is not worth it */
1078 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1081 /* if decrement 16 bits in register */
1082 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1087 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1088 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1089 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1090 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1092 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1093 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1094 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1096 /* size is 3 or 4 */
1097 emitpcode(POC_MOVLW, popGetLit(0xff));
1098 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1100 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1102 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1104 pic14_emitcode("movlw","0xff");
1105 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1108 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1110 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1114 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1116 pic14_emitcode("skpnc","");
1118 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1127 /* if the sizes are greater than 1 then we cannot */
1128 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1129 AOP_SIZE(IC_LEFT(ic)) > 1 )
1132 /* we can if the aops of the left & result match or
1133 if they are in registers and the registers are the
1135 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1138 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1140 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1145 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1146 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1147 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1150 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1151 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1153 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1154 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1162 /*-----------------------------------------------------------------*/
1163 /* addSign - propogate sign bit to higher bytes */
1164 /*-----------------------------------------------------------------*/
1165 void addSign(operand *result, int offset, int sign)
1167 int size = (pic14_getDataSize(result) - offset);
1168 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1171 if(sign && offset) {
1174 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1175 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1176 emitpcode(POC_DECF, popGet(AOP(result),offset));
1179 emitpcode(POC_MOVLW, popGetLit(0));
1180 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1181 emitpcode(POC_MOVLW, popGetLit(0xff));
1183 emitpcode(POC_MOVWF, popGet(AOP(result),size));
1188 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1192 /*-----------------------------------------------------------------*/
1193 /* genMinusBits - generates code for subtraction of two bits */
1194 /*-----------------------------------------------------------------*/
1195 void genMinusBits (iCode *ic)
1197 symbol *lbl = newiTempLabel(NULL);
1198 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1199 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1200 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1201 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1202 pic14_emitcode("cpl","c");
1203 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1204 pic14_outBitC(IC_RESULT(ic));
1207 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1208 pic14_emitcode("subb","a,acc");
1209 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1210 pic14_emitcode("inc","a");
1211 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1212 aopPut(AOP(IC_RESULT(ic)),"a",0);
1213 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1217 /*-----------------------------------------------------------------*/
1218 /* genMinus - generates code for subtraction */
1219 /*-----------------------------------------------------------------*/
1220 void genMinus (iCode *ic)
1222 int size, offset = 0, same=0;
1223 unsigned long lit = 0L;
1225 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1226 aopOp (IC_LEFT(ic),ic,FALSE);
1227 aopOp (IC_RIGHT(ic),ic,FALSE);
1228 aopOp (IC_RESULT(ic),ic,TRUE);
1230 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1231 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1232 operand *t = IC_RIGHT(ic);
1233 IC_RIGHT(ic) = IC_LEFT(ic);
1237 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1238 AopType(AOP_TYPE(IC_RESULT(ic))),
1239 AopType(AOP_TYPE(IC_LEFT(ic))),
1240 AopType(AOP_TYPE(IC_RIGHT(ic))));
1242 /* special cases :- */
1243 /* if both left & right are in bit space */
1244 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1245 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1250 /* if I can do an decrement instead
1251 of subtract then GOOD for ME */
1252 // if (genMinusDec (ic) == TRUE)
1255 size = pic14_getDataSize(IC_RESULT(ic));
1256 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1258 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1259 /* Add a literal to something else */
1261 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1264 genAddLit ( ic, lit);
1267 /* add the first byte: */
1268 pic14_emitcode("movlw","0x%x", lit & 0xff);
1269 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1270 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1271 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1283 if((lit & 0xff) == 0xff) {
1284 emitpcode(POC_MOVLW, popGetLit(0xff));
1286 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1288 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1290 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1291 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1295 /* do the rlf known zero trick here */
1296 emitpcode(POC_MOVLW, popGetLit(1));
1298 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1303 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1306 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1307 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1308 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1310 /* here we are subtracting a bit from a char or int */
1312 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1314 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1315 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1317 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1318 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1319 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1320 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1323 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1324 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1325 emitpcode(POC_XORLW , popGetLit(1));
1326 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1327 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1329 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1331 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1332 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1334 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1335 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1338 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1340 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1342 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1343 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1347 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1348 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1349 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1350 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1355 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1356 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1357 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1360 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1362 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1365 emitpcode(POC_ANDLW , popGetLit(1));
1367 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1369 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1376 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1377 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1378 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1380 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1381 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1382 AopType(AOP_TYPE(IC_RESULT(ic))),
1383 AopType(AOP_TYPE(IC_LEFT(ic))),
1384 AopType(AOP_TYPE(IC_RIGHT(ic))));
1387 if( (size == 1) && ((lit & 0xff) == 0) ) {
1388 /* res = 0 - right */
1389 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1390 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1391 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1393 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1394 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1395 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1400 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1401 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1402 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1410 /* This is the last byte in a multibyte subtraction
1411 * There are a couple of tricks we can do by not worrying about
1412 * propogating the carry */
1414 /* 0xff - x == ~x */
1416 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1418 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1420 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1421 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1423 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1426 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1428 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1429 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1430 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1439 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1441 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1442 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1445 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1451 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1452 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1454 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1456 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1458 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1459 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1466 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1467 AopType(AOP_TYPE(IC_RESULT(ic))),
1468 AopType(AOP_TYPE(IC_LEFT(ic))),
1469 AopType(AOP_TYPE(IC_RIGHT(ic))));
1471 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1472 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1473 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1474 emitpcode(POC_SUBLW, popGetLit(0));
1475 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1478 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1479 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1480 emitpcode(POC_SUBLW, popGetLit(0));
1481 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1482 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1485 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1486 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1487 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1489 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1490 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1492 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1493 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1494 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1496 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1498 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1499 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1500 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1502 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1504 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1511 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1513 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1514 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1516 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1517 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1524 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1525 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1526 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1528 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1530 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1531 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1539 // adjustArithmeticResult(ic);
1542 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1543 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1544 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1546 /*-----------------------------------------------------------------*
1547 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1550 *-----------------------------------------------------------------*/
1551 void genUMult8XLit_16 (operand *left,
1554 pCodeOpReg *result_hi)
1559 unsigned int i,have_first_bit;
1563 if (AOP_TYPE(right) != AOP_LIT){
1564 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1570 result_hi = PCOR(popGet(AOP(result),1));
1573 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1575 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1577 same = pic14_sameRegs(AOP(left), AOP(result));
1582 emitpcode(POC_CLRF, popGet(AOP(left),0));
1585 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1586 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1589 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1590 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1591 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1594 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1595 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1596 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1597 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1600 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1601 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1602 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1603 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1606 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1607 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1608 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1609 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1610 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1613 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1614 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1615 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1616 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1617 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F
1620 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1621 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1622 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1623 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1624 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1627 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1628 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1629 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1630 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1631 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1632 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1635 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1636 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1637 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1638 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1639 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1640 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1643 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1644 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1645 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1646 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1647 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1648 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F
1651 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1652 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1653 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1654 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1655 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1656 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1657 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1660 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1661 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1662 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1663 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1664 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1665 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*F
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_ADDFW, popGet(AOP(left),0)); // W = 5*F
1672 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1673 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F
1674 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F
1677 temp = popGetTempReg();
1679 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1682 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1683 emitpcode(POC_MOVWF, temp);
1684 emitpcode(POC_ANDLW, popGetLit(0xf0));
1685 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1686 emitpcode(POC_SWAPFW, temp);
1687 emitpcode(POC_SUBWF, popGet(AOP(left),0));
1688 popReleaseTempReg(temp);
1691 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1692 emitpcode(POC_ANDLW, popGetLit(0xf0));
1693 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1696 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1697 emitpcode(POC_ANDLW, popGetLit(0xf0));
1698 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1701 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1702 emitpcode(POC_RLFW, popGet(AOP(left),0));
1703 emitpcode(POC_ANDLW, popGetLit(0xe0));
1704 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1707 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1708 emitpcode(POC_RLF, popGet(AOP(left),0));
1709 emitpcode(POC_RLFW, popGet(AOP(left),0));
1710 emitpcode(POC_ANDLW, popGetLit(0xc0));
1711 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1714 emitpcode(POC_RRFW, popGet(AOP(left),0));
1715 emitpcode(POC_CLRF, popGet(AOP(left),0));
1716 emitpcode(POC_RRF, popGet(AOP(left),0));
1724 emitpcode(POC_CLRF, popGet(AOP(result),0));
1725 emitpcode(POC_CLRF, popCopyReg(result_hi));
1728 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1729 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1730 emitpcode(POC_ADDWF, popGet(AOP(result),0));
1731 emitpcode(POC_CLRF, popCopyReg(result_hi));
1732 emitpcode(POC_RLF, popCopyReg(result_hi));
1738 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1739 emitpcode(POC_CLRF, popGet(AOP(result),0));
1740 emitpcode(POC_CLRF, popCopyReg(result_hi));
1743 for(i=0; i<8; i++) {
1746 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1750 if(have_first_bit) {
1751 emitpcode(POC_RRF, popCopyReg(result_hi));
1752 emitpcode(POC_RRF, popGet(AOP(result),0));
1760 /*-----------------------------------------------------------------*
1761 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1764 *-----------------------------------------------------------------*/
1765 void genUMult8X8_16 (operand *left,
1768 pCodeOpReg *result_hi)
1776 result_hi = PCOR(popGet(AOP(result),1));
1779 if (AOP_TYPE(right) == AOP_LIT) {
1780 genUMult8XLit_16(left,right,result,result_hi);
1785 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1787 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1788 emitpcode(POC_CLRF, popGet(AOP(result),0));
1789 emitpcode(POC_CLRF, popCopyReg(result_hi));
1792 for(i=0; i<8; i++) {
1793 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1794 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1795 emitpcode(POC_RRF, popCopyReg(result_hi));
1796 emitpcode(POC_RRF, popGet(AOP(result),0));
1801 Here's another version that does the same thing and takes the
1802 same number of instructions. The one above is slightly better
1803 because the entry instructions have a higher probability of
1804 being optimized out.
1807 emitpcode(POC_CLRF, popCopyReg(result_hi));
1808 emitpcode(POC_RRFW, popGet(AOP(left),0));
1809 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1810 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1812 for(i=0; i<8; i++) {
1814 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1815 emitpcode(POC_RRF, popCopyReg(result_hi));
1816 emitpcode(POC_RRF, popGet(AOP(result),0));
1821 symbol *tlbl = newiTempLabel(NULL);
1825 pic14_emitcode(";","Looped 8 X 8 multiplication");
1827 emitpcode(POC_CLRF, popGet(AOP(result),0));
1828 emitpcode(POC_CLRF, popCopyReg(result_hi));
1830 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1832 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1834 temp = popGetTempReg();
1835 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1837 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1839 emitpLabel(tlbl->key);
1841 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1843 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1845 emitpcode(POC_RRF, popCopyReg(result_hi));
1846 emitpcode(POC_RRF, popGet(AOP(result),0));
1849 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1851 popReleaseTempReg(temp);
1856 /*-----------------------------------------------------------------*
1857 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1859 * this routine will call the unsigned multiply routine and then
1860 * post-fix the sign bit.
1861 *-----------------------------------------------------------------*/
1862 void genSMult8X8_16 (operand *left,
1865 pCodeOpReg *result_hi)
1869 result_hi = PCOR(popGet(AOP(result),1));
1872 genUMult8X8_16(left,right,result,result_hi);
1874 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1875 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1876 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1877 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1878 emitpcode(POC_SUBWF, popGet(AOP(result),1));
1882 /*-----------------------------------------------------------------*
1883 * genMult8X8_8 - multiplication of two 8-bit numbers
1885 * this routine will call the unsigned multiply 8X8=>16 routine and
1886 * then throw away the high byte of the result.
1888 *-----------------------------------------------------------------*/
1889 void genMult8X8_8 (operand *left,
1893 pCodeOp *result_hi = popGetTempReg();
1895 if (AOP_TYPE(right) == AOP_LIT)
1896 genUMult8XLit_16(left,right,result,PCOR(result_hi));
1898 genUMult8X8_16(left,right,result,PCOR(result_hi));
1900 popReleaseTempReg(result_hi);
1903 /*-----------------------------------------------------------------*/
1904 /* constMult - generates code for multiplication by a constant */
1905 /*-----------------------------------------------------------------*/
1906 void genMultConst(unsigned C)
1910 unsigned sr3; // Shift right 3
1916 Convert a string of 3 binary 1's in the lit into
1920 mask = 7 << ( (size*8) - 3);
1924 while(mask < (1<<size*8)) {
1926 if( (mask & lit) == lit) {
1929 /* We found 3 (or more) consecutive 1's */
1931 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1933 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1935 lit ^= consecutive_bits;
1939 sr3 |= (consecutive + lsb);