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) );
984 if ((AOP_TYPE(left) == AOP_PCODE) && (
985 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
986 (AOP(left)->aopu.pcop->type == PO_DIR) ||
987 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
989 // add to literal operand
992 for(i=0; i<size; i++) {
993 if (AOP_TYPE(right) == AOP_ACC) {
994 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
996 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
997 if(i) { // add with carry
998 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
999 } else { // add without
1000 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1003 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1006 // add leftover bytes
1007 if (SPEC_USIGN(getSpec(operandType(right)))) {
1008 // right is unsigned
1009 for(i=size; i< AOP_SIZE(result); i++) {
1010 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1011 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1012 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1016 // right is signed, oh dear ...
1017 for(i=size; i< AOP_SIZE(result); i++) {
1018 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1019 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),size-1,FALSE,FALSE),7,0));
1020 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
1021 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1022 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1032 for(i=0; i<size; i++) {
1033 if (AOP_TYPE(right) != AOP_ACC)
1034 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),i));
1035 if (pic16_sameRegs(AOP(left), AOP(result)))
1037 if(i) { // add with carry
1038 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1039 } else { // add without
1040 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1042 } else { // not same
1043 if(i) { // add with carry
1044 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1045 } else { // add without
1046 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1048 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1052 // add leftover bytes
1053 if (SPEC_USIGN(getSpec(operandType(right)))) {
1054 // right is unsigned
1055 for(i=size; i< AOP_SIZE(result); i++) {
1056 if (pic16_sameRegs(AOP(left), AOP(result)))
1058 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1059 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1060 } else { // not same
1061 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),i));
1062 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1067 for(i=size; i< AOP_SIZE(result); i++) {
1068 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1069 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0));
1070 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1071 if (pic16_sameRegs(AOP(left), AOP(result)))
1073 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1074 } else { // not same
1075 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1076 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1085 // TODO: anything from here to before "release:" is probably obsolete and should be removed
1086 // when the regression tests are stable
1088 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1089 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1090 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1093 /* Need to extend result to higher bytes */
1094 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1096 /* First grab the carry from the lower bytes */
1097 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1098 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1102 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1105 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1106 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1107 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1108 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1110 /* if chars or ints or being signed extended to longs: */
1112 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1113 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1114 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1122 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1124 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1131 //adjustArithmeticResult(ic);
1134 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1135 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1136 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1139 /*-----------------------------------------------------------------*/
1140 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1141 /*-----------------------------------------------------------------*/
1142 bool pic16_genMinusDec (iCode *ic)
1144 unsigned int icount ;
1145 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1147 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1148 /* will try to generate an increment */
1149 /* if the right side is not a literal
1151 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1152 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1153 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1156 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1158 /* if the literal value of the right hand side
1159 is greater than 4 then it is not worth it */
1160 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1163 /* if decrement 16 bits in register */
1164 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1169 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1170 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1171 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1172 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1174 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1175 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1176 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1178 /* size is 3 or 4 */
1179 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1180 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1182 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1184 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1186 pic16_emitcode("movlw","0xff");
1187 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1190 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1192 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1196 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1198 pic16_emitcode("skpnc","");
1200 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1209 /* if the sizes are greater than 1 then we cannot */
1210 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1211 AOP_SIZE(IC_LEFT(ic)) > 1 )
1214 /* we can if the aops of the left & result match or
1215 if they are in registers and the registers are the
1217 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1220 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1222 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1227 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1228 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1229 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1232 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1233 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1235 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1236 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1244 /*-----------------------------------------------------------------*/
1245 /* pic16_addSign - propogate sign bit to higher bytes */
1246 /*-----------------------------------------------------------------*/
1247 void pic16_addSign(operand *result, int offset, int sign)
1249 int size = (pic16_getDataSize(result) - offset);
1250 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1253 if(sign && offset) {
1256 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1257 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1258 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1261 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1262 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1263 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1265 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1270 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1274 /*-----------------------------------------------------------------*/
1275 /* pic16_genMinusBits - generates code for subtraction of two bits */
1276 /*-----------------------------------------------------------------*/
1277 void pic16_genMinusBits (iCode *ic)
1279 symbol *lbl = newiTempLabel(NULL);
1280 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1281 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1282 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1283 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1284 pic16_emitcode("cpl","c");
1285 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1286 pic16_outBitC(IC_RESULT(ic));
1289 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1290 pic16_emitcode("subb","a,acc");
1291 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1292 pic16_emitcode("inc","a");
1293 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1294 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1295 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1299 /*-----------------------------------------------------------------*/
1300 /* pic16_genMinus - generates code for subtraction */
1301 /*-----------------------------------------------------------------*/
1302 void pic16_genMinus (iCode *ic)
1304 int size, offset = 0, same=0;
1305 unsigned long lit = 0L;
1307 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1308 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1309 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1310 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1312 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1313 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1314 operand *t = IC_RIGHT(ic);
1315 IC_RIGHT(ic) = IC_LEFT(ic);
1319 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1320 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1321 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1322 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1324 /* special cases :- */
1325 /* if both left & right are in bit space */
1326 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1327 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1328 pic16_genPlusBits (ic);
1332 /* if I can do an decrement instead
1333 of subtract then GOOD for ME */
1334 // if (pic16_genMinusDec (ic) == TRUE)
1337 size = pic16_getDataSize(IC_RESULT(ic));
1338 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1340 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1341 /* Add a literal to something else */
1343 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1346 genAddLit ( ic, lit);
1349 /* add the first byte: */
1350 pic16_emitcode("movlw","0x%x", lit & 0xff);
1351 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1352 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1353 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1365 if((lit & 0xff) == 0xff) {
1366 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1368 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1370 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1372 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1373 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1377 /* do the rlf known zero trick here */
1378 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1380 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1385 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1388 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1389 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1390 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1392 /* here we are subtracting a bit from a char or int */
1394 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1396 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1397 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1399 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1400 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1401 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1402 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1405 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1406 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1407 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1408 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1409 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1411 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1413 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1414 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1416 pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1417 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1420 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1422 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1424 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1425 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1429 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1430 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1431 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1432 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1437 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1438 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1439 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1442 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1444 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1447 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1449 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1451 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1458 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1459 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1460 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1462 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1463 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1464 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1465 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1466 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1469 if( (size == 1) && ((lit & 0xff) == 0) ) {
1470 /* res = 0 - right */
1471 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1472 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1473 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1475 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1476 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1477 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1482 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1483 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1484 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1492 /* This is the last byte in a multibyte subtraction
1493 * There are a couple of tricks we can do by not worrying about
1494 * propogating the carry */
1496 /* 0xff - x == ~x */
1498 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1500 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1502 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1503 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1505 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1508 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1510 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1511 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1512 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1521 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1523 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
1524 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1527 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1533 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1534 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1536 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1538 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1540 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1541 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1548 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1549 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1550 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1551 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1553 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1554 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1555 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1556 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1557 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1560 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1561 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1562 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1563 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1564 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1567 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1568 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1569 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1571 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1572 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1574 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1575 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1576 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1578 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1580 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1581 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1582 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1584 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1586 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1593 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1595 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1596 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1598 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1599 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1606 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1607 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1608 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1610 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1612 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1613 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1621 // adjustArithmeticResult(ic);
1624 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1625 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1626 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1629 /*-----------------------------------------------------------------*
1630 * pic_genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1633 *-----------------------------------------------------------------*/
1634 void pic16_genUMult8XLit_16 (operand *left,
1637 pCodeOpReg *result_hi)
1642 unsigned int i,have_first_bit;
1646 if (AOP_TYPE(right) != AOP_LIT){
1647 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1653 result_hi = PCOR(pic16_popGet(AOP(result),1));
1656 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1658 pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1660 same = pic16_sameRegs(AOP(left), AOP(result));
1665 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(left),0));
1668 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1669 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1672 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1673 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1674 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1677 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1678 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1679 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1680 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1683 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1684 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1685 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1686 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1689 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1690 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1691 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1692 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1693 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1696 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1697 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1698 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1699 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1700 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 7*F
1703 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1704 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1705 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1706 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1707 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
1710 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1711 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1712 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1713 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1714 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1715 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1718 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1719 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1720 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1721 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1722 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1723 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1726 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1727 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1728 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1729 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1730 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
1731 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 11*F
1734 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1735 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1736 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1737 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1738 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1739 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1740 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1743 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1744 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1745 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1746 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1747 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
1748 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 13*F
1751 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1752 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1753 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1754 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1755 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
1756 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 11*F
1757 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 14*F
1760 temp = pic16_popGetTempReg();
1762 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1765 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1766 pic16_emitpcode(POC_MOVWF, temp);
1767 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1768 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1769 pic16_emitpcode(POC_SWAPFW, temp);
1770 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(left),0));
1771 pic16_popReleaseTempReg(temp);
1774 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1775 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1776 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1779 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1780 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1781 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1784 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
1785 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
1786 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xe0));
1787 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1790 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
1791 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1792 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
1793 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xc0));
1794 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1797 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
1798 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(left),0));
1799 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),0));
1807 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1808 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1811 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1812 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1813 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
1814 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1815 pic16_emitpcode(POC_RLCF, pic16_popCopyReg(result_hi));
1821 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1822 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1823 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1826 for(i=0; i<8; i++) {
1829 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1833 if(have_first_bit) {
1834 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1835 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1844 /*-----------------------------------------------------------------*
1845 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1848 *-----------------------------------------------------------------*/
1849 void pic16_genUMult8XLit_8 (operand *left,
1856 if (AOP_TYPE(right) != AOP_LIT){
1857 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1861 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1863 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1864 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1866 same = pic16_sameRegs(AOP(left), AOP(result));
1870 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1873 // its faster to left shift
1874 pic16_emitpcode(POC_RLNCF, pic16_popGet(AOP(left),0));
1878 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1879 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1880 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1881 pic16_popGet(AOP(result), 0)));
1885 // operands different
1888 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1891 pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left), 0));
1892 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1895 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1896 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1897 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1898 pic16_popGet(AOP(result), 0)));
1904 /*-----------------------------------------------------------------*
1905 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1908 *-----------------------------------------------------------------*/
1909 void pic16_genUMult8X8_16 (operand *left,
1912 pCodeOpReg *result_hi)
1920 result_hi = PCOR(pic16_popGet(AOP(result),1));
1923 if (AOP_TYPE(right) == AOP_LIT) {
1924 pic16_genUMult8XLit_16(left,right,result,result_hi);
1929 pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1931 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1932 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1933 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1936 for(i=0; i<8; i++) {
1937 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),i,0));
1938 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1939 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1940 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1945 Here's another version that does the same thing and takes the
1946 same number of instructions. The one above is slightly better
1947 because the entry instructions have a higher probability of
1948 being optimized out.
1951 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1952 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
1953 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1954 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1956 for(i=0; i<8; i++) {
1958 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1959 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1960 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1965 symbol *tlbl = newiTempLabel(NULL);
1968 pic16_emitpcomment("; Looped 8 X 8 multiplication");
1969 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1970 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1972 pic16_emitpcode(POC_BSF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),0,FALSE,FALSE),7,0));
1974 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1976 temp = pic16_popGetTempReg();
1977 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(PCOR(temp)));
1979 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1981 pic16_emitpLabel(tlbl->key);
1983 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(PCOR(temp)));
1985 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1987 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1988 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1991 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl->key));
1993 pic16_popReleaseTempReg(temp);
1997 /*-----------------------------------------------------------------*
1998 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
2001 *-----------------------------------------------------------------*/
2002 void pic16_genUMult8X8_8 (operand *left,
2007 if (AOP_TYPE(right) == AOP_LIT) {
2008 pic16_genUMult8XLit_8(left,right,result);
2012 pic16_emitpcomment("; Looped 8 X 8 multiplication");
2019 /* if result == right then exchange left and right */
2020 if(pic16_sameRegs(AOP(result), AOP(right))) {
2027 if(AOP_TYPE(left) != AOP_ACC) {
2029 if(AOP_TYPE(right) != AOP_ACC) {
2030 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2031 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2033 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2036 // left is WREG, right cannot be WREG (or can?!)
2037 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
2040 /* result is in PRODL:PRODH */
2041 if(AOP_TYPE(result) != AOP_ACC) {
2042 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
2043 pic16_popGet(AOP(result), 0)));
2045 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2049 /*-----------------------------------------------------------------*
2050 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
2052 * this routine will call the unsigned multiply routine and then
2053 * post-fix the sign bit.
2054 *-----------------------------------------------------------------*/
2055 void pic16_genSMult8X8_16 (operand *left,
2058 pCodeOpReg *result_hi)
2062 result_hi = PCOR(pic16_popGet(AOP(result),1));
2065 pic16_genUMult8X8_16(left,right,result,result_hi);
2067 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0));
2068 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2069 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
2070 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0));
2071 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2075 /*-----------------------------------------------------------------*
2076 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers
2078 * this routine will call the unsigned multiply 8X8=>16 routine and
2079 * then throw away the high byte of the result.
2081 *-----------------------------------------------------------------*/
2082 void pic16_genMult8X8_8 (operand *left,
2086 if (AOP_TYPE(right) == AOP_LIT)
2087 pic16_genUMult8XLit_8(left,right,result);
2089 pic16_genUMult8X8_8(left,right,result);
2092 /*-----------------------------------------------------------------*/
2093 /* constMult - generates code for multiplication by a constant */
2094 /*-----------------------------------------------------------------*/
2095 void genMultConst(unsigned C)
2099 unsigned sr3; // Shift right 3
2105 Convert a string of 3 binary 1's in the lit into
2109 mask = 7 << ( (size*8) - 3);
2113 while(mask < (1<<size*8)) {
2115 if( (mask & lit) == lit) {
2118 /* We found 3 (or more) consecutive 1's */
2120 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2122 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2124 lit ^= consecutive_bits;
2128 sr3 |= (consecutive + lsb);