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 PIC_OPCODE poc = POC_ADDFW;
910 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL)
912 emitpcode(poc, 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));
919 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
924 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
925 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
926 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
928 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
929 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
932 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
934 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
935 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
938 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
940 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
941 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
949 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
950 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
951 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
954 /* Need to extend result to higher bytes */
955 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
957 /* First grab the carry from the lower bytes */
958 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
959 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
963 /* Now this is really horrid. Gotta check the sign of the addends and propogate
966 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
967 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
968 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
969 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
971 /* if chars or ints or being signed extended to longs: */
973 emitpcode(POC_MOVLW, popGetLit(0));
974 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
975 emitpcode(POC_MOVLW, popGetLit(0xff));
983 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
985 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
992 //adjustArithmeticResult(ic);
995 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
996 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
997 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1000 /*-----------------------------------------------------------------*/
1001 /* genMinusDec :- does subtraction with decrement if possible */
1002 /*-----------------------------------------------------------------*/
1003 bool genMinusDec (iCode *ic)
1005 unsigned int icount ;
1006 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1009 /* will try to generate an increment */
1010 /* if the right side is not a literal
1012 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1013 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1014 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1017 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1019 /* if the literal value of the right hand side
1020 is greater than 4 then it is not worth it */
1021 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1024 /* if decrement 16 bits in register */
1025 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1030 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1031 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1032 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1033 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1035 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1036 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1037 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1039 /* size is 3 or 4 */
1040 emitpcode(POC_MOVLW, popGetLit(0xff));
1041 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1043 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1045 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1047 pic14_emitcode("movlw","0xff");
1048 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1051 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1053 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1057 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1059 pic14_emitcode("skpnc","");
1061 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1070 /* if the sizes are greater than 1 then we cannot */
1071 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1072 AOP_SIZE(IC_LEFT(ic)) > 1 )
1075 /* we can if the aops of the left & result match or
1076 if they are in registers and the registers are the
1078 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1081 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1083 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1088 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1089 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1090 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1093 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1094 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1096 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1097 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1105 /*-----------------------------------------------------------------*/
1106 /* addSign - propogate sign bit to higher bytes */
1107 /*-----------------------------------------------------------------*/
1108 void addSign(operand *result, int offset, int sign)
1110 int size = (pic14_getDataSize(result) - offset);
1111 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1114 if(sign && offset) {
1117 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1118 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1119 emitpcode(POC_DECF, popGet(AOP(result),offset));
1122 emitpcode(POC_MOVLW, popGetLit(0));
1123 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1124 emitpcode(POC_MOVLW, popGetLit(0xff));
1126 emitpcode(POC_MOVWF, popGet(AOP(result),size));
1131 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1135 /*-----------------------------------------------------------------*/
1136 /* genMinusBits - generates code for subtraction of two bits */
1137 /*-----------------------------------------------------------------*/
1138 void genMinusBits (iCode *ic)
1140 symbol *lbl = newiTempLabel(NULL);
1141 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1142 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1143 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1144 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1145 pic14_emitcode("cpl","c");
1146 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1147 pic14_outBitC(IC_RESULT(ic));
1150 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1151 pic14_emitcode("subb","a,acc");
1152 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1153 pic14_emitcode("inc","a");
1154 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1155 aopPut(AOP(IC_RESULT(ic)),"a",0);
1156 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1160 /*-----------------------------------------------------------------*/
1161 /* genMinus - generates code for subtraction */
1162 /*-----------------------------------------------------------------*/
1163 void genMinus (iCode *ic)
1165 int size, offset = 0, same=0;
1166 unsigned long lit = 0L;
1168 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1169 aopOp (IC_LEFT(ic),ic,FALSE);
1170 aopOp (IC_RIGHT(ic),ic,FALSE);
1171 aopOp (IC_RESULT(ic),ic,TRUE);
1173 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1174 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1175 operand *t = IC_RIGHT(ic);
1176 IC_RIGHT(ic) = IC_LEFT(ic);
1180 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1181 AopType(AOP_TYPE(IC_RESULT(ic))),
1182 AopType(AOP_TYPE(IC_LEFT(ic))),
1183 AopType(AOP_TYPE(IC_RIGHT(ic))));
1185 /* special cases :- */
1186 /* if both left & right are in bit space */
1187 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1188 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1193 /* if I can do an decrement instead
1194 of subtract then GOOD for ME */
1195 // if (genMinusDec (ic) == TRUE)
1198 size = pic14_getDataSize(IC_RESULT(ic));
1199 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1201 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1202 /* Add a literal to something else */
1204 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1207 genAddLit ( ic, lit);
1210 /* add the first byte: */
1211 pic14_emitcode("movlw","0x%x", lit & 0xff);
1212 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1213 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1214 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1226 if((lit & 0xff) == 0xff) {
1227 emitpcode(POC_MOVLW, popGetLit(0xff));
1229 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1231 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1233 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1234 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1238 /* do the rlf known zero trick here */
1239 emitpcode(POC_MOVLW, popGetLit(1));
1241 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1246 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1249 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1250 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1251 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1253 /* here we are subtracting a bit from a char or int */
1255 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1257 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1258 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1260 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1261 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1262 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1263 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1266 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1267 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1268 emitpcode(POC_XORLW , popGetLit(1));
1269 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1270 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1272 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1274 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1275 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1277 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1278 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1281 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1283 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1285 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1286 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1290 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1291 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1292 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1293 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1298 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1299 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1300 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1303 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1305 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1308 emitpcode(POC_ANDLW , popGetLit(1));
1310 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1312 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1319 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1320 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1321 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1323 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1324 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1325 AopType(AOP_TYPE(IC_RESULT(ic))),
1326 AopType(AOP_TYPE(IC_LEFT(ic))),
1327 AopType(AOP_TYPE(IC_RIGHT(ic))));
1330 if( (size == 1) && ((lit & 0xff) == 0) ) {
1331 /* res = 0 - right */
1332 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1333 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1334 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1336 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1337 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1338 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1343 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1344 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1345 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1353 /* This is the last byte in a multibyte subtraction
1354 * There are a couple of tricks we can do by not worrying about
1355 * propogating the carry */
1357 /* 0xff - x == ~x */
1359 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1361 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1363 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1364 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1366 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1369 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1371 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1372 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1373 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1382 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1384 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1385 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1388 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1394 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1395 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1397 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1399 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1401 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1402 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1409 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1410 AopType(AOP_TYPE(IC_RESULT(ic))),
1411 AopType(AOP_TYPE(IC_LEFT(ic))),
1412 AopType(AOP_TYPE(IC_RIGHT(ic))));
1414 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1415 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1416 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1417 emitpcode(POC_SUBLW, popGetLit(0));
1418 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1421 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1422 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1423 emitpcode(POC_SUBLW, popGetLit(0));
1424 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1425 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1428 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1429 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1430 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1432 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1433 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1435 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1436 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1437 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1439 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1441 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1442 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1443 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1445 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1447 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1454 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1456 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1457 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1459 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1460 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1467 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1468 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1469 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1471 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1473 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1474 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1482 // adjustArithmeticResult(ic);
1485 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1486 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1487 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1489 /*-----------------------------------------------------------------*
1490 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1493 *-----------------------------------------------------------------*/
1494 void genUMult8XLit_16 (operand *left,
1497 pCodeOpReg *result_hi)
1502 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");
1519 same = pic14_sameRegs(AOP(left), AOP(result));
1524 emitpcode(POC_CLRF, popGet(AOP(left),0));
1527 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1528 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1531 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1532 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1533 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1536 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1537 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1538 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1541 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1542 emitpcode(POC_ANDLW, popGetLit(0xf0));
1543 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1546 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1547 emitpcode(POC_ANDLW, popGetLit(0xf0));
1548 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1556 emitpcode(POC_CLRF, popGet(AOP(result),0));
1557 emitpcode(POC_CLRF, popCopyReg(result_hi));
1560 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1561 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1562 emitpcode(POC_ADDWF, popGet(AOP(result),0));
1563 emitpcode(POC_CLRF, popCopyReg(result_hi));
1564 emitpcode(POC_RLF, popCopyReg(result_hi));
1570 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1571 emitpcode(POC_CLRF, popGet(AOP(result),0));
1572 emitpcode(POC_CLRF, popCopyReg(result_hi));
1575 for(i=0; i<8; i++) {
1578 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1582 if(have_first_bit) {
1583 emitpcode(POC_RRF, popCopyReg(result_hi));
1584 emitpcode(POC_RRF, popGet(AOP(result),0));
1592 /*-----------------------------------------------------------------*
1593 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1596 *-----------------------------------------------------------------*/
1597 void genUMult8X8_16 (operand *left,
1600 pCodeOpReg *result_hi)
1608 result_hi = PCOR(popGet(AOP(result),1));
1611 if (AOP_TYPE(right) == AOP_LIT) {
1612 genUMult8XLit_16(left,right,result,result_hi);
1617 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1619 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1620 emitpcode(POC_CLRF, popGet(AOP(result),0));
1621 emitpcode(POC_CLRF, popCopyReg(result_hi));
1624 for(i=0; i<8; i++) {
1625 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1626 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1627 emitpcode(POC_RRF, popCopyReg(result_hi));
1628 emitpcode(POC_RRF, popGet(AOP(result),0));
1633 Here's another version that does the same thing and takes the
1634 same number of instructions. The one above is slightly better
1635 because the entry instructions have a higher probability of
1636 being optimized out.
1639 emitpcode(POC_CLRF, popCopyReg(result_hi));
1640 emitpcode(POC_RRFW, popGet(AOP(left),0));
1641 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1642 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1644 for(i=0; i<8; i++) {
1646 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1647 emitpcode(POC_RRF, popCopyReg(result_hi));
1648 emitpcode(POC_RRF, popGet(AOP(result),0));
1653 symbol *tlbl = newiTempLabel(NULL);
1657 pic14_emitcode(";","Looped 8 X 8 multiplication");
1659 emitpcode(POC_CLRF, popGet(AOP(result),0));
1660 emitpcode(POC_CLRF, popCopyReg(result_hi));
1662 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1664 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1666 temp = popGetTempReg();
1667 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1669 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1671 emitpLabel(tlbl->key);
1673 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1675 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1677 emitpcode(POC_RRF, popCopyReg(result_hi));
1678 emitpcode(POC_RRF, popGet(AOP(result),0));
1681 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1683 popReleaseTempReg(temp);
1688 /*-----------------------------------------------------------------*
1689 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1691 * this routine will call the unsigned multiply routine and then
1692 * post-fix the sign bit.
1693 *-----------------------------------------------------------------*/
1694 void genSMult8X8_16 (operand *left,
1697 pCodeOpReg *result_hi)
1701 result_hi = PCOR(popGet(AOP(result),1));
1704 genUMult8X8_16(left,right,result,result_hi);
1706 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1707 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1708 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1709 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1710 emitpcode(POC_SUBWF, popGet(AOP(result),1));
1714 /*-----------------------------------------------------------------*
1715 * genMult8X8_8 - multiplication of two 8-bit numbers
1717 * this routine will call the unsigned multiply 8X8=>16 routine and
1718 * then throw away the high byte of the result.
1720 *-----------------------------------------------------------------*/
1721 void genMult8X8_8 (operand *left,
1725 pCodeOp *result_hi = popGetTempReg();
1727 if (AOP_TYPE(right) == AOP_LIT)
1728 genUMult8XLit_16(left,right,result,PCOR(result_hi));
1730 genUMult8X8_16(left,right,result,PCOR(result_hi));
1732 popReleaseTempReg(result_hi);
1735 /*-----------------------------------------------------------------*/
1736 /* constMult - generates code for multiplication by a constant */
1737 /*-----------------------------------------------------------------*/
1738 void genMultConst(unsigned C)
1742 unsigned sr3; // Shift right 3
1748 Convert a string of 3 binary 1's in the lit into
1752 mask = 7 << ( (size*8) - 3);
1756 while(mask < (1<<size*8)) {
1758 if( (mask & lit) == lit) {
1761 /* We found 3 (or more) consecutive 1's */
1763 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1765 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1767 lit ^= consecutive_bits;
1771 sr3 |= (consecutive + lsb);