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"
39 #if defined(_MSC_VER) && (_MSC_VER < 1300)
40 #define __FUNCTION__ __FILE__
44 #include "SDCCpeeph.h"
50 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
51 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result);
53 const char *AopType(short type)
100 const char *pCodeOpType( pCodeOp *pcop)
119 case PO_GPR_REGISTER:
120 return "PO_GPR_REGISTER";
124 return "PO_GPR_TEMP";
125 case PO_SFR_REGISTER:
126 return "PO_SFR_REGISTER";
134 return "PO_IMMEDIATE";
150 return "BAD PO_TYPE";
153 /*-----------------------------------------------------------------*/
154 /* genPlusIncr :- does addition with increment if possible */
155 /*-----------------------------------------------------------------*/
156 bool genPlusIncr (iCode *ic)
158 unsigned int icount ;
159 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
161 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
162 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
163 AopType(AOP_TYPE(IC_RESULT(ic))),
164 AopType(AOP_TYPE(IC_LEFT(ic))),
165 AopType(AOP_TYPE(IC_RIGHT(ic))));
167 /* will try to generate an increment */
168 /* if the right side is not a literal
170 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
173 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
174 /* if the literal value of the right hand side
175 is greater than 1 then it is faster to add */
176 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
179 /* if increment 16 bits in register */
180 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
185 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB));
186 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
190 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
191 //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
197 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
198 /* if left is in accumulator - probably a bit operation*/
199 if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
200 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
202 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
203 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
204 AOP(IC_RESULT(ic))->aopu.aop_dir,
205 AOP(IC_RESULT(ic))->aopu.aop_dir);
207 emitpcode(POC_XORLW,popGetLit(1));
208 //pic14_emitcode("xorlw","1");
210 emitpcode(POC_ANDLW,popGetLit(1));
211 //pic14_emitcode("andlw","1");
214 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
215 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
216 AOP(IC_RESULT(ic))->aopu.aop_dir,
217 AOP(IC_RESULT(ic))->aopu.aop_dir);
224 /* if the sizes are greater than 1 then we cannot */
225 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
226 AOP_SIZE(IC_LEFT(ic)) > 1 )
229 /* If we are incrementing the same register by two: */
231 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
234 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
235 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
240 DEBUGpic14_emitcode ("; ","couldn't increment ");
245 /*-----------------------------------------------------------------*/
246 /* pic14_outBitAcc - output a bit in acc */
247 /*-----------------------------------------------------------------*/
248 void pic14_outBitAcc(operand *result)
250 symbol *tlbl = newiTempLabel(NULL);
251 /* if the result is a bit */
252 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
254 if (AOP_TYPE(result) == AOP_CRY){
255 aopPut(AOP(result),"a",0);
258 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
259 pic14_emitcode("mov","a,#01");
260 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
261 pic14_outAcc(result);
265 /*-----------------------------------------------------------------*/
266 /* genPlusBits - generates code for addition of two bits */
267 /*-----------------------------------------------------------------*/
268 void genPlusBits (iCode *ic)
271 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
273 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
274 AopType(AOP_TYPE(IC_RESULT(ic))),
275 AopType(AOP_TYPE(IC_LEFT(ic))),
276 AopType(AOP_TYPE(IC_RIGHT(ic))));
278 The following block of code will add two bits.
279 Note that it'll even work if the destination is
280 the carry (C in the status register).
281 It won't work if the 'Z' bit is a source or destination.
284 /* If the result is stored in the accumulator (w) */
285 //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
286 switch(AOP_TYPE(IC_RESULT(ic))) {
288 emitpcode(POC_CLRW, NULL);
289 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
290 emitpcode(POC_XORLW, popGetLit(1));
291 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
292 emitpcode(POC_XORLW, popGetLit(1));
294 pic14_emitcode("clrw","");
295 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
296 AOP(IC_RIGHT(ic))->aopu.aop_dir,
297 AOP(IC_RIGHT(ic))->aopu.aop_dir);
298 pic14_emitcode("xorlw","1");
299 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
300 AOP(IC_LEFT(ic))->aopu.aop_dir,
301 AOP(IC_LEFT(ic))->aopu.aop_dir);
302 pic14_emitcode("xorlw","1");
305 emitpcode(POC_MOVLW, popGetLit(0));
306 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
307 emitpcode(POC_XORLW, popGetLit(1));
308 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
309 emitpcode(POC_XORLW, popGetLit(1));
310 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
313 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
314 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
315 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
316 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
317 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
318 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
320 pic14_emitcode("movlw","(1 << (%s & 7))",
321 AOP(IC_RESULT(ic))->aopu.aop_dir,
322 AOP(IC_RESULT(ic))->aopu.aop_dir);
323 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
324 AOP(IC_RESULT(ic))->aopu.aop_dir,
325 AOP(IC_RESULT(ic))->aopu.aop_dir);
326 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
327 AOP(IC_RIGHT(ic))->aopu.aop_dir,
328 AOP(IC_RIGHT(ic))->aopu.aop_dir);
329 pic14_emitcode("xorwf","(%s >>3),f",
330 AOP(IC_RESULT(ic))->aopu.aop_dir);
331 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
332 AOP(IC_LEFT(ic))->aopu.aop_dir,
333 AOP(IC_LEFT(ic))->aopu.aop_dir);
334 pic14_emitcode("xorwf","(%s>>3),f",
335 AOP(IC_RESULT(ic))->aopu.aop_dir);
342 /* This is the original version of this code.
344 * This is being kept around for reference,
345 * because I am not entirely sure I got it right...
347 static void adjustArithmeticResult(iCode *ic)
349 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
350 AOP_SIZE(IC_LEFT(ic)) == 3 &&
351 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
352 aopPut(AOP(IC_RESULT(ic)),
353 aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
356 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
357 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
358 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
359 aopPut(AOP(IC_RESULT(ic)),
360 aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
363 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
364 AOP_SIZE(IC_LEFT(ic)) < 3 &&
365 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
366 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
367 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
369 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
370 aopPut(AOP(IC_RESULT(ic)),buffer,2);
374 /* This is the pure and virtuous version of this code.
375 * I'm pretty certain it's right, but not enough to toss the old
378 static void adjustArithmeticResult(iCode *ic)
380 if (opIsGptr(IC_RESULT(ic)) &&
381 opIsGptr(IC_LEFT(ic)) &&
382 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
384 aopPut(AOP(IC_RESULT(ic)),
385 aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
389 if (opIsGptr(IC_RESULT(ic)) &&
390 opIsGptr(IC_RIGHT(ic)) &&
391 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
393 aopPut(AOP(IC_RESULT(ic)),
394 aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
398 if (opIsGptr(IC_RESULT(ic)) &&
399 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
400 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
401 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
402 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
404 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
405 aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
410 /*-----------------------------------------------------------------*/
411 /* genAddlit - generates code for addition */
412 /*-----------------------------------------------------------------*/
413 static void genAddLit2byte (operand *result, int offr, int lit)
420 emitpcode(POC_INCF, popGet(AOP(result),offr));
423 emitpcode(POC_DECF, popGet(AOP(result),offr));
426 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
427 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
432 static void emitMOVWF(operand *reg, int offset)
437 if (AOP_TYPE(reg) == AOP_ACC) {
438 DEBUGpic14_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
442 emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
446 static void genAddLit (iCode *ic, int lit)
455 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
459 result = IC_RESULT(ic);
460 same = pic14_sameRegs(AOP(left), AOP(result));
461 size = pic14_getDataSize(result);
465 /* Handle special cases first */
467 genAddLit2byte (result, 0, lit);
470 int hi = 0xff & (lit >> 8);
477 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
482 emitpcode(POC_INCF, popGet(AOP(result),0));
484 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
487 emitpcode(POC_DECF, popGet(AOP(result),0));
488 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
489 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
493 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
494 emitpcode(POC_ADDWF,popGet(AOP(result),0));
496 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
504 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
507 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
510 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
511 emitpcode(POC_INCF, popGet(AOP(result),0));
513 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
515 case 0xff: /* 0x01ff */
516 emitpcode(POC_DECF, popGet(AOP(result),0));
517 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
518 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
519 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
524 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
528 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
531 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
532 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
534 /* case 0xff: * 0xffff *
535 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
536 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
537 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
541 emitpcode(POC_MOVLW,popGetLit(lo));
542 emitpcode(POC_ADDWF,popGet(AOP(result),0));
544 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
551 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
556 genAddLit2byte (result, MSB16, hi);
559 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
560 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
561 emitpcode(POC_MOVLW,popGetLit(hi));
562 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
564 /* case 0xff: * 0xHHff *
565 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
566 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
567 emitpcode(POC_MOVLW,popGetLit(hi));
568 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
570 */ default: /* 0xHHLL */
571 emitpcode(POC_MOVLW,popGetLit(lo));
572 emitpcode(POC_ADDWF, popGet(AOP(result),0));
573 emitpcode(POC_MOVLW,popGetLit(hi));
575 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
576 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
585 DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
588 lo = BYTEofLONG(lit,0);
596 emitpcode(POC_INCF, popGet(AOP(result),offset));
599 emitpcode(POC_RLFW, popGet(AOP(result),offset));
600 emitpcode(POC_ANDLW,popGetLit(1));
601 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
603 default: /* carry_info = 3 */
605 emitpcode(POC_INCF, popGet(AOP(result),offset));
611 emitpcode(POC_MOVLW,popGetLit(lo));
616 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
619 emitpcode(POC_MOVLW,popGetLit(lo));
624 emitpcode(POC_MOVLW,popGetLit(lo+1));
625 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
630 /* no carry info from previous step */
631 /* this means this is the first time to add */
636 emitpcode(POC_INCF, popGet(AOP(result),offset));
640 emitpcode(POC_MOVLW,popGetLit(lo));
641 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
643 carry_info = 3; /* Were adding only one byte and propogating the carry */
654 lo = BYTEofLONG(lit,0);
659 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
662 emitpcode(POC_MOVLW,popGetLit(lo));
663 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
666 emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
668 emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
670 emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
680 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
684 if(AOP_TYPE(left) == AOP_ACC) {
685 /* left addend is already in accumulator */
688 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
692 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
693 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
697 /* left addend is in a register */
700 emitpcode(POC_MOVFW, popGet(AOP(left),0));
701 emitMOVWF(result, 0);
702 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
706 emitpcode(POC_INCFW, popGet(AOP(left),0));
707 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
711 emitpcode(POC_DECFW, popGet(AOP(left),0));
712 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
716 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
717 emitpcode(POC_ADDFW, popGet(AOP(left),0));
718 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
726 /* left is not the accumulator */
728 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
729 emitpcode(POC_ADDFW, popGet(AOP(left),0));
731 emitpcode(POC_MOVFW, popGet(AOP(left),0));
732 /* We don't know the state of the carry bit at this point */
735 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
742 /* The ls byte of the lit must've been zero - that
743 means we don't have to deal with carry */
745 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
746 emitpcode(POC_ADDFW, popGet(AOP(left),offset));
747 emitpcode(POC_MOVWF, popGet(AOP(left),offset));
752 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
753 //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
754 emitMOVWF(result,offset);
755 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
757 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
758 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
762 emitpcode(POC_CLRF, popGet(AOP(result),offset));
763 emitpcode(POC_RLF, popGet(AOP(result),offset));
764 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
765 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
773 /*-----------------------------------------------------------------*/
774 /* genPlus - generates code for addition */
775 /*-----------------------------------------------------------------*/
776 void genPlus (iCode *ic)
778 int size, offset = 0;
780 /* special cases :- */
781 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
783 aopOp (IC_LEFT(ic),ic,FALSE);
784 aopOp (IC_RIGHT(ic),ic,FALSE);
785 aopOp (IC_RESULT(ic),ic,TRUE);
787 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
789 /* if literal, literal on the right or
790 if left requires ACC or right is already
793 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
794 operand *t = IC_RIGHT(ic);
795 IC_RIGHT(ic) = IC_LEFT(ic);
799 /* if both left & right are in bit space */
800 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
801 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
806 /* if left in bit space & right literal */
807 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
808 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
809 /* if result in bit space */
810 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
811 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
812 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
813 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
814 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
815 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
818 size = pic14_getDataSize(IC_RESULT(ic));
820 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
821 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
822 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
828 /* if I can do an increment instead
829 of add then GOOD for ME */
830 if (genPlusIncr (ic) == TRUE)
833 size = pic14_getDataSize(IC_RESULT(ic));
835 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
836 /* Add a literal to something else */
838 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
842 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
847 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
849 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
850 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
851 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
853 /* here we are adding a bit to a char or int */
855 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
857 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
858 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
860 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
861 AOP(IC_RIGHT(ic))->aopu.aop_dir,
862 AOP(IC_RIGHT(ic))->aopu.aop_dir);
863 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
866 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
867 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
868 emitpcode(POC_XORLW , popGetLit(1));
870 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
871 AOP(IC_RIGHT(ic))->aopu.aop_dir,
872 AOP(IC_RIGHT(ic))->aopu.aop_dir);
873 pic14_emitcode(" xorlw","1");
875 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
876 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
877 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
879 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
880 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
881 AOP(IC_RIGHT(ic))->aopu.aop_dir,
882 AOP(IC_RIGHT(ic))->aopu.aop_dir);
883 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
886 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
888 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
889 emitpcode(POC_ANDLW , popGetLit(1));
890 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
892 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
894 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
895 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
902 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
903 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
905 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
906 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
908 pic14_emitcode("clrz","");
910 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
911 AOP(IC_RIGHT(ic))->aopu.aop_dir,
912 AOP(IC_RIGHT(ic))->aopu.aop_dir);
913 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
917 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
918 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
919 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
920 //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
921 emitMOVWF(IC_RIGHT(ic),0);
923 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
924 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
925 AOP(IC_RIGHT(ic))->aopu.aop_dir,
926 AOP(IC_RIGHT(ic))->aopu.aop_dir);
927 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
928 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
934 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
935 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
941 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
943 /* Add the first bytes */
945 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
946 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
947 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
950 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
951 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
952 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
953 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
956 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
958 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
959 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
961 PIC_OPCODE poc = POC_ADDFW;
963 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
964 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
965 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
967 emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0));
968 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
969 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
974 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
979 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
980 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
981 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
983 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
984 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
987 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
989 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
990 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
993 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
995 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
996 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1004 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1005 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1006 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1009 /* Need to extend result to higher bytes */
1010 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1012 /* First grab the carry from the lower bytes */
1013 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1014 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
1018 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1021 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1022 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1023 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1024 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1026 /* if chars or ints or being signed extended to longs: */
1028 emitpcode(POC_MOVLW, popGetLit(0));
1029 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1030 emitpcode(POC_MOVLW, popGetLit(0xff));
1038 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1040 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1047 //adjustArithmeticResult(ic);
1050 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1051 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1052 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1055 /*-----------------------------------------------------------------*/
1056 /* genMinusDec :- does subtraction with decrement if possible */
1057 /*-----------------------------------------------------------------*/
1058 bool genMinusDec (iCode *ic)
1060 unsigned int icount ;
1061 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1063 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1064 /* will try to generate an increment */
1065 /* if the right side is not a literal
1067 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1068 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1069 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1072 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1074 /* if the literal value of the right hand side
1075 is greater than 4 then it is not worth it */
1076 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1079 /* if decrement 16 bits in register */
1080 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1085 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1086 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1087 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1088 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1090 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1091 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1092 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1094 /* size is 3 or 4 */
1095 emitpcode(POC_MOVLW, popGetLit(0xff));
1096 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1098 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1100 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1102 pic14_emitcode("movlw","0xff");
1103 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1106 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1108 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1112 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1114 pic14_emitcode("skpnc","");
1116 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1125 /* if the sizes are greater than 1 then we cannot */
1126 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1127 AOP_SIZE(IC_LEFT(ic)) > 1 )
1130 /* we can if the aops of the left & result match or
1131 if they are in registers and the registers are the
1133 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1136 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1138 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1143 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1144 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1145 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1148 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1149 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1151 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1152 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1160 /*-----------------------------------------------------------------*/
1161 /* addSign - propogate sign bit to higher bytes */
1162 /*-----------------------------------------------------------------*/
1163 void addSign(operand *result, int offset, int sign)
1165 int size = (pic14_getDataSize(result) - offset);
1166 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1169 if(sign && offset) {
1172 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1173 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1174 emitpcode(POC_DECF, popGet(AOP(result),offset));
1177 emitpcode(POC_MOVLW, popGetLit(0));
1178 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1179 emitpcode(POC_MOVLW, popGetLit(0xff));
1181 emitpcode(POC_MOVWF, popGet(AOP(result),size));
1186 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1190 /*-----------------------------------------------------------------*/
1191 /* genMinusBits - generates code for subtraction of two bits */
1192 /*-----------------------------------------------------------------*/
1193 void genMinusBits (iCode *ic)
1195 symbol *lbl = newiTempLabel(NULL);
1196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1197 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1198 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1199 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1200 pic14_emitcode("cpl","c");
1201 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1202 pic14_outBitC(IC_RESULT(ic));
1205 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1206 pic14_emitcode("subb","a,acc");
1207 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1208 pic14_emitcode("inc","a");
1209 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1210 aopPut(AOP(IC_RESULT(ic)),"a",0);
1211 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1215 /*-----------------------------------------------------------------*/
1216 /* genMinus - generates code for subtraction */
1217 /*-----------------------------------------------------------------*/
1218 void genMinus (iCode *ic)
1220 int size, offset = 0, same=0;
1221 unsigned long lit = 0L;
1223 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1224 aopOp (IC_LEFT(ic),ic,FALSE);
1225 aopOp (IC_RIGHT(ic),ic,FALSE);
1226 aopOp (IC_RESULT(ic),ic,TRUE);
1228 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1229 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1230 operand *t = IC_RIGHT(ic);
1231 IC_RIGHT(ic) = IC_LEFT(ic);
1235 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1236 AopType(AOP_TYPE(IC_RESULT(ic))),
1237 AopType(AOP_TYPE(IC_LEFT(ic))),
1238 AopType(AOP_TYPE(IC_RIGHT(ic))));
1240 /* special cases :- */
1241 /* if both left & right are in bit space */
1242 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1243 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1248 /* if I can do an decrement instead
1249 of subtract then GOOD for ME */
1250 // if (genMinusDec (ic) == TRUE)
1253 size = pic14_getDataSize(IC_RESULT(ic));
1254 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1256 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1257 /* Add a literal to something else */
1259 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1262 genAddLit ( ic, lit);
1265 /* add the first byte: */
1266 pic14_emitcode("movlw","0x%x", lit & 0xff);
1267 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1268 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1269 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1281 if((lit & 0xff) == 0xff) {
1282 emitpcode(POC_MOVLW, popGetLit(0xff));
1284 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1286 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1288 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1289 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1293 /* do the rlf known zero trick here */
1294 emitpcode(POC_MOVLW, popGetLit(1));
1296 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1301 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1304 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1305 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1306 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1308 /* here we are subtracting a bit from a char or int */
1310 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1312 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1313 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1315 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1316 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1317 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1318 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1321 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1322 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1323 emitpcode(POC_XORLW , popGetLit(1));
1324 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1325 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1327 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1329 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1330 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1332 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1333 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1336 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1338 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1340 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1341 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1345 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1346 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1347 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1348 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1353 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1354 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1355 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1358 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1360 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1363 emitpcode(POC_ANDLW , popGetLit(1));
1365 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1367 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1374 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1375 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1376 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1378 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1379 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1380 AopType(AOP_TYPE(IC_RESULT(ic))),
1381 AopType(AOP_TYPE(IC_LEFT(ic))),
1382 AopType(AOP_TYPE(IC_RIGHT(ic))));
1385 if( (size == 1) && ((lit & 0xff) == 0) ) {
1386 /* res = 0 - right */
1387 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1388 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1389 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1391 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1392 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1393 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1398 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1399 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1400 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1408 /* This is the last byte in a multibyte subtraction
1409 * There are a couple of tricks we can do by not worrying about
1410 * propogating the carry */
1412 /* 0xff - x == ~x */
1414 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1416 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1418 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1419 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1421 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1424 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1426 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1427 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1428 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1437 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1439 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1440 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1443 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1449 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1450 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1452 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1454 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1456 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1457 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1464 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1465 AopType(AOP_TYPE(IC_RESULT(ic))),
1466 AopType(AOP_TYPE(IC_LEFT(ic))),
1467 AopType(AOP_TYPE(IC_RIGHT(ic))));
1469 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1470 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1471 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1472 emitpcode(POC_SUBLW, popGetLit(0));
1473 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1476 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1477 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1478 emitpcode(POC_SUBLW, popGetLit(0));
1479 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1480 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1483 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1484 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1485 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1487 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1488 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1490 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1491 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1492 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1494 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1496 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1497 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1498 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1500 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1502 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1509 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1511 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1512 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1514 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1515 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1522 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1523 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1524 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1526 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1528 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1529 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1537 // adjustArithmeticResult(ic);
1540 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1541 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1542 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1544 /*-----------------------------------------------------------------*
1545 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1548 *-----------------------------------------------------------------*/
1549 void genUMult8XLit_16 (operand *left,
1552 pCodeOpReg *result_hi)
1557 unsigned int i,have_first_bit;
1561 if (AOP_TYPE(right) != AOP_LIT){
1562 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1568 result_hi = PCOR(popGet(AOP(result),1));
1571 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1573 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1575 same = pic14_sameRegs(AOP(left), AOP(result));
1580 emitpcode(POC_CLRF, popGet(AOP(left),0));
1583 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1584 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1587 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1588 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1589 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1592 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1593 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1594 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1595 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1598 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1599 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1600 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1601 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1604 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1605 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1606 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1607 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1608 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1611 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1612 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1613 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1614 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1615 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F
1618 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1619 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1620 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1621 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1622 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1625 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1626 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1627 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1628 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1629 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1630 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1633 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1634 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1635 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1636 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1637 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1638 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1641 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1642 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1643 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1644 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1645 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1646 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F
1649 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1650 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1651 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1652 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1653 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1654 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1655 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1658 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1659 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1660 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1661 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1662 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1663 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*F
1666 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1667 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1668 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1669 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1670 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1671 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F
1672 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F
1675 temp = popGetTempReg();
1677 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1680 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1681 emitpcode(POC_MOVWF, temp);
1682 emitpcode(POC_ANDLW, popGetLit(0xf0));
1683 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1684 emitpcode(POC_SWAPFW, temp);
1685 emitpcode(POC_SUBWF, popGet(AOP(left),0));
1686 popReleaseTempReg(temp);
1689 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1690 emitpcode(POC_ANDLW, popGetLit(0xf0));
1691 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1694 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1695 emitpcode(POC_ANDLW, popGetLit(0xf0));
1696 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1699 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1700 emitpcode(POC_RLFW, popGet(AOP(left),0));
1701 emitpcode(POC_ANDLW, popGetLit(0xe0));
1702 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1705 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1706 emitpcode(POC_RLF, popGet(AOP(left),0));
1707 emitpcode(POC_RLFW, popGet(AOP(left),0));
1708 emitpcode(POC_ANDLW, popGetLit(0xc0));
1709 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1712 emitpcode(POC_RRFW, popGet(AOP(left),0));
1713 emitpcode(POC_CLRF, popGet(AOP(left),0));
1714 emitpcode(POC_RRF, popGet(AOP(left),0));
1722 emitpcode(POC_CLRF, popGet(AOP(result),0));
1723 emitpcode(POC_CLRF, popCopyReg(result_hi));
1726 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1727 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1728 emitpcode(POC_ADDWF, popGet(AOP(result),0));
1729 emitpcode(POC_CLRF, popCopyReg(result_hi));
1730 emitpcode(POC_RLF, popCopyReg(result_hi));
1736 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1737 emitpcode(POC_CLRF, popGet(AOP(result),0));
1738 emitpcode(POC_CLRF, popCopyReg(result_hi));
1741 for(i=0; i<8; i++) {
1744 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1748 if(have_first_bit) {
1749 emitpcode(POC_RRF, popCopyReg(result_hi));
1750 emitpcode(POC_RRF, popGet(AOP(result),0));
1758 /*-----------------------------------------------------------------*
1759 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1762 *-----------------------------------------------------------------*/
1763 void genUMult8X8_16 (operand *left,
1766 pCodeOpReg *result_hi)
1774 result_hi = PCOR(popGet(AOP(result),1));
1777 if (AOP_TYPE(right) == AOP_LIT) {
1778 genUMult8XLit_16(left,right,result,result_hi);
1783 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1785 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1786 emitpcode(POC_CLRF, popGet(AOP(result),0));
1787 emitpcode(POC_CLRF, popCopyReg(result_hi));
1790 for(i=0; i<8; i++) {
1791 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1792 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1793 emitpcode(POC_RRF, popCopyReg(result_hi));
1794 emitpcode(POC_RRF, popGet(AOP(result),0));
1799 Here's another version that does the same thing and takes the
1800 same number of instructions. The one above is slightly better
1801 because the entry instructions have a higher probability of
1802 being optimized out.
1805 emitpcode(POC_CLRF, popCopyReg(result_hi));
1806 emitpcode(POC_RRFW, popGet(AOP(left),0));
1807 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1808 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1810 for(i=0; i<8; i++) {
1812 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1813 emitpcode(POC_RRF, popCopyReg(result_hi));
1814 emitpcode(POC_RRF, popGet(AOP(result),0));
1819 symbol *tlbl = newiTempLabel(NULL);
1823 pic14_emitcode(";","Looped 8 X 8 multiplication");
1825 emitpcode(POC_CLRF, popGet(AOP(result),0));
1826 emitpcode(POC_CLRF, popCopyReg(result_hi));
1828 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1830 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1832 temp = popGetTempReg();
1833 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1835 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1837 emitpLabel(tlbl->key);
1839 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1841 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1843 emitpcode(POC_RRF, popCopyReg(result_hi));
1844 emitpcode(POC_RRF, popGet(AOP(result),0));
1847 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1849 popReleaseTempReg(temp);
1854 /*-----------------------------------------------------------------*
1855 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1857 * this routine will call the unsigned multiply routine and then
1858 * post-fix the sign bit.
1859 *-----------------------------------------------------------------*/
1860 void genSMult8X8_16 (operand *left,
1863 pCodeOpReg *result_hi)
1867 result_hi = PCOR(popGet(AOP(result),1));
1870 genUMult8X8_16(left,right,result,result_hi);
1872 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1873 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1874 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1875 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1876 emitpcode(POC_SUBWF, popGet(AOP(result),1));
1880 /*-----------------------------------------------------------------*
1881 * genMult8X8_8 - multiplication of two 8-bit numbers
1883 * this routine will call the unsigned multiply 8X8=>16 routine and
1884 * then throw away the high byte of the result.
1886 *-----------------------------------------------------------------*/
1887 void genMult8X8_8 (operand *left,
1891 pCodeOp *result_hi = popGetTempReg();
1893 if (AOP_TYPE(right) == AOP_LIT)
1894 genUMult8XLit_16(left,right,result,PCOR(result_hi));
1896 genUMult8X8_16(left,right,result,PCOR(result_hi));
1898 popReleaseTempReg(result_hi);
1901 /*-----------------------------------------------------------------*/
1902 /* constMult - generates code for multiplication by a constant */
1903 /*-----------------------------------------------------------------*/
1904 void genMultConst(unsigned C)
1908 unsigned sr3; // Shift right 3
1914 Convert a string of 3 binary 1's in the lit into
1918 mask = 7 << ( (size*8) - 3);
1922 while(mask < (1<<size*8)) {
1924 if( (mask & lit) == lit) {
1927 /* We found 3 (or more) consecutive 1's */
1929 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1931 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1933 lit ^= consecutive_bits;
1937 sr3 |= (consecutive + lsb);