1 /*-------------------------------------------------------------------------
2 genarith.c - source file for code generation - arithmetic
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
40 #define __FUNCTION__ __FILE__
43 #ifdef HAVE_SYS_ISA_DEFS_H
44 #include <sys/isa_defs.h>
46 #ifdef HAVE_MACHINE_ENDIAN_H
47 #include <machine/endian.h>
52 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
53 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
54 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
61 #include "SDCCpeeph.h"
67 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
68 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result);
70 const char *AopType(short type)
116 /*-----------------------------------------------------------------*/
117 /* genPlusIncr :- does addition with increment if possible */
118 /*-----------------------------------------------------------------*/
119 bool genPlusIncr (iCode *ic)
121 unsigned int icount ;
122 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
124 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
125 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
126 AopType(AOP_TYPE(IC_RESULT(ic))),
127 AopType(AOP_TYPE(IC_LEFT(ic))),
128 AopType(AOP_TYPE(IC_RIGHT(ic))));
130 /* will try to generate an increment */
131 /* if the right side is not a literal
133 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
136 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
137 /* if the literal value of the right hand side
138 is greater than 1 then it is faster to add */
139 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
142 /* if increment 16 bits in register */
143 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
148 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB));
149 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
153 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
154 //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
160 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
161 /* if left is in accumulator - probably a bit operation*/
162 if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
163 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
165 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
166 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
167 AOP(IC_RESULT(ic))->aopu.aop_dir,
168 AOP(IC_RESULT(ic))->aopu.aop_dir);
170 emitpcode(POC_XORLW,popGetLit(1));
171 //pic14_emitcode("xorlw","1");
173 emitpcode(POC_ANDLW,popGetLit(1));
174 //pic14_emitcode("andlw","1");
177 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
178 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
179 AOP(IC_RESULT(ic))->aopu.aop_dir,
180 AOP(IC_RESULT(ic))->aopu.aop_dir);
187 /* if the sizes are greater than 1 then we cannot */
188 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
189 AOP_SIZE(IC_LEFT(ic)) > 1 )
192 /* If we are incrementing the same register by two: */
194 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
197 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
198 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
203 DEBUGpic14_emitcode ("; ","couldn't increment ");
208 /*-----------------------------------------------------------------*/
209 /* pic14_outBitAcc - output a bit in acc */
210 /*-----------------------------------------------------------------*/
211 void pic14_outBitAcc(operand *result)
213 symbol *tlbl = newiTempLabel(NULL);
214 /* if the result is a bit */
215 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
217 if (AOP_TYPE(result) == AOP_CRY){
218 aopPut(AOP(result),"a",0);
221 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
222 pic14_emitcode("mov","a,#01");
223 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
224 pic14_outAcc(result);
228 /*-----------------------------------------------------------------*/
229 /* genPlusBits - generates code for addition of two bits */
230 /*-----------------------------------------------------------------*/
231 void genPlusBits (iCode *ic)
234 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
236 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
237 AopType(AOP_TYPE(IC_RESULT(ic))),
238 AopType(AOP_TYPE(IC_LEFT(ic))),
239 AopType(AOP_TYPE(IC_RIGHT(ic))));
241 The following block of code will add two bits.
242 Note that it'll even work if the destination is
243 the carry (C in the status register).
244 It won't work if the 'Z' bit is a source or destination.
247 /* If the result is stored in the accumulator (w) */
248 //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
249 switch(AOP_TYPE(IC_RESULT(ic))) {
251 emitpcode(POC_CLRW, NULL);
252 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
253 emitpcode(POC_XORLW, popGetLit(1));
254 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
255 emitpcode(POC_XORLW, popGetLit(1));
257 pic14_emitcode("clrw","");
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("xorlw","1");
262 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
263 AOP(IC_LEFT(ic))->aopu.aop_dir,
264 AOP(IC_LEFT(ic))->aopu.aop_dir);
265 pic14_emitcode("xorlw","1");
268 emitpcode(POC_MOVLW, popGetLit(0));
269 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
270 emitpcode(POC_XORLW, popGetLit(1));
271 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
272 emitpcode(POC_XORLW, popGetLit(1));
273 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
276 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
277 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
278 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
279 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
280 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
281 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
283 pic14_emitcode("movlw","(1 << (%s & 7))",
284 AOP(IC_RESULT(ic))->aopu.aop_dir,
285 AOP(IC_RESULT(ic))->aopu.aop_dir);
286 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
287 AOP(IC_RESULT(ic))->aopu.aop_dir,
288 AOP(IC_RESULT(ic))->aopu.aop_dir);
289 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
290 AOP(IC_RIGHT(ic))->aopu.aop_dir,
291 AOP(IC_RIGHT(ic))->aopu.aop_dir);
292 pic14_emitcode("xorwf","(%s >>3),f",
293 AOP(IC_RESULT(ic))->aopu.aop_dir);
294 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
295 AOP(IC_LEFT(ic))->aopu.aop_dir,
296 AOP(IC_LEFT(ic))->aopu.aop_dir);
297 pic14_emitcode("xorwf","(%s>>3),f",
298 AOP(IC_RESULT(ic))->aopu.aop_dir);
305 /* This is the original version of this code.
307 * This is being kept around for reference,
308 * because I am not entirely sure I got it right...
310 static void adjustArithmeticResult(iCode *ic)
312 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
313 AOP_SIZE(IC_LEFT(ic)) == 3 &&
314 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
315 aopPut(AOP(IC_RESULT(ic)),
316 aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
319 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
320 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
321 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
322 aopPut(AOP(IC_RESULT(ic)),
323 aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
326 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
327 AOP_SIZE(IC_LEFT(ic)) < 3 &&
328 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
329 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
330 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
332 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
333 aopPut(AOP(IC_RESULT(ic)),buffer,2);
337 /* This is the pure and virtuous version of this code.
338 * I'm pretty certain it's right, but not enough to toss the old
341 static void adjustArithmeticResult(iCode *ic)
343 if (opIsGptr(IC_RESULT(ic)) &&
344 opIsGptr(IC_LEFT(ic)) &&
345 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
347 aopPut(AOP(IC_RESULT(ic)),
348 aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
352 if (opIsGptr(IC_RESULT(ic)) &&
353 opIsGptr(IC_RIGHT(ic)) &&
354 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
356 aopPut(AOP(IC_RESULT(ic)),
357 aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
361 if (opIsGptr(IC_RESULT(ic)) &&
362 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
363 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
364 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
365 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
367 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
368 aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
373 /*-----------------------------------------------------------------*/
374 /* genAddlit - generates code for addition */
375 /*-----------------------------------------------------------------*/
376 static void genAddLit2byte (operand *result, int offr, int lit)
383 emitpcode(POC_INCF, popGet(AOP(result),offr));
386 emitpcode(POC_DECF, popGet(AOP(result),offr));
389 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
390 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
395 static void emitMOVWF(operand *reg, int offset)
400 if (AOP_TYPE(reg) == AOP_ACC) {
401 DEBUGpic14_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
405 emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
409 static void genAddLit (iCode *ic, int lit)
418 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
422 result = IC_RESULT(ic);
423 same = pic14_sameRegs(AOP(left), AOP(result));
424 size = pic14_getDataSize(result);
428 /* Handle special cases first */
430 genAddLit2byte (result, 0, lit);
433 int hi = 0xff & (lit >> 8);
440 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
445 emitpcode(POC_INCF, popGet(AOP(result),0));
447 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
450 emitpcode(POC_DECF, popGet(AOP(result),0));
451 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
452 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
456 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
457 emitpcode(POC_ADDWF,popGet(AOP(result),0));
459 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
467 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
470 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
473 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
474 emitpcode(POC_INCF, popGet(AOP(result),0));
476 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
478 case 0xff: /* 0x01ff */
479 emitpcode(POC_DECF, popGet(AOP(result),0));
480 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
481 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
482 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
487 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
491 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
494 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
495 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
497 /* case 0xff: * 0xffff *
498 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
499 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
500 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
504 emitpcode(POC_MOVLW,popGetLit(lo));
505 emitpcode(POC_ADDWF,popGet(AOP(result),0));
507 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
514 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
519 genAddLit2byte (result, MSB16, hi);
522 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
523 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
524 emitpcode(POC_MOVLW,popGetLit(hi));
525 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
527 /* case 0xff: * 0xHHff *
528 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
529 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
530 emitpcode(POC_MOVLW,popGetLit(hi));
531 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
533 */ default: /* 0xHHLL */
534 emitpcode(POC_MOVLW,popGetLit(lo));
535 emitpcode(POC_ADDWF, popGet(AOP(result),0));
536 emitpcode(POC_MOVLW,popGetLit(hi));
538 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
539 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
548 DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
551 lo = BYTEofLONG(lit,0);
559 emitpcode(POC_INCF, popGet(AOP(result),offset));
562 emitpcode(POC_RLFW, popGet(AOP(result),offset));
563 emitpcode(POC_ANDLW,popGetLit(1));
564 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
566 default: /* carry_info = 3 */
568 emitpcode(POC_INCF, popGet(AOP(result),offset));
574 emitpcode(POC_MOVLW,popGetLit(lo));
579 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
582 emitpcode(POC_MOVLW,popGetLit(lo));
587 emitpcode(POC_MOVLW,popGetLit(lo+1));
588 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
593 /* no carry info from previous step */
594 /* this means this is the first time to add */
599 emitpcode(POC_INCF, popGet(AOP(result),offset));
603 emitpcode(POC_MOVLW,popGetLit(lo));
604 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
606 carry_info = 3; /* Were adding only one byte and propogating the carry */
617 lo = BYTEofLONG(lit,0);
622 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
625 emitpcode(POC_MOVLW,popGetLit(lo));
626 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
629 emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
631 emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
633 emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
643 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
647 if(AOP_TYPE(left) == AOP_ACC) {
648 /* left addend is already in accumulator */
651 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
655 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
656 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
660 /* left addend is in a register */
663 emitpcode(POC_MOVFW, popGet(AOP(left),0));
664 emitMOVWF(result, 0);
665 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
669 emitpcode(POC_INCFW, popGet(AOP(left),0));
670 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
674 emitpcode(POC_DECFW, popGet(AOP(left),0));
675 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
679 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
680 emitpcode(POC_ADDFW, popGet(AOP(left),0));
681 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
688 /* left is not the accumulator */
690 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
691 emitpcode(POC_ADDFW, popGet(AOP(left),0));
693 emitpcode(POC_MOVFW, popGet(AOP(left),0));
695 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
701 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
702 //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
703 emitMOVWF(result,offset);
704 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
706 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
707 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
709 emitpcode(POC_CLRF, popGet(AOP(result),offset));
710 emitpcode(POC_RLF, popGet(AOP(result),offset));
711 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
712 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
720 /*-----------------------------------------------------------------*/
721 /* genPlus - generates code for addition */
722 /*-----------------------------------------------------------------*/
723 void genPlus (iCode *ic)
725 int size, offset = 0;
727 /* special cases :- */
728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
730 aopOp (IC_LEFT(ic),ic,FALSE);
731 aopOp (IC_RIGHT(ic),ic,FALSE);
732 aopOp (IC_RESULT(ic),ic,TRUE);
734 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
736 /* if literal, literal on the right or
737 if left requires ACC or right is already
740 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
741 operand *t = IC_RIGHT(ic);
742 IC_RIGHT(ic) = IC_LEFT(ic);
746 /* if both left & right are in bit space */
747 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
748 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
753 /* if left in bit space & right literal */
754 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
755 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
756 /* if result in bit space */
757 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
758 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
759 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
760 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
761 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
762 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
765 size = pic14_getDataSize(IC_RESULT(ic));
767 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
768 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
769 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
775 /* if I can do an increment instead
776 of add then GOOD for ME */
777 if (genPlusIncr (ic) == TRUE)
780 size = pic14_getDataSize(IC_RESULT(ic));
782 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
783 /* Add a literal to something else */
785 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
789 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
794 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
796 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
797 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
798 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
800 /* here we are adding a bit to a char or int */
802 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
804 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
805 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
807 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
808 AOP(IC_RIGHT(ic))->aopu.aop_dir,
809 AOP(IC_RIGHT(ic))->aopu.aop_dir);
810 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
813 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
814 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
815 emitpcode(POC_XORLW , popGetLit(1));
817 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
818 AOP(IC_RIGHT(ic))->aopu.aop_dir,
819 AOP(IC_RIGHT(ic))->aopu.aop_dir);
820 pic14_emitcode(" xorlw","1");
822 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
823 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
824 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
826 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
827 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
828 AOP(IC_RIGHT(ic))->aopu.aop_dir,
829 AOP(IC_RIGHT(ic))->aopu.aop_dir);
830 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
833 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
835 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
836 emitpcode(POC_ANDLW , popGetLit(1));
837 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
839 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
841 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
842 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
849 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
850 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
852 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
853 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
855 pic14_emitcode("clrz","");
857 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
858 AOP(IC_RIGHT(ic))->aopu.aop_dir,
859 AOP(IC_RIGHT(ic))->aopu.aop_dir);
860 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
864 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
865 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
866 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
867 //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
868 emitMOVWF(IC_RIGHT(ic),0);
870 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
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,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
875 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
881 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
882 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
888 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
890 /* Add the first bytes */
892 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
893 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
894 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
897 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
898 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
899 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
900 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
903 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
905 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
906 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
908 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
909 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
910 emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0));
912 emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0));
913 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
914 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
920 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
925 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
926 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
927 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
929 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
930 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
933 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
935 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
936 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
939 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
941 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
942 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
950 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
951 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
952 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
955 /* Need to extend result to higher bytes */
956 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
958 /* First grab the carry from the lower bytes */
959 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
960 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
964 /* Now this is really horrid. Gotta check the sign of the addends and propogate
967 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
968 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
969 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
970 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
972 /* if chars or ints or being signed extended to longs: */
974 emitpcode(POC_MOVLW, popGetLit(0));
975 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
976 emitpcode(POC_MOVLW, popGetLit(0xff));
984 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
986 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
993 //adjustArithmeticResult(ic);
996 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
997 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
998 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1001 /*-----------------------------------------------------------------*/
1002 /* genMinusDec :- does subtraction with decrement if possible */
1003 /*-----------------------------------------------------------------*/
1004 bool genMinusDec (iCode *ic)
1006 unsigned int icount ;
1007 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1009 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1010 /* will try to generate an increment */
1011 /* if the right side is not a literal
1013 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1014 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1015 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1018 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1020 /* if the literal value of the right hand side
1021 is greater than 4 then it is not worth it */
1022 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1025 /* if decrement 16 bits in register */
1026 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1031 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1032 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1033 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1034 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1036 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1037 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1038 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1040 /* size is 3 or 4 */
1041 emitpcode(POC_MOVLW, popGetLit(0xff));
1042 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1044 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1046 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1048 pic14_emitcode("movlw","0xff");
1049 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1052 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1054 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1058 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1060 pic14_emitcode("skpnc","");
1062 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1071 /* if the sizes are greater than 1 then we cannot */
1072 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1073 AOP_SIZE(IC_LEFT(ic)) > 1 )
1076 /* we can if the aops of the left & result match or
1077 if they are in registers and the registers are the
1079 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1082 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1084 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1089 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1090 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1091 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1094 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1095 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1097 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1098 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1106 /*-----------------------------------------------------------------*/
1107 /* addSign - complete with sign */
1108 /*-----------------------------------------------------------------*/
1109 void addSign(operand *result, int offset, int sign)
1111 int size = (pic14_getDataSize(result) - offset);
1112 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1115 pic14_emitcode("rlc","a");
1116 pic14_emitcode("subb","a,acc");
1118 aopPut(AOP(result),"a",offset++);
1121 aopPut(AOP(result),"#0",offset++);
1125 /*-----------------------------------------------------------------*/
1126 /* genMinusBits - generates code for subtraction of two bits */
1127 /*-----------------------------------------------------------------*/
1128 void genMinusBits (iCode *ic)
1130 symbol *lbl = newiTempLabel(NULL);
1131 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1132 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1133 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1134 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1135 pic14_emitcode("cpl","c");
1136 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1137 pic14_outBitC(IC_RESULT(ic));
1140 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1141 pic14_emitcode("subb","a,acc");
1142 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1143 pic14_emitcode("inc","a");
1144 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1145 aopPut(AOP(IC_RESULT(ic)),"a",0);
1146 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1150 /*-----------------------------------------------------------------*/
1151 /* genMinus - generates code for subtraction */
1152 /*-----------------------------------------------------------------*/
1153 void genMinus (iCode *ic)
1155 int size, offset = 0, same=0;
1156 unsigned long lit = 0L;
1158 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1159 aopOp (IC_LEFT(ic),ic,FALSE);
1160 aopOp (IC_RIGHT(ic),ic,FALSE);
1161 aopOp (IC_RESULT(ic),ic,TRUE);
1163 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1164 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1165 operand *t = IC_RIGHT(ic);
1166 IC_RIGHT(ic) = IC_LEFT(ic);
1170 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1171 AopType(AOP_TYPE(IC_RESULT(ic))),
1172 AopType(AOP_TYPE(IC_LEFT(ic))),
1173 AopType(AOP_TYPE(IC_RIGHT(ic))));
1175 /* special cases :- */
1176 /* if both left & right are in bit space */
1177 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1178 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1183 /* if I can do an decrement instead
1184 of subtract then GOOD for ME */
1185 // if (genMinusDec (ic) == TRUE)
1188 size = pic14_getDataSize(IC_RESULT(ic));
1189 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1191 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1192 /* Add a literal to something else */
1194 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1197 genAddLit ( ic, lit);
1200 /* add the first byte: */
1201 pic14_emitcode("movlw","0x%x", lit & 0xff);
1202 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1203 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1204 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1216 if((lit & 0xff) == 0xff) {
1217 emitpcode(POC_MOVLW, popGetLit(0xff));
1219 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1221 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1223 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1224 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1228 /* do the rlf known zero trick here */
1229 emitpcode(POC_MOVLW, popGetLit(1));
1231 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1236 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1239 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1240 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1241 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1243 /* here we are subtracting a bit from a char or int */
1245 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1247 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1248 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1250 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1251 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1252 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1253 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1256 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1257 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1258 emitpcode(POC_XORLW , popGetLit(1));
1259 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1260 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1262 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1264 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1265 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1267 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1268 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1271 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1273 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1275 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1276 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1280 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1281 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1282 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1283 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1288 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1289 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1290 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1293 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1295 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1298 emitpcode(POC_ANDLW , popGetLit(1));
1300 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1302 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1309 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1310 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1311 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1313 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1314 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1315 AopType(AOP_TYPE(IC_RESULT(ic))),
1316 AopType(AOP_TYPE(IC_LEFT(ic))),
1317 AopType(AOP_TYPE(IC_RIGHT(ic))));
1320 if( (size == 1) && ((lit & 0xff) == 0) ) {
1321 /* res = 0 - right */
1322 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1323 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1324 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1326 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1327 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1328 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1333 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1334 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1335 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1343 /* This is the last byte in a multibyte subtraction
1344 * There are a couple of tricks we can do by not worrying about
1345 * propogating the carry */
1347 /* 0xff - x == ~x */
1349 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1351 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1353 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1354 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1356 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1359 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1361 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1362 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1363 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1372 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1374 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1375 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1378 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1384 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1385 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1387 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1389 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1391 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1392 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1399 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1400 AopType(AOP_TYPE(IC_RESULT(ic))),
1401 AopType(AOP_TYPE(IC_LEFT(ic))),
1402 AopType(AOP_TYPE(IC_RIGHT(ic))));
1404 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1405 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1406 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1407 emitpcode(POC_SUBLW, popGetLit(0));
1408 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1411 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1412 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1413 emitpcode(POC_SUBLW, popGetLit(0));
1414 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1415 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1418 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1419 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1420 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1422 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1423 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1425 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1426 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1427 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1429 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1431 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1432 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1433 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1435 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1437 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1444 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1446 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1447 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1449 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1450 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1457 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1458 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1459 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1461 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1463 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1464 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1472 // adjustArithmeticResult(ic);
1475 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1476 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1477 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1479 /*-----------------------------------------------------------------*
1480 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1483 *-----------------------------------------------------------------*/
1484 void genUMult8XLit_16 (operand *left,
1487 pCodeOpReg *result_hi)
1492 unsigned int i,have_first_bit;
1494 if (AOP_TYPE(right) != AOP_LIT){
1495 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1501 result_hi = PCOR(popGet(AOP(result),1));
1504 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1506 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1510 emitpcode(POC_CLRF, popGet(AOP(result),0));
1511 emitpcode(POC_CLRF, popCopyReg(result_hi));
1515 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1516 emitpcode(POC_CLRF, popGet(AOP(result),0));
1517 emitpcode(POC_CLRF, popCopyReg(result_hi));
1520 for(i=0; i<8; i++) {
1523 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1527 if(have_first_bit) {
1528 emitpcode(POC_RRF, popCopyReg(result_hi));
1529 emitpcode(POC_RRF, popGet(AOP(result),0));
1537 /*-----------------------------------------------------------------*
1538 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1541 *-----------------------------------------------------------------*/
1542 void genUMult8X8_16 (operand *left,
1545 pCodeOpReg *result_hi)
1553 result_hi = PCOR(popGet(AOP(result),1));
1557 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1559 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1560 emitpcode(POC_CLRF, popGet(AOP(result),0));
1561 emitpcode(POC_CLRF, popCopyReg(result_hi));
1564 for(i=0; i<8; i++) {
1565 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1566 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1567 emitpcode(POC_RRF, popCopyReg(result_hi));
1568 emitpcode(POC_RRF, popGet(AOP(result),0));
1573 Here's another version that does the same thing and takes the
1574 same number of instructions. The one above is slightly better
1575 because the entry instructions have a higher probability of
1576 being optimized out.
1579 emitpcode(POC_CLRF, popCopyReg(result_hi));
1580 emitpcode(POC_RRFW, popGet(AOP(left),0));
1581 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1582 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1584 for(i=0; i<8; i++) {
1586 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1587 emitpcode(POC_RRF, popCopyReg(result_hi));
1588 emitpcode(POC_RRF, popGet(AOP(result),0));
1593 symbol *tlbl = newiTempLabel(NULL);
1594 pCodeOp *temp = popGetTempReg();
1597 pic14_emitcode(";","Looped 8 X 8 multiplication");
1599 emitpcode(POC_CLRF, popGet(AOP(result),0));
1600 emitpcode(POC_CLRF, popCopyReg(result_hi));
1601 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1603 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1604 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1606 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1608 emitpLabel(tlbl->key);
1610 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1612 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1614 emitpcode(POC_RRF, popCopyReg(result_hi));
1615 emitpcode(POC_RRF, popGet(AOP(result),0));
1618 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1620 popReleaseTempReg(temp);
1625 /*-----------------------------------------------------------------*
1626 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1628 * this routine will call the unsigned multiply routine and then
1629 * post-fix the sign bit.
1630 *-----------------------------------------------------------------*/
1631 void genSMult8X8_16 (operand *left,
1634 pCodeOpReg *result_hi)
1638 result_hi = PCOR(popGet(AOP(result),1));
1641 genUMult8X8_16(left,right,result,result_hi);
1643 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1644 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1645 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1646 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1647 emitpcode(POC_SUBWF, popGet(AOP(result),1));
1651 /*-----------------------------------------------------------------*
1652 * genMult8X8_8 - multiplication of two 8-bit numbers
1654 * this routine will call the unsigned multiply 8X8=>16 routine and
1655 * then throw away the high byte of the result.
1657 *-----------------------------------------------------------------*/
1658 void genMult8X8_8 (operand *left,
1662 pCodeOp *result_hi = popGetTempReg();
1664 if (AOP_TYPE(right) == AOP_LIT)
1665 genUMult8XLit_16(left,right,result,PCOR(result_hi));
1667 genUMult8X8_16(left,right,result,PCOR(result_hi));
1669 popReleaseTempReg(result_hi);
1672 /*-----------------------------------------------------------------*/
1673 /* constMult - generates code for multiplication by a constant */
1674 /*-----------------------------------------------------------------*/
1675 void genMultConst(unsigned C)
1679 unsigned sr3; // Shift right 3
1685 Convert a string of 3 binary 1's in the lit into
1689 mask = 7 << ( (size*8) - 3);
1693 while(mask < (1<<size*8)) {
1695 if( (mask & lit) == lit) {
1698 /* We found 3 (or more) consecutive 1's */
1700 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1702 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1704 lit ^= consecutive_bits;
1708 sr3 |= (consecutive + lsb);