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)
117 const char *pCodeOpType( pCodeOp *pcop)
136 case PO_GPR_REGISTER:
137 return "PO_GPR_REGISTER";
141 return "PO_GPR_TEMP";
142 case PO_SFR_REGISTER:
143 return "PO_SFR_REGISTER";
151 return "PO_IMMEDIATE";
167 return "BAD PO_TYPE";
170 /*-----------------------------------------------------------------*/
171 /* genPlusIncr :- does addition with increment if possible */
172 /*-----------------------------------------------------------------*/
173 bool genPlusIncr (iCode *ic)
175 unsigned int icount ;
176 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
178 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
179 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
180 AopType(AOP_TYPE(IC_RESULT(ic))),
181 AopType(AOP_TYPE(IC_LEFT(ic))),
182 AopType(AOP_TYPE(IC_RIGHT(ic))));
184 /* will try to generate an increment */
185 /* if the right side is not a literal
187 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
190 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
191 /* if the literal value of the right hand side
192 is greater than 1 then it is faster to add */
193 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
196 /* if increment 16 bits in register */
197 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
202 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB));
203 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
207 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
208 //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
214 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
215 /* if left is in accumulator - probably a bit operation*/
216 if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
217 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
219 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
220 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
221 AOP(IC_RESULT(ic))->aopu.aop_dir,
222 AOP(IC_RESULT(ic))->aopu.aop_dir);
224 emitpcode(POC_XORLW,popGetLit(1));
225 //pic14_emitcode("xorlw","1");
227 emitpcode(POC_ANDLW,popGetLit(1));
228 //pic14_emitcode("andlw","1");
231 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
232 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
233 AOP(IC_RESULT(ic))->aopu.aop_dir,
234 AOP(IC_RESULT(ic))->aopu.aop_dir);
241 /* if the sizes are greater than 1 then we cannot */
242 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
243 AOP_SIZE(IC_LEFT(ic)) > 1 )
246 /* If we are incrementing the same register by two: */
248 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
251 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
252 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
257 DEBUGpic14_emitcode ("; ","couldn't increment ");
262 /*-----------------------------------------------------------------*/
263 /* pic14_outBitAcc - output a bit in acc */
264 /*-----------------------------------------------------------------*/
265 void pic14_outBitAcc(operand *result)
267 symbol *tlbl = newiTempLabel(NULL);
268 /* if the result is a bit */
269 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
271 if (AOP_TYPE(result) == AOP_CRY){
272 aopPut(AOP(result),"a",0);
275 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
276 pic14_emitcode("mov","a,#01");
277 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
278 pic14_outAcc(result);
282 /*-----------------------------------------------------------------*/
283 /* genPlusBits - generates code for addition of two bits */
284 /*-----------------------------------------------------------------*/
285 void genPlusBits (iCode *ic)
288 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
290 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
291 AopType(AOP_TYPE(IC_RESULT(ic))),
292 AopType(AOP_TYPE(IC_LEFT(ic))),
293 AopType(AOP_TYPE(IC_RIGHT(ic))));
295 The following block of code will add two bits.
296 Note that it'll even work if the destination is
297 the carry (C in the status register).
298 It won't work if the 'Z' bit is a source or destination.
301 /* If the result is stored in the accumulator (w) */
302 //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
303 switch(AOP_TYPE(IC_RESULT(ic))) {
305 emitpcode(POC_CLRW, NULL);
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));
311 pic14_emitcode("clrw","");
312 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
313 AOP(IC_RIGHT(ic))->aopu.aop_dir,
314 AOP(IC_RIGHT(ic))->aopu.aop_dir);
315 pic14_emitcode("xorlw","1");
316 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
317 AOP(IC_LEFT(ic))->aopu.aop_dir,
318 AOP(IC_LEFT(ic))->aopu.aop_dir);
319 pic14_emitcode("xorlw","1");
322 emitpcode(POC_MOVLW, popGetLit(0));
323 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
324 emitpcode(POC_XORLW, popGetLit(1));
325 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
326 emitpcode(POC_XORLW, popGetLit(1));
327 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
330 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
331 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
332 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
333 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
334 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
335 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
337 pic14_emitcode("movlw","(1 << (%s & 7))",
338 AOP(IC_RESULT(ic))->aopu.aop_dir,
339 AOP(IC_RESULT(ic))->aopu.aop_dir);
340 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
341 AOP(IC_RESULT(ic))->aopu.aop_dir,
342 AOP(IC_RESULT(ic))->aopu.aop_dir);
343 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
344 AOP(IC_RIGHT(ic))->aopu.aop_dir,
345 AOP(IC_RIGHT(ic))->aopu.aop_dir);
346 pic14_emitcode("xorwf","(%s >>3),f",
347 AOP(IC_RESULT(ic))->aopu.aop_dir);
348 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
349 AOP(IC_LEFT(ic))->aopu.aop_dir,
350 AOP(IC_LEFT(ic))->aopu.aop_dir);
351 pic14_emitcode("xorwf","(%s>>3),f",
352 AOP(IC_RESULT(ic))->aopu.aop_dir);
359 /* This is the original version of this code.
361 * This is being kept around for reference,
362 * because I am not entirely sure I got it right...
364 static void adjustArithmeticResult(iCode *ic)
366 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
367 AOP_SIZE(IC_LEFT(ic)) == 3 &&
368 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
369 aopPut(AOP(IC_RESULT(ic)),
370 aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
373 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
374 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
375 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
376 aopPut(AOP(IC_RESULT(ic)),
377 aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
380 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
381 AOP_SIZE(IC_LEFT(ic)) < 3 &&
382 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
383 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
384 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
386 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
387 aopPut(AOP(IC_RESULT(ic)),buffer,2);
391 /* This is the pure and virtuous version of this code.
392 * I'm pretty certain it's right, but not enough to toss the old
395 static void adjustArithmeticResult(iCode *ic)
397 if (opIsGptr(IC_RESULT(ic)) &&
398 opIsGptr(IC_LEFT(ic)) &&
399 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
401 aopPut(AOP(IC_RESULT(ic)),
402 aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
406 if (opIsGptr(IC_RESULT(ic)) &&
407 opIsGptr(IC_RIGHT(ic)) &&
408 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
410 aopPut(AOP(IC_RESULT(ic)),
411 aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
415 if (opIsGptr(IC_RESULT(ic)) &&
416 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
417 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
418 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
419 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
421 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
422 aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
427 /*-----------------------------------------------------------------*/
428 /* genAddlit - generates code for addition */
429 /*-----------------------------------------------------------------*/
430 static void genAddLit2byte (operand *result, int offr, int lit)
437 emitpcode(POC_INCF, popGet(AOP(result),offr));
440 emitpcode(POC_DECF, popGet(AOP(result),offr));
443 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
444 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
449 static void emitMOVWF(operand *reg, int offset)
454 if (AOP_TYPE(reg) == AOP_ACC) {
455 DEBUGpic14_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
459 emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
463 static void genAddLit (iCode *ic, int lit)
472 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
476 result = IC_RESULT(ic);
477 same = pic14_sameRegs(AOP(left), AOP(result));
478 size = pic14_getDataSize(result);
482 /* Handle special cases first */
484 genAddLit2byte (result, 0, lit);
487 int hi = 0xff & (lit >> 8);
494 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
499 emitpcode(POC_INCF, popGet(AOP(result),0));
501 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
504 emitpcode(POC_DECF, popGet(AOP(result),0));
505 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
506 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
510 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
511 emitpcode(POC_ADDWF,popGet(AOP(result),0));
513 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
521 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
524 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
527 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
528 emitpcode(POC_INCF, popGet(AOP(result),0));
530 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
532 case 0xff: /* 0x01ff */
533 emitpcode(POC_DECF, popGet(AOP(result),0));
534 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
535 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
536 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
541 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
545 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
548 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
549 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
551 /* case 0xff: * 0xffff *
552 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
553 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
554 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
558 emitpcode(POC_MOVLW,popGetLit(lo));
559 emitpcode(POC_ADDWF,popGet(AOP(result),0));
561 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
568 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
573 genAddLit2byte (result, MSB16, hi);
576 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
577 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
578 emitpcode(POC_MOVLW,popGetLit(hi));
579 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
581 /* case 0xff: * 0xHHff *
582 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
583 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
584 emitpcode(POC_MOVLW,popGetLit(hi));
585 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
587 */ default: /* 0xHHLL */
588 emitpcode(POC_MOVLW,popGetLit(lo));
589 emitpcode(POC_ADDWF, popGet(AOP(result),0));
590 emitpcode(POC_MOVLW,popGetLit(hi));
592 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
593 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
602 DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
605 lo = BYTEofLONG(lit,0);
613 emitpcode(POC_INCF, popGet(AOP(result),offset));
616 emitpcode(POC_RLFW, popGet(AOP(result),offset));
617 emitpcode(POC_ANDLW,popGetLit(1));
618 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
620 default: /* carry_info = 3 */
622 emitpcode(POC_INCF, popGet(AOP(result),offset));
628 emitpcode(POC_MOVLW,popGetLit(lo));
633 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
636 emitpcode(POC_MOVLW,popGetLit(lo));
641 emitpcode(POC_MOVLW,popGetLit(lo+1));
642 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
647 /* no carry info from previous step */
648 /* this means this is the first time to add */
653 emitpcode(POC_INCF, popGet(AOP(result),offset));
657 emitpcode(POC_MOVLW,popGetLit(lo));
658 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
660 carry_info = 3; /* Were adding only one byte and propogating the carry */
671 lo = BYTEofLONG(lit,0);
676 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
679 emitpcode(POC_MOVLW,popGetLit(lo));
680 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
683 emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
685 emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
687 emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
697 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
701 if(AOP_TYPE(left) == AOP_ACC) {
702 /* left addend is already in accumulator */
705 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
709 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
710 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
714 /* left addend is in a register */
717 emitpcode(POC_MOVFW, popGet(AOP(left),0));
718 emitMOVWF(result, 0);
719 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
723 emitpcode(POC_INCFW, popGet(AOP(left),0));
724 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
728 emitpcode(POC_DECFW, popGet(AOP(left),0));
729 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
733 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
734 emitpcode(POC_ADDFW, popGet(AOP(left),0));
735 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
742 /* left is not the accumulator */
744 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
745 emitpcode(POC_ADDFW, popGet(AOP(left),0));
747 emitpcode(POC_MOVFW, popGet(AOP(left),0));
749 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
755 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
756 //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
757 emitMOVWF(result,offset);
758 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
760 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
761 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
763 emitpcode(POC_CLRF, popGet(AOP(result),offset));
764 emitpcode(POC_RLF, popGet(AOP(result),offset));
765 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
766 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
774 /*-----------------------------------------------------------------*/
775 /* genPlus - generates code for addition */
776 /*-----------------------------------------------------------------*/
777 void genPlus (iCode *ic)
779 int size, offset = 0;
781 /* special cases :- */
782 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
784 aopOp (IC_LEFT(ic),ic,FALSE);
785 aopOp (IC_RIGHT(ic),ic,FALSE);
786 aopOp (IC_RESULT(ic),ic,TRUE);
788 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
790 /* if literal, literal on the right or
791 if left requires ACC or right is already
794 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
795 operand *t = IC_RIGHT(ic);
796 IC_RIGHT(ic) = IC_LEFT(ic);
800 /* if both left & right are in bit space */
801 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
802 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
807 /* if left in bit space & right literal */
808 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
809 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
810 /* if result in bit space */
811 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
812 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
813 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
814 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
815 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
816 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
819 size = pic14_getDataSize(IC_RESULT(ic));
821 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
822 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
823 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
829 /* if I can do an increment instead
830 of add then GOOD for ME */
831 if (genPlusIncr (ic) == TRUE)
834 size = pic14_getDataSize(IC_RESULT(ic));
836 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
837 /* Add a literal to something else */
839 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
843 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
848 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
850 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
851 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
852 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
854 /* here we are adding a bit to a char or int */
856 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
858 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
859 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
861 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
862 AOP(IC_RIGHT(ic))->aopu.aop_dir,
863 AOP(IC_RIGHT(ic))->aopu.aop_dir);
864 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
867 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
868 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
869 emitpcode(POC_XORLW , popGetLit(1));
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(" xorlw","1");
876 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
877 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
878 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
880 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
881 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
882 AOP(IC_RIGHT(ic))->aopu.aop_dir,
883 AOP(IC_RIGHT(ic))->aopu.aop_dir);
884 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
887 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
889 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
890 emitpcode(POC_ANDLW , popGetLit(1));
891 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
893 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
895 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
896 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
903 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
904 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
906 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
907 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
909 pic14_emitcode("clrz","");
911 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
912 AOP(IC_RIGHT(ic))->aopu.aop_dir,
913 AOP(IC_RIGHT(ic))->aopu.aop_dir);
914 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
918 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
919 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
920 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
921 //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
922 emitMOVWF(IC_RIGHT(ic),0);
924 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
925 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
926 AOP(IC_RIGHT(ic))->aopu.aop_dir,
927 AOP(IC_RIGHT(ic))->aopu.aop_dir);
928 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
929 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
935 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
936 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
942 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
944 /* Add the first bytes */
946 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
947 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
948 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
951 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
952 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
953 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
954 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
957 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
959 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
960 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
962 PIC_OPCODE poc = POC_ADDFW;
964 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL)
966 emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0));
967 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
968 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
973 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
978 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
979 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
980 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
982 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
983 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
986 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
988 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
989 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
992 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
994 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
995 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1003 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1004 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1005 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1008 /* Need to extend result to higher bytes */
1009 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1011 /* First grab the carry from the lower bytes */
1012 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1013 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
1017 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1020 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1021 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1022 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1023 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1025 /* if chars or ints or being signed extended to longs: */
1027 emitpcode(POC_MOVLW, popGetLit(0));
1028 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1029 emitpcode(POC_MOVLW, popGetLit(0xff));
1037 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1039 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1046 //adjustArithmeticResult(ic);
1049 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1050 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1051 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1054 /*-----------------------------------------------------------------*/
1055 /* genMinusDec :- does subtraction with decrement if possible */
1056 /*-----------------------------------------------------------------*/
1057 bool genMinusDec (iCode *ic)
1059 unsigned int icount ;
1060 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1062 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1063 /* will try to generate an increment */
1064 /* if the right side is not a literal
1066 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1067 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1068 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1071 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1073 /* if the literal value of the right hand side
1074 is greater than 4 then it is not worth it */
1075 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1078 /* if decrement 16 bits in register */
1079 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1084 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1085 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1086 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1087 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1089 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1090 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1091 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1093 /* size is 3 or 4 */
1094 emitpcode(POC_MOVLW, popGetLit(0xff));
1095 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1097 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1099 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1101 pic14_emitcode("movlw","0xff");
1102 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1105 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1107 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1111 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1113 pic14_emitcode("skpnc","");
1115 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1124 /* if the sizes are greater than 1 then we cannot */
1125 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1126 AOP_SIZE(IC_LEFT(ic)) > 1 )
1129 /* we can if the aops of the left & result match or
1130 if they are in registers and the registers are the
1132 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1135 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1137 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1142 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1143 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1144 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1147 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1148 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1150 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1151 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1159 /*-----------------------------------------------------------------*/
1160 /* addSign - propogate sign bit to higher bytes */
1161 /*-----------------------------------------------------------------*/
1162 void addSign(operand *result, int offset, int sign)
1164 int size = (pic14_getDataSize(result) - offset);
1165 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1168 if(sign && offset) {
1171 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1172 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1173 emitpcode(POC_DECF, popGet(AOP(result),offset));
1176 emitpcode(POC_MOVLW, popGetLit(0));
1177 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1178 emitpcode(POC_MOVLW, popGetLit(0xff));
1180 emitpcode(POC_MOVWF, popGet(AOP(result),size));
1185 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1189 /*-----------------------------------------------------------------*/
1190 /* genMinusBits - generates code for subtraction of two bits */
1191 /*-----------------------------------------------------------------*/
1192 void genMinusBits (iCode *ic)
1194 symbol *lbl = newiTempLabel(NULL);
1195 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1196 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1197 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1198 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1199 pic14_emitcode("cpl","c");
1200 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1201 pic14_outBitC(IC_RESULT(ic));
1204 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1205 pic14_emitcode("subb","a,acc");
1206 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1207 pic14_emitcode("inc","a");
1208 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1209 aopPut(AOP(IC_RESULT(ic)),"a",0);
1210 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1214 /*-----------------------------------------------------------------*/
1215 /* genMinus - generates code for subtraction */
1216 /*-----------------------------------------------------------------*/
1217 void genMinus (iCode *ic)
1219 int size, offset = 0, same=0;
1220 unsigned long lit = 0L;
1222 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1223 aopOp (IC_LEFT(ic),ic,FALSE);
1224 aopOp (IC_RIGHT(ic),ic,FALSE);
1225 aopOp (IC_RESULT(ic),ic,TRUE);
1227 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1228 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1229 operand *t = IC_RIGHT(ic);
1230 IC_RIGHT(ic) = IC_LEFT(ic);
1234 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1235 AopType(AOP_TYPE(IC_RESULT(ic))),
1236 AopType(AOP_TYPE(IC_LEFT(ic))),
1237 AopType(AOP_TYPE(IC_RIGHT(ic))));
1239 /* special cases :- */
1240 /* if both left & right are in bit space */
1241 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1242 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1247 /* if I can do an decrement instead
1248 of subtract then GOOD for ME */
1249 // if (genMinusDec (ic) == TRUE)
1252 size = pic14_getDataSize(IC_RESULT(ic));
1253 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1255 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1256 /* Add a literal to something else */
1258 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1261 genAddLit ( ic, lit);
1264 /* add the first byte: */
1265 pic14_emitcode("movlw","0x%x", lit & 0xff);
1266 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1267 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1268 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1280 if((lit & 0xff) == 0xff) {
1281 emitpcode(POC_MOVLW, popGetLit(0xff));
1283 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1285 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1287 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1288 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1292 /* do the rlf known zero trick here */
1293 emitpcode(POC_MOVLW, popGetLit(1));
1295 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1300 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1303 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1304 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1305 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1307 /* here we are subtracting a bit from a char or int */
1309 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1311 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1312 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1314 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1315 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1316 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1317 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1320 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1321 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1322 emitpcode(POC_XORLW , popGetLit(1));
1323 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1324 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1326 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1328 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1329 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1331 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1332 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1335 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1337 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1339 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1340 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1344 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1345 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1346 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1347 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1352 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1353 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1354 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1357 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1359 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1362 emitpcode(POC_ANDLW , popGetLit(1));
1364 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1366 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1373 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1374 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1375 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1377 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1378 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1379 AopType(AOP_TYPE(IC_RESULT(ic))),
1380 AopType(AOP_TYPE(IC_LEFT(ic))),
1381 AopType(AOP_TYPE(IC_RIGHT(ic))));
1384 if( (size == 1) && ((lit & 0xff) == 0) ) {
1385 /* res = 0 - right */
1386 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1387 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1388 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1390 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1391 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1392 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1397 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1398 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1399 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1407 /* This is the last byte in a multibyte subtraction
1408 * There are a couple of tricks we can do by not worrying about
1409 * propogating the carry */
1411 /* 0xff - x == ~x */
1413 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1415 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1417 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1418 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1420 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1423 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1425 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1426 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1427 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1436 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1438 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1439 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1442 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1448 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1449 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1451 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1453 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1455 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1456 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1463 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1464 AopType(AOP_TYPE(IC_RESULT(ic))),
1465 AopType(AOP_TYPE(IC_LEFT(ic))),
1466 AopType(AOP_TYPE(IC_RIGHT(ic))));
1468 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1469 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1470 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1471 emitpcode(POC_SUBLW, popGetLit(0));
1472 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1475 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1476 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1477 emitpcode(POC_SUBLW, popGetLit(0));
1478 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1479 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1482 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1483 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1484 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1486 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1487 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1489 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1490 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1491 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1493 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1495 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1496 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1497 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1499 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1501 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1508 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1510 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1511 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1513 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1514 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1521 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1522 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1523 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1525 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1527 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1528 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1536 // adjustArithmeticResult(ic);
1539 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1540 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1541 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1543 /*-----------------------------------------------------------------*
1544 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1547 *-----------------------------------------------------------------*/
1548 void genUMult8XLit_16 (operand *left,
1551 pCodeOpReg *result_hi)
1556 unsigned int i,have_first_bit;
1559 if (AOP_TYPE(right) != AOP_LIT){
1560 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1566 result_hi = PCOR(popGet(AOP(result),1));
1569 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1571 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1573 same = pic14_sameRegs(AOP(left), AOP(result));
1578 emitpcode(POC_CLRF, popGet(AOP(left),0));
1581 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1582 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1585 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1586 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1587 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1590 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1591 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1592 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1595 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1596 emitpcode(POC_ANDLW, popGetLit(0xf0));
1597 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1600 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1601 emitpcode(POC_ANDLW, popGetLit(0xf0));
1602 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1610 emitpcode(POC_CLRF, popGet(AOP(result),0));
1611 emitpcode(POC_CLRF, popCopyReg(result_hi));
1614 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1615 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1616 emitpcode(POC_ADDWF, popGet(AOP(result),0));
1617 emitpcode(POC_CLRF, popCopyReg(result_hi));
1618 emitpcode(POC_RLF, popCopyReg(result_hi));
1624 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1625 emitpcode(POC_CLRF, popGet(AOP(result),0));
1626 emitpcode(POC_CLRF, popCopyReg(result_hi));
1629 for(i=0; i<8; i++) {
1632 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1636 if(have_first_bit) {
1637 emitpcode(POC_RRF, popCopyReg(result_hi));
1638 emitpcode(POC_RRF, popGet(AOP(result),0));
1646 /*-----------------------------------------------------------------*
1647 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1650 *-----------------------------------------------------------------*/
1651 void genUMult8X8_16 (operand *left,
1654 pCodeOpReg *result_hi)
1662 result_hi = PCOR(popGet(AOP(result),1));
1665 if (AOP_TYPE(right) == AOP_LIT) {
1666 genUMult8XLit_16(left,right,result,result_hi);
1671 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1673 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1674 emitpcode(POC_CLRF, popGet(AOP(result),0));
1675 emitpcode(POC_CLRF, popCopyReg(result_hi));
1678 for(i=0; i<8; i++) {
1679 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1680 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1681 emitpcode(POC_RRF, popCopyReg(result_hi));
1682 emitpcode(POC_RRF, popGet(AOP(result),0));
1687 Here's another version that does the same thing and takes the
1688 same number of instructions. The one above is slightly better
1689 because the entry instructions have a higher probability of
1690 being optimized out.
1693 emitpcode(POC_CLRF, popCopyReg(result_hi));
1694 emitpcode(POC_RRFW, popGet(AOP(left),0));
1695 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1696 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1698 for(i=0; i<8; i++) {
1700 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1701 emitpcode(POC_RRF, popCopyReg(result_hi));
1702 emitpcode(POC_RRF, popGet(AOP(result),0));
1707 symbol *tlbl = newiTempLabel(NULL);
1711 pic14_emitcode(";","Looped 8 X 8 multiplication");
1713 emitpcode(POC_CLRF, popGet(AOP(result),0));
1714 emitpcode(POC_CLRF, popCopyReg(result_hi));
1716 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1718 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1720 temp = popGetTempReg();
1721 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1723 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1725 emitpLabel(tlbl->key);
1727 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1729 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1731 emitpcode(POC_RRF, popCopyReg(result_hi));
1732 emitpcode(POC_RRF, popGet(AOP(result),0));
1735 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1737 popReleaseTempReg(temp);
1742 /*-----------------------------------------------------------------*
1743 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1745 * this routine will call the unsigned multiply routine and then
1746 * post-fix the sign bit.
1747 *-----------------------------------------------------------------*/
1748 void genSMult8X8_16 (operand *left,
1751 pCodeOpReg *result_hi)
1755 result_hi = PCOR(popGet(AOP(result),1));
1758 genUMult8X8_16(left,right,result,result_hi);
1760 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1761 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1762 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1763 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1764 emitpcode(POC_SUBWF, popGet(AOP(result),1));
1768 /*-----------------------------------------------------------------*
1769 * genMult8X8_8 - multiplication of two 8-bit numbers
1771 * this routine will call the unsigned multiply 8X8=>16 routine and
1772 * then throw away the high byte of the result.
1774 *-----------------------------------------------------------------*/
1775 void genMult8X8_8 (operand *left,
1779 pCodeOp *result_hi = popGetTempReg();
1781 if (AOP_TYPE(right) == AOP_LIT)
1782 genUMult8XLit_16(left,right,result,PCOR(result_hi));
1784 genUMult8X8_16(left,right,result,PCOR(result_hi));
1786 popReleaseTempReg(result_hi);
1789 /*-----------------------------------------------------------------*/
1790 /* constMult - generates code for multiplication by a constant */
1791 /*-----------------------------------------------------------------*/
1792 void genMultConst(unsigned C)
1796 unsigned sr3; // Shift right 3
1802 Convert a string of 3 binary 1's in the lit into
1806 mask = 7 << ( (size*8) - 3);
1810 while(mask < (1<<size*8)) {
1812 if( (mask & lit) == lit) {
1815 /* We found 3 (or more) consecutive 1's */
1817 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1819 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1821 lit ^= consecutive_bits;
1825 sr3 |= (consecutive + lsb);