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"
66 const char *AopType(short type)
109 /*-----------------------------------------------------------------*/
110 /* genPlusIncr :- does addition with increment if possible */
111 /*-----------------------------------------------------------------*/
112 bool genPlusIncr (iCode *ic)
114 unsigned int icount ;
115 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
117 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
118 DEBUGpic14_emitcode ("; ","result %d, left %d, right %d",
119 AOP_TYPE(IC_RESULT(ic)),
120 AOP_TYPE(IC_LEFT(ic)),
121 AOP_TYPE(IC_RIGHT(ic)));
123 /* will try to generate an increment */
124 /* if the right side is not a literal
126 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
129 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
130 /* if the literal value of the right hand side
131 is greater than 1 then it is faster to add */
132 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
135 /* if increment 16 bits in register */
136 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
141 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
142 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
146 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
147 //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
153 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
154 /* if left is in accumulator - probably a bit operation*/
155 if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
156 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
158 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
159 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
160 AOP(IC_RESULT(ic))->aopu.aop_dir,
161 AOP(IC_RESULT(ic))->aopu.aop_dir);
163 emitpcode(POC_XORLW,popGetLit(1));
164 //pic14_emitcode("xorlw","1");
166 emitpcode(POC_ANDLW,popGetLit(1));
167 //pic14_emitcode("andlw","1");
170 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
171 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
172 AOP(IC_RESULT(ic))->aopu.aop_dir,
173 AOP(IC_RESULT(ic))->aopu.aop_dir);
180 /* if the sizes are greater than 1 then we cannot */
181 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
182 AOP_SIZE(IC_LEFT(ic)) > 1 )
185 /* If we are incrementing the same register by two: */
187 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
190 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
191 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
196 DEBUGpic14_emitcode ("; ","couldn't increment result-%s left-%s",
197 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
198 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
202 /*-----------------------------------------------------------------*/
203 /* pic14_outBitAcc - output a bit in acc */
204 /*-----------------------------------------------------------------*/
205 void pic14_outBitAcc(operand *result)
207 symbol *tlbl = newiTempLabel(NULL);
208 /* if the result is a bit */
209 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
211 if (AOP_TYPE(result) == AOP_CRY){
212 aopPut(AOP(result),"a",0);
215 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
216 pic14_emitcode("mov","a,#01");
217 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
218 pic14_outAcc(result);
222 /*-----------------------------------------------------------------*/
223 /* genPlusBits - generates code for addition of two bits */
224 /*-----------------------------------------------------------------*/
225 void genPlusBits (iCode *ic)
228 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
230 The following block of code will add two bits.
231 Note that it'll even work if the destination is
232 the carry (C in the status register).
233 It won't work if the 'Z' bit is a source or destination.
236 /* If the result is stored in the accumulator (w) */
237 //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
238 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
239 //emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
240 // popGet(AOP(result),0,FALSE,FALSE));
242 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
243 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
244 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
245 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
246 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
247 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
249 pic14_emitcode("movlw","(1 << (%s & 7))",
250 AOP(IC_RESULT(ic))->aopu.aop_dir,
251 AOP(IC_RESULT(ic))->aopu.aop_dir);
252 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
253 AOP(IC_RESULT(ic))->aopu.aop_dir,
254 AOP(IC_RESULT(ic))->aopu.aop_dir);
255 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
256 AOP(IC_RIGHT(ic))->aopu.aop_dir,
257 AOP(IC_RIGHT(ic))->aopu.aop_dir);
258 pic14_emitcode("xorwf","(%s >>3),f",
259 AOP(IC_RESULT(ic))->aopu.aop_dir);
260 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
261 AOP(IC_LEFT(ic))->aopu.aop_dir,
262 AOP(IC_LEFT(ic))->aopu.aop_dir);
263 pic14_emitcode("xorwf","(%s>>3),f",
264 AOP(IC_RESULT(ic))->aopu.aop_dir);
267 emitpcode(POC_CLRW, NULL);
268 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
269 emitpcode(POC_XORLW, popGetLit(1));
270 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
271 emitpcode(POC_XORLW, popGetLit(1));
273 pic14_emitcode("clrw","");
274 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
275 AOP(IC_RIGHT(ic))->aopu.aop_dir,
276 AOP(IC_RIGHT(ic))->aopu.aop_dir);
277 pic14_emitcode("xorlw","1");
278 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
279 AOP(IC_LEFT(ic))->aopu.aop_dir,
280 AOP(IC_LEFT(ic))->aopu.aop_dir);
281 pic14_emitcode("xorlw","1");
287 /* This is the original version of this code.
289 * This is being kept around for reference,
290 * because I am not entirely sure I got it right...
292 static void adjustArithmeticResult(iCode *ic)
294 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
295 AOP_SIZE(IC_LEFT(ic)) == 3 &&
296 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
297 aopPut(AOP(IC_RESULT(ic)),
298 aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
301 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
302 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
303 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
304 aopPut(AOP(IC_RESULT(ic)),
305 aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
308 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
309 AOP_SIZE(IC_LEFT(ic)) < 3 &&
310 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
311 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
312 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
314 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
315 aopPut(AOP(IC_RESULT(ic)),buffer,2);
319 /* This is the pure and virtuous version of this code.
320 * I'm pretty certain it's right, but not enough to toss the old
323 static void adjustArithmeticResult(iCode *ic)
325 if (opIsGptr(IC_RESULT(ic)) &&
326 opIsGptr(IC_LEFT(ic)) &&
327 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
329 aopPut(AOP(IC_RESULT(ic)),
330 aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
334 if (opIsGptr(IC_RESULT(ic)) &&
335 opIsGptr(IC_RIGHT(ic)) &&
336 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
338 aopPut(AOP(IC_RESULT(ic)),
339 aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
343 if (opIsGptr(IC_RESULT(ic)) &&
344 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
345 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
346 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
347 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
349 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
350 aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
355 /*-----------------------------------------------------------------*/
356 /* genAddlit - generates code for addition */
357 /*-----------------------------------------------------------------*/
358 static void genAddLit2byte (operand *result, int offr, int lit)
365 emitpcode(POC_INCF, popGet(AOP(result),offr,FALSE,FALSE));
368 emitpcode(POC_DECF, popGet(AOP(result),offr,FALSE,FALSE));
371 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
372 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
377 static void genAddLit (operand *result,operand *left, int lit)
382 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
383 size = pic14_getDataSize(result);
385 same = ((left == result) || (AOP(left) == AOP(result)));
389 /* Handle special cases first */
391 genAddLit2byte (result, 0, lit);
394 int hi = 0xff & (lit >> 8);
401 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
406 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
408 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
411 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
412 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
413 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
417 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
418 emitpcode(POC_ADDWF,popGet(AOP(result),0,FALSE,FALSE));
420 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
428 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
431 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
434 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
435 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
437 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
439 case 0xff: /* 0x01ff */
440 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
441 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
442 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
443 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
448 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
452 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
455 emitpcode(POC_INCFSZ, popGet(AOP(result),0,FALSE,FALSE));
456 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
458 /* case 0xff: * 0xffff *
459 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
460 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
461 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
465 emitpcode(POC_MOVLW,popGetLit(lo));
466 emitpcode(POC_ADDWF,popGet(AOP(result),0,FALSE,FALSE));
468 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
475 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
480 genAddLit2byte (result, MSB16, hi);
483 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
484 emitpcode(POC_INCFSZ, popGet(AOP(result),0,FALSE,FALSE));
485 emitpcode(POC_MOVLW,popGetLit(hi));
486 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
488 /* case 0xff: * 0xHHff *
489 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
490 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
491 emitpcode(POC_MOVLW,popGetLit(hi));
492 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
494 */ default: /* 0xHHLL */
495 emitpcode(POC_MOVLW,popGetLit(lo));
496 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
497 emitpcode(POC_MOVLW,popGetLit(hi));
499 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
500 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
508 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
514 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
515 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
518 emitpcode(POC_INCFW, popGet(AOP(left),0,FALSE,FALSE));
519 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
522 emitpcode(POC_DECFW, popGet(AOP(left),0,FALSE,FALSE));
523 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
526 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
527 emitpcode(POC_ADDFW, popGet(AOP(left),0,FALSE,FALSE));
528 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
533 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
534 emitpcode(POC_ADDFW, popGet(AOP(left),0,FALSE,FALSE));
536 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
538 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
543 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
544 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
545 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
547 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
548 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
550 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
551 emitpcode(POC_RLF, popGet(AOP(result),offset,FALSE,FALSE));
552 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
553 emitpcode(POC_ADDWF, popGet(AOP(result),offset,FALSE,FALSE));
561 /*-----------------------------------------------------------------*/
562 /* genPlus - generates code for addition */
563 /*-----------------------------------------------------------------*/
564 void genPlus (iCode *ic)
566 int size, offset = 0;
568 /* special cases :- */
569 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
571 aopOp (IC_LEFT(ic),ic,FALSE);
572 aopOp (IC_RIGHT(ic),ic,FALSE);
573 aopOp (IC_RESULT(ic),ic,TRUE);
575 /* if literal, literal on the right or
576 if left requires ACC or right is already
579 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
580 operand *t = IC_RIGHT(ic);
581 IC_RIGHT(ic) = IC_LEFT(ic);
585 /* if both left & right are in bit space */
586 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
587 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
592 /* if left in bit space & right literal */
593 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
594 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
595 /* if result in bit space */
596 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
597 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
598 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
599 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
600 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
601 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
604 size = pic14_getDataSize(IC_RESULT(ic));
606 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
607 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
608 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
614 /* if I can do an increment instead
615 of add then GOOD for ME */
616 if (genPlusIncr (ic) == TRUE)
619 size = pic14_getDataSize(IC_RESULT(ic));
621 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
622 /* Add a literal to something else */
624 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
628 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
630 genAddLit ( IC_RESULT(ic),IC_LEFT(ic), lit);
634 DEBUGpic14_emitcode(";","size %d",size);
636 switch (lit & 0xff) {
640 if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))))
641 emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
644 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
645 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
646 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
650 if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))))
651 emitpcode(POC_DECF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
654 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
655 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
656 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
660 if( !know_W || ( (lit&0xff) != l1) ) {
662 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
664 if(pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
665 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
668 emitpcode(POC_INCF, popGet(AOP(IC_LEFT(ic)),offset+1,FALSE,FALSE));
673 emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
674 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
677 emitpcode(POC_INCFW, popGet(AOP(IC_RESULT(ic)),offset+1,FALSE,FALSE));
688 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
690 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
691 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
692 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
694 /* here we are adding a bit to a char or int */
696 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
698 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
699 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
701 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
702 AOP(IC_RIGHT(ic))->aopu.aop_dir,
703 AOP(IC_RIGHT(ic))->aopu.aop_dir);
704 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
707 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
708 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
709 emitpcode(POC_XORLW , popGetLit(1));
711 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
712 AOP(IC_RIGHT(ic))->aopu.aop_dir,
713 AOP(IC_RIGHT(ic))->aopu.aop_dir);
714 pic14_emitcode(" xorlw","1");
716 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
717 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
718 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
720 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
721 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
722 AOP(IC_RIGHT(ic))->aopu.aop_dir,
723 AOP(IC_RIGHT(ic))->aopu.aop_dir);
724 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
727 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
729 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
730 emitpcode(POC_ANDLW , popGetLit(1));
731 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
733 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
735 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
736 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
744 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
746 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
747 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
749 pic14_emitcode("clrz","");
751 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
752 AOP(IC_RIGHT(ic))->aopu.aop_dir,
753 AOP(IC_RIGHT(ic))->aopu.aop_dir);
754 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
758 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
759 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
760 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
761 emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
764 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
765 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
766 AOP(IC_RIGHT(ic))->aopu.aop_dir,
767 AOP(IC_RIGHT(ic))->aopu.aop_dir);
768 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
769 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
775 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
776 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
783 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
784 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
785 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
788 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
789 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
790 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
791 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
794 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
796 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
797 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
799 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
800 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
801 emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
803 emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
804 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
805 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
815 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
816 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
817 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
819 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
820 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
823 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
825 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
826 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
829 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
831 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
832 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
840 //adjustArithmeticResult(ic);
843 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
844 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
845 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
848 /*-----------------------------------------------------------------*/
849 /* genMinusDec :- does subtraction with decrement if possible */
850 /*-----------------------------------------------------------------*/
851 bool genMinusDec (iCode *ic)
853 unsigned int icount ;
854 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
856 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
857 /* will try to generate an increment */
858 /* if the right side is not a literal
860 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
861 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
862 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
865 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
867 /* if the literal value of the right hand side
868 is greater than 4 then it is not worth it */
869 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
872 /* if decrement 16 bits in register */
873 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
878 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
879 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
880 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
881 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
883 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
884 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
885 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
888 emitpcode(POC_MOVLW, popGetLit(0xff));
889 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
891 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
893 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
895 pic14_emitcode("movlw","0xff");
896 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
899 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
901 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
905 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
907 pic14_emitcode("skpnc","");
909 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
918 /* if the sizes are greater than 1 then we cannot */
919 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
920 AOP_SIZE(IC_LEFT(ic)) > 1 )
923 /* we can if the aops of the left & result match or
924 if they are in registers and the registers are the
926 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
929 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
931 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
936 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
937 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
938 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
941 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
942 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
944 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
945 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
953 /*-----------------------------------------------------------------*/
954 /* addSign - complete with sign */
955 /*-----------------------------------------------------------------*/
956 void addSign(operand *result, int offset, int sign)
958 int size = (pic14_getDataSize(result) - offset);
959 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
962 pic14_emitcode("rlc","a");
963 pic14_emitcode("subb","a,acc");
965 aopPut(AOP(result),"a",offset++);
968 aopPut(AOP(result),"#0",offset++);
972 /*-----------------------------------------------------------------*/
973 /* genMinusBits - generates code for subtraction of two bits */
974 /*-----------------------------------------------------------------*/
975 void genMinusBits (iCode *ic)
977 symbol *lbl = newiTempLabel(NULL);
978 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
979 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
980 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
981 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
982 pic14_emitcode("cpl","c");
983 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
984 pic14_outBitC(IC_RESULT(ic));
987 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
988 pic14_emitcode("subb","a,acc");
989 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
990 pic14_emitcode("inc","a");
991 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
992 aopPut(AOP(IC_RESULT(ic)),"a",0);
993 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
997 /*-----------------------------------------------------------------*/
998 /* genMinus - generates code for subtraction */
999 /*-----------------------------------------------------------------*/
1000 void genMinus (iCode *ic)
1002 int size, offset = 0,same;
1003 unsigned long lit = 0L;
1005 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1006 aopOp (IC_LEFT(ic),ic,FALSE);
1007 aopOp (IC_RIGHT(ic),ic,FALSE);
1008 aopOp (IC_RESULT(ic),ic,TRUE);
1010 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1011 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1012 operand *t = IC_RIGHT(ic);
1013 IC_RIGHT(ic) = IC_LEFT(ic);
1017 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1018 AopType(AOP_TYPE(IC_RESULT(ic))),
1019 AopType(AOP_TYPE(IC_LEFT(ic))),
1020 AopType(AOP_TYPE(IC_RIGHT(ic))));
1022 /* special cases :- */
1023 /* if both left & right are in bit space */
1024 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1025 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1030 /* if I can do an decrement instead
1031 of subtract then GOOD for ME */
1032 // if (genMinusDec (ic) == TRUE)
1035 size = pic14_getDataSize(IC_RESULT(ic));
1036 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1038 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1039 /* Add a literal to something else */
1041 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1044 genAddLit ( IC_RESULT(ic),IC_LEFT(ic), lit);
1047 /* add the first byte: */
1048 pic14_emitcode("movlw","0x%x", lit & 0xff);
1049 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1050 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1051 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1063 if((lit & 0xff) == 0xff) {
1064 emitpcode(POC_MOVLW, popGetLit(0xff));
1066 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1068 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1070 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1071 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1075 /* do the rlf known zero trick here */
1076 emitpcode(POC_MOVLW, popGetLit(1));
1078 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1083 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1086 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1087 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1088 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1090 /* here we are subtracting a bit from a char or int */
1092 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1094 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1095 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1097 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1098 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1099 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1100 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1103 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1104 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1105 emitpcode(POC_XORLW , popGetLit(1));
1106 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1107 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1109 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1111 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1112 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1114 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1115 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1118 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1120 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1122 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1123 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1127 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1128 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1129 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1130 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1135 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1136 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1137 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1140 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1142 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1145 emitpcode(POC_ANDLW , popGetLit(1));
1147 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1149 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1156 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1157 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1158 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1160 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1161 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1162 AopType(AOP_TYPE(IC_RESULT(ic))),
1163 AopType(AOP_TYPE(IC_LEFT(ic))),
1164 AopType(AOP_TYPE(IC_RIGHT(ic))));
1167 if( (size == 1) && ((lit & 0xff) == 0) ) {
1168 /* res = 0 - right */
1169 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1170 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1172 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1173 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1178 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1179 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1180 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1188 /* This is the last byte in a multibyte subtraction
1189 * There are a couple of tricks we can do by not worrying about
1190 * propogating the carry */
1192 /* 0xff - x == ~x */
1194 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1196 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1198 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1199 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1201 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1204 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1206 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1207 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1208 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1217 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1219 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1220 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1223 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1229 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1230 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1232 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1234 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1236 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1237 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1244 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1245 AopType(AOP_TYPE(IC_RESULT(ic))),
1246 AopType(AOP_TYPE(IC_LEFT(ic))),
1247 AopType(AOP_TYPE(IC_RIGHT(ic))));
1249 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1250 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1251 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1252 emitpcode(POC_SUBLW, popGetLit(0));
1253 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1256 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1257 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1258 emitpcode(POC_SUBLW, popGetLit(0));
1259 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1260 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1263 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1264 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1265 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1267 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1268 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1270 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1271 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1272 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1274 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1276 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1277 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1278 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1280 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1282 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1289 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1291 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1292 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1294 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1295 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1302 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1303 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1304 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1306 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1308 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1309 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1317 // adjustArithmeticResult(ic);
1320 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1321 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1322 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);