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) && (
965 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
966 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
968 emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0));
969 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
970 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
975 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
980 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
981 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
982 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
984 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
985 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
988 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
990 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
991 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
994 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
996 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
997 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1005 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1006 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1007 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1010 /* Need to extend result to higher bytes */
1011 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1013 /* First grab the carry from the lower bytes */
1014 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1015 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
1019 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1022 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1023 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1024 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1025 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1027 /* if chars or ints or being signed extended to longs: */
1029 emitpcode(POC_MOVLW, popGetLit(0));
1030 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1031 emitpcode(POC_MOVLW, popGetLit(0xff));
1039 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1041 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1048 //adjustArithmeticResult(ic);
1051 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1052 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1053 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1056 /*-----------------------------------------------------------------*/
1057 /* genMinusDec :- does subtraction with decrement if possible */
1058 /*-----------------------------------------------------------------*/
1059 bool genMinusDec (iCode *ic)
1061 unsigned int icount ;
1062 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1064 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1065 /* will try to generate an increment */
1066 /* if the right side is not a literal
1068 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1069 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1070 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1073 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1075 /* if the literal value of the right hand side
1076 is greater than 4 then it is not worth it */
1077 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1080 /* if decrement 16 bits in register */
1081 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1086 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1087 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1088 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1089 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1091 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1092 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1093 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1095 /* size is 3 or 4 */
1096 emitpcode(POC_MOVLW, popGetLit(0xff));
1097 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1099 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1101 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1103 pic14_emitcode("movlw","0xff");
1104 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1107 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1109 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1113 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1115 pic14_emitcode("skpnc","");
1117 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1126 /* if the sizes are greater than 1 then we cannot */
1127 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1128 AOP_SIZE(IC_LEFT(ic)) > 1 )
1131 /* we can if the aops of the left & result match or
1132 if they are in registers and the registers are the
1134 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1137 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1139 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1144 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1145 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1146 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1149 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1150 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1152 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1153 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1161 /*-----------------------------------------------------------------*/
1162 /* addSign - propogate sign bit to higher bytes */
1163 /*-----------------------------------------------------------------*/
1164 void addSign(operand *result, int offset, int sign)
1166 int size = (pic14_getDataSize(result) - offset);
1167 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1170 if(sign && offset) {
1173 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1174 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1175 emitpcode(POC_DECF, popGet(AOP(result),offset));
1178 emitpcode(POC_MOVLW, popGetLit(0));
1179 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1180 emitpcode(POC_MOVLW, popGetLit(0xff));
1182 emitpcode(POC_MOVWF, popGet(AOP(result),size));
1187 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1191 /*-----------------------------------------------------------------*/
1192 /* genMinusBits - generates code for subtraction of two bits */
1193 /*-----------------------------------------------------------------*/
1194 void genMinusBits (iCode *ic)
1196 symbol *lbl = newiTempLabel(NULL);
1197 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1198 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1199 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1200 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1201 pic14_emitcode("cpl","c");
1202 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1203 pic14_outBitC(IC_RESULT(ic));
1206 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1207 pic14_emitcode("subb","a,acc");
1208 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1209 pic14_emitcode("inc","a");
1210 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1211 aopPut(AOP(IC_RESULT(ic)),"a",0);
1212 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1216 /*-----------------------------------------------------------------*/
1217 /* genMinus - generates code for subtraction */
1218 /*-----------------------------------------------------------------*/
1219 void genMinus (iCode *ic)
1221 int size, offset = 0, same=0;
1222 unsigned long lit = 0L;
1224 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1225 aopOp (IC_LEFT(ic),ic,FALSE);
1226 aopOp (IC_RIGHT(ic),ic,FALSE);
1227 aopOp (IC_RESULT(ic),ic,TRUE);
1229 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1230 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1231 operand *t = IC_RIGHT(ic);
1232 IC_RIGHT(ic) = IC_LEFT(ic);
1236 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1237 AopType(AOP_TYPE(IC_RESULT(ic))),
1238 AopType(AOP_TYPE(IC_LEFT(ic))),
1239 AopType(AOP_TYPE(IC_RIGHT(ic))));
1241 /* special cases :- */
1242 /* if both left & right are in bit space */
1243 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1244 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1249 /* if I can do an decrement instead
1250 of subtract then GOOD for ME */
1251 // if (genMinusDec (ic) == TRUE)
1254 size = pic14_getDataSize(IC_RESULT(ic));
1255 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1257 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1258 /* Add a literal to something else */
1260 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1263 genAddLit ( ic, lit);
1266 /* add the first byte: */
1267 pic14_emitcode("movlw","0x%x", lit & 0xff);
1268 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1269 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1270 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1282 if((lit & 0xff) == 0xff) {
1283 emitpcode(POC_MOVLW, popGetLit(0xff));
1285 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1287 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1289 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1290 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1294 /* do the rlf known zero trick here */
1295 emitpcode(POC_MOVLW, popGetLit(1));
1297 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1302 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1305 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1306 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1307 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1309 /* here we are subtracting a bit from a char or int */
1311 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1313 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1314 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1316 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1317 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1318 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1319 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1322 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1323 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1324 emitpcode(POC_XORLW , popGetLit(1));
1325 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1326 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1328 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1330 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1331 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1333 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1334 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1337 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1339 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1341 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1342 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1346 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1347 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1348 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1349 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1354 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1355 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1356 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1359 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1361 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1364 emitpcode(POC_ANDLW , popGetLit(1));
1366 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1368 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1375 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1376 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1377 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1379 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1380 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1381 AopType(AOP_TYPE(IC_RESULT(ic))),
1382 AopType(AOP_TYPE(IC_LEFT(ic))),
1383 AopType(AOP_TYPE(IC_RIGHT(ic))));
1386 if( (size == 1) && ((lit & 0xff) == 0) ) {
1387 /* res = 0 - right */
1388 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1389 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1390 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1392 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1393 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1394 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1399 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1400 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1401 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1409 /* This is the last byte in a multibyte subtraction
1410 * There are a couple of tricks we can do by not worrying about
1411 * propogating the carry */
1413 /* 0xff - x == ~x */
1415 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1417 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1419 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1420 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1422 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1425 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1427 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1428 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1429 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1438 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1440 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1441 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1444 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1450 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1451 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1453 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1455 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1457 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1458 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1465 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1466 AopType(AOP_TYPE(IC_RESULT(ic))),
1467 AopType(AOP_TYPE(IC_LEFT(ic))),
1468 AopType(AOP_TYPE(IC_RIGHT(ic))));
1470 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1471 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1472 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1473 emitpcode(POC_SUBLW, popGetLit(0));
1474 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1477 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1478 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1479 emitpcode(POC_SUBLW, popGetLit(0));
1480 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1481 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1484 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1485 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1486 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1488 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1489 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1491 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1492 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1493 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1495 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1497 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1498 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1499 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1501 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1503 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1510 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1512 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1513 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1515 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1516 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1523 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1524 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1525 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1527 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1529 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1530 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1538 // adjustArithmeticResult(ic);
1541 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1542 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1543 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1545 /*-----------------------------------------------------------------*
1546 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1549 *-----------------------------------------------------------------*/
1550 void genUMult8XLit_16 (operand *left,
1553 pCodeOpReg *result_hi)
1558 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));
1597 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1598 emitpcode(POC_ANDLW, popGetLit(0xf0));
1599 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1602 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1603 emitpcode(POC_ANDLW, popGetLit(0xf0));
1604 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1612 emitpcode(POC_CLRF, popGet(AOP(result),0));
1613 emitpcode(POC_CLRF, popCopyReg(result_hi));
1616 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1617 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1618 emitpcode(POC_ADDWF, popGet(AOP(result),0));
1619 emitpcode(POC_CLRF, popCopyReg(result_hi));
1620 emitpcode(POC_RLF, popCopyReg(result_hi));
1626 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1627 emitpcode(POC_CLRF, popGet(AOP(result),0));
1628 emitpcode(POC_CLRF, popCopyReg(result_hi));
1631 for(i=0; i<8; i++) {
1634 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1638 if(have_first_bit) {
1639 emitpcode(POC_RRF, popCopyReg(result_hi));
1640 emitpcode(POC_RRF, popGet(AOP(result),0));
1648 /*-----------------------------------------------------------------*
1649 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1652 *-----------------------------------------------------------------*/
1653 void genUMult8X8_16 (operand *left,
1656 pCodeOpReg *result_hi)
1664 result_hi = PCOR(popGet(AOP(result),1));
1667 if (AOP_TYPE(right) == AOP_LIT) {
1668 genUMult8XLit_16(left,right,result,result_hi);
1673 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1675 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1676 emitpcode(POC_CLRF, popGet(AOP(result),0));
1677 emitpcode(POC_CLRF, popCopyReg(result_hi));
1680 for(i=0; i<8; i++) {
1681 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1682 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1683 emitpcode(POC_RRF, popCopyReg(result_hi));
1684 emitpcode(POC_RRF, popGet(AOP(result),0));
1689 Here's another version that does the same thing and takes the
1690 same number of instructions. The one above is slightly better
1691 because the entry instructions have a higher probability of
1692 being optimized out.
1695 emitpcode(POC_CLRF, popCopyReg(result_hi));
1696 emitpcode(POC_RRFW, popGet(AOP(left),0));
1697 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1698 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1700 for(i=0; i<8; i++) {
1702 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1703 emitpcode(POC_RRF, popCopyReg(result_hi));
1704 emitpcode(POC_RRF, popGet(AOP(result),0));
1709 symbol *tlbl = newiTempLabel(NULL);
1713 pic14_emitcode(";","Looped 8 X 8 multiplication");
1715 emitpcode(POC_CLRF, popGet(AOP(result),0));
1716 emitpcode(POC_CLRF, popCopyReg(result_hi));
1718 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1720 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1722 temp = popGetTempReg();
1723 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1725 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1727 emitpLabel(tlbl->key);
1729 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1731 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1733 emitpcode(POC_RRF, popCopyReg(result_hi));
1734 emitpcode(POC_RRF, popGet(AOP(result),0));
1737 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1739 popReleaseTempReg(temp);
1744 /*-----------------------------------------------------------------*
1745 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1747 * this routine will call the unsigned multiply routine and then
1748 * post-fix the sign bit.
1749 *-----------------------------------------------------------------*/
1750 void genSMult8X8_16 (operand *left,
1753 pCodeOpReg *result_hi)
1757 result_hi = PCOR(popGet(AOP(result),1));
1760 genUMult8X8_16(left,right,result,result_hi);
1762 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1763 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1764 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1765 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1766 emitpcode(POC_SUBWF, popGet(AOP(result),1));
1770 /*-----------------------------------------------------------------*
1771 * genMult8X8_8 - multiplication of two 8-bit numbers
1773 * this routine will call the unsigned multiply 8X8=>16 routine and
1774 * then throw away the high byte of the result.
1776 *-----------------------------------------------------------------*/
1777 void genMult8X8_8 (operand *left,
1781 pCodeOp *result_hi = popGetTempReg();
1783 if (AOP_TYPE(right) == AOP_LIT)
1784 genUMult8XLit_16(left,right,result,PCOR(result_hi));
1786 genUMult8X8_16(left,right,result,PCOR(result_hi));
1788 popReleaseTempReg(result_hi);
1791 /*-----------------------------------------------------------------*/
1792 /* constMult - generates code for multiplication by a constant */
1793 /*-----------------------------------------------------------------*/
1794 void genMultConst(unsigned C)
1798 unsigned sr3; // Shift right 3
1804 Convert a string of 3 binary 1's in the lit into
1808 mask = 7 << ( (size*8) - 3);
1812 while(mask < (1<<size*8)) {
1814 if( (mask & lit) == lit) {
1817 /* We found 3 (or more) consecutive 1's */
1819 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1821 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1823 lit ^= consecutive_bits;
1827 sr3 |= (consecutive + lsb);