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 - propogate sign bit to higher bytes */
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 if(sign && offset) {
1118 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1119 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1120 emitpcode(POC_DECF, popGet(AOP(result),offset));
1123 emitpcode(POC_MOVLW, popGetLit(0));
1124 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1125 emitpcode(POC_MOVLW, popGetLit(0xff));
1127 emitpcode(POC_MOVWF, popGet(AOP(result),size));
1132 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1136 /*-----------------------------------------------------------------*/
1137 /* genMinusBits - generates code for subtraction of two bits */
1138 /*-----------------------------------------------------------------*/
1139 void genMinusBits (iCode *ic)
1141 symbol *lbl = newiTempLabel(NULL);
1142 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1143 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1144 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1145 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1146 pic14_emitcode("cpl","c");
1147 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1148 pic14_outBitC(IC_RESULT(ic));
1151 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1152 pic14_emitcode("subb","a,acc");
1153 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1154 pic14_emitcode("inc","a");
1155 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1156 aopPut(AOP(IC_RESULT(ic)),"a",0);
1157 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1161 /*-----------------------------------------------------------------*/
1162 /* genMinus - generates code for subtraction */
1163 /*-----------------------------------------------------------------*/
1164 void genMinus (iCode *ic)
1166 int size, offset = 0, same=0;
1167 unsigned long lit = 0L;
1169 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1170 aopOp (IC_LEFT(ic),ic,FALSE);
1171 aopOp (IC_RIGHT(ic),ic,FALSE);
1172 aopOp (IC_RESULT(ic),ic,TRUE);
1174 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1175 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1176 operand *t = IC_RIGHT(ic);
1177 IC_RIGHT(ic) = IC_LEFT(ic);
1181 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1182 AopType(AOP_TYPE(IC_RESULT(ic))),
1183 AopType(AOP_TYPE(IC_LEFT(ic))),
1184 AopType(AOP_TYPE(IC_RIGHT(ic))));
1186 /* special cases :- */
1187 /* if both left & right are in bit space */
1188 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1189 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1194 /* if I can do an decrement instead
1195 of subtract then GOOD for ME */
1196 // if (genMinusDec (ic) == TRUE)
1199 size = pic14_getDataSize(IC_RESULT(ic));
1200 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1202 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1203 /* Add a literal to something else */
1205 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1208 genAddLit ( ic, lit);
1211 /* add the first byte: */
1212 pic14_emitcode("movlw","0x%x", lit & 0xff);
1213 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1214 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1215 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1227 if((lit & 0xff) == 0xff) {
1228 emitpcode(POC_MOVLW, popGetLit(0xff));
1230 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1232 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1234 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1235 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1239 /* do the rlf known zero trick here */
1240 emitpcode(POC_MOVLW, popGetLit(1));
1242 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1247 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1250 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1251 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1252 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1254 /* here we are subtracting a bit from a char or int */
1256 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1258 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1259 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1261 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1262 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1263 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1264 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1267 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1268 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1269 emitpcode(POC_XORLW , popGetLit(1));
1270 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1271 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1273 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1275 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1276 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1278 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1279 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1282 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1284 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1286 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1287 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1291 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1292 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1293 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1294 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1299 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1300 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1301 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1304 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1306 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1309 emitpcode(POC_ANDLW , popGetLit(1));
1311 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1313 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1320 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1321 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1322 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1324 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1325 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1326 AopType(AOP_TYPE(IC_RESULT(ic))),
1327 AopType(AOP_TYPE(IC_LEFT(ic))),
1328 AopType(AOP_TYPE(IC_RIGHT(ic))));
1331 if( (size == 1) && ((lit & 0xff) == 0) ) {
1332 /* res = 0 - right */
1333 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1334 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1335 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1337 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1338 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1339 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1344 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1345 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1346 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1354 /* This is the last byte in a multibyte subtraction
1355 * There are a couple of tricks we can do by not worrying about
1356 * propogating the carry */
1358 /* 0xff - x == ~x */
1360 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1362 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1364 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1365 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1367 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1370 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1372 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1373 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1374 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1383 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1385 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1386 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1389 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1395 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1396 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1398 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1400 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1402 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1403 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1410 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1411 AopType(AOP_TYPE(IC_RESULT(ic))),
1412 AopType(AOP_TYPE(IC_LEFT(ic))),
1413 AopType(AOP_TYPE(IC_RIGHT(ic))));
1415 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1416 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1417 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1418 emitpcode(POC_SUBLW, popGetLit(0));
1419 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1422 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1423 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1424 emitpcode(POC_SUBLW, popGetLit(0));
1425 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1426 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1429 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1430 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1431 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1433 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1434 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1436 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1437 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1438 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1440 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1442 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1443 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1444 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1446 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1448 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1455 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1457 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1458 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1460 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1461 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1468 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1469 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1470 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1472 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1474 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1475 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1483 // adjustArithmeticResult(ic);
1486 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1487 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1488 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1490 /*-----------------------------------------------------------------*
1491 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1494 *-----------------------------------------------------------------*/
1495 void genUMult8XLit_16 (operand *left,
1498 pCodeOpReg *result_hi)
1503 unsigned int i,have_first_bit;
1505 if (AOP_TYPE(right) != AOP_LIT){
1506 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1512 result_hi = PCOR(popGet(AOP(result),1));
1515 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1517 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1521 emitpcode(POC_CLRF, popGet(AOP(result),0));
1522 emitpcode(POC_CLRF, popCopyReg(result_hi));
1526 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1527 emitpcode(POC_CLRF, popGet(AOP(result),0));
1528 emitpcode(POC_CLRF, popCopyReg(result_hi));
1531 for(i=0; i<8; i++) {
1534 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1538 if(have_first_bit) {
1539 emitpcode(POC_RRF, popCopyReg(result_hi));
1540 emitpcode(POC_RRF, popGet(AOP(result),0));
1548 /*-----------------------------------------------------------------*
1549 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1552 *-----------------------------------------------------------------*/
1553 void genUMult8X8_16 (operand *left,
1556 pCodeOpReg *result_hi)
1564 result_hi = PCOR(popGet(AOP(result),1));
1568 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1570 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1571 emitpcode(POC_CLRF, popGet(AOP(result),0));
1572 emitpcode(POC_CLRF, popCopyReg(result_hi));
1575 for(i=0; i<8; i++) {
1576 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1577 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1578 emitpcode(POC_RRF, popCopyReg(result_hi));
1579 emitpcode(POC_RRF, popGet(AOP(result),0));
1584 Here's another version that does the same thing and takes the
1585 same number of instructions. The one above is slightly better
1586 because the entry instructions have a higher probability of
1587 being optimized out.
1590 emitpcode(POC_CLRF, popCopyReg(result_hi));
1591 emitpcode(POC_RRFW, popGet(AOP(left),0));
1592 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1593 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1595 for(i=0; i<8; i++) {
1597 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1598 emitpcode(POC_RRF, popCopyReg(result_hi));
1599 emitpcode(POC_RRF, popGet(AOP(result),0));
1604 symbol *tlbl = newiTempLabel(NULL);
1605 pCodeOp *temp = popGetTempReg();
1608 pic14_emitcode(";","Looped 8 X 8 multiplication");
1610 emitpcode(POC_CLRF, popGet(AOP(result),0));
1611 emitpcode(POC_CLRF, popCopyReg(result_hi));
1612 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1614 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1615 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1617 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1619 emitpLabel(tlbl->key);
1621 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1623 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1625 emitpcode(POC_RRF, popCopyReg(result_hi));
1626 emitpcode(POC_RRF, popGet(AOP(result),0));
1629 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1631 popReleaseTempReg(temp);
1636 /*-----------------------------------------------------------------*
1637 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1639 * this routine will call the unsigned multiply routine and then
1640 * post-fix the sign bit.
1641 *-----------------------------------------------------------------*/
1642 void genSMult8X8_16 (operand *left,
1645 pCodeOpReg *result_hi)
1649 result_hi = PCOR(popGet(AOP(result),1));
1652 genUMult8X8_16(left,right,result,result_hi);
1654 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1655 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1656 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1657 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1658 emitpcode(POC_SUBWF, popGet(AOP(result),1));
1662 /*-----------------------------------------------------------------*
1663 * genMult8X8_8 - multiplication of two 8-bit numbers
1665 * this routine will call the unsigned multiply 8X8=>16 routine and
1666 * then throw away the high byte of the result.
1668 *-----------------------------------------------------------------*/
1669 void genMult8X8_8 (operand *left,
1673 pCodeOp *result_hi = popGetTempReg();
1675 if (AOP_TYPE(right) == AOP_LIT)
1676 genUMult8XLit_16(left,right,result,PCOR(result_hi));
1678 genUMult8X8_16(left,right,result,PCOR(result_hi));
1680 popReleaseTempReg(result_hi);
1683 /*-----------------------------------------------------------------*/
1684 /* constMult - generates code for multiplication by a constant */
1685 /*-----------------------------------------------------------------*/
1686 void genMultConst(unsigned C)
1690 unsigned sr3; // Shift right 3
1696 Convert a string of 3 binary 1's in the lit into
1700 mask = 7 << ( (size*8) - 3);
1704 while(mask < (1<<size*8)) {
1706 if( (mask & lit) == lit) {
1709 /* We found 3 (or more) consecutive 1's */
1711 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1713 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1715 lit ^= consecutive_bits;
1719 sr3 |= (consecutive + lsb);