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_PCODE) ||
910 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
911 emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0));
913 emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0));
915 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
916 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
921 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
926 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
927 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
928 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
930 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
931 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
934 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
936 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
937 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
940 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
942 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
943 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
951 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
952 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
953 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
956 /* Need to extend result to higher bytes */
957 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
959 /* First grab the carry from the lower bytes */
960 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
961 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
965 /* Now this is really horrid. Gotta check the sign of the addends and propogate
968 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
969 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
970 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
971 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
973 /* if chars or ints or being signed extended to longs: */
975 emitpcode(POC_MOVLW, popGetLit(0));
976 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
977 emitpcode(POC_MOVLW, popGetLit(0xff));
985 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
987 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
994 //adjustArithmeticResult(ic);
997 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
998 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
999 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1002 /*-----------------------------------------------------------------*/
1003 /* genMinusDec :- does subtraction with decrement if possible */
1004 /*-----------------------------------------------------------------*/
1005 bool genMinusDec (iCode *ic)
1007 unsigned int icount ;
1008 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1010 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1011 /* will try to generate an increment */
1012 /* if the right side is not a literal
1014 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1015 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1016 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1019 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1021 /* if the literal value of the right hand side
1022 is greater than 4 then it is not worth it */
1023 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1026 /* if decrement 16 bits in register */
1027 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1032 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1033 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1034 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1035 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1037 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1038 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1039 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1041 /* size is 3 or 4 */
1042 emitpcode(POC_MOVLW, popGetLit(0xff));
1043 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1045 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1047 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1049 pic14_emitcode("movlw","0xff");
1050 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1053 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1055 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1059 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1061 pic14_emitcode("skpnc","");
1063 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1072 /* if the sizes are greater than 1 then we cannot */
1073 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1074 AOP_SIZE(IC_LEFT(ic)) > 1 )
1077 /* we can if the aops of the left & result match or
1078 if they are in registers and the registers are the
1080 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1083 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1085 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1090 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1091 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1092 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1095 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1096 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1098 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1099 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1107 /*-----------------------------------------------------------------*/
1108 /* addSign - propogate sign bit to higher bytes */
1109 /*-----------------------------------------------------------------*/
1110 void addSign(operand *result, int offset, int sign)
1112 int size = (pic14_getDataSize(result) - offset);
1113 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1116 if(sign && offset) {
1119 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1120 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1121 emitpcode(POC_DECF, popGet(AOP(result),offset));
1124 emitpcode(POC_MOVLW, popGetLit(0));
1125 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1126 emitpcode(POC_MOVLW, popGetLit(0xff));
1128 emitpcode(POC_MOVWF, popGet(AOP(result),size));
1133 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1137 /*-----------------------------------------------------------------*/
1138 /* genMinusBits - generates code for subtraction of two bits */
1139 /*-----------------------------------------------------------------*/
1140 void genMinusBits (iCode *ic)
1142 symbol *lbl = newiTempLabel(NULL);
1143 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1144 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1145 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1146 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1147 pic14_emitcode("cpl","c");
1148 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1149 pic14_outBitC(IC_RESULT(ic));
1152 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1153 pic14_emitcode("subb","a,acc");
1154 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1155 pic14_emitcode("inc","a");
1156 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1157 aopPut(AOP(IC_RESULT(ic)),"a",0);
1158 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1162 /*-----------------------------------------------------------------*/
1163 /* genMinus - generates code for subtraction */
1164 /*-----------------------------------------------------------------*/
1165 void genMinus (iCode *ic)
1167 int size, offset = 0, same=0;
1168 unsigned long lit = 0L;
1170 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1171 aopOp (IC_LEFT(ic),ic,FALSE);
1172 aopOp (IC_RIGHT(ic),ic,FALSE);
1173 aopOp (IC_RESULT(ic),ic,TRUE);
1175 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1176 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1177 operand *t = IC_RIGHT(ic);
1178 IC_RIGHT(ic) = IC_LEFT(ic);
1182 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1183 AopType(AOP_TYPE(IC_RESULT(ic))),
1184 AopType(AOP_TYPE(IC_LEFT(ic))),
1185 AopType(AOP_TYPE(IC_RIGHT(ic))));
1187 /* special cases :- */
1188 /* if both left & right are in bit space */
1189 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1190 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1195 /* if I can do an decrement instead
1196 of subtract then GOOD for ME */
1197 // if (genMinusDec (ic) == TRUE)
1200 size = pic14_getDataSize(IC_RESULT(ic));
1201 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1203 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1204 /* Add a literal to something else */
1206 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1209 genAddLit ( ic, lit);
1212 /* add the first byte: */
1213 pic14_emitcode("movlw","0x%x", lit & 0xff);
1214 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1215 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1216 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1228 if((lit & 0xff) == 0xff) {
1229 emitpcode(POC_MOVLW, popGetLit(0xff));
1231 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1233 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1235 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1236 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1240 /* do the rlf known zero trick here */
1241 emitpcode(POC_MOVLW, popGetLit(1));
1243 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1248 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1251 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1252 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1253 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1255 /* here we are subtracting a bit from a char or int */
1257 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1259 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1260 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1262 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1263 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1264 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1265 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1268 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1269 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1270 emitpcode(POC_XORLW , popGetLit(1));
1271 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1272 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1274 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1276 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1277 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1279 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1280 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1283 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1285 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1287 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1288 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1292 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1293 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1294 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1295 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1300 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1301 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1302 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1305 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1307 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1310 emitpcode(POC_ANDLW , popGetLit(1));
1312 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1314 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1321 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1322 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1323 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1325 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1326 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1327 AopType(AOP_TYPE(IC_RESULT(ic))),
1328 AopType(AOP_TYPE(IC_LEFT(ic))),
1329 AopType(AOP_TYPE(IC_RIGHT(ic))));
1332 if( (size == 1) && ((lit & 0xff) == 0) ) {
1333 /* res = 0 - right */
1334 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1335 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1336 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1338 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1339 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1340 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1345 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1346 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1347 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1355 /* This is the last byte in a multibyte subtraction
1356 * There are a couple of tricks we can do by not worrying about
1357 * propogating the carry */
1359 /* 0xff - x == ~x */
1361 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1363 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1365 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1366 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1368 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1371 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1373 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1374 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1375 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1384 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1386 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1387 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1390 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1396 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1397 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1399 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1401 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1403 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1404 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1411 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1412 AopType(AOP_TYPE(IC_RESULT(ic))),
1413 AopType(AOP_TYPE(IC_LEFT(ic))),
1414 AopType(AOP_TYPE(IC_RIGHT(ic))));
1416 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1417 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1418 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1419 emitpcode(POC_SUBLW, popGetLit(0));
1420 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1423 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1424 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1425 emitpcode(POC_SUBLW, popGetLit(0));
1426 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1427 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1430 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1431 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1432 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1434 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1435 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1437 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1438 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1439 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1441 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1443 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1444 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1445 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1447 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1449 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1456 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1458 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1459 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1461 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1462 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1469 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1470 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1471 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1473 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1475 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1476 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1484 // adjustArithmeticResult(ic);
1487 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1488 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1489 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1491 /*-----------------------------------------------------------------*
1492 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1495 *-----------------------------------------------------------------*/
1496 void genUMult8XLit_16 (operand *left,
1499 pCodeOpReg *result_hi)
1504 unsigned int i,have_first_bit;
1506 if (AOP_TYPE(right) != AOP_LIT){
1507 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1513 result_hi = PCOR(popGet(AOP(result),1));
1516 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1518 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1522 emitpcode(POC_CLRF, popGet(AOP(result),0));
1523 emitpcode(POC_CLRF, popCopyReg(result_hi));
1527 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1528 emitpcode(POC_CLRF, popGet(AOP(result),0));
1529 emitpcode(POC_CLRF, popCopyReg(result_hi));
1532 for(i=0; i<8; i++) {
1535 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1539 if(have_first_bit) {
1540 emitpcode(POC_RRF, popCopyReg(result_hi));
1541 emitpcode(POC_RRF, popGet(AOP(result),0));
1549 /*-----------------------------------------------------------------*
1550 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1553 *-----------------------------------------------------------------*/
1554 void genUMult8X8_16 (operand *left,
1557 pCodeOpReg *result_hi)
1565 result_hi = PCOR(popGet(AOP(result),1));
1569 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1571 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1572 emitpcode(POC_CLRF, popGet(AOP(result),0));
1573 emitpcode(POC_CLRF, popCopyReg(result_hi));
1576 for(i=0; i<8; i++) {
1577 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1578 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1579 emitpcode(POC_RRF, popCopyReg(result_hi));
1580 emitpcode(POC_RRF, popGet(AOP(result),0));
1585 Here's another version that does the same thing and takes the
1586 same number of instructions. The one above is slightly better
1587 because the entry instructions have a higher probability of
1588 being optimized out.
1591 emitpcode(POC_CLRF, popCopyReg(result_hi));
1592 emitpcode(POC_RRFW, popGet(AOP(left),0));
1593 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1594 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1596 for(i=0; i<8; i++) {
1598 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1599 emitpcode(POC_RRF, popCopyReg(result_hi));
1600 emitpcode(POC_RRF, popGet(AOP(result),0));
1605 symbol *tlbl = newiTempLabel(NULL);
1606 pCodeOp *temp = popGetTempReg();
1609 pic14_emitcode(";","Looped 8 X 8 multiplication");
1611 emitpcode(POC_CLRF, popGet(AOP(result),0));
1612 emitpcode(POC_CLRF, popCopyReg(result_hi));
1613 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1615 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1616 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1618 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1620 emitpLabel(tlbl->key);
1622 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1624 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1626 emitpcode(POC_RRF, popCopyReg(result_hi));
1627 emitpcode(POC_RRF, popGet(AOP(result),0));
1630 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1632 popReleaseTempReg(temp);
1637 /*-----------------------------------------------------------------*
1638 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1640 * this routine will call the unsigned multiply routine and then
1641 * post-fix the sign bit.
1642 *-----------------------------------------------------------------*/
1643 void genSMult8X8_16 (operand *left,
1646 pCodeOpReg *result_hi)
1650 result_hi = PCOR(popGet(AOP(result),1));
1653 genUMult8X8_16(left,right,result,result_hi);
1655 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1656 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1657 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1658 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1659 emitpcode(POC_SUBWF, popGet(AOP(result),1));
1663 /*-----------------------------------------------------------------*
1664 * genMult8X8_8 - multiplication of two 8-bit numbers
1666 * this routine will call the unsigned multiply 8X8=>16 routine and
1667 * then throw away the high byte of the result.
1669 *-----------------------------------------------------------------*/
1670 void genMult8X8_8 (operand *left,
1674 pCodeOp *result_hi = popGetTempReg();
1676 if (AOP_TYPE(right) == AOP_LIT)
1677 genUMult8XLit_16(left,right,result,PCOR(result_hi));
1679 genUMult8X8_16(left,right,result,PCOR(result_hi));
1681 popReleaseTempReg(result_hi);
1684 /*-----------------------------------------------------------------*/
1685 /* constMult - generates code for multiplication by a constant */
1686 /*-----------------------------------------------------------------*/
1687 void genMultConst(unsigned C)
1691 unsigned sr3; // Shift right 3
1697 Convert a string of 3 binary 1's in the lit into
1701 mask = 7 << ( (size*8) - 3);
1705 while(mask < (1<<size*8)) {
1707 if( (mask & lit) == lit) {
1710 /* We found 3 (or more) consecutive 1's */
1712 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1714 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1716 lit ^= consecutive_bits;
1720 sr3 |= (consecutive + lsb);