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"
40 #define __FUNCTION__ __FILE__
43 #ifdef HAVE_SYS_ISA_DEFS_H
44 #include <sys/isa_defs.h>
46 #ifdef HAVE_MACHINE_ENDIAN_H
47 #include <machine/endian.h>
52 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
53 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
54 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
61 #include "SDCCpeeph.h"
67 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
68 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result);
70 const char *AopType(short type)
113 /*-----------------------------------------------------------------*/
114 /* genPlusIncr :- does addition with increment if possible */
115 /*-----------------------------------------------------------------*/
116 bool genPlusIncr (iCode *ic)
118 unsigned int icount ;
119 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
121 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
122 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
123 AopType(AOP_TYPE(IC_RESULT(ic))),
124 AopType(AOP_TYPE(IC_LEFT(ic))),
125 AopType(AOP_TYPE(IC_RIGHT(ic))));
127 /* will try to generate an increment */
128 /* if the right side is not a literal
130 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
133 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
134 /* if the literal value of the right hand side
135 is greater than 1 then it is faster to add */
136 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
139 /* if increment 16 bits in register */
140 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
145 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB));
146 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
150 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
151 //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
157 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
158 /* if left is in accumulator - probably a bit operation*/
159 if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
160 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
162 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
163 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
164 AOP(IC_RESULT(ic))->aopu.aop_dir,
165 AOP(IC_RESULT(ic))->aopu.aop_dir);
167 emitpcode(POC_XORLW,popGetLit(1));
168 //pic14_emitcode("xorlw","1");
170 emitpcode(POC_ANDLW,popGetLit(1));
171 //pic14_emitcode("andlw","1");
174 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
175 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
176 AOP(IC_RESULT(ic))->aopu.aop_dir,
177 AOP(IC_RESULT(ic))->aopu.aop_dir);
184 /* if the sizes are greater than 1 then we cannot */
185 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
186 AOP_SIZE(IC_LEFT(ic)) > 1 )
189 /* If we are incrementing the same register by two: */
191 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
194 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
195 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
200 DEBUGpic14_emitcode ("; ","couldn't increment ");
205 /*-----------------------------------------------------------------*/
206 /* pic14_outBitAcc - output a bit in acc */
207 /*-----------------------------------------------------------------*/
208 void pic14_outBitAcc(operand *result)
210 symbol *tlbl = newiTempLabel(NULL);
211 /* if the result is a bit */
212 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
214 if (AOP_TYPE(result) == AOP_CRY){
215 aopPut(AOP(result),"a",0);
218 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
219 pic14_emitcode("mov","a,#01");
220 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
221 pic14_outAcc(result);
225 /*-----------------------------------------------------------------*/
226 /* genPlusBits - generates code for addition of two bits */
227 /*-----------------------------------------------------------------*/
228 void genPlusBits (iCode *ic)
231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
233 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
234 AopType(AOP_TYPE(IC_RESULT(ic))),
235 AopType(AOP_TYPE(IC_LEFT(ic))),
236 AopType(AOP_TYPE(IC_RIGHT(ic))));
238 The following block of code will add two bits.
239 Note that it'll even work if the destination is
240 the carry (C in the status register).
241 It won't work if the 'Z' bit is a source or destination.
244 /* If the result is stored in the accumulator (w) */
245 //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
246 switch(AOP_TYPE(IC_RESULT(ic))) {
248 emitpcode(POC_CLRW, NULL);
249 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
250 emitpcode(POC_XORLW, popGetLit(1));
251 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
252 emitpcode(POC_XORLW, popGetLit(1));
254 pic14_emitcode("clrw","");
255 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
256 AOP(IC_RIGHT(ic))->aopu.aop_dir,
257 AOP(IC_RIGHT(ic))->aopu.aop_dir);
258 pic14_emitcode("xorlw","1");
259 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
260 AOP(IC_LEFT(ic))->aopu.aop_dir,
261 AOP(IC_LEFT(ic))->aopu.aop_dir);
262 pic14_emitcode("xorlw","1");
265 emitpcode(POC_MOVLW, popGetLit(0));
266 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
267 emitpcode(POC_XORLW, popGetLit(1));
268 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
269 emitpcode(POC_XORLW, popGetLit(1));
270 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
273 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
274 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
275 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
276 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
277 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
278 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
280 pic14_emitcode("movlw","(1 << (%s & 7))",
281 AOP(IC_RESULT(ic))->aopu.aop_dir,
282 AOP(IC_RESULT(ic))->aopu.aop_dir);
283 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
284 AOP(IC_RESULT(ic))->aopu.aop_dir,
285 AOP(IC_RESULT(ic))->aopu.aop_dir);
286 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
287 AOP(IC_RIGHT(ic))->aopu.aop_dir,
288 AOP(IC_RIGHT(ic))->aopu.aop_dir);
289 pic14_emitcode("xorwf","(%s >>3),f",
290 AOP(IC_RESULT(ic))->aopu.aop_dir);
291 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
292 AOP(IC_LEFT(ic))->aopu.aop_dir,
293 AOP(IC_LEFT(ic))->aopu.aop_dir);
294 pic14_emitcode("xorwf","(%s>>3),f",
295 AOP(IC_RESULT(ic))->aopu.aop_dir);
302 /* This is the original version of this code.
304 * This is being kept around for reference,
305 * because I am not entirely sure I got it right...
307 static void adjustArithmeticResult(iCode *ic)
309 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
310 AOP_SIZE(IC_LEFT(ic)) == 3 &&
311 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
312 aopPut(AOP(IC_RESULT(ic)),
313 aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
316 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
317 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
318 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
319 aopPut(AOP(IC_RESULT(ic)),
320 aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
323 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
324 AOP_SIZE(IC_LEFT(ic)) < 3 &&
325 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
326 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
327 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
329 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
330 aopPut(AOP(IC_RESULT(ic)),buffer,2);
334 /* This is the pure and virtuous version of this code.
335 * I'm pretty certain it's right, but not enough to toss the old
338 static void adjustArithmeticResult(iCode *ic)
340 if (opIsGptr(IC_RESULT(ic)) &&
341 opIsGptr(IC_LEFT(ic)) &&
342 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
344 aopPut(AOP(IC_RESULT(ic)),
345 aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
349 if (opIsGptr(IC_RESULT(ic)) &&
350 opIsGptr(IC_RIGHT(ic)) &&
351 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
353 aopPut(AOP(IC_RESULT(ic)),
354 aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
358 if (opIsGptr(IC_RESULT(ic)) &&
359 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
360 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
361 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
362 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
364 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
365 aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
370 /*-----------------------------------------------------------------*/
371 /* genAddlit - generates code for addition */
372 /*-----------------------------------------------------------------*/
373 static void genAddLit2byte (operand *result, int offr, int lit)
380 emitpcode(POC_INCF, popGet(AOP(result),offr));
383 emitpcode(POC_DECF, popGet(AOP(result),offr));
386 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
387 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
392 static void emitMOVWF(operand *reg, int offset)
397 if (AOP_TYPE(reg) == AOP_ACC) {
398 DEBUGpic14_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
402 emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
406 static void genAddLit (iCode *ic, int lit)
415 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
419 result = IC_RESULT(ic);
420 same = pic14_sameRegs(AOP(left), AOP(result));
421 size = pic14_getDataSize(result);
425 /* Handle special cases first */
427 genAddLit2byte (result, 0, lit);
430 int hi = 0xff & (lit >> 8);
437 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
442 emitpcode(POC_INCF, popGet(AOP(result),0));
444 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
447 emitpcode(POC_DECF, popGet(AOP(result),0));
448 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
449 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
453 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
454 emitpcode(POC_ADDWF,popGet(AOP(result),0));
456 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
464 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
467 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
470 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
471 emitpcode(POC_INCF, popGet(AOP(result),0));
473 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
475 case 0xff: /* 0x01ff */
476 emitpcode(POC_DECF, popGet(AOP(result),0));
477 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
478 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
479 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
484 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
488 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
491 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
492 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
494 /* case 0xff: * 0xffff *
495 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
496 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
497 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
501 emitpcode(POC_MOVLW,popGetLit(lo));
502 emitpcode(POC_ADDWF,popGet(AOP(result),0));
504 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
511 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
516 genAddLit2byte (result, MSB16, hi);
519 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
520 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
521 emitpcode(POC_MOVLW,popGetLit(hi));
522 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
524 /* case 0xff: * 0xHHff *
525 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
526 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
527 emitpcode(POC_MOVLW,popGetLit(hi));
528 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
530 */ default: /* 0xHHLL */
531 emitpcode(POC_MOVLW,popGetLit(lo));
532 emitpcode(POC_ADDWF, popGet(AOP(result),0));
533 emitpcode(POC_MOVLW,popGetLit(hi));
535 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
536 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
545 DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
548 lo = BYTEofLONG(lit,0);
556 emitpcode(POC_INCF, popGet(AOP(result),offset));
559 emitpcode(POC_RLFW, popGet(AOP(result),offset));
560 emitpcode(POC_ANDLW,popGetLit(1));
561 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
563 default: /* carry_info = 3 */
565 emitpcode(POC_INCF, popGet(AOP(result),offset));
571 emitpcode(POC_MOVLW,popGetLit(lo));
576 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
579 emitpcode(POC_MOVLW,popGetLit(lo));
584 emitpcode(POC_MOVLW,popGetLit(lo+1));
585 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
590 /* no carry info from previous step */
591 /* this means this is the first time to add */
596 emitpcode(POC_INCF, popGet(AOP(result),offset));
600 emitpcode(POC_MOVLW,popGetLit(lo));
601 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
603 carry_info = 3; /* Were adding only one byte and propogating the carry */
614 lo = BYTEofLONG(lit,0);
619 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
622 emitpcode(POC_MOVLW,popGetLit(lo));
623 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
626 emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
628 emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
630 emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
640 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
644 if(AOP_TYPE(left) == AOP_ACC) {
645 /* left addend is already in accumulator */
648 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
652 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
653 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
657 /* left addend is in a register */
660 emitpcode(POC_MOVFW, popGet(AOP(left),0));
661 emitMOVWF(result, 0);
662 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
666 emitpcode(POC_INCFW, popGet(AOP(left),0));
667 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
671 emitpcode(POC_DECFW, popGet(AOP(left),0));
672 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
676 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
677 emitpcode(POC_ADDFW, popGet(AOP(left),0));
678 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
685 /* left is not the accumulator */
687 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
688 emitpcode(POC_ADDFW, popGet(AOP(left),0));
690 emitpcode(POC_MOVFW, popGet(AOP(left),0));
692 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
698 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
699 //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
700 emitMOVWF(result,offset);
701 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
703 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
704 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
706 emitpcode(POC_CLRF, popGet(AOP(result),offset));
707 emitpcode(POC_RLF, popGet(AOP(result),offset));
708 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
709 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
717 /*-----------------------------------------------------------------*/
718 /* genPlus - generates code for addition */
719 /*-----------------------------------------------------------------*/
720 void genPlus (iCode *ic)
722 int size, offset = 0;
724 /* special cases :- */
725 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
727 aopOp (IC_LEFT(ic),ic,FALSE);
728 aopOp (IC_RIGHT(ic),ic,FALSE);
729 aopOp (IC_RESULT(ic),ic,TRUE);
731 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
733 /* if literal, literal on the right or
734 if left requires ACC or right is already
737 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
738 operand *t = IC_RIGHT(ic);
739 IC_RIGHT(ic) = IC_LEFT(ic);
743 /* if both left & right are in bit space */
744 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
745 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
750 /* if left in bit space & right literal */
751 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
752 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
753 /* if result in bit space */
754 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
755 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
756 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
757 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
758 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
759 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
762 size = pic14_getDataSize(IC_RESULT(ic));
764 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
765 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
766 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
772 /* if I can do an increment instead
773 of add then GOOD for ME */
774 if (genPlusIncr (ic) == TRUE)
777 size = pic14_getDataSize(IC_RESULT(ic));
779 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
780 /* Add a literal to something else */
782 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
786 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
791 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
793 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
794 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
795 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
797 /* here we are adding a bit to a char or int */
799 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
801 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
802 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
804 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
805 AOP(IC_RIGHT(ic))->aopu.aop_dir,
806 AOP(IC_RIGHT(ic))->aopu.aop_dir);
807 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
810 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
811 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
812 emitpcode(POC_XORLW , popGetLit(1));
814 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
815 AOP(IC_RIGHT(ic))->aopu.aop_dir,
816 AOP(IC_RIGHT(ic))->aopu.aop_dir);
817 pic14_emitcode(" xorlw","1");
819 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
820 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
821 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
823 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
824 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
825 AOP(IC_RIGHT(ic))->aopu.aop_dir,
826 AOP(IC_RIGHT(ic))->aopu.aop_dir);
827 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
830 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
832 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
833 emitpcode(POC_ANDLW , popGetLit(1));
834 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
836 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
838 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
839 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
846 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
847 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
849 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
850 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
852 pic14_emitcode("clrz","");
854 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
855 AOP(IC_RIGHT(ic))->aopu.aop_dir,
856 AOP(IC_RIGHT(ic))->aopu.aop_dir);
857 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
861 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
862 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
863 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
864 //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
865 emitMOVWF(IC_RIGHT(ic),0);
867 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
868 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
869 AOP(IC_RIGHT(ic))->aopu.aop_dir,
870 AOP(IC_RIGHT(ic))->aopu.aop_dir);
871 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
872 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
878 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
879 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
885 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
887 /* Add the first bytes */
889 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
890 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
891 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
894 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
895 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
896 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
897 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
900 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
902 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
903 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
905 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
906 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
907 emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0));
909 emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0));
910 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
911 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
917 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
922 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
923 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
924 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
926 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
927 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
930 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
932 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
933 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
936 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
938 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
939 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
947 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
948 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
949 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
952 /* Need to extend result to higher bytes */
953 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
955 /* First grab the carry from the lower bytes */
956 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
957 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
961 /* Now this is really horrid. Gotta check the sign of the addends and propogate
964 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
965 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
966 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
967 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
969 /* if chars or ints or being signed extended to longs: */
971 emitpcode(POC_MOVLW, popGetLit(0));
972 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
973 emitpcode(POC_MOVLW, popGetLit(0xff));
981 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
983 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
990 //adjustArithmeticResult(ic);
993 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
994 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
995 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
998 /*-----------------------------------------------------------------*/
999 /* genMinusDec :- does subtraction with decrement if possible */
1000 /*-----------------------------------------------------------------*/
1001 bool genMinusDec (iCode *ic)
1003 unsigned int icount ;
1004 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1006 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1007 /* will try to generate an increment */
1008 /* if the right side is not a literal
1010 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1011 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1012 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1015 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1017 /* if the literal value of the right hand side
1018 is greater than 4 then it is not worth it */
1019 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1022 /* if decrement 16 bits in register */
1023 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1028 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1029 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1030 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1031 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1033 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1034 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1035 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1037 /* size is 3 or 4 */
1038 emitpcode(POC_MOVLW, popGetLit(0xff));
1039 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1041 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1043 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1045 pic14_emitcode("movlw","0xff");
1046 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1049 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1051 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1055 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1057 pic14_emitcode("skpnc","");
1059 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1068 /* if the sizes are greater than 1 then we cannot */
1069 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1070 AOP_SIZE(IC_LEFT(ic)) > 1 )
1073 /* we can if the aops of the left & result match or
1074 if they are in registers and the registers are the
1076 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1079 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1081 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1086 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1087 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1088 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1091 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1092 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1094 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1095 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1103 /*-----------------------------------------------------------------*/
1104 /* addSign - complete with sign */
1105 /*-----------------------------------------------------------------*/
1106 void addSign(operand *result, int offset, int sign)
1108 int size = (pic14_getDataSize(result) - offset);
1109 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1112 pic14_emitcode("rlc","a");
1113 pic14_emitcode("subb","a,acc");
1115 aopPut(AOP(result),"a",offset++);
1118 aopPut(AOP(result),"#0",offset++);
1122 /*-----------------------------------------------------------------*/
1123 /* genMinusBits - generates code for subtraction of two bits */
1124 /*-----------------------------------------------------------------*/
1125 void genMinusBits (iCode *ic)
1127 symbol *lbl = newiTempLabel(NULL);
1128 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1129 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1130 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1131 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1132 pic14_emitcode("cpl","c");
1133 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1134 pic14_outBitC(IC_RESULT(ic));
1137 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1138 pic14_emitcode("subb","a,acc");
1139 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1140 pic14_emitcode("inc","a");
1141 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1142 aopPut(AOP(IC_RESULT(ic)),"a",0);
1143 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1147 /*-----------------------------------------------------------------*/
1148 /* genMinus - generates code for subtraction */
1149 /*-----------------------------------------------------------------*/
1150 void genMinus (iCode *ic)
1152 int size, offset = 0, same=0;
1153 unsigned long lit = 0L;
1155 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1156 aopOp (IC_LEFT(ic),ic,FALSE);
1157 aopOp (IC_RIGHT(ic),ic,FALSE);
1158 aopOp (IC_RESULT(ic),ic,TRUE);
1160 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1161 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1162 operand *t = IC_RIGHT(ic);
1163 IC_RIGHT(ic) = IC_LEFT(ic);
1167 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1168 AopType(AOP_TYPE(IC_RESULT(ic))),
1169 AopType(AOP_TYPE(IC_LEFT(ic))),
1170 AopType(AOP_TYPE(IC_RIGHT(ic))));
1172 /* special cases :- */
1173 /* if both left & right are in bit space */
1174 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1175 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1180 /* if I can do an decrement instead
1181 of subtract then GOOD for ME */
1182 // if (genMinusDec (ic) == TRUE)
1185 size = pic14_getDataSize(IC_RESULT(ic));
1186 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1188 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1189 /* Add a literal to something else */
1191 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1194 genAddLit ( ic, lit);
1197 /* add the first byte: */
1198 pic14_emitcode("movlw","0x%x", lit & 0xff);
1199 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1200 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1201 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1213 if((lit & 0xff) == 0xff) {
1214 emitpcode(POC_MOVLW, popGetLit(0xff));
1216 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1218 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1220 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1221 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1225 /* do the rlf known zero trick here */
1226 emitpcode(POC_MOVLW, popGetLit(1));
1228 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1233 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1236 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1237 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1238 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1240 /* here we are subtracting a bit from a char or int */
1242 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1244 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1245 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1247 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1248 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1249 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1250 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1253 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1254 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1255 emitpcode(POC_XORLW , popGetLit(1));
1256 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1257 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1259 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1261 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1262 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1264 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1265 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1268 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1270 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1272 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1273 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1277 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1278 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1279 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1280 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1285 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1286 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1287 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1290 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1292 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1295 emitpcode(POC_ANDLW , popGetLit(1));
1297 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1299 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1306 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1307 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1308 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1310 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1311 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1312 AopType(AOP_TYPE(IC_RESULT(ic))),
1313 AopType(AOP_TYPE(IC_LEFT(ic))),
1314 AopType(AOP_TYPE(IC_RIGHT(ic))));
1317 if( (size == 1) && ((lit & 0xff) == 0) ) {
1318 /* res = 0 - right */
1319 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1320 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1321 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1323 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1324 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1325 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1330 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1331 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1332 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1340 /* This is the last byte in a multibyte subtraction
1341 * There are a couple of tricks we can do by not worrying about
1342 * propogating the carry */
1344 /* 0xff - x == ~x */
1346 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1348 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1350 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1351 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1353 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1356 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1358 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1359 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1360 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1369 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1371 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1372 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1375 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1381 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1382 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1384 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1386 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1388 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1389 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1396 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1397 AopType(AOP_TYPE(IC_RESULT(ic))),
1398 AopType(AOP_TYPE(IC_LEFT(ic))),
1399 AopType(AOP_TYPE(IC_RIGHT(ic))));
1401 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1402 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1403 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1404 emitpcode(POC_SUBLW, popGetLit(0));
1405 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1408 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1409 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1410 emitpcode(POC_SUBLW, popGetLit(0));
1411 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1412 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1415 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1416 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1417 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1419 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1420 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1422 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1423 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1424 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1426 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1428 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1429 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1430 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1432 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1434 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1441 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1443 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1444 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1446 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1447 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1454 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1455 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1456 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1458 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1460 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1461 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1469 // adjustArithmeticResult(ic);
1472 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1473 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1474 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);