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)
69 const char *AopType(short type)
112 /*-----------------------------------------------------------------*/
113 /* genPlusIncr :- does addition with increment if possible */
114 /*-----------------------------------------------------------------*/
115 bool genPlusIncr (iCode *ic)
117 unsigned int icount ;
118 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
120 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
121 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
122 AopType(AOP_TYPE(IC_RESULT(ic))),
123 AopType(AOP_TYPE(IC_LEFT(ic))),
124 AopType(AOP_TYPE(IC_RIGHT(ic))));
126 /* will try to generate an increment */
127 /* if the right side is not a literal
129 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
132 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
133 /* if the literal value of the right hand side
134 is greater than 1 then it is faster to add */
135 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
138 /* if increment 16 bits in register */
139 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
144 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB));
145 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
149 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
150 //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
156 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
157 /* if left is in accumulator - probably a bit operation*/
158 if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
159 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
161 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
162 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
163 AOP(IC_RESULT(ic))->aopu.aop_dir,
164 AOP(IC_RESULT(ic))->aopu.aop_dir);
166 emitpcode(POC_XORLW,popGetLit(1));
167 //pic14_emitcode("xorlw","1");
169 emitpcode(POC_ANDLW,popGetLit(1));
170 //pic14_emitcode("andlw","1");
173 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
174 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
175 AOP(IC_RESULT(ic))->aopu.aop_dir,
176 AOP(IC_RESULT(ic))->aopu.aop_dir);
183 /* if the sizes are greater than 1 then we cannot */
184 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
185 AOP_SIZE(IC_LEFT(ic)) > 1 )
188 /* If we are incrementing the same register by two: */
190 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
193 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
194 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
199 DEBUGpic14_emitcode ("; ","couldn't increment ");
204 /*-----------------------------------------------------------------*/
205 /* pic14_outBitAcc - output a bit in acc */
206 /*-----------------------------------------------------------------*/
207 void pic14_outBitAcc(operand *result)
209 symbol *tlbl = newiTempLabel(NULL);
210 /* if the result is a bit */
211 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
213 if (AOP_TYPE(result) == AOP_CRY){
214 aopPut(AOP(result),"a",0);
217 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
218 pic14_emitcode("mov","a,#01");
219 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
220 pic14_outAcc(result);
224 /*-----------------------------------------------------------------*/
225 /* genPlusBits - generates code for addition of two bits */
226 /*-----------------------------------------------------------------*/
227 void genPlusBits (iCode *ic)
230 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
232 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
233 AopType(AOP_TYPE(IC_RESULT(ic))),
234 AopType(AOP_TYPE(IC_LEFT(ic))),
235 AopType(AOP_TYPE(IC_RIGHT(ic))));
237 The following block of code will add two bits.
238 Note that it'll even work if the destination is
239 the carry (C in the status register).
240 It won't work if the 'Z' bit is a source or destination.
243 /* If the result is stored in the accumulator (w) */
244 //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
245 switch(AOP_TYPE(IC_RESULT(ic))) {
247 emitpcode(POC_CLRW, NULL);
248 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
249 emitpcode(POC_XORLW, popGetLit(1));
250 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
251 emitpcode(POC_XORLW, popGetLit(1));
253 pic14_emitcode("clrw","");
254 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
255 AOP(IC_RIGHT(ic))->aopu.aop_dir,
256 AOP(IC_RIGHT(ic))->aopu.aop_dir);
257 pic14_emitcode("xorlw","1");
258 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
259 AOP(IC_LEFT(ic))->aopu.aop_dir,
260 AOP(IC_LEFT(ic))->aopu.aop_dir);
261 pic14_emitcode("xorlw","1");
264 emitpcode(POC_MOVLW, popGetLit(0));
265 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
266 emitpcode(POC_XORLW, popGetLit(1));
267 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
268 emitpcode(POC_XORLW, popGetLit(1));
269 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
272 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
273 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
274 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
275 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
276 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
277 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
279 pic14_emitcode("movlw","(1 << (%s & 7))",
280 AOP(IC_RESULT(ic))->aopu.aop_dir,
281 AOP(IC_RESULT(ic))->aopu.aop_dir);
282 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
283 AOP(IC_RESULT(ic))->aopu.aop_dir,
284 AOP(IC_RESULT(ic))->aopu.aop_dir);
285 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
286 AOP(IC_RIGHT(ic))->aopu.aop_dir,
287 AOP(IC_RIGHT(ic))->aopu.aop_dir);
288 pic14_emitcode("xorwf","(%s >>3),f",
289 AOP(IC_RESULT(ic))->aopu.aop_dir);
290 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
291 AOP(IC_LEFT(ic))->aopu.aop_dir,
292 AOP(IC_LEFT(ic))->aopu.aop_dir);
293 pic14_emitcode("xorwf","(%s>>3),f",
294 AOP(IC_RESULT(ic))->aopu.aop_dir);
301 /* This is the original version of this code.
303 * This is being kept around for reference,
304 * because I am not entirely sure I got it right...
306 static void adjustArithmeticResult(iCode *ic)
308 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
309 AOP_SIZE(IC_LEFT(ic)) == 3 &&
310 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
311 aopPut(AOP(IC_RESULT(ic)),
312 aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
315 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
316 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
317 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
318 aopPut(AOP(IC_RESULT(ic)),
319 aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
322 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
323 AOP_SIZE(IC_LEFT(ic)) < 3 &&
324 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
325 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
326 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
328 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
329 aopPut(AOP(IC_RESULT(ic)),buffer,2);
333 /* This is the pure and virtuous version of this code.
334 * I'm pretty certain it's right, but not enough to toss the old
337 static void adjustArithmeticResult(iCode *ic)
339 if (opIsGptr(IC_RESULT(ic)) &&
340 opIsGptr(IC_LEFT(ic)) &&
341 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
343 aopPut(AOP(IC_RESULT(ic)),
344 aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
348 if (opIsGptr(IC_RESULT(ic)) &&
349 opIsGptr(IC_RIGHT(ic)) &&
350 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
352 aopPut(AOP(IC_RESULT(ic)),
353 aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
357 if (opIsGptr(IC_RESULT(ic)) &&
358 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
359 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
360 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
361 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
363 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
364 aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
369 /*-----------------------------------------------------------------*/
370 /* genAddlit - generates code for addition */
371 /*-----------------------------------------------------------------*/
372 static void genAddLit2byte (operand *result, int offr, int lit)
379 emitpcode(POC_INCF, popGet(AOP(result),offr));
382 emitpcode(POC_DECF, popGet(AOP(result),offr));
385 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
386 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
391 static void emitMOVWF(operand *reg, int offset)
396 if (AOP_TYPE(reg) == AOP_ACC) {
397 DEBUGpic14_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
401 emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
405 static void genAddLit (iCode *ic, int lit)
414 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
418 result = IC_RESULT(ic);
419 same = pic14_sameRegs(AOP(left), AOP(result));
420 size = pic14_getDataSize(result);
424 /* Handle special cases first */
426 genAddLit2byte (result, 0, lit);
429 int hi = 0xff & (lit >> 8);
436 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
441 emitpcode(POC_INCF, popGet(AOP(result),0));
443 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
446 emitpcode(POC_DECF, popGet(AOP(result),0));
447 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
448 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
452 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
453 emitpcode(POC_ADDWF,popGet(AOP(result),0));
455 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
463 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
466 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
469 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
470 emitpcode(POC_INCF, popGet(AOP(result),0));
472 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
474 case 0xff: /* 0x01ff */
475 emitpcode(POC_DECF, popGet(AOP(result),0));
476 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
477 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
478 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
483 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
487 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
490 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
491 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
493 /* case 0xff: * 0xffff *
494 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
495 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
496 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
500 emitpcode(POC_MOVLW,popGetLit(lo));
501 emitpcode(POC_ADDWF,popGet(AOP(result),0));
503 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
510 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
515 genAddLit2byte (result, MSB16, hi);
518 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
519 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
520 emitpcode(POC_MOVLW,popGetLit(hi));
521 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
523 /* case 0xff: * 0xHHff *
524 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
525 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
526 emitpcode(POC_MOVLW,popGetLit(hi));
527 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
529 */ default: /* 0xHHLL */
530 emitpcode(POC_MOVLW,popGetLit(lo));
531 emitpcode(POC_ADDWF, popGet(AOP(result),0));
532 emitpcode(POC_MOVLW,popGetLit(hi));
534 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
535 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
544 DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
547 lo = BYTEofLONG(lit,0);
555 emitpcode(POC_INCF, popGet(AOP(result),offset));
558 emitpcode(POC_RLFW, popGet(AOP(result),offset));
559 emitpcode(POC_ANDLW,popGetLit(1));
560 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
562 default: /* carry_info = 3 */
564 emitpcode(POC_INCF, popGet(AOP(result),offset));
570 emitpcode(POC_MOVLW,popGetLit(lo));
575 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
578 emitpcode(POC_MOVLW,popGetLit(lo));
583 emitpcode(POC_MOVLW,popGetLit(lo+1));
584 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
589 /* no carry info from previous step */
590 /* this means this is the first time to add */
595 emitpcode(POC_INCF, popGet(AOP(result),offset));
599 emitpcode(POC_MOVLW,popGetLit(lo));
600 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
602 carry_info = 3; /* Were adding only one byte and propogating the carry */
613 lo = BYTEofLONG(lit,0);
618 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
621 emitpcode(POC_MOVLW,popGetLit(lo));
622 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
625 emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
627 emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
629 emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
639 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
643 if(AOP_TYPE(left) == AOP_ACC) {
644 /* left addend is already in accumulator */
647 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
651 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
652 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
656 /* left addend is in a register */
659 emitpcode(POC_MOVFW, popGet(AOP(left),0));
660 emitMOVWF(result, 0);
661 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
665 emitpcode(POC_INCFW, popGet(AOP(left),0));
666 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
670 emitpcode(POC_DECFW, popGet(AOP(left),0));
671 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
675 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
676 emitpcode(POC_ADDFW, popGet(AOP(left),0));
677 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
684 /* left is not the accumulator */
686 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
687 emitpcode(POC_ADDFW, popGet(AOP(left),0));
689 emitpcode(POC_MOVFW, popGet(AOP(left),0));
691 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
697 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
698 //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
699 emitMOVWF(result,offset);
700 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
702 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
703 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
705 emitpcode(POC_CLRF, popGet(AOP(result),offset));
706 emitpcode(POC_RLF, popGet(AOP(result),offset));
707 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
708 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
716 /*-----------------------------------------------------------------*/
717 /* genPlus - generates code for addition */
718 /*-----------------------------------------------------------------*/
719 void genPlus (iCode *ic)
721 int size, offset = 0;
723 /* special cases :- */
724 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
726 aopOp (IC_LEFT(ic),ic,FALSE);
727 aopOp (IC_RIGHT(ic),ic,FALSE);
728 aopOp (IC_RESULT(ic),ic,TRUE);
730 /* if literal, literal on the right or
731 if left requires ACC or right is already
734 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
735 operand *t = IC_RIGHT(ic);
736 IC_RIGHT(ic) = IC_LEFT(ic);
740 /* if both left & right are in bit space */
741 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
742 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
747 /* if left in bit space & right literal */
748 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
749 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
750 /* if result in bit space */
751 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
752 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
753 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
754 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
755 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
756 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
759 size = pic14_getDataSize(IC_RESULT(ic));
761 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
762 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
763 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
769 /* if I can do an increment instead
770 of add then GOOD for ME */
771 if (genPlusIncr (ic) == TRUE)
774 size = pic14_getDataSize(IC_RESULT(ic));
776 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
777 /* Add a literal to something else */
779 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
783 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
787 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
789 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
790 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
791 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
793 /* here we are adding a bit to a char or int */
795 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
797 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
798 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
800 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
801 AOP(IC_RIGHT(ic))->aopu.aop_dir,
802 AOP(IC_RIGHT(ic))->aopu.aop_dir);
803 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
806 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
807 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
808 emitpcode(POC_XORLW , popGetLit(1));
810 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
811 AOP(IC_RIGHT(ic))->aopu.aop_dir,
812 AOP(IC_RIGHT(ic))->aopu.aop_dir);
813 pic14_emitcode(" xorlw","1");
815 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
816 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
817 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
819 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
820 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
821 AOP(IC_RIGHT(ic))->aopu.aop_dir,
822 AOP(IC_RIGHT(ic))->aopu.aop_dir);
823 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
826 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
828 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
829 emitpcode(POC_ANDLW , popGetLit(1));
830 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
832 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
834 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
835 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
842 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
843 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
845 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
846 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
848 pic14_emitcode("clrz","");
850 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
851 AOP(IC_RIGHT(ic))->aopu.aop_dir,
852 AOP(IC_RIGHT(ic))->aopu.aop_dir);
853 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
857 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
858 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
859 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
860 //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
861 emitMOVWF(IC_RIGHT(ic),0);
863 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
864 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
865 AOP(IC_RIGHT(ic))->aopu.aop_dir,
866 AOP(IC_RIGHT(ic))->aopu.aop_dir);
867 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
868 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
874 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
875 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
881 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
882 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
883 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
884 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
887 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
888 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
889 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
890 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
893 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
895 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
896 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
898 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
899 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
900 emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0));
902 emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0));
903 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
904 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
914 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
915 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
916 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
918 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
919 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
922 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
924 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
925 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
928 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
930 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
931 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
939 //adjustArithmeticResult(ic);
942 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
943 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
944 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
947 /*-----------------------------------------------------------------*/
948 /* genMinusDec :- does subtraction with decrement if possible */
949 /*-----------------------------------------------------------------*/
950 bool genMinusDec (iCode *ic)
952 unsigned int icount ;
953 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
955 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
956 /* will try to generate an increment */
957 /* if the right side is not a literal
959 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
960 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
961 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
964 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
966 /* if the literal value of the right hand side
967 is greater than 4 then it is not worth it */
968 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
971 /* if decrement 16 bits in register */
972 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
977 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
978 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
979 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
980 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
982 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
983 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
984 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
987 emitpcode(POC_MOVLW, popGetLit(0xff));
988 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
990 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
992 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
994 pic14_emitcode("movlw","0xff");
995 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
998 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1000 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1004 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1006 pic14_emitcode("skpnc","");
1008 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1017 /* if the sizes are greater than 1 then we cannot */
1018 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1019 AOP_SIZE(IC_LEFT(ic)) > 1 )
1022 /* we can if the aops of the left & result match or
1023 if they are in registers and the registers are the
1025 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1028 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1030 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1035 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1036 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1037 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1040 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1041 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1043 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1044 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1052 /*-----------------------------------------------------------------*/
1053 /* addSign - complete with sign */
1054 /*-----------------------------------------------------------------*/
1055 void addSign(operand *result, int offset, int sign)
1057 int size = (pic14_getDataSize(result) - offset);
1058 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1061 pic14_emitcode("rlc","a");
1062 pic14_emitcode("subb","a,acc");
1064 aopPut(AOP(result),"a",offset++);
1067 aopPut(AOP(result),"#0",offset++);
1071 /*-----------------------------------------------------------------*/
1072 /* genMinusBits - generates code for subtraction of two bits */
1073 /*-----------------------------------------------------------------*/
1074 void genMinusBits (iCode *ic)
1076 symbol *lbl = newiTempLabel(NULL);
1077 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1078 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1079 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1080 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1081 pic14_emitcode("cpl","c");
1082 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1083 pic14_outBitC(IC_RESULT(ic));
1086 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1087 pic14_emitcode("subb","a,acc");
1088 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1089 pic14_emitcode("inc","a");
1090 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1091 aopPut(AOP(IC_RESULT(ic)),"a",0);
1092 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1096 /*-----------------------------------------------------------------*/
1097 /* genMinus - generates code for subtraction */
1098 /*-----------------------------------------------------------------*/
1099 void genMinus (iCode *ic)
1101 int size, offset = 0, same=0;
1102 unsigned long lit = 0L;
1104 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1105 aopOp (IC_LEFT(ic),ic,FALSE);
1106 aopOp (IC_RIGHT(ic),ic,FALSE);
1107 aopOp (IC_RESULT(ic),ic,TRUE);
1109 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1110 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1111 operand *t = IC_RIGHT(ic);
1112 IC_RIGHT(ic) = IC_LEFT(ic);
1116 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1117 AopType(AOP_TYPE(IC_RESULT(ic))),
1118 AopType(AOP_TYPE(IC_LEFT(ic))),
1119 AopType(AOP_TYPE(IC_RIGHT(ic))));
1121 /* special cases :- */
1122 /* if both left & right are in bit space */
1123 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1124 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1129 /* if I can do an decrement instead
1130 of subtract then GOOD for ME */
1131 // if (genMinusDec (ic) == TRUE)
1134 size = pic14_getDataSize(IC_RESULT(ic));
1135 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1137 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1138 /* Add a literal to something else */
1140 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1143 genAddLit ( ic, lit);
1146 /* add the first byte: */
1147 pic14_emitcode("movlw","0x%x", lit & 0xff);
1148 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1149 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1150 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1162 if((lit & 0xff) == 0xff) {
1163 emitpcode(POC_MOVLW, popGetLit(0xff));
1165 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1167 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1169 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1170 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1174 /* do the rlf known zero trick here */
1175 emitpcode(POC_MOVLW, popGetLit(1));
1177 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1182 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1185 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1186 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1187 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1189 /* here we are subtracting a bit from a char or int */
1191 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1193 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1194 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1196 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1197 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1198 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1199 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1202 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1203 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1204 emitpcode(POC_XORLW , popGetLit(1));
1205 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1206 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1208 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1210 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1211 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1213 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1214 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1217 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1219 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1221 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1222 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1226 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1227 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1228 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1229 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1234 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1235 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1236 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1239 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1241 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1244 emitpcode(POC_ANDLW , popGetLit(1));
1246 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1248 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1255 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1256 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1257 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1259 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1260 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1261 AopType(AOP_TYPE(IC_RESULT(ic))),
1262 AopType(AOP_TYPE(IC_LEFT(ic))),
1263 AopType(AOP_TYPE(IC_RIGHT(ic))));
1266 if( (size == 1) && ((lit & 0xff) == 0) ) {
1267 /* res = 0 - right */
1268 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1269 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1270 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1272 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1273 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1274 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1279 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1280 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1281 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1289 /* This is the last byte in a multibyte subtraction
1290 * There are a couple of tricks we can do by not worrying about
1291 * propogating the carry */
1293 /* 0xff - x == ~x */
1295 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1297 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1299 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1300 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1302 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1305 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1307 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1308 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1309 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1318 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1320 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1321 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1324 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1330 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1331 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1333 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1335 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1337 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1338 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1345 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1346 AopType(AOP_TYPE(IC_RESULT(ic))),
1347 AopType(AOP_TYPE(IC_LEFT(ic))),
1348 AopType(AOP_TYPE(IC_RIGHT(ic))));
1350 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1351 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1352 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1353 emitpcode(POC_SUBLW, popGetLit(0));
1354 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1357 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1358 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1359 emitpcode(POC_SUBLW, popGetLit(0));
1360 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1361 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1364 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1365 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1366 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1368 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1369 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1371 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1372 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1373 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1375 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1377 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1378 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1379 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1381 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1383 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1390 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1392 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1393 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1395 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1396 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1403 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1404 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1405 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1407 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1409 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1410 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1418 // adjustArithmeticResult(ic);
1421 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1422 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1423 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);