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 %d, left %d, right %d",
122 AOP_TYPE(IC_RESULT(ic)),
123 AOP_TYPE(IC_LEFT(ic)),
124 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,FALSE,FALSE));
145 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
149 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
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,FALSE,FALSE));
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,FALSE,FALSE));
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,FALSE,FALSE));
194 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
199 DEBUGpic14_emitcode ("; ","couldn't increment result-%s left-%s",
200 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
201 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
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 The following block of code will add two bits.
234 Note that it'll even work if the destination is
235 the carry (C in the status register).
236 It won't work if the 'Z' bit is a source or destination.
239 /* If the result is stored in the accumulator (w) */
240 //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
241 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
242 //emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
243 // popGet(AOP(result),0,FALSE,FALSE));
245 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
246 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
247 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
248 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
249 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
250 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
252 pic14_emitcode("movlw","(1 << (%s & 7))",
253 AOP(IC_RESULT(ic))->aopu.aop_dir,
254 AOP(IC_RESULT(ic))->aopu.aop_dir);
255 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
256 AOP(IC_RESULT(ic))->aopu.aop_dir,
257 AOP(IC_RESULT(ic))->aopu.aop_dir);
258 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
259 AOP(IC_RIGHT(ic))->aopu.aop_dir,
260 AOP(IC_RIGHT(ic))->aopu.aop_dir);
261 pic14_emitcode("xorwf","(%s >>3),f",
262 AOP(IC_RESULT(ic))->aopu.aop_dir);
263 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
264 AOP(IC_LEFT(ic))->aopu.aop_dir,
265 AOP(IC_LEFT(ic))->aopu.aop_dir);
266 pic14_emitcode("xorwf","(%s>>3),f",
267 AOP(IC_RESULT(ic))->aopu.aop_dir);
270 emitpcode(POC_CLRW, NULL);
271 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
272 emitpcode(POC_XORLW, popGetLit(1));
273 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
274 emitpcode(POC_XORLW, popGetLit(1));
276 pic14_emitcode("clrw","");
277 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
278 AOP(IC_RIGHT(ic))->aopu.aop_dir,
279 AOP(IC_RIGHT(ic))->aopu.aop_dir);
280 pic14_emitcode("xorlw","1");
281 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
282 AOP(IC_LEFT(ic))->aopu.aop_dir,
283 AOP(IC_LEFT(ic))->aopu.aop_dir);
284 pic14_emitcode("xorlw","1");
290 /* This is the original version of this code.
292 * This is being kept around for reference,
293 * because I am not entirely sure I got it right...
295 static void adjustArithmeticResult(iCode *ic)
297 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
298 AOP_SIZE(IC_LEFT(ic)) == 3 &&
299 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
300 aopPut(AOP(IC_RESULT(ic)),
301 aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
304 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
305 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
306 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
307 aopPut(AOP(IC_RESULT(ic)),
308 aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
311 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
312 AOP_SIZE(IC_LEFT(ic)) < 3 &&
313 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
314 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
315 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
317 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
318 aopPut(AOP(IC_RESULT(ic)),buffer,2);
322 /* This is the pure and virtuous version of this code.
323 * I'm pretty certain it's right, but not enough to toss the old
326 static void adjustArithmeticResult(iCode *ic)
328 if (opIsGptr(IC_RESULT(ic)) &&
329 opIsGptr(IC_LEFT(ic)) &&
330 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
332 aopPut(AOP(IC_RESULT(ic)),
333 aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
337 if (opIsGptr(IC_RESULT(ic)) &&
338 opIsGptr(IC_RIGHT(ic)) &&
339 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
341 aopPut(AOP(IC_RESULT(ic)),
342 aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
346 if (opIsGptr(IC_RESULT(ic)) &&
347 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
348 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
349 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
350 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
352 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
353 aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
358 /*-----------------------------------------------------------------*/
359 /* genAddlit - generates code for addition */
360 /*-----------------------------------------------------------------*/
361 static void genAddLit2byte (operand *result, int offr, int lit)
368 emitpcode(POC_INCF, popGet(AOP(result),offr,FALSE,FALSE));
371 emitpcode(POC_DECF, popGet(AOP(result),offr,FALSE,FALSE));
374 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
375 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
380 static void genAddLit (operand *result,operand *left, int lit)
386 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
387 size = pic14_getDataSize(result);
389 same = ((left == result) || (AOP(left) == AOP(result)));
393 /* Handle special cases first */
395 genAddLit2byte (result, 0, lit);
398 int hi = 0xff & (lit >> 8);
405 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
410 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
412 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
415 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
416 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
417 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
421 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
422 emitpcode(POC_ADDWF,popGet(AOP(result),0,FALSE,FALSE));
424 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
432 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
435 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
438 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
439 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
441 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
443 case 0xff: /* 0x01ff */
444 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
445 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
446 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
447 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
452 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
456 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
459 emitpcode(POC_INCFSZ, popGet(AOP(result),0,FALSE,FALSE));
460 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
462 /* case 0xff: * 0xffff *
463 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
464 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
465 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
469 emitpcode(POC_MOVLW,popGetLit(lo));
470 emitpcode(POC_ADDWF,popGet(AOP(result),0,FALSE,FALSE));
472 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
479 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
484 genAddLit2byte (result, MSB16, hi);
487 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
488 emitpcode(POC_INCFSZ, popGet(AOP(result),0,FALSE,FALSE));
489 emitpcode(POC_MOVLW,popGetLit(hi));
490 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
492 /* case 0xff: * 0xHHff *
493 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
494 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
495 emitpcode(POC_MOVLW,popGetLit(hi));
496 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
498 */ default: /* 0xHHLL */
499 emitpcode(POC_MOVLW,popGetLit(lo));
500 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
501 emitpcode(POC_MOVLW,popGetLit(hi));
503 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
504 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
513 DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
516 lo = BYTEofLONG(lit,0);
524 emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE));
527 emitpcode(POC_RLFW, popGet(AOP(result),offset,FALSE,FALSE));
528 emitpcode(POC_ANDLW,popGetLit(1));
529 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
531 default: /* carry_info = 3 */
533 emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE));
539 emitpcode(POC_MOVLW,popGetLit(lo));
544 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
547 emitpcode(POC_MOVLW,popGetLit(lo));
552 emitpcode(POC_MOVLW,popGetLit(lo+1));
553 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
558 /* no carry info from previous step */
559 /* this means this is the first time to add */
564 emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE));
568 emitpcode(POC_MOVLW,popGetLit(lo));
569 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
571 carry_info = 3; /* Were adding only one byte and propogating the carry */
582 lo = BYTEofLONG(lit,0);
587 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
590 emitpcode(POC_MOVLW,popGetLit(lo));
591 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
594 emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
596 emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
598 emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
608 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
614 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
615 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
618 emitpcode(POC_INCFW, popGet(AOP(left),0,FALSE,FALSE));
619 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
622 emitpcode(POC_DECFW, popGet(AOP(left),0,FALSE,FALSE));
623 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
626 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
627 emitpcode(POC_ADDFW, popGet(AOP(left),0,FALSE,FALSE));
628 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
635 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
636 emitpcode(POC_ADDFW, popGet(AOP(left),0,FALSE,FALSE));
638 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
640 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
645 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
646 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
647 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
649 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
650 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
652 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
653 emitpcode(POC_RLF, popGet(AOP(result),offset,FALSE,FALSE));
654 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
655 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
663 /*-----------------------------------------------------------------*/
664 /* genPlus - generates code for addition */
665 /*-----------------------------------------------------------------*/
666 void genPlus (iCode *ic)
668 int size, offset = 0;
670 /* special cases :- */
671 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
673 aopOp (IC_LEFT(ic),ic,FALSE);
674 aopOp (IC_RIGHT(ic),ic,FALSE);
675 aopOp (IC_RESULT(ic),ic,TRUE);
677 /* if literal, literal on the right or
678 if left requires ACC or right is already
681 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
682 operand *t = IC_RIGHT(ic);
683 IC_RIGHT(ic) = IC_LEFT(ic);
687 /* if both left & right are in bit space */
688 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
689 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
694 /* if left in bit space & right literal */
695 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
696 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
697 /* if result in bit space */
698 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
699 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
700 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
701 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
702 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
703 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
706 size = pic14_getDataSize(IC_RESULT(ic));
708 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
709 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
710 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
716 /* if I can do an increment instead
717 of add then GOOD for ME */
718 if (genPlusIncr (ic) == TRUE)
721 size = pic14_getDataSize(IC_RESULT(ic));
723 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
724 /* Add a literal to something else */
726 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
730 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
732 genAddLit ( IC_RESULT(ic),IC_LEFT(ic), lit);
736 DEBUGpic14_emitcode(";","size %d",size);
738 switch (lit & 0xff) {
742 if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))))
743 emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
746 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
747 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
748 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
752 if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))))
753 emitpcode(POC_DECF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
756 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
757 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
758 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
762 if( !know_W || ( (lit&0xff) != l1) ) {
764 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
766 if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
767 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
770 emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset+1,FALSE,FALSE));
775 emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
776 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
779 emitpcode(POC_INCFW, popGet(AOP(IC_RESULT(ic)),offset+1,FALSE,FALSE));
790 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
792 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
793 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
794 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
796 /* here we are adding a bit to a char or int */
798 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
800 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
801 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
803 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
804 AOP(IC_RIGHT(ic))->aopu.aop_dir,
805 AOP(IC_RIGHT(ic))->aopu.aop_dir);
806 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
809 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
810 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
811 emitpcode(POC_XORLW , popGetLit(1));
813 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
814 AOP(IC_RIGHT(ic))->aopu.aop_dir,
815 AOP(IC_RIGHT(ic))->aopu.aop_dir);
816 pic14_emitcode(" xorlw","1");
818 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
819 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
820 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
822 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
823 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
824 AOP(IC_RIGHT(ic))->aopu.aop_dir,
825 AOP(IC_RIGHT(ic))->aopu.aop_dir);
826 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
829 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
831 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
832 emitpcode(POC_ANDLW , popGetLit(1));
833 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
835 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
837 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
838 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
846 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
848 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
849 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
851 pic14_emitcode("clrz","");
853 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
854 AOP(IC_RIGHT(ic))->aopu.aop_dir,
855 AOP(IC_RIGHT(ic))->aopu.aop_dir);
856 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
860 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
861 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
862 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
863 emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
866 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
867 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
868 AOP(IC_RIGHT(ic))->aopu.aop_dir,
869 AOP(IC_RIGHT(ic))->aopu.aop_dir);
870 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
871 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
877 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
878 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
885 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
886 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
887 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
890 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
891 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
892 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
893 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
896 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
898 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
899 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
901 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
902 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
903 emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
905 emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
906 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
907 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
917 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
918 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
919 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
921 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
922 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
925 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
927 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
928 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
931 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
933 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
934 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
942 //adjustArithmeticResult(ic);
945 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
946 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
947 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
950 /*-----------------------------------------------------------------*/
951 /* genMinusDec :- does subtraction with decrement if possible */
952 /*-----------------------------------------------------------------*/
953 bool genMinusDec (iCode *ic)
955 unsigned int icount ;
956 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
958 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
959 /* will try to generate an increment */
960 /* if the right side is not a literal
962 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
963 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
964 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
967 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
969 /* if the literal value of the right hand side
970 is greater than 4 then it is not worth it */
971 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
974 /* if decrement 16 bits in register */
975 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
980 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
981 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
982 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
983 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
985 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
986 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
987 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
990 emitpcode(POC_MOVLW, popGetLit(0xff));
991 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
993 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
995 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
997 pic14_emitcode("movlw","0xff");
998 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1001 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1003 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1007 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1009 pic14_emitcode("skpnc","");
1011 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1020 /* if the sizes are greater than 1 then we cannot */
1021 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1022 AOP_SIZE(IC_LEFT(ic)) > 1 )
1025 /* we can if the aops of the left & result match or
1026 if they are in registers and the registers are the
1028 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1031 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1033 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1038 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1039 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1040 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1043 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1044 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1046 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1047 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1055 /*-----------------------------------------------------------------*/
1056 /* addSign - complete with sign */
1057 /*-----------------------------------------------------------------*/
1058 void addSign(operand *result, int offset, int sign)
1060 int size = (pic14_getDataSize(result) - offset);
1061 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1064 pic14_emitcode("rlc","a");
1065 pic14_emitcode("subb","a,acc");
1067 aopPut(AOP(result),"a",offset++);
1070 aopPut(AOP(result),"#0",offset++);
1074 /*-----------------------------------------------------------------*/
1075 /* genMinusBits - generates code for subtraction of two bits */
1076 /*-----------------------------------------------------------------*/
1077 void genMinusBits (iCode *ic)
1079 symbol *lbl = newiTempLabel(NULL);
1080 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1081 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1082 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1083 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1084 pic14_emitcode("cpl","c");
1085 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1086 pic14_outBitC(IC_RESULT(ic));
1089 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1090 pic14_emitcode("subb","a,acc");
1091 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1092 pic14_emitcode("inc","a");
1093 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1094 aopPut(AOP(IC_RESULT(ic)),"a",0);
1095 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1099 /*-----------------------------------------------------------------*/
1100 /* genMinus - generates code for subtraction */
1101 /*-----------------------------------------------------------------*/
1102 void genMinus (iCode *ic)
1104 int size, offset = 0,same;
1105 unsigned long lit = 0L;
1107 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1108 aopOp (IC_LEFT(ic),ic,FALSE);
1109 aopOp (IC_RIGHT(ic),ic,FALSE);
1110 aopOp (IC_RESULT(ic),ic,TRUE);
1112 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1113 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1114 operand *t = IC_RIGHT(ic);
1115 IC_RIGHT(ic) = IC_LEFT(ic);
1119 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1120 AopType(AOP_TYPE(IC_RESULT(ic))),
1121 AopType(AOP_TYPE(IC_LEFT(ic))),
1122 AopType(AOP_TYPE(IC_RIGHT(ic))));
1124 /* special cases :- */
1125 /* if both left & right are in bit space */
1126 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1127 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1132 /* if I can do an decrement instead
1133 of subtract then GOOD for ME */
1134 // if (genMinusDec (ic) == TRUE)
1137 size = pic14_getDataSize(IC_RESULT(ic));
1138 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1140 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1141 /* Add a literal to something else */
1143 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1146 genAddLit ( IC_RESULT(ic),IC_LEFT(ic), lit);
1149 /* add the first byte: */
1150 pic14_emitcode("movlw","0x%x", lit & 0xff);
1151 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1152 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1153 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1165 if((lit & 0xff) == 0xff) {
1166 emitpcode(POC_MOVLW, popGetLit(0xff));
1168 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1170 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1172 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1173 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1177 /* do the rlf known zero trick here */
1178 emitpcode(POC_MOVLW, popGetLit(1));
1180 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1185 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1188 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1189 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1190 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1192 /* here we are subtracting a bit from a char or int */
1194 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1196 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1197 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1199 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1200 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1201 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1202 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1205 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1206 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1207 emitpcode(POC_XORLW , popGetLit(1));
1208 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1209 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1211 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1213 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1214 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1216 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1217 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1220 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1222 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1224 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1225 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1229 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1230 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1231 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1232 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1237 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1238 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1239 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1242 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1244 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1247 emitpcode(POC_ANDLW , popGetLit(1));
1249 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1251 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1258 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1259 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1260 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1262 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1263 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1264 AopType(AOP_TYPE(IC_RESULT(ic))),
1265 AopType(AOP_TYPE(IC_LEFT(ic))),
1266 AopType(AOP_TYPE(IC_RIGHT(ic))));
1269 if( (size == 1) && ((lit & 0xff) == 0) ) {
1270 /* res = 0 - right */
1271 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1272 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1274 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1275 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1280 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1281 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1282 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1290 /* This is the last byte in a multibyte subtraction
1291 * There are a couple of tricks we can do by not worrying about
1292 * propogating the carry */
1294 /* 0xff - x == ~x */
1296 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1298 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1300 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1301 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1303 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1306 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1308 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1309 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1310 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1319 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1321 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1322 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1325 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1331 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1332 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1334 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1336 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1338 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1339 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1346 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1347 AopType(AOP_TYPE(IC_RESULT(ic))),
1348 AopType(AOP_TYPE(IC_LEFT(ic))),
1349 AopType(AOP_TYPE(IC_RIGHT(ic))));
1351 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1352 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1353 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1354 emitpcode(POC_SUBLW, popGetLit(0));
1355 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1358 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1359 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1360 emitpcode(POC_SUBLW, popGetLit(0));
1361 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1362 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1365 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1366 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1367 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1369 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1370 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1372 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1373 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1374 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1376 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1378 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1379 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1380 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1382 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1384 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1391 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1393 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1394 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1396 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1397 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1404 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1405 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1406 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1408 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1410 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1411 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1419 // adjustArithmeticResult(ic);
1422 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1423 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1424 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);