1 /*-------------------------------------------------------------------------
3 genarith.c - source file for code generation - arithmetic
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 and - Jean-Louis VERN.jlvern@writeme.com (1999)
7 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
8 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2, or (at your option) any
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 In other words, you are welcome to use, share and improve this program.
26 You are forbidden to forbid anyone else to use, share and improve
27 what you give them. Help stamp out software-hoarding!
30 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
31 Made everything static
32 -------------------------------------------------------------------------*/
38 #include "SDCCglobl.h"
41 #if defined(_MSC_VER) && (_MSC_VER < 1300)
42 #define __FUNCTION__ __FILE__
46 #include "SDCCpeeph.h"
52 #define pic16_emitcode DEBUGpic16_emitcode
55 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
56 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
57 void pic16_emitpcomment(char *, ...);
58 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst);
59 const char *pic16_AopType(short type)
106 const char *pic16_pCodeOpType(pCodeOp *pcop)
129 case PO_GPR_REGISTER:
130 return "PO_GPR_REGISTER";
134 return "PO_GPR_TEMP";
135 case PO_SFR_REGISTER:
136 return "PO_SFR_REGISTER";
150 return "PO_REL_ADDR";
152 return "PO_IMMEDIATE";
168 return "BAD PO_TYPE";
171 const char *pic16_pCodeOpSubType(pCodeOp *pcop)
174 if(pcop && (pcop->type == PO_GPR_BIT)) {
176 switch(PCORB(pcop)->subtype) {
194 case PO_GPR_REGISTER:
195 return "PO_GPR_REGISTER";
199 return "PO_GPR_TEMP";
200 case PO_SFR_REGISTER:
201 return "PO_SFR_REGISTER";
215 return "PO_REL_ADDR";
217 return "PO_IMMEDIATE";
233 return "BAD PO_TYPE";
236 /*-----------------------------------------------------------------*/
237 /* pic16_genPlusIncr :- does addition with increment if possible */
238 /*-----------------------------------------------------------------*/
239 bool pic16_genPlusIncr (iCode *ic)
241 unsigned int icount ;
242 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
244 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
245 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
246 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
247 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
248 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
250 /* will try to generate an increment */
251 /* if the right side is not a literal
253 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
256 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
257 /* if the literal value of the right hand side
258 is greater than 2 then it is faster to add */
259 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
262 /* if increment 16 bits in register */
263 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
268 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
269 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
273 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
274 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
280 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
281 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
282 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
283 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
285 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
286 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
287 AOP(IC_RESULT(ic))->aopu.aop_dir,
288 AOP(IC_RESULT(ic))->aopu.aop_dir);
290 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
291 //pic16_emitcode("xorlw","1");
293 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
294 //pic16_emitcode("andlw","1");
297 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
298 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
299 AOP(IC_RESULT(ic))->aopu.aop_dir,
300 AOP(IC_RESULT(ic))->aopu.aop_dir);
306 /* if the sizes are greater than 1 then we cannot */
307 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
308 AOP_SIZE(IC_LEFT(ic)) > 1 )
311 /* If we are incrementing the same register by two: */
313 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
316 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
317 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
322 DEBUGpic16_emitcode ("; ","couldn't increment ");
327 /*-----------------------------------------------------------------*/
328 /* pic16_outBitAcc - output a bit in acc */
329 /*-----------------------------------------------------------------*/
330 void pic16_outBitAcc(operand *result)
332 symbol *tlbl = newiTempLabel(NULL);
333 /* if the result is a bit */
334 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
336 if (AOP_TYPE(result) == AOP_CRY){
337 pic16_aopPut(AOP(result),"a",0);
340 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
341 pic16_emitcode("mov","a,#01");
342 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
343 pic16_outAcc(result);
347 /*-----------------------------------------------------------------*/
348 /* pic16_genPlusBits - generates code for addition of two bits */
349 /*-----------------------------------------------------------------*/
350 void pic16_genPlusBits (iCode *ic)
353 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
355 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
356 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
357 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
358 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
360 The following block of code will add two bits.
361 Note that it'll even work if the destination is
362 the carry (C in the status register).
363 It won't work if the 'Z' bit is a source or destination.
366 /* If the result is stored in the accumulator (w) */
367 //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
368 switch(AOP_TYPE(IC_RESULT(ic))) {
370 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
371 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
372 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
373 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
374 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
376 pic16_emitcode("clrw","");
377 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
378 AOP(IC_RIGHT(ic))->aopu.aop_dir,
379 AOP(IC_RIGHT(ic))->aopu.aop_dir);
380 pic16_emitcode("xorlw","1");
381 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
382 AOP(IC_LEFT(ic))->aopu.aop_dir,
383 AOP(IC_LEFT(ic))->aopu.aop_dir);
384 pic16_emitcode("xorlw","1");
387 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
388 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
389 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
390 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
391 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
392 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
395 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
396 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
397 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
398 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
399 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
400 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
402 pic16_emitcode("movlw","(1 << (%s & 7))",
403 AOP(IC_RESULT(ic))->aopu.aop_dir,
404 AOP(IC_RESULT(ic))->aopu.aop_dir);
405 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
406 AOP(IC_RESULT(ic))->aopu.aop_dir,
407 AOP(IC_RESULT(ic))->aopu.aop_dir);
408 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
409 AOP(IC_RIGHT(ic))->aopu.aop_dir,
410 AOP(IC_RIGHT(ic))->aopu.aop_dir);
411 pic16_emitcode("xorwf","(%s >>3),f",
412 AOP(IC_RESULT(ic))->aopu.aop_dir);
413 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
414 AOP(IC_LEFT(ic))->aopu.aop_dir,
415 AOP(IC_LEFT(ic))->aopu.aop_dir);
416 pic16_emitcode("xorwf","(%s>>3),f",
417 AOP(IC_RESULT(ic))->aopu.aop_dir);
424 /* This is the original version of this code.
426 * This is being kept around for reference,
427 * because I am not entirely sure I got it right...
429 static void adjustArithmeticResult(iCode *ic)
431 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
432 AOP_SIZE(IC_LEFT(ic)) == 3 &&
433 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
434 pic16_aopPut(AOP(IC_RESULT(ic)),
435 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
438 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
439 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
440 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
441 pic16_aopPut(AOP(IC_RESULT(ic)),
442 pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
445 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
446 AOP_SIZE(IC_LEFT(ic)) < 3 &&
447 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
448 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
449 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
451 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
452 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
456 /* This is the pure and virtuous version of this code.
457 * I'm pretty certain it's right, but not enough to toss the old
460 static void adjustArithmeticResult(iCode *ic)
462 if (opIsGptr(IC_RESULT(ic)) &&
463 opIsGptr(IC_LEFT(ic)) &&
464 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
466 pic16_aopPut(AOP(IC_RESULT(ic)),
467 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
471 if (opIsGptr(IC_RESULT(ic)) &&
472 opIsGptr(IC_RIGHT(ic)) &&
473 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
475 pic16_aopPut(AOP(IC_RESULT(ic)),
476 pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
480 if (opIsGptr(IC_RESULT(ic)) &&
481 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
482 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
483 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
484 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
486 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
487 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
492 /*-----------------------------------------------------------------*/
493 /* genAddlit - generates code for addition */
494 /*-----------------------------------------------------------------*/
495 static void genAddLit2byte (operand *result, int offr, int lit)
502 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
505 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
508 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
509 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
514 static void emitMOVWF(operand *reg, int offset)
519 if (AOP_TYPE(reg) == AOP_ACC) {
520 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
524 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
528 static void genAddLit (iCode *ic, int lit)
537 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
541 result = IC_RESULT(ic);
542 same = pic16_sameRegs(AOP(left), AOP(result));
543 size = pic16_getDataSize(result);
547 /* Handle special cases first */
549 genAddLit2byte (result, 0, lit);
552 int hi = 0xff & (lit >> 8);
559 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
564 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
566 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
569 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
570 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
571 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
575 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
576 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
578 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
586 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
589 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
592 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
593 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
595 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
597 case 0xff: /* 0x01ff */
598 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
599 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
600 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
601 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
606 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
610 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
613 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
614 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
616 /* case 0xff: * 0xffff *
617 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
618 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
619 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
623 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
624 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
626 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
633 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
638 genAddLit2byte (result, MSB16, hi);
641 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1)&0xff));
642 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
643 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
644 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
646 /* case 0xff: * 0xHHff *
647 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
648 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
649 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
650 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
652 */ default: /* 0xHHLL */
653 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
654 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
655 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
657 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1) & 0xff));
658 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
667 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
670 lo = BYTEofLONG(lit,0);
678 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
681 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
682 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(1));
683 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
685 default: /* carry_info = 3 */
687 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
693 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
698 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
701 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
706 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo+1));
707 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
712 /* no carry info from previous step */
713 /* this means this is the first time to add */
718 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
722 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
723 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
725 carry_info = 3; /* Were adding only one byte and propogating the carry */
736 lo = BYTEofLONG(lit,0);
741 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
744 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
745 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
748 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
750 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
752 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
762 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
766 if(AOP_TYPE(left) == AOP_ACC) {
767 /* left addend is already in accumulator */
770 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
774 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
775 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
779 /* left addend is in a register */
782 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
783 emitMOVWF(result, 0);
784 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
788 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
789 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
793 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
794 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
798 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
799 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
800 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
808 /* left is not the accumulator */
810 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
811 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
813 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
814 /* We don't know the state of the carry bit at this point */
817 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
824 /* The ls byte of the lit must've been zero - that
825 means we don't have to deal with carry */
827 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
828 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
829 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),offset));
834 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
835 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset,FALSE,FALSE));
836 emitMOVWF(result,offset);
837 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
839 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
840 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
844 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
845 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset));
846 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
847 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
855 /*-----------------------------------------------------------------*/
856 /* pic16_genPlus - generates code for addition */
857 /*-----------------------------------------------------------------*/
858 void pic16_genPlus (iCode *ic)
860 int i, size, offset = 0;
861 operand *result, *left, *right;
863 /* special cases :- */
864 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
867 result = IC_RESULT(ic);
869 right = IC_RIGHT(ic);
870 pic16_aopOp (left,ic,FALSE);
871 pic16_aopOp (right,ic,FALSE);
872 pic16_aopOp (result,ic,TRUE);
873 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
874 // pic16_DumpOp("(left)",left);
876 /* if literal, literal on the right or
877 if left requires ACC or right is already
880 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
886 /* if both left & right are in bit space */
887 if (AOP_TYPE(left) == AOP_CRY &&
888 AOP_TYPE(right) == AOP_CRY) {
889 pic16_genPlusBits (ic);
893 /* if left in bit space & right literal */
894 if (AOP_TYPE(left) == AOP_CRY &&
895 AOP_TYPE(right) == AOP_LIT) {
896 /* if result in bit space */
897 if(AOP_TYPE(result) == AOP_CRY){
898 if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
899 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
900 if (!pic16_sameRegs(AOP(left), AOP(result)) )
901 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
902 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
905 size = pic16_getDataSize(result);
907 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
908 pic16_emitcode("addc","a,#00 ;%d",__LINE__);
909 pic16_aopPut(AOP(result),"a",offset++);
915 /* if I can do an increment instead
916 of add then GOOD for ME */
917 if (pic16_genPlusIncr (ic) == TRUE)
920 size = pic16_getDataSize(IC_RESULT(ic));
922 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
923 /* Add a literal to something else */
925 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
929 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
934 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
936 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
937 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
938 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
940 /* here we are adding a bit to a char or int */
942 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
944 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
945 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
947 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
948 AOP(IC_RIGHT(ic))->aopu.aop_dir,
949 AOP(IC_RIGHT(ic))->aopu.aop_dir);
950 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
953 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
954 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
955 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
957 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
958 AOP(IC_RIGHT(ic))->aopu.aop_dir,
959 AOP(IC_RIGHT(ic))->aopu.aop_dir);
960 pic16_emitcode(" xorlw","1");
962 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
963 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
964 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
966 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
967 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
968 AOP(IC_RIGHT(ic))->aopu.aop_dir,
969 AOP(IC_RIGHT(ic))->aopu.aop_dir);
970 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
973 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
975 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
976 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
977 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
979 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
981 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
982 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
989 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
990 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
992 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
993 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
995 pic16_emitcode("clrz","");
997 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
998 AOP(IC_RIGHT(ic))->aopu.aop_dir,
999 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1000 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1004 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1005 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1006 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1007 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1008 emitMOVWF(IC_RIGHT(ic),0);
1010 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1011 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1012 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1013 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1014 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1015 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1021 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
1022 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
1030 // Note: the following is an example of WISC code, eg.
1031 // it's supposed to run on a Weird Instruction Set Computer :o)
1033 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1035 if ( AOP_TYPE(left) == AOP_ACC) {
1036 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1037 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
1038 if ( AOP_TYPE(result) != AOP_ACC)
1039 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1040 goto release; // we're done, since WREG is 1 byte
1044 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1046 size = min( AOP_SIZE(result), AOP_SIZE(right) );
1047 size = min( size, AOP_SIZE(left) );
1050 if(pic16_debug_verbose) {
1051 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
1052 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
1053 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
1058 if ((AOP_TYPE(left) == AOP_PCODE) && (
1059 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
1060 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
1061 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
1063 // add to literal operand
1066 for(i=0; i<size; i++) {
1067 if (AOP_TYPE(right) == AOP_ACC) {
1068 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1070 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1071 if(i) { // add with carry
1072 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1073 } else { // add without
1074 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1077 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1080 // add leftover bytes
1081 if (SPEC_USIGN(getSpec(operandType(right)))) {
1082 // right is unsigned
1083 for(i=size; i< AOP_SIZE(result); i++) {
1084 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1085 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1086 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1090 // right is signed, oh dear ...
1091 for(i=size; i< AOP_SIZE(result); i++) {
1092 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1093 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1094 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
1095 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1096 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1106 for(i=0; i<size; i++) {
1107 if (AOP_TYPE(right) != AOP_ACC)
1108 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),i));
1109 if (pic16_sameRegs(AOP(left), AOP(result)))
1111 if(i) { // add with carry
1112 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1113 } else { // add without
1114 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1116 } else { // not same
1117 if(i) { // add with carry
1118 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1119 } else { // add without
1120 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1122 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1126 // add leftover bytes
1127 if (SPEC_USIGN(getSpec(operandType(right)))) {
1128 // right is unsigned
1129 for(i=size; i< AOP_SIZE(result); i++) {
1130 if (pic16_sameRegs(AOP(left), AOP(result)))
1132 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1133 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1134 } else { // not same
1135 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),i));
1136 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1141 for(i=size; i< AOP_SIZE(result); i++) {
1142 if(size < AOP_SIZE(left)) {
1143 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1144 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1145 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1146 if (pic16_sameRegs(AOP(left), AOP(result)))
1148 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1149 } else { // not same
1150 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1151 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1154 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1155 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1164 // TODO: anything from here to before "release:" is probably obsolete and should be removed
1165 // when the regression tests are stable
1167 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1168 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1169 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1172 /* Need to extend result to higher bytes */
1173 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1175 /* First grab the carry from the lower bytes */
1176 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1177 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1181 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1184 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1185 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1186 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1187 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1189 /* if chars or ints or being signed extended to longs: */
1191 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1192 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1193 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1201 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1203 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1210 //adjustArithmeticResult(ic);
1213 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1214 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1215 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1218 /*-----------------------------------------------------------------*/
1219 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1220 /*-----------------------------------------------------------------*/
1221 bool pic16_genMinusDec (iCode *ic)
1223 unsigned int icount ;
1224 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1226 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1227 /* will try to generate an increment */
1228 /* if the right side is not a literal
1230 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1231 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1232 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1235 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1237 /* if the literal value of the right hand side
1238 is greater than 4 then it is not worth it */
1239 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1242 /* if decrement 16 bits in register */
1243 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1248 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1249 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1250 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1251 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1253 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1254 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1255 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1257 /* size is 3 or 4 */
1258 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1259 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1261 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1263 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1265 pic16_emitcode("movlw","0xff");
1266 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1269 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1271 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1275 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1277 pic16_emitcode("skpnc","");
1279 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1288 /* if the sizes are greater than 1 then we cannot */
1289 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1290 AOP_SIZE(IC_LEFT(ic)) > 1 )
1293 /* we can if the aops of the left & result match or
1294 if they are in registers and the registers are the
1296 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1299 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1301 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1306 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1307 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1308 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1311 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1312 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1314 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1315 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1323 /*-----------------------------------------------------------------*/
1324 /* pic16_addSign - propogate sign bit to higher bytes */
1325 /*-----------------------------------------------------------------*/
1326 void pic16_addSign(operand *result, int offset, int sign)
1328 int size = (pic16_getDataSize(result) - offset);
1329 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1332 if(sign && offset) {
1335 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1336 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1337 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1340 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1341 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1342 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1344 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1349 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1353 /*-----------------------------------------------------------------*/
1354 /* pic16_genMinusBits - generates code for subtraction of two bits */
1355 /*-----------------------------------------------------------------*/
1356 void pic16_genMinusBits (iCode *ic)
1358 symbol *lbl = newiTempLabel(NULL);
1359 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1360 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1361 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1362 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1363 pic16_emitcode("cpl","c");
1364 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1365 pic16_outBitC(IC_RESULT(ic));
1368 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1369 pic16_emitcode("subb","a,acc");
1370 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1371 pic16_emitcode("inc","a");
1372 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1373 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1374 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1378 /*-----------------------------------------------------------------*/
1379 /* pic16_genMinus - generates code for subtraction */
1380 /*-----------------------------------------------------------------*/
1381 void pic16_genMinus (iCode *ic)
1383 int size, offset = 0, same=0;
1384 unsigned long lit = 0L;
1386 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1387 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1388 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1389 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1391 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1392 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1393 operand *t = IC_RIGHT(ic);
1394 IC_RIGHT(ic) = IC_LEFT(ic);
1398 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1399 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1400 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1401 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1403 /* special cases :- */
1404 /* if both left & right are in bit space */
1405 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1406 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1407 pic16_genPlusBits (ic);
1411 /* if I can do an decrement instead
1412 of subtract then GOOD for ME */
1413 // if (pic16_genMinusDec (ic) == TRUE)
1416 size = pic16_getDataSize(IC_RESULT(ic));
1417 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1419 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1420 /* Add a literal to something else */
1422 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1425 genAddLit ( ic, lit);
1428 /* add the first byte: */
1429 pic16_emitcode("movlw","0x%x", lit & 0xff);
1430 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1431 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1432 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1444 if((lit & 0xff) == 0xff) {
1445 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1447 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1449 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1451 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1452 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1456 /* do the rlf known zero trick here */
1457 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1459 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1464 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1467 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1468 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1469 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1471 /* here we are subtracting a bit from a char or int */
1473 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1475 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1476 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1478 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1479 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1480 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1481 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1484 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1485 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1486 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1487 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1488 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1490 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1492 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1493 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1495 pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1496 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1499 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1501 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1503 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1504 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1508 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1509 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1510 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1511 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1516 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1517 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1518 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1521 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1523 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1526 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1528 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1530 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1537 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1538 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1539 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1541 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1542 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1543 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1544 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1545 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1548 if( (size == 1) && ((lit & 0xff) == 0) ) {
1549 /* res = 0 - right */
1550 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1551 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1552 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1554 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1555 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1556 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1561 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1562 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1563 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1571 /* This is the last byte in a multibyte subtraction
1572 * There are a couple of tricks we can do by not worrying about
1573 * propogating the carry */
1575 /* 0xff - x == ~x */
1577 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1579 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1581 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1582 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1584 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1587 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1589 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1590 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1591 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1600 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1602 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
1603 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1606 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1612 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1613 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1615 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1617 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1619 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1620 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1627 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1628 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1629 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1630 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1632 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1633 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1634 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1635 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1636 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1639 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1640 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1641 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1642 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1643 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1646 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1647 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1648 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1650 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1651 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1653 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1654 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1655 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1657 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1659 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1660 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1661 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1663 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1665 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1672 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1674 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1675 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1677 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1678 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1685 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1686 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1687 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1689 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1691 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1692 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1700 // adjustArithmeticResult(ic);
1703 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1704 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1705 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1709 /*-----------------------------------------------------------------*
1710 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1713 *-----------------------------------------------------------------*/
1714 void pic16_genUMult8XLit_8 (operand *left,
1722 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1724 if (AOP_TYPE(right) != AOP_LIT){
1725 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1729 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1731 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1732 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1734 same = pic16_sameRegs(AOP(left), AOP(result));
1738 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1741 // its faster to left shift
1743 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1747 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1748 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1749 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1750 pic16_popGet(AOP(result), 0)));
1754 // operands different
1757 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1761 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1762 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1765 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1766 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1767 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1768 pic16_popGet(AOP(result), 0)));
1774 /*-----------------------------------------------------------------------*
1775 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1776 *-----------------------------------------------------------------------*/
1777 void pic16_genUMult16XLit_16 (operand *left,
1781 pCodeOp *pct1, *pct2, *pct3, *pct4;
1786 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1788 if (AOP_TYPE(right) != AOP_LIT){
1789 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1793 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1796 same = pic16_sameRegs(AOP(left), AOP(result));
1800 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1801 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1804 // its faster to left shift
1806 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1807 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1811 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1813 pct1 = pic16_popGetTempReg();
1814 pct2 = pic16_popGetTempReg();
1815 pct3 = pic16_popGetTempReg();
1816 pct4 = pic16_popGetTempReg();
1818 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1819 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1820 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1821 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1822 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1823 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1825 /* WREG still holds the low literal */
1826 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1827 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1828 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1830 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1831 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1832 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1833 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1836 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1837 pct1, pic16_popGet(AOP(result), 0)));
1838 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1839 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1840 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1841 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1843 pic16_popReleaseTempReg( pct4 );
1844 pic16_popReleaseTempReg( pct3 );
1845 pic16_popReleaseTempReg( pct2 );
1846 pic16_popReleaseTempReg( pct1 );
1850 // operands different
1853 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1854 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1858 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1859 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1860 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1861 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1865 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1866 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1867 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1868 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1869 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1870 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1872 /* WREG still holds the low literal */
1873 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1874 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1875 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1877 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1878 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1879 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1880 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1888 /*-----------------------------------------------------------------*
1889 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1892 *-----------------------------------------------------------------*/
1893 void pic16_genUMult8X8_8 (operand *left,
1898 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1901 if (AOP_TYPE(right) == AOP_LIT) {
1902 pic16_genUMult8XLit_8(left,right,result);
1912 /* if result == right then exchange left and right */
1913 if(pic16_sameRegs(AOP(result), AOP(right))) {
1920 if(AOP_TYPE(left) != AOP_ACC) {
1922 if(AOP_TYPE(right) != AOP_ACC) {
1923 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1924 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1926 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1929 // left is WREG, right cannot be WREG (or can?!)
1930 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1933 /* result is in PRODL:PRODH */
1934 if(AOP_TYPE(result) != AOP_ACC) {
1935 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1936 pic16_popGet(AOP(result), 0)));
1939 if(AOP_SIZE(result)>1) {
1942 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1943 pic16_popGet(AOP(result), 1)));
1945 for(i=2;i<AOP_SIZE(result);i++)
1946 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1949 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1953 /*------------------------------------------------------------------*
1954 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1955 *------------------------------------------------------------------*/
1956 void pic16_genUMult16X16_16 (operand *left,
1961 pCodeOp *pct1, *pct2, *pct3, *pct4;
1963 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1966 if (AOP_TYPE(right) == AOP_LIT) {
1967 pic16_genUMult8XLit_8(left,right,result);
1975 /* if result == right then exchange left and right */
1976 if(pic16_sameRegs(AOP(result), AOP(right))) {
1984 if(pic16_sameRegs(AOP(result), AOP(left))) {
1986 pct1 = pic16_popGetTempReg();
1987 pct2 = pic16_popGetTempReg();
1988 pct3 = pic16_popGetTempReg();
1989 pct4 = pic16_popGetTempReg();
1991 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1992 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1993 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1994 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1995 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1996 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1998 /* WREG still holds the lower left */
1999 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2000 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2001 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2003 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2004 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2005 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2006 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2009 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2010 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2011 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2012 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2013 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2014 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2016 pic16_popReleaseTempReg( pct4 );
2017 pic16_popReleaseTempReg( pct3 );
2018 pic16_popReleaseTempReg( pct2 );
2019 pic16_popReleaseTempReg( pct1 );
2023 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2024 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2025 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2026 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2027 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2028 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2030 /* WREG still holds the lower left */
2031 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2032 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2033 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2035 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2036 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2037 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2038 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2043 void pic16_genSMult16X16_16(operand *left,
2051 /*-----------------------------------------------------------------*
2052 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
2054 * this routine will call the unsigned multiply routine and then
2055 * post-fix the sign bit.
2056 *-----------------------------------------------------------------*/
2057 void pic16_genSMult8X8_8 (operand *left,
2060 pCodeOpReg *result_hi)
2062 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2066 result_hi = PCOR(pic16_popGet(AOP(result),1));
2070 pic16_genUMult8X8_8(left,right,result);
2074 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2075 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2076 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
2077 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2078 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2083 /*-----------------------------------------------------------------*
2084 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
2085 *-----------------------------------------------------------------*/
2086 void pic16_genMult8X8_8 (operand *left,
2090 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2092 if(AOP_TYPE(right) == AOP_LIT)
2093 pic16_genUMult8XLit_8(left,right,result);
2095 pic16_genUMult8X8_8(left,right,result);
2099 /*-----------------------------------------------------------------*
2100 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
2101 *-----------------------------------------------------------------*/
2102 void pic16_genMult16X16_16 (operand *left,
2106 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2108 if (AOP_TYPE(right) == AOP_LIT)
2109 pic16_genUMult16XLit_16(left,right,result);
2111 pic16_genUMult16X16_16(left,right,result);
2118 /*-----------------------------------------------------------------------*
2119 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2120 *-----------------------------------------------------------------------*/
2121 void pic16_genUMult32XLit_32 (operand *left,
2125 pCodeOp *pct1, *pct2, *pct3, *pct4;
2130 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2132 if (AOP_TYPE(right) != AOP_LIT){
2133 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2137 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2140 same = pic16_sameRegs(AOP(left), AOP(result));
2144 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2145 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2148 // its faster to left shift
2150 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2151 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2155 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2157 pct1 = pic16_popGetTempReg();
2158 pct2 = pic16_popGetTempReg();
2159 pct3 = pic16_popGetTempReg();
2160 pct4 = pic16_popGetTempReg();
2162 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2163 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2164 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2165 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2166 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2167 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2169 /* WREG still holds the low literal */
2170 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2171 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2172 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2174 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2175 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2176 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2177 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2180 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2181 pct1, pic16_popGet(AOP(result), 0)));
2182 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2183 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2184 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2185 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2187 pic16_popReleaseTempReg( pct4 );
2188 pic16_popReleaseTempReg( pct3 );
2189 pic16_popReleaseTempReg( pct2 );
2190 pic16_popReleaseTempReg( pct1 );
2194 // operands different
2197 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2198 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2202 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2203 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2204 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2205 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2209 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2210 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2211 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2212 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2213 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2214 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2216 /* WREG still holds the low literal */
2217 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2218 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2219 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2221 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2222 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2223 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2224 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2232 /*------------------------------------------------------------------*
2233 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2234 *------------------------------------------------------------------*/
2235 void pic16_genUMult32X32_32 (operand *left,
2240 pCodeOp *pct1, *pct2, *pct3, *pct4;
2242 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2245 if (AOP_TYPE(right) == AOP_LIT) {
2246 pic16_genUMult8XLit_8(left,right,result);
2254 /* if result == right then exchange left and right */
2255 if(pic16_sameRegs(AOP(result), AOP(right))) {
2263 if(pic16_sameRegs(AOP(result), AOP(left))) {
2265 pct1 = pic16_popGetTempReg();
2266 pct2 = pic16_popGetTempReg();
2267 pct3 = pic16_popGetTempReg();
2268 pct4 = pic16_popGetTempReg();
2270 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2271 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2272 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2273 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2274 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2275 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2277 /* WREG still holds the lower left */
2278 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2279 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2280 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2282 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2283 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2284 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2285 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2288 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2289 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2290 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2291 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2292 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2293 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2295 pic16_popReleaseTempReg( pct4 );
2296 pic16_popReleaseTempReg( pct3 );
2297 pic16_popReleaseTempReg( pct2 );
2298 pic16_popReleaseTempReg( pct1 );
2302 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2303 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2304 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2305 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2306 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2307 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2309 /* WREG still holds the lower left */
2310 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2311 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2312 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2314 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2315 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2316 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2317 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2322 /*-----------------------------------------------------------------*
2323 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2324 *-----------------------------------------------------------------*/
2325 void pic16_genMult32X32_32 (operand *left,
2329 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2331 if (AOP_TYPE(right) == AOP_LIT)
2332 pic16_genUMult32XLit_32(left,right,result);
2334 pic16_genUMult32X32_32(left,right,result);
2345 /*-----------------------------------------------------------------*/
2346 /* constMult - generates code for multiplication by a constant */
2347 /*-----------------------------------------------------------------*/
2348 void genMultConst(unsigned C)
2352 unsigned sr3; // Shift right 3
2358 Convert a string of 3 binary 1's in the lit into
2362 mask = 7 << ( (size*8) - 3);
2366 while(mask < (1<<size*8)) {
2368 if( (mask & lit) == lit) {
2371 /* We found 3 (or more) consecutive 1's */
2373 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2375 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2377 lit ^= consecutive_bits;
2381 sr3 |= (consecutive + lsb);