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);
58 const char *pic16_AopType(short type)
105 const char *pic16_pCodeOpType( pCodeOp *pcop)
128 case PO_GPR_REGISTER:
129 return "PO_GPR_REGISTER";
133 return "PO_GPR_TEMP";
134 case PO_SFR_REGISTER:
135 return "PO_SFR_REGISTER";
143 return "PO_REL_ADDR";
145 return "PO_IMMEDIATE";
161 return "BAD PO_TYPE";
164 /*-----------------------------------------------------------------*/
165 /* pic16_genPlusIncr :- does addition with increment if possible */
166 /*-----------------------------------------------------------------*/
167 bool pic16_genPlusIncr (iCode *ic)
169 unsigned int icount ;
170 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
172 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
173 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
174 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
175 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
176 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
178 /* will try to generate an increment */
179 /* if the right side is not a literal
181 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
184 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
185 /* if the literal value of the right hand side
186 is greater than 2 then it is faster to add */
187 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
190 /* if increment 16 bits in register */
191 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
196 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
197 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
201 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
202 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
208 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
209 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
210 if( strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
211 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
213 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
214 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
215 AOP(IC_RESULT(ic))->aopu.aop_dir,
216 AOP(IC_RESULT(ic))->aopu.aop_dir);
218 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
219 //pic16_emitcode("xorlw","1");
221 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
222 //pic16_emitcode("andlw","1");
225 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
226 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
227 AOP(IC_RESULT(ic))->aopu.aop_dir,
228 AOP(IC_RESULT(ic))->aopu.aop_dir);
234 /* if the sizes are greater than 1 then we cannot */
235 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
236 AOP_SIZE(IC_LEFT(ic)) > 1 )
239 /* If we are incrementing the same register by two: */
241 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
244 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
245 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
250 DEBUGpic16_emitcode ("; ","couldn't increment ");
255 /*-----------------------------------------------------------------*/
256 /* pic16_outBitAcc - output a bit in acc */
257 /*-----------------------------------------------------------------*/
258 void pic16_outBitAcc(operand *result)
260 symbol *tlbl = newiTempLabel(NULL);
261 /* if the result is a bit */
262 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
264 if (AOP_TYPE(result) == AOP_CRY){
265 pic16_aopPut(AOP(result),"a",0);
268 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
269 pic16_emitcode("mov","a,#01");
270 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
271 pic16_outAcc(result);
275 /*-----------------------------------------------------------------*/
276 /* pic16_genPlusBits - generates code for addition of two bits */
277 /*-----------------------------------------------------------------*/
278 void pic16_genPlusBits (iCode *ic)
281 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
283 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
284 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
285 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
286 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
288 The following block of code will add two bits.
289 Note that it'll even work if the destination is
290 the carry (C in the status register).
291 It won't work if the 'Z' bit is a source or destination.
294 /* If the result is stored in the accumulator (w) */
295 //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
296 switch(AOP_TYPE(IC_RESULT(ic))) {
298 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
299 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
300 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
301 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
302 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
304 pic16_emitcode("clrw","");
305 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
306 AOP(IC_RIGHT(ic))->aopu.aop_dir,
307 AOP(IC_RIGHT(ic))->aopu.aop_dir);
308 pic16_emitcode("xorlw","1");
309 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
310 AOP(IC_LEFT(ic))->aopu.aop_dir,
311 AOP(IC_LEFT(ic))->aopu.aop_dir);
312 pic16_emitcode("xorlw","1");
315 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
316 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
317 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
318 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
319 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
320 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
323 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
324 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
325 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
326 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
327 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
328 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
330 pic16_emitcode("movlw","(1 << (%s & 7))",
331 AOP(IC_RESULT(ic))->aopu.aop_dir,
332 AOP(IC_RESULT(ic))->aopu.aop_dir);
333 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
334 AOP(IC_RESULT(ic))->aopu.aop_dir,
335 AOP(IC_RESULT(ic))->aopu.aop_dir);
336 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
337 AOP(IC_RIGHT(ic))->aopu.aop_dir,
338 AOP(IC_RIGHT(ic))->aopu.aop_dir);
339 pic16_emitcode("xorwf","(%s >>3),f",
340 AOP(IC_RESULT(ic))->aopu.aop_dir);
341 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
342 AOP(IC_LEFT(ic))->aopu.aop_dir,
343 AOP(IC_LEFT(ic))->aopu.aop_dir);
344 pic16_emitcode("xorwf","(%s>>3),f",
345 AOP(IC_RESULT(ic))->aopu.aop_dir);
352 /* This is the original version of this code.
354 * This is being kept around for reference,
355 * because I am not entirely sure I got it right...
357 static void adjustArithmeticResult(iCode *ic)
359 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
360 AOP_SIZE(IC_LEFT(ic)) == 3 &&
361 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
362 pic16_aopPut(AOP(IC_RESULT(ic)),
363 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
366 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
367 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
368 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
369 pic16_aopPut(AOP(IC_RESULT(ic)),
370 pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
373 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
374 AOP_SIZE(IC_LEFT(ic)) < 3 &&
375 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
376 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
377 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
379 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
380 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
384 /* This is the pure and virtuous version of this code.
385 * I'm pretty certain it's right, but not enough to toss the old
388 static void adjustArithmeticResult(iCode *ic)
390 if (opIsGptr(IC_RESULT(ic)) &&
391 opIsGptr(IC_LEFT(ic)) &&
392 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
394 pic16_aopPut(AOP(IC_RESULT(ic)),
395 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
399 if (opIsGptr(IC_RESULT(ic)) &&
400 opIsGptr(IC_RIGHT(ic)) &&
401 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
403 pic16_aopPut(AOP(IC_RESULT(ic)),
404 pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
408 if (opIsGptr(IC_RESULT(ic)) &&
409 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
410 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
411 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
412 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
414 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
415 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
420 /*-----------------------------------------------------------------*/
421 /* genAddlit - generates code for addition */
422 /*-----------------------------------------------------------------*/
423 static void genAddLit2byte (operand *result, int offr, int lit)
430 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
433 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
436 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
437 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
442 static void emitMOVWF(operand *reg, int offset)
447 if (AOP_TYPE(reg) == AOP_ACC) {
448 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
452 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
456 static void genAddLit (iCode *ic, int lit)
465 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
469 result = IC_RESULT(ic);
470 same = pic16_sameRegs(AOP(left), AOP(result));
471 size = pic16_getDataSize(result);
475 /* Handle special cases first */
477 genAddLit2byte (result, 0, lit);
480 int hi = 0xff & (lit >> 8);
487 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
492 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
494 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
497 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
498 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
499 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
503 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
504 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
506 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
514 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
517 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
520 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
521 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
523 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
525 case 0xff: /* 0x01ff */
526 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
527 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
528 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
529 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
534 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
538 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
541 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
542 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
544 /* case 0xff: * 0xffff *
545 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
546 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
547 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
551 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
552 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
554 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
561 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
566 genAddLit2byte (result, MSB16, hi);
569 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1)&0xff));
570 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
571 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
572 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
574 /* case 0xff: * 0xHHff *
575 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
576 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
577 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
578 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
580 */ default: /* 0xHHLL */
581 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
582 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
583 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
585 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1) & 0xff));
586 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
595 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
598 lo = BYTEofLONG(lit,0);
606 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
609 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
610 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(1));
611 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
613 default: /* carry_info = 3 */
615 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
621 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
626 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
629 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
634 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo+1));
635 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
640 /* no carry info from previous step */
641 /* this means this is the first time to add */
646 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
650 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
651 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
653 carry_info = 3; /* Were adding only one byte and propogating the carry */
664 lo = BYTEofLONG(lit,0);
669 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
672 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
673 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
676 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
678 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
680 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
690 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
694 if(AOP_TYPE(left) == AOP_ACC) {
695 /* left addend is already in accumulator */
698 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
702 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
703 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
707 /* left addend is in a register */
710 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
711 emitMOVWF(result, 0);
712 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
716 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
717 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
721 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
722 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
726 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
727 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
728 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
736 /* left is not the accumulator */
738 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
739 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
741 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
742 /* We don't know the state of the carry bit at this point */
745 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
752 /* The ls byte of the lit must've been zero - that
753 means we don't have to deal with carry */
755 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
756 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
757 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),offset));
762 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
763 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset,FALSE,FALSE));
764 emitMOVWF(result,offset);
765 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
767 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
768 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
772 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
773 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset));
774 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
775 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
783 /*-----------------------------------------------------------------*/
784 /* pic16_genPlus - generates code for addition */
785 /*-----------------------------------------------------------------*/
786 void pic16_genPlus (iCode *ic)
788 int size, offset = 0;
789 operand *result, *left, *right;
791 /* special cases :- */
792 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
796 result = IC_RESULT(ic);
798 right = IC_RIGHT(ic);
799 pic16_aopOp (left,ic,FALSE);
800 pic16_aopOp (right,ic,FALSE);
801 pic16_aopOp (result,ic,TRUE);
802 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
805 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
806 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
807 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
808 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
812 /* if literal, literal on the right or
813 if left requires ACC or right is already
816 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
817 operand *t = IC_RIGHT(ic);
818 IC_RIGHT(ic) = IC_LEFT(ic);
822 /* if both left & right are in bit space */
823 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
824 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
825 pic16_genPlusBits (ic);
829 /* if left in bit space & right literal */
830 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
831 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
832 /* if result in bit space */
833 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
834 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
835 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
836 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
837 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
838 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
841 size = pic16_getDataSize(IC_RESULT(ic));
843 MOVA(pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
844 pic16_emitcode("addc","a,#00 ;%d",__LINE__);
845 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
851 /* if I can do an increment instead
852 of add then GOOD for ME */
853 if (pic16_genPlusIncr (ic) == TRUE)
856 size = pic16_getDataSize(IC_RESULT(ic));
858 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
859 /* Add a literal to something else */
861 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
865 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
870 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
872 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
873 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
874 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
876 /* here we are adding a bit to a char or int */
878 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
880 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
881 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
883 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
884 AOP(IC_RIGHT(ic))->aopu.aop_dir,
885 AOP(IC_RIGHT(ic))->aopu.aop_dir);
886 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
889 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
890 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
891 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
893 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
894 AOP(IC_RIGHT(ic))->aopu.aop_dir,
895 AOP(IC_RIGHT(ic))->aopu.aop_dir);
896 pic16_emitcode(" xorlw","1");
898 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
899 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
900 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
902 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
903 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
904 AOP(IC_RIGHT(ic))->aopu.aop_dir,
905 AOP(IC_RIGHT(ic))->aopu.aop_dir);
906 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
909 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
911 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
912 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
913 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
915 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
917 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
918 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
925 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
926 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
928 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
929 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
931 pic16_emitcode("clrz","");
933 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
934 AOP(IC_RIGHT(ic))->aopu.aop_dir,
935 AOP(IC_RIGHT(ic))->aopu.aop_dir);
936 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
940 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
941 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
942 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
943 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
944 emitMOVWF(IC_RIGHT(ic),0);
946 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
947 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
948 AOP(IC_RIGHT(ic))->aopu.aop_dir,
949 AOP(IC_RIGHT(ic))->aopu.aop_dir);
950 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
951 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
957 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
958 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
964 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
966 /* Add the first bytes */
968 if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
969 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
970 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
973 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
974 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
975 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
976 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
979 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
981 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
982 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
984 PIC_OPCODE poc = POC_ADDFW;
986 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
987 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
988 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
990 pic16_emitpcode(poc, pic16_popGet(AOP(IC_LEFT(ic)),0));
991 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
992 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
997 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1002 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1003 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1004 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1006 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1007 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1010 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1012 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1013 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1016 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1018 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1019 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1027 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1028 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1029 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1032 /* Need to extend result to higher bytes */
1033 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1035 /* First grab the carry from the lower bytes */
1036 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1037 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1041 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1044 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1045 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1046 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1047 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1049 /* if chars or ints or being signed extended to longs: */
1051 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1052 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1053 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1061 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1063 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1070 //adjustArithmeticResult(ic);
1073 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1074 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1075 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1078 /*-----------------------------------------------------------------*/
1079 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1080 /*-----------------------------------------------------------------*/
1081 bool pic16_genMinusDec (iCode *ic)
1083 unsigned int icount ;
1084 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1086 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1087 /* will try to generate an increment */
1088 /* if the right side is not a literal
1090 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1091 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1092 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1095 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1097 /* if the literal value of the right hand side
1098 is greater than 4 then it is not worth it */
1099 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1102 /* if decrement 16 bits in register */
1103 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1108 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1109 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1110 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1111 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1113 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1114 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1115 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1117 /* size is 3 or 4 */
1118 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1119 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1121 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1123 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1125 pic16_emitcode("movlw","0xff");
1126 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1129 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1131 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1135 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1137 pic16_emitcode("skpnc","");
1139 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1148 /* if the sizes are greater than 1 then we cannot */
1149 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1150 AOP_SIZE(IC_LEFT(ic)) > 1 )
1153 /* we can if the aops of the left & result match or
1154 if they are in registers and the registers are the
1156 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1159 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1161 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1166 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1167 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1168 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1171 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1172 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1174 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1175 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1183 /*-----------------------------------------------------------------*/
1184 /* pic16_addSign - propogate sign bit to higher bytes */
1185 /*-----------------------------------------------------------------*/
1186 void pic16_addSign(operand *result, int offset, int sign)
1188 int size = (pic16_getDataSize(result) - offset);
1189 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1192 if(sign && offset) {
1195 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1196 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1197 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1200 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1201 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1202 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1204 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),size));
1209 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1213 /*-----------------------------------------------------------------*/
1214 /* pic16_genMinusBits - generates code for subtraction of two bits */
1215 /*-----------------------------------------------------------------*/
1216 void pic16_genMinusBits (iCode *ic)
1218 symbol *lbl = newiTempLabel(NULL);
1219 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1220 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1221 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1222 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1223 pic16_emitcode("cpl","c");
1224 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1225 pic16_outBitC(IC_RESULT(ic));
1228 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1229 pic16_emitcode("subb","a,acc");
1230 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1231 pic16_emitcode("inc","a");
1232 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1233 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1234 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1238 /*-----------------------------------------------------------------*/
1239 /* pic16_genMinus - generates code for subtraction */
1240 /*-----------------------------------------------------------------*/
1241 void pic16_genMinus (iCode *ic)
1243 int size, offset = 0, same=0;
1244 unsigned long lit = 0L;
1246 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1247 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1248 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1249 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1251 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1252 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1253 operand *t = IC_RIGHT(ic);
1254 IC_RIGHT(ic) = IC_LEFT(ic);
1258 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1259 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1260 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1261 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1263 /* special cases :- */
1264 /* if both left & right are in bit space */
1265 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1266 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1267 pic16_genPlusBits (ic);
1271 /* if I can do an decrement instead
1272 of subtract then GOOD for ME */
1273 // if (pic16_genMinusDec (ic) == TRUE)
1276 size = pic16_getDataSize(IC_RESULT(ic));
1277 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1279 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1280 /* Add a literal to something else */
1282 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1285 genAddLit ( ic, lit);
1288 /* add the first byte: */
1289 pic16_emitcode("movlw","0x%x", lit & 0xff);
1290 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1291 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1292 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1304 if((lit & 0xff) == 0xff) {
1305 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1307 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1309 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1311 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1312 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1316 /* do the rlf known zero trick here */
1317 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1319 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1324 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1327 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1328 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1329 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1331 /* here we are subtracting a bit from a char or int */
1333 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1335 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1336 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1338 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1339 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1340 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1341 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1344 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1345 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1346 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1347 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1348 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1350 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1352 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1353 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1355 pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1356 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1359 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1361 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1363 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1364 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1368 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1369 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1370 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1371 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1376 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1377 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1378 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1381 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1383 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1386 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1388 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1390 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1397 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1398 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1399 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1401 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1402 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1403 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1404 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1405 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1408 if( (size == 1) && ((lit & 0xff) == 0) ) {
1409 /* res = 0 - right */
1410 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1411 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1412 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1414 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1415 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1416 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1421 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1422 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1423 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1431 /* This is the last byte in a multibyte subtraction
1432 * There are a couple of tricks we can do by not worrying about
1433 * propogating the carry */
1435 /* 0xff - x == ~x */
1437 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1439 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1441 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1442 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1444 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1447 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1449 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1450 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1451 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1460 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1462 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
1463 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1466 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1472 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1473 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1475 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1477 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1479 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1480 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1487 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1488 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1489 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1490 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1492 if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1493 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1494 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1495 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1496 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1499 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1500 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1501 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1502 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1503 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1506 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1507 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1508 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1510 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1511 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1513 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1514 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1515 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1517 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1519 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1520 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1521 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1523 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1525 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1532 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1534 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1535 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1537 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1538 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1545 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1546 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1547 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1549 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1551 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1552 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1560 // adjustArithmeticResult(ic);
1563 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1564 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1565 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1567 /*-----------------------------------------------------------------*
1568 * pic_genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1571 *-----------------------------------------------------------------*/
1572 void pic16_genUMult8XLit_16 (operand *left,
1575 pCodeOpReg *result_hi)
1580 unsigned int i,have_first_bit;
1584 if (AOP_TYPE(right) != AOP_LIT){
1585 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1591 result_hi = PCOR(pic16_popGet(AOP(result),1));
1594 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1596 pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1598 same = pic16_sameRegs(AOP(left), AOP(result));
1603 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(left),0));
1606 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1607 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1610 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1611 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1612 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1615 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1616 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1617 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1618 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1621 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1622 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1623 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1624 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1627 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1628 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1629 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1630 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1631 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1634 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1635 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1636 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1637 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1638 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 7*F
1641 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1642 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1643 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1644 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1645 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
1648 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1649 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1650 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1651 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1652 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1653 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1656 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1657 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1658 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1659 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1660 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1661 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1664 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1665 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1666 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1667 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1668 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
1669 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 11*F
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));
1675 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1676 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));
1681 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1682 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1683 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1684 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1685 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
1686 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 13*F
1689 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1690 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1691 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1692 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1693 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
1694 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 11*F
1695 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 14*F
1698 temp = pic16_popGetTempReg();
1700 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1703 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1704 pic16_emitpcode(POC_MOVWF, temp);
1705 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1706 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1707 pic16_emitpcode(POC_SWAPFW, temp);
1708 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(left),0));
1709 pic16_popReleaseTempReg(temp);
1712 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1713 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1714 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1717 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1718 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1719 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1722 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
1723 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
1724 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xe0));
1725 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1728 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
1729 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1730 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
1731 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xc0));
1732 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1735 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
1736 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(left),0));
1737 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),0));
1745 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1746 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1749 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1750 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1751 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
1752 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1753 pic16_emitpcode(POC_RLCF, pic16_popCopyReg(result_hi));
1759 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1760 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1761 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1764 for(i=0; i<8; i++) {
1767 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1771 if(have_first_bit) {
1772 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1773 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1781 /*-----------------------------------------------------------------*
1782 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1785 *-----------------------------------------------------------------*/
1786 void pic16_genUMult8X8_16 (operand *left,
1789 pCodeOpReg *result_hi)
1797 result_hi = PCOR(pic16_popGet(AOP(result),1));
1800 if (AOP_TYPE(right) == AOP_LIT) {
1801 pic16_genUMult8XLit_16(left,right,result,result_hi);
1806 pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1808 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1809 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1810 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1813 for(i=0; i<8; i++) {
1814 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),i,0));
1815 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1816 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1817 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1822 Here's another version that does the same thing and takes the
1823 same number of instructions. The one above is slightly better
1824 because the entry instructions have a higher probability of
1825 being optimized out.
1828 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1829 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
1830 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1831 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1833 for(i=0; i<8; i++) {
1835 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1836 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1837 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1842 symbol *tlbl = newiTempLabel(NULL);
1846 pic16_emitcode(";","Looped 8 X 8 multiplication");
1848 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1849 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1851 pic16_emitpcode(POC_BSF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),0,FALSE,FALSE),7,0));
1853 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1855 temp = pic16_popGetTempReg();
1856 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(PCOR(temp)));
1858 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1860 pic16_emitpLabel(tlbl->key);
1862 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(PCOR(temp)));
1864 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1866 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1867 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1870 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl->key));
1872 pic16_popReleaseTempReg(temp);
1877 /*-----------------------------------------------------------------*
1878 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1880 * this routine will call the unsigned multiply routine and then
1881 * post-fix the sign bit.
1882 *-----------------------------------------------------------------*/
1883 void pic16_genSMult8X8_16 (operand *left,
1886 pCodeOpReg *result_hi)
1890 result_hi = PCOR(pic16_popGet(AOP(result),1));
1893 pic16_genUMult8X8_16(left,right,result,result_hi);
1895 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0));
1896 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
1897 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1898 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0));
1899 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
1903 /*-----------------------------------------------------------------*
1904 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers
1906 * this routine will call the unsigned multiply 8X8=>16 routine and
1907 * then throw away the high byte of the result.
1909 *-----------------------------------------------------------------*/
1910 void pic16_genMult8X8_8 (operand *left,
1914 pCodeOp *result_hi = pic16_popGetTempReg();
1916 if (AOP_TYPE(right) == AOP_LIT)
1917 pic16_genUMult8XLit_16(left,right,result,PCOR(result_hi));
1919 pic16_genUMult8X8_16(left,right,result,PCOR(result_hi));
1921 pic16_popReleaseTempReg(result_hi);
1924 /*-----------------------------------------------------------------*/
1925 /* constMult - generates code for multiplication by a constant */
1926 /*-----------------------------------------------------------------*/
1927 void genMultConst(unsigned C)
1931 unsigned sr3; // Shift right 3
1937 Convert a string of 3 binary 1's in the lit into
1941 mask = 7 << ( (size*8) - 3);
1945 while(mask < (1<<size*8)) {
1947 if( (mask & lit) == lit) {
1950 /* We found 3 (or more) consecutive 1's */
1952 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1954 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1956 lit ^= consecutive_bits;
1960 sr3 |= (consecutive + lsb);