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 (iCode *ic, int lit)
389 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
393 result = IC_RESULT(ic);
394 same = pic14_sameRegs(AOP(left), AOP(result));
395 size = pic14_getDataSize(result);
399 /* Handle special cases first */
401 genAddLit2byte (result, 0, lit);
404 int hi = 0xff & (lit >> 8);
411 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
416 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
418 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
421 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
422 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
423 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
427 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
428 emitpcode(POC_ADDWF,popGet(AOP(result),0,FALSE,FALSE));
430 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
438 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
441 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
444 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
445 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
447 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
449 case 0xff: /* 0x01ff */
450 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
451 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
452 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
453 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
458 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
462 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
465 emitpcode(POC_INCFSZ, popGet(AOP(result),0,FALSE,FALSE));
466 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
468 /* case 0xff: * 0xffff *
469 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
470 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
471 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
475 emitpcode(POC_MOVLW,popGetLit(lo));
476 emitpcode(POC_ADDWF,popGet(AOP(result),0,FALSE,FALSE));
478 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
485 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
490 genAddLit2byte (result, MSB16, hi);
493 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
494 emitpcode(POC_INCFSZ, popGet(AOP(result),0,FALSE,FALSE));
495 emitpcode(POC_MOVLW,popGetLit(hi));
496 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
498 /* case 0xff: * 0xHHff *
499 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
500 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
501 emitpcode(POC_MOVLW,popGetLit(hi));
502 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
504 */ default: /* 0xHHLL */
505 emitpcode(POC_MOVLW,popGetLit(lo));
506 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
507 emitpcode(POC_MOVLW,popGetLit(hi));
509 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
510 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
519 DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
522 lo = BYTEofLONG(lit,0);
530 emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE));
533 emitpcode(POC_RLFW, popGet(AOP(result),offset,FALSE,FALSE));
534 emitpcode(POC_ANDLW,popGetLit(1));
535 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
537 default: /* carry_info = 3 */
539 emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE));
545 emitpcode(POC_MOVLW,popGetLit(lo));
550 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
553 emitpcode(POC_MOVLW,popGetLit(lo));
558 emitpcode(POC_MOVLW,popGetLit(lo+1));
559 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
564 /* no carry info from previous step */
565 /* this means this is the first time to add */
570 emitpcode(POC_INCF, popGet(AOP(result),offset,FALSE,FALSE));
574 emitpcode(POC_MOVLW,popGetLit(lo));
575 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
577 carry_info = 3; /* Were adding only one byte and propogating the carry */
588 lo = BYTEofLONG(lit,0);
593 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
596 emitpcode(POC_MOVLW,popGetLit(lo));
597 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
600 emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
602 emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
604 emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
614 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
618 if(AOP_TYPE(left) == AOP_ACC) {
619 /* left addend is already in accumulator */
622 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
625 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
626 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
629 /* left addend is in a register */
632 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
633 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
636 emitpcode(POC_INCFW, popGet(AOP(left),0,FALSE,FALSE));
637 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
640 emitpcode(POC_DECFW, popGet(AOP(left),0,FALSE,FALSE));
641 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
644 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
645 emitpcode(POC_ADDFW, popGet(AOP(left),0,FALSE,FALSE));
646 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
653 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
654 emitpcode(POC_ADDFW, popGet(AOP(left),0,FALSE,FALSE));
656 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
658 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
663 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
664 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
665 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
667 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
668 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
670 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
671 emitpcode(POC_RLF, popGet(AOP(result),offset,FALSE,FALSE));
672 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
673 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
681 /*-----------------------------------------------------------------*/
682 /* genPlus - generates code for addition */
683 /*-----------------------------------------------------------------*/
684 void genPlus (iCode *ic)
686 int size, offset = 0;
688 /* special cases :- */
689 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
691 aopOp (IC_LEFT(ic),ic,FALSE);
692 aopOp (IC_RIGHT(ic),ic,FALSE);
693 aopOp (IC_RESULT(ic),ic,TRUE);
695 /* if literal, literal on the right or
696 if left requires ACC or right is already
699 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
700 operand *t = IC_RIGHT(ic);
701 IC_RIGHT(ic) = IC_LEFT(ic);
705 /* if both left & right are in bit space */
706 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
707 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
712 /* if left in bit space & right literal */
713 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
714 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
715 /* if result in bit space */
716 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
717 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
718 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
719 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
720 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
721 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
724 size = pic14_getDataSize(IC_RESULT(ic));
726 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
727 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
728 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
734 /* if I can do an increment instead
735 of add then GOOD for ME */
736 if (genPlusIncr (ic) == TRUE)
739 size = pic14_getDataSize(IC_RESULT(ic));
741 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
742 /* Add a literal to something else */
744 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
748 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
754 DEBUGpic14_emitcode(";","size %d",size);
756 switch (lit & 0xff) {
760 if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))))
761 emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
764 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
765 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
766 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
770 if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))))
771 emitpcode(POC_DECF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
774 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
775 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
776 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
780 if( !know_W || ( (lit&0xff) != l1) ) {
782 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
784 if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
785 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
788 emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset+1,FALSE,FALSE));
793 emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
794 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
797 emitpcode(POC_INCFW, popGet(AOP(IC_RESULT(ic)),offset+1,FALSE,FALSE));
808 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
810 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
811 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
812 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
814 /* here we are adding a bit to a char or int */
816 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
818 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
819 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
821 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
822 AOP(IC_RIGHT(ic))->aopu.aop_dir,
823 AOP(IC_RIGHT(ic))->aopu.aop_dir);
824 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
827 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
828 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
829 emitpcode(POC_XORLW , popGetLit(1));
831 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
832 AOP(IC_RIGHT(ic))->aopu.aop_dir,
833 AOP(IC_RIGHT(ic))->aopu.aop_dir);
834 pic14_emitcode(" xorlw","1");
836 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
837 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
838 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
840 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
841 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
842 AOP(IC_RIGHT(ic))->aopu.aop_dir,
843 AOP(IC_RIGHT(ic))->aopu.aop_dir);
844 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
847 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
849 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
850 emitpcode(POC_ANDLW , popGetLit(1));
851 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
853 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
855 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
856 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
864 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
866 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
867 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
869 pic14_emitcode("clrz","");
871 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
872 AOP(IC_RIGHT(ic))->aopu.aop_dir,
873 AOP(IC_RIGHT(ic))->aopu.aop_dir);
874 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
878 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
879 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
880 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
881 emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
884 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
885 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
886 AOP(IC_RIGHT(ic))->aopu.aop_dir,
887 AOP(IC_RIGHT(ic))->aopu.aop_dir);
888 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
889 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
895 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
896 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
903 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
904 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
905 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
908 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
909 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
910 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
911 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
914 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
916 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
917 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
919 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
920 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
921 emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
923 emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
924 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
925 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
935 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
936 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
937 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
939 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
940 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
943 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
945 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
946 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
949 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
951 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
952 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
960 //adjustArithmeticResult(ic);
963 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
964 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
965 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
968 /*-----------------------------------------------------------------*/
969 /* genMinusDec :- does subtraction with decrement if possible */
970 /*-----------------------------------------------------------------*/
971 bool genMinusDec (iCode *ic)
973 unsigned int icount ;
974 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
976 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
977 /* will try to generate an increment */
978 /* if the right side is not a literal
980 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
981 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
982 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
985 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
987 /* if the literal value of the right hand side
988 is greater than 4 then it is not worth it */
989 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
992 /* if decrement 16 bits in register */
993 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
998 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
999 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1000 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1001 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1003 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1004 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1005 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1007 /* size is 3 or 4 */
1008 emitpcode(POC_MOVLW, popGetLit(0xff));
1009 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1011 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1013 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1015 pic14_emitcode("movlw","0xff");
1016 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1019 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1021 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1025 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1027 pic14_emitcode("skpnc","");
1029 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1038 /* if the sizes are greater than 1 then we cannot */
1039 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1040 AOP_SIZE(IC_LEFT(ic)) > 1 )
1043 /* we can if the aops of the left & result match or
1044 if they are in registers and the registers are the
1046 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1049 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1051 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1056 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1057 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1058 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1061 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1062 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1064 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1065 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1073 /*-----------------------------------------------------------------*/
1074 /* addSign - complete with sign */
1075 /*-----------------------------------------------------------------*/
1076 void addSign(operand *result, int offset, int sign)
1078 int size = (pic14_getDataSize(result) - offset);
1079 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1082 pic14_emitcode("rlc","a");
1083 pic14_emitcode("subb","a,acc");
1085 aopPut(AOP(result),"a",offset++);
1088 aopPut(AOP(result),"#0",offset++);
1092 /*-----------------------------------------------------------------*/
1093 /* genMinusBits - generates code for subtraction of two bits */
1094 /*-----------------------------------------------------------------*/
1095 void genMinusBits (iCode *ic)
1097 symbol *lbl = newiTempLabel(NULL);
1098 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1099 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1100 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1101 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1102 pic14_emitcode("cpl","c");
1103 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1104 pic14_outBitC(IC_RESULT(ic));
1107 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1108 pic14_emitcode("subb","a,acc");
1109 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1110 pic14_emitcode("inc","a");
1111 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1112 aopPut(AOP(IC_RESULT(ic)),"a",0);
1113 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1117 /*-----------------------------------------------------------------*/
1118 /* genMinus - generates code for subtraction */
1119 /*-----------------------------------------------------------------*/
1120 void genMinus (iCode *ic)
1122 int size, offset = 0,same;
1123 unsigned long lit = 0L;
1125 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1126 aopOp (IC_LEFT(ic),ic,FALSE);
1127 aopOp (IC_RIGHT(ic),ic,FALSE);
1128 aopOp (IC_RESULT(ic),ic,TRUE);
1130 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1131 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1132 operand *t = IC_RIGHT(ic);
1133 IC_RIGHT(ic) = IC_LEFT(ic);
1137 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1138 AopType(AOP_TYPE(IC_RESULT(ic))),
1139 AopType(AOP_TYPE(IC_LEFT(ic))),
1140 AopType(AOP_TYPE(IC_RIGHT(ic))));
1142 DEBUGpic14_emitcode ("; ","same = %d, result-%s left-%s",same,
1143 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1144 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1146 /* special cases :- */
1147 /* if both left & right are in bit space */
1148 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1149 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1154 /* if I can do an decrement instead
1155 of subtract then GOOD for ME */
1156 // if (genMinusDec (ic) == TRUE)
1159 size = pic14_getDataSize(IC_RESULT(ic));
1160 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1162 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1163 /* Add a literal to something else */
1165 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1168 genAddLit ( ic, lit);
1171 /* add the first byte: */
1172 pic14_emitcode("movlw","0x%x", lit & 0xff);
1173 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1174 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1175 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1187 if((lit & 0xff) == 0xff) {
1188 emitpcode(POC_MOVLW, popGetLit(0xff));
1190 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1192 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1194 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1195 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1199 /* do the rlf known zero trick here */
1200 emitpcode(POC_MOVLW, popGetLit(1));
1202 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1207 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1210 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1211 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1212 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1214 /* here we are subtracting a bit from a char or int */
1216 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1218 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1219 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1221 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1222 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1223 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1224 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1227 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1228 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1229 emitpcode(POC_XORLW , popGetLit(1));
1230 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1231 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1233 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1235 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1236 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1238 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1239 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1242 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1244 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1246 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1247 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1251 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1252 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1253 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1254 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1259 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1260 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1261 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1264 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1266 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1269 emitpcode(POC_ANDLW , popGetLit(1));
1271 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1273 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1280 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1281 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1282 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1284 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1285 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1286 AopType(AOP_TYPE(IC_RESULT(ic))),
1287 AopType(AOP_TYPE(IC_LEFT(ic))),
1288 AopType(AOP_TYPE(IC_RIGHT(ic))));
1291 if( (size == 1) && ((lit & 0xff) == 0) ) {
1292 /* res = 0 - right */
1293 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1294 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1296 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1297 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1302 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1303 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1304 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1312 /* This is the last byte in a multibyte subtraction
1313 * There are a couple of tricks we can do by not worrying about
1314 * propogating the carry */
1316 /* 0xff - x == ~x */
1318 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1320 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1322 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1323 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1325 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1328 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1330 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1331 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1332 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1341 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1343 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1344 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1347 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1353 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1354 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1356 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1358 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1360 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1361 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1368 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1369 AopType(AOP_TYPE(IC_RESULT(ic))),
1370 AopType(AOP_TYPE(IC_LEFT(ic))),
1371 AopType(AOP_TYPE(IC_RIGHT(ic))));
1373 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1374 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1375 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1376 emitpcode(POC_SUBLW, popGetLit(0));
1377 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1380 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1381 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1382 emitpcode(POC_SUBLW, popGetLit(0));
1383 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1384 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1387 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1388 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1389 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1391 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1392 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1394 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1395 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1396 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1398 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1400 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1401 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1402 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1404 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1406 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1413 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1415 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1416 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1418 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1419 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1426 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1427 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1428 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1430 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1432 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1433 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1441 // adjustArithmeticResult(ic);
1444 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1445 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1446 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);