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 /*-----------------------------------------------------------------*/
172 /* pic16_genPlusIncr :- does addition with increment if possible */
173 /*-----------------------------------------------------------------*/
174 bool pic16_genPlusIncr (iCode *ic)
176 unsigned int icount ;
177 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
179 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
180 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
181 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
182 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
183 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
185 /* will try to generate an increment */
186 /* if the right side is not a literal
188 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
191 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
192 /* if the literal value of the right hand side
193 is greater than 2 then it is faster to add */
194 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
197 /* if increment 16 bits in register */
198 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
203 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
204 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
208 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
209 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
215 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
216 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
217 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
218 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
220 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
221 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
222 AOP(IC_RESULT(ic))->aopu.aop_dir,
223 AOP(IC_RESULT(ic))->aopu.aop_dir);
225 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
226 //pic16_emitcode("xorlw","1");
228 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
229 //pic16_emitcode("andlw","1");
232 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
233 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
234 AOP(IC_RESULT(ic))->aopu.aop_dir,
235 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 (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
251 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
252 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
257 DEBUGpic16_emitcode ("; ","couldn't increment ");
262 /*-----------------------------------------------------------------*/
263 /* pic16_outBitAcc - output a bit in acc */
264 /*-----------------------------------------------------------------*/
265 void pic16_outBitAcc(operand *result)
267 symbol *tlbl = newiTempLabel(NULL);
268 /* if the result is a bit */
269 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
271 if (AOP_TYPE(result) == AOP_CRY){
272 pic16_aopPut(AOP(result),"a",0);
275 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
276 pic16_emitcode("mov","a,#01");
277 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
278 pic16_outAcc(result);
282 /*-----------------------------------------------------------------*/
283 /* pic16_genPlusBits - generates code for addition of two bits */
284 /*-----------------------------------------------------------------*/
285 void pic16_genPlusBits (iCode *ic)
288 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
290 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
291 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
292 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
293 pic16_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(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
303 switch(AOP_TYPE(IC_RESULT(ic))) {
305 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
306 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
307 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
308 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
309 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
311 pic16_emitcode("clrw","");
312 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
313 AOP(IC_RIGHT(ic))->aopu.aop_dir,
314 AOP(IC_RIGHT(ic))->aopu.aop_dir);
315 pic16_emitcode("xorlw","1");
316 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
317 AOP(IC_LEFT(ic))->aopu.aop_dir,
318 AOP(IC_LEFT(ic))->aopu.aop_dir);
319 pic16_emitcode("xorlw","1");
322 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
323 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
324 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
325 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
326 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
327 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
330 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
331 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
332 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
333 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
334 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
335 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
337 pic16_emitcode("movlw","(1 << (%s & 7))",
338 AOP(IC_RESULT(ic))->aopu.aop_dir,
339 AOP(IC_RESULT(ic))->aopu.aop_dir);
340 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
341 AOP(IC_RESULT(ic))->aopu.aop_dir,
342 AOP(IC_RESULT(ic))->aopu.aop_dir);
343 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
344 AOP(IC_RIGHT(ic))->aopu.aop_dir,
345 AOP(IC_RIGHT(ic))->aopu.aop_dir);
346 pic16_emitcode("xorwf","(%s >>3),f",
347 AOP(IC_RESULT(ic))->aopu.aop_dir);
348 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
349 AOP(IC_LEFT(ic))->aopu.aop_dir,
350 AOP(IC_LEFT(ic))->aopu.aop_dir);
351 pic16_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 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
369 pic16_aopPut(AOP(IC_RESULT(ic)),
370 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
373 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
374 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
375 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
376 pic16_aopPut(AOP(IC_RESULT(ic)),
377 pic16_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 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
384 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
386 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
387 pic16_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 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
401 pic16_aopPut(AOP(IC_RESULT(ic)),
402 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
406 if (opIsGptr(IC_RESULT(ic)) &&
407 opIsGptr(IC_RIGHT(ic)) &&
408 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
410 pic16_aopPut(AOP(IC_RESULT(ic)),
411 pic16_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 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
419 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
421 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
422 pic16_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 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
440 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
443 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
444 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
449 static void emitMOVWF(operand *reg, int offset)
454 if (AOP_TYPE(reg) == AOP_ACC) {
455 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
459 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
463 static void genAddLit (iCode *ic, int lit)
472 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
476 result = IC_RESULT(ic);
477 same = pic16_sameRegs(AOP(left), AOP(result));
478 size = pic16_getDataSize(result);
482 /* Handle special cases first */
484 genAddLit2byte (result, 0, lit);
487 int hi = 0xff & (lit >> 8);
494 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
499 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
501 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
504 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
505 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
506 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
510 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
511 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
513 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
521 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
524 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
527 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
528 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
530 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
532 case 0xff: /* 0x01ff */
533 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
534 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
535 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
536 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
541 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
545 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
548 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
549 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
551 /* case 0xff: * 0xffff *
552 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
553 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
554 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
558 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
559 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
561 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
568 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
573 genAddLit2byte (result, MSB16, hi);
576 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1)&0xff));
577 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
578 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
579 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
581 /* case 0xff: * 0xHHff *
582 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
583 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
584 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
585 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
587 */ default: /* 0xHHLL */
588 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
589 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
590 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
592 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1) & 0xff));
593 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
602 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
605 lo = BYTEofLONG(lit,0);
613 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
616 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
617 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(1));
618 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
620 default: /* carry_info = 3 */
622 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
628 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
633 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
636 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
641 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo+1));
642 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
647 /* no carry info from previous step */
648 /* this means this is the first time to add */
653 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
657 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
658 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
660 carry_info = 3; /* Were adding only one byte and propogating the carry */
671 lo = BYTEofLONG(lit,0);
676 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
679 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
680 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
683 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
685 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
687 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
697 DEBUGpic16_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 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
709 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
710 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
714 /* left addend is in a register */
717 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
718 emitMOVWF(result, 0);
719 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
723 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
724 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
728 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
729 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
733 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
734 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
735 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
743 /* left is not the accumulator */
745 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
746 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
748 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
749 /* We don't know the state of the carry bit at this point */
752 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
759 /* The ls byte of the lit must've been zero - that
760 means we don't have to deal with carry */
762 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
763 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
764 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),offset));
769 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
770 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset,FALSE,FALSE));
771 emitMOVWF(result,offset);
772 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
774 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
775 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
779 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
780 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset));
781 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
782 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
790 /*-----------------------------------------------------------------*/
791 /* pic16_genPlus - generates code for addition */
792 /*-----------------------------------------------------------------*/
793 void pic16_genPlus (iCode *ic)
795 int i, size, offset = 0;
796 operand *result, *left, *right;
798 /* special cases :- */
799 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
802 result = IC_RESULT(ic);
804 right = IC_RIGHT(ic);
805 pic16_aopOp (left,ic,FALSE);
806 pic16_aopOp (right,ic,FALSE);
807 pic16_aopOp (result,ic,TRUE);
808 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
809 // pic16_DumpOp("(left)",left);
811 /* if literal, literal on the right or
812 if left requires ACC or right is already
815 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
821 /* if both left & right are in bit space */
822 if (AOP_TYPE(left) == AOP_CRY &&
823 AOP_TYPE(right) == AOP_CRY) {
824 pic16_genPlusBits (ic);
828 /* if left in bit space & right literal */
829 if (AOP_TYPE(left) == AOP_CRY &&
830 AOP_TYPE(right) == AOP_LIT) {
831 /* if result in bit space */
832 if(AOP_TYPE(result) == AOP_CRY){
833 if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
834 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
835 if (!pic16_sameRegs(AOP(left), AOP(result)) )
836 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
837 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
840 size = pic16_getDataSize(result);
842 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
843 pic16_emitcode("addc","a,#00 ;%d",__LINE__);
844 pic16_aopPut(AOP(result),"a",offset++);
850 /* if I can do an increment instead
851 of add then GOOD for ME */
852 if (pic16_genPlusIncr (ic) == TRUE)
855 size = pic16_getDataSize(IC_RESULT(ic));
857 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
858 /* Add a literal to something else */
860 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
864 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
869 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
871 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
872 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
873 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
875 /* here we are adding a bit to a char or int */
877 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
879 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
880 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
882 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
883 AOP(IC_RIGHT(ic))->aopu.aop_dir,
884 AOP(IC_RIGHT(ic))->aopu.aop_dir);
885 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
888 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
889 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
890 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
892 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
893 AOP(IC_RIGHT(ic))->aopu.aop_dir,
894 AOP(IC_RIGHT(ic))->aopu.aop_dir);
895 pic16_emitcode(" xorlw","1");
897 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
898 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
899 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
901 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
902 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
903 AOP(IC_RIGHT(ic))->aopu.aop_dir,
904 AOP(IC_RIGHT(ic))->aopu.aop_dir);
905 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
908 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
910 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
911 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
912 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
914 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
916 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
917 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
924 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
925 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
927 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
928 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
930 pic16_emitcode("clrz","");
932 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
933 AOP(IC_RIGHT(ic))->aopu.aop_dir,
934 AOP(IC_RIGHT(ic))->aopu.aop_dir);
935 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
939 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
940 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
941 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
942 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
943 emitMOVWF(IC_RIGHT(ic),0);
945 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
946 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
947 AOP(IC_RIGHT(ic))->aopu.aop_dir,
948 AOP(IC_RIGHT(ic))->aopu.aop_dir);
949 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
950 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
956 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
957 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
965 // Note: the following is an example of WISC code, eg.
966 // it's supposed to run on a Weird Instruction Set Computer :o)
968 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
970 if ( AOP_TYPE(left) == AOP_ACC) {
971 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
972 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
973 if ( AOP_TYPE(result) != AOP_ACC)
974 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
975 goto release; // we're done, since WREG is 1 byte
979 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
981 size = min( AOP_SIZE(result), AOP_SIZE(right) );
982 size = min( size, AOP_SIZE(left) );
985 if(pic16_debug_verbose) {
986 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
987 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
988 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
993 if ((AOP_TYPE(left) == AOP_PCODE) && (
994 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
995 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
996 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
998 // add to literal operand
1001 for(i=0; i<size; i++) {
1002 if (AOP_TYPE(right) == AOP_ACC) {
1003 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1005 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1006 if(i) { // add with carry
1007 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1008 } else { // add without
1009 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1012 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1015 // add leftover bytes
1016 if (SPEC_USIGN(getSpec(operandType(right)))) {
1017 // right is unsigned
1018 for(i=size; i< AOP_SIZE(result); i++) {
1019 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1020 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1021 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1025 // right is signed, oh dear ...
1026 for(i=size; i< AOP_SIZE(result); i++) {
1027 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1028 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),size-1,FALSE,FALSE),7,0));
1029 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
1030 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1031 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1041 for(i=0; i<size; i++) {
1042 if (AOP_TYPE(right) != AOP_ACC)
1043 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),i));
1044 if (pic16_sameRegs(AOP(left), AOP(result)))
1046 if(i) { // add with carry
1047 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1048 } else { // add without
1049 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1051 } else { // not same
1052 if(i) { // add with carry
1053 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1054 } else { // add without
1055 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1057 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1061 // add leftover bytes
1062 if (SPEC_USIGN(getSpec(operandType(right)))) {
1063 // right is unsigned
1064 for(i=size; i< AOP_SIZE(result); i++) {
1065 if (pic16_sameRegs(AOP(left), AOP(result)))
1067 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1068 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1069 } else { // not same
1070 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),i));
1071 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1076 for(i=size; i< AOP_SIZE(result); i++) {
1077 if(size < AOP_SIZE(left)) {
1078 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1079 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0));
1080 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1081 if (pic16_sameRegs(AOP(left), AOP(result)))
1083 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1084 } else { // not same
1085 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1086 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1089 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1090 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1099 // TODO: anything from here to before "release:" is probably obsolete and should be removed
1100 // when the regression tests are stable
1102 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1103 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1104 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1107 /* Need to extend result to higher bytes */
1108 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1110 /* First grab the carry from the lower bytes */
1111 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1112 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1116 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1119 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1120 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1121 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1122 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1124 /* if chars or ints or being signed extended to longs: */
1126 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1127 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1128 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1136 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1138 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1145 //adjustArithmeticResult(ic);
1148 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1149 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1150 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1153 /*-----------------------------------------------------------------*/
1154 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1155 /*-----------------------------------------------------------------*/
1156 bool pic16_genMinusDec (iCode *ic)
1158 unsigned int icount ;
1159 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1161 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1162 /* will try to generate an increment */
1163 /* if the right side is not a literal
1165 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1166 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1167 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1170 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1172 /* if the literal value of the right hand side
1173 is greater than 4 then it is not worth it */
1174 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1177 /* if decrement 16 bits in register */
1178 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1183 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1184 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1185 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1186 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1188 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1189 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1190 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1192 /* size is 3 or 4 */
1193 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1194 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1196 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1198 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1200 pic16_emitcode("movlw","0xff");
1201 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1204 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1206 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1210 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1212 pic16_emitcode("skpnc","");
1214 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1223 /* if the sizes are greater than 1 then we cannot */
1224 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1225 AOP_SIZE(IC_LEFT(ic)) > 1 )
1228 /* we can if the aops of the left & result match or
1229 if they are in registers and the registers are the
1231 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1234 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1236 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1241 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1242 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1243 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1246 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1247 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1249 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1250 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1258 /*-----------------------------------------------------------------*/
1259 /* pic16_addSign - propogate sign bit to higher bytes */
1260 /*-----------------------------------------------------------------*/
1261 void pic16_addSign(operand *result, int offset, int sign)
1263 int size = (pic16_getDataSize(result) - offset);
1264 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1267 if(sign && offset) {
1270 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1271 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1272 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1275 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1276 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1277 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1279 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1284 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1288 /*-----------------------------------------------------------------*/
1289 /* pic16_genMinusBits - generates code for subtraction of two bits */
1290 /*-----------------------------------------------------------------*/
1291 void pic16_genMinusBits (iCode *ic)
1293 symbol *lbl = newiTempLabel(NULL);
1294 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1295 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1296 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1297 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1298 pic16_emitcode("cpl","c");
1299 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1300 pic16_outBitC(IC_RESULT(ic));
1303 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1304 pic16_emitcode("subb","a,acc");
1305 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1306 pic16_emitcode("inc","a");
1307 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1308 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1309 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1313 /*-----------------------------------------------------------------*/
1314 /* pic16_genMinus - generates code for subtraction */
1315 /*-----------------------------------------------------------------*/
1316 void pic16_genMinus (iCode *ic)
1318 int size, offset = 0, same=0;
1319 unsigned long lit = 0L;
1321 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1322 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1323 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1324 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1326 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1327 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1328 operand *t = IC_RIGHT(ic);
1329 IC_RIGHT(ic) = IC_LEFT(ic);
1333 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1334 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1335 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1336 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1338 /* special cases :- */
1339 /* if both left & right are in bit space */
1340 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1341 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1342 pic16_genPlusBits (ic);
1346 /* if I can do an decrement instead
1347 of subtract then GOOD for ME */
1348 // if (pic16_genMinusDec (ic) == TRUE)
1351 size = pic16_getDataSize(IC_RESULT(ic));
1352 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1354 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1355 /* Add a literal to something else */
1357 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1360 genAddLit ( ic, lit);
1363 /* add the first byte: */
1364 pic16_emitcode("movlw","0x%x", lit & 0xff);
1365 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1366 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1367 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1379 if((lit & 0xff) == 0xff) {
1380 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1382 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1384 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1386 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1387 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1391 /* do the rlf known zero trick here */
1392 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1394 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1399 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1402 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1403 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1404 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1406 /* here we are subtracting a bit from a char or int */
1408 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1410 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1411 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1413 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1414 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1415 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1416 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1419 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1420 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1421 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1422 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1423 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1425 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1427 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1428 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1430 pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1431 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1434 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1436 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1438 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1439 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1443 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1444 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1445 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1446 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1451 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1452 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1453 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1456 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1458 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1461 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1463 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1465 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1472 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1473 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1474 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1476 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1477 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1478 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1479 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1480 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1483 if( (size == 1) && ((lit & 0xff) == 0) ) {
1484 /* res = 0 - right */
1485 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1486 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1487 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1489 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1490 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1491 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1496 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1497 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1498 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1506 /* This is the last byte in a multibyte subtraction
1507 * There are a couple of tricks we can do by not worrying about
1508 * propogating the carry */
1510 /* 0xff - x == ~x */
1512 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1514 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1516 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1517 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1519 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1522 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1524 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1525 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1526 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1535 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1537 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
1538 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1541 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1547 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1548 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1550 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1552 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1554 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1555 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1562 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1563 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1564 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1565 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1567 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1568 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1569 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1570 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1571 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1574 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1575 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1576 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1577 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1578 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1581 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1582 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1583 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1585 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1586 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1588 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1589 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1590 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1592 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1594 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1595 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1596 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1598 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1600 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1607 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1609 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1610 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1612 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1613 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1620 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1621 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1622 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1624 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1626 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1627 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1635 // adjustArithmeticResult(ic);
1638 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1639 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1640 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1644 /*-----------------------------------------------------------------*
1645 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1648 *-----------------------------------------------------------------*/
1649 void pic16_genUMult8XLit_8 (operand *left,
1657 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1659 if (AOP_TYPE(right) != AOP_LIT){
1660 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1664 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1666 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1667 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1669 same = pic16_sameRegs(AOP(left), AOP(result));
1673 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1676 // its faster to left shift
1678 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1682 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1683 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1684 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1685 pic16_popGet(AOP(result), 0)));
1689 // operands different
1692 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1696 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1697 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1700 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1701 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1702 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1703 pic16_popGet(AOP(result), 0)));
1709 /*-----------------------------------------------------------------------*
1710 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1711 *-----------------------------------------------------------------------*/
1712 void pic16_genUMult16XLit_16 (operand *left,
1716 pCodeOp *pct1, *pct2, *pct3, *pct4;
1721 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1723 if (AOP_TYPE(right) != AOP_LIT){
1724 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1728 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1731 same = pic16_sameRegs(AOP(left), AOP(result));
1735 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1736 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1739 // its faster to left shift
1741 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1742 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1746 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1748 pct1 = pic16_popGetTempReg();
1749 pct2 = pic16_popGetTempReg();
1750 pct3 = pic16_popGetTempReg();
1751 pct4 = pic16_popGetTempReg();
1753 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1754 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1755 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1756 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1757 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1758 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1760 /* WREG still holds the low literal */
1761 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1762 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1763 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1765 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1766 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1767 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1768 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1771 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1772 pct1, pic16_popGet(AOP(result), 0)));
1773 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1774 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1775 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1776 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1778 pic16_popReleaseTempReg( pct4 );
1779 pic16_popReleaseTempReg( pct3 );
1780 pic16_popReleaseTempReg( pct2 );
1781 pic16_popReleaseTempReg( pct1 );
1785 // operands different
1788 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1789 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1793 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1794 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1795 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1796 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1800 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1801 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1802 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1803 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1804 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1805 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1807 /* WREG still holds the low literal */
1808 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1809 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1810 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1812 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1813 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1814 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1815 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1823 /*-----------------------------------------------------------------*
1824 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1827 *-----------------------------------------------------------------*/
1828 void pic16_genUMult8X8_8 (operand *left,
1833 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1836 if (AOP_TYPE(right) == AOP_LIT) {
1837 pic16_genUMult8XLit_8(left,right,result);
1847 /* if result == right then exchange left and right */
1848 if(pic16_sameRegs(AOP(result), AOP(right))) {
1855 if(AOP_TYPE(left) != AOP_ACC) {
1857 if(AOP_TYPE(right) != AOP_ACC) {
1858 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1859 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1861 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1864 // left is WREG, right cannot be WREG (or can?!)
1865 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1868 /* result is in PRODL:PRODH */
1869 if(AOP_TYPE(result) != AOP_ACC) {
1870 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1871 pic16_popGet(AOP(result), 0)));
1874 if(AOP_SIZE(result)>1) {
1877 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1878 pic16_popGet(AOP(result), 1)));
1880 for(i=2;i<AOP_SIZE(result);i++)
1881 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1884 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1888 /*------------------------------------------------------------------*
1889 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1890 *------------------------------------------------------------------*/
1891 void pic16_genUMult16X16_16 (operand *left,
1896 pCodeOp *pct1, *pct2, *pct3, *pct4;
1898 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1901 if (AOP_TYPE(right) == AOP_LIT) {
1902 pic16_genUMult8XLit_8(left,right,result);
1910 /* if result == right then exchange left and right */
1911 if(pic16_sameRegs(AOP(result), AOP(right))) {
1919 if(pic16_sameRegs(AOP(result), AOP(left))) {
1921 pct1 = pic16_popGetTempReg();
1922 pct2 = pic16_popGetTempReg();
1923 pct3 = pic16_popGetTempReg();
1924 pct4 = pic16_popGetTempReg();
1926 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1927 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1928 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1929 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1930 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1931 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1933 /* WREG still holds the lower left */
1934 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1935 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1936 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1938 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1939 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1940 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1941 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1944 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1945 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
1946 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
1947 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1948 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1949 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1951 pic16_popReleaseTempReg( pct4 );
1952 pic16_popReleaseTempReg( pct3 );
1953 pic16_popReleaseTempReg( pct2 );
1954 pic16_popReleaseTempReg( pct1 );
1958 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1959 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1960 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1961 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1962 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1963 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1965 /* WREG still holds the lower left */
1966 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1967 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1968 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1970 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1971 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1972 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1973 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1978 void pic16_genSMult16X16_16(operand *left,
1986 /*-----------------------------------------------------------------*
1987 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1989 * this routine will call the unsigned multiply routine and then
1990 * post-fix the sign bit.
1991 *-----------------------------------------------------------------*/
1992 void pic16_genSMult8X8_8 (operand *left,
1995 pCodeOpReg *result_hi)
1997 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2001 result_hi = PCOR(pic16_popGet(AOP(result),1));
2005 pic16_genUMult8X8_8(left,right,result);
2009 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0));
2010 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2011 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
2012 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0));
2013 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2018 /*-----------------------------------------------------------------*
2019 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
2020 *-----------------------------------------------------------------*/
2021 void pic16_genMult8X8_8 (operand *left,
2025 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2027 if(AOP_TYPE(right) == AOP_LIT)
2028 pic16_genUMult8XLit_8(left,right,result);
2030 pic16_genUMult8X8_8(left,right,result);
2034 /*-----------------------------------------------------------------*
2035 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
2036 *-----------------------------------------------------------------*/
2037 void pic16_genMult16X16_16 (operand *left,
2041 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2043 if (AOP_TYPE(right) == AOP_LIT)
2044 pic16_genUMult16XLit_16(left,right,result);
2046 pic16_genUMult16X16_16(left,right,result);
2053 /*-----------------------------------------------------------------------*
2054 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2055 *-----------------------------------------------------------------------*/
2056 void pic16_genUMult32XLit_32 (operand *left,
2060 pCodeOp *pct1, *pct2, *pct3, *pct4;
2065 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2067 if (AOP_TYPE(right) != AOP_LIT){
2068 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2072 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2075 same = pic16_sameRegs(AOP(left), AOP(result));
2079 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2080 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2083 // its faster to left shift
2085 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2086 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2090 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2092 pct1 = pic16_popGetTempReg();
2093 pct2 = pic16_popGetTempReg();
2094 pct3 = pic16_popGetTempReg();
2095 pct4 = pic16_popGetTempReg();
2097 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2098 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2099 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2100 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2101 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2102 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2104 /* WREG still holds the low literal */
2105 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2106 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2107 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2109 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2110 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2111 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2112 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2115 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2116 pct1, pic16_popGet(AOP(result), 0)));
2117 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2118 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2119 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2120 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2122 pic16_popReleaseTempReg( pct4 );
2123 pic16_popReleaseTempReg( pct3 );
2124 pic16_popReleaseTempReg( pct2 );
2125 pic16_popReleaseTempReg( pct1 );
2129 // operands different
2132 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2133 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2137 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2138 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2139 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2140 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2144 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2145 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2146 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2147 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2148 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2149 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2151 /* WREG still holds the low literal */
2152 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2153 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2154 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2156 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2157 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2158 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2159 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2167 /*------------------------------------------------------------------*
2168 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2169 *------------------------------------------------------------------*/
2170 void pic16_genUMult32X32_32 (operand *left,
2175 pCodeOp *pct1, *pct2, *pct3, *pct4;
2177 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2180 if (AOP_TYPE(right) == AOP_LIT) {
2181 pic16_genUMult8XLit_8(left,right,result);
2189 /* if result == right then exchange left and right */
2190 if(pic16_sameRegs(AOP(result), AOP(right))) {
2198 if(pic16_sameRegs(AOP(result), AOP(left))) {
2200 pct1 = pic16_popGetTempReg();
2201 pct2 = pic16_popGetTempReg();
2202 pct3 = pic16_popGetTempReg();
2203 pct4 = pic16_popGetTempReg();
2205 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2206 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2207 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2208 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2209 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2210 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2212 /* WREG still holds the lower left */
2213 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2214 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2215 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2217 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2218 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2219 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2220 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2223 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2224 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2225 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2226 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2227 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2228 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2230 pic16_popReleaseTempReg( pct4 );
2231 pic16_popReleaseTempReg( pct3 );
2232 pic16_popReleaseTempReg( pct2 );
2233 pic16_popReleaseTempReg( pct1 );
2237 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2238 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2239 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2240 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2241 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2242 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2244 /* WREG still holds the lower left */
2245 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2246 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2247 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2249 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2250 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2251 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2252 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2257 /*-----------------------------------------------------------------*
2258 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2259 *-----------------------------------------------------------------*/
2260 void pic16_genMult32X32_32 (operand *left,
2264 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2266 if (AOP_TYPE(right) == AOP_LIT)
2267 pic16_genUMult32XLit_32(left,right,result);
2269 pic16_genUMult32X32_32(left,right,result);
2280 /*-----------------------------------------------------------------*/
2281 /* constMult - generates code for multiplication by a constant */
2282 /*-----------------------------------------------------------------*/
2283 void genMultConst(unsigned C)
2287 unsigned sr3; // Shift right 3
2293 Convert a string of 3 binary 1's in the lit into
2297 mask = 7 << ( (size*8) - 3);
2301 while(mask < (1<<size*8)) {
2303 if( (mask & lit) == lit) {
2306 /* We found 3 (or more) consecutive 1's */
2308 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2310 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2312 lit ^= consecutive_bits;
2316 sr3 |= (consecutive + lsb);