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 BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
53 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
55 const char *pic16_AopType(short type)
102 const char *pic16_pCodeOpType( pCodeOp *pcop)
125 case PO_GPR_REGISTER:
126 return "PO_GPR_REGISTER";
130 return "PO_GPR_TEMP";
131 case PO_SFR_REGISTER:
132 return "PO_SFR_REGISTER";
140 return "PO_REL_ADDR";
142 return "PO_IMMEDIATE";
158 return "BAD PO_TYPE";
161 /*-----------------------------------------------------------------*/
162 /* pic16_genPlusIncr :- does addition with increment if possible */
163 /*-----------------------------------------------------------------*/
164 bool pic16_genPlusIncr (iCode *ic)
166 unsigned int icount ;
167 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
169 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
170 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
171 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
172 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
173 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
175 /* will try to generate an increment */
176 /* if the right side is not a literal
178 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
181 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
182 /* if the literal value of the right hand side
183 is greater than 1 then it is faster to add */
184 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 1) // this was > 2 why? VR
187 /* if increment 16 bits in register */
188 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
193 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
194 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
198 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
199 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
205 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
206 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
207 if( strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
208 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
210 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
211 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
212 AOP(IC_RESULT(ic))->aopu.aop_dir,
213 AOP(IC_RESULT(ic))->aopu.aop_dir);
215 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
216 //pic16_emitcode("xorlw","1");
218 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
219 //pic16_emitcode("andlw","1");
222 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
223 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
224 AOP(IC_RESULT(ic))->aopu.aop_dir,
225 AOP(IC_RESULT(ic))->aopu.aop_dir);
232 /* if the sizes are greater than 1 then we cannot */
233 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
234 AOP_SIZE(IC_LEFT(ic)) > 1 )
237 /* If we are incrementing the same register by two: */
239 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
242 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
243 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
248 DEBUGpic16_emitcode ("; ","couldn't increment ");
253 /*-----------------------------------------------------------------*/
254 /* pic16_outBitAcc - output a bit in acc */
255 /*-----------------------------------------------------------------*/
256 void pic16_outBitAcc(operand *result)
258 symbol *tlbl = newiTempLabel(NULL);
259 /* if the result is a bit */
260 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
262 if (AOP_TYPE(result) == AOP_CRY){
263 pic16_aopPut(AOP(result),"a",0);
266 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
267 pic16_emitcode("mov","a,#01");
268 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
269 pic16_outAcc(result);
273 /*-----------------------------------------------------------------*/
274 /* pic16_genPlusBits - generates code for addition of two bits */
275 /*-----------------------------------------------------------------*/
276 void pic16_genPlusBits (iCode *ic)
279 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
281 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
282 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
283 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
284 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
286 The following block of code will add two bits.
287 Note that it'll even work if the destination is
288 the carry (C in the status register).
289 It won't work if the 'Z' bit is a source or destination.
292 /* If the result is stored in the accumulator (w) */
293 //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
294 switch(AOP_TYPE(IC_RESULT(ic))) {
296 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
297 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
298 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
299 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
300 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
302 pic16_emitcode("clrw","");
303 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
304 AOP(IC_RIGHT(ic))->aopu.aop_dir,
305 AOP(IC_RIGHT(ic))->aopu.aop_dir);
306 pic16_emitcode("xorlw","1");
307 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
308 AOP(IC_LEFT(ic))->aopu.aop_dir,
309 AOP(IC_LEFT(ic))->aopu.aop_dir);
310 pic16_emitcode("xorlw","1");
313 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
314 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
315 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
316 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
317 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
318 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
321 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
322 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
323 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
324 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
325 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
326 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
328 pic16_emitcode("movlw","(1 << (%s & 7))",
329 AOP(IC_RESULT(ic))->aopu.aop_dir,
330 AOP(IC_RESULT(ic))->aopu.aop_dir);
331 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
332 AOP(IC_RESULT(ic))->aopu.aop_dir,
333 AOP(IC_RESULT(ic))->aopu.aop_dir);
334 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
335 AOP(IC_RIGHT(ic))->aopu.aop_dir,
336 AOP(IC_RIGHT(ic))->aopu.aop_dir);
337 pic16_emitcode("xorwf","(%s >>3),f",
338 AOP(IC_RESULT(ic))->aopu.aop_dir);
339 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
340 AOP(IC_LEFT(ic))->aopu.aop_dir,
341 AOP(IC_LEFT(ic))->aopu.aop_dir);
342 pic16_emitcode("xorwf","(%s>>3),f",
343 AOP(IC_RESULT(ic))->aopu.aop_dir);
350 /* This is the original version of this code.
352 * This is being kept around for reference,
353 * because I am not entirely sure I got it right...
355 static void adjustArithmeticResult(iCode *ic)
357 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
358 AOP_SIZE(IC_LEFT(ic)) == 3 &&
359 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
360 pic16_aopPut(AOP(IC_RESULT(ic)),
361 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
364 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
365 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
366 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
367 pic16_aopPut(AOP(IC_RESULT(ic)),
368 pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
371 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
372 AOP_SIZE(IC_LEFT(ic)) < 3 &&
373 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
374 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
375 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
377 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
378 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
382 /* This is the pure and virtuous version of this code.
383 * I'm pretty certain it's right, but not enough to toss the old
386 static void adjustArithmeticResult(iCode *ic)
388 if (opIsGptr(IC_RESULT(ic)) &&
389 opIsGptr(IC_LEFT(ic)) &&
390 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
392 pic16_aopPut(AOP(IC_RESULT(ic)),
393 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
397 if (opIsGptr(IC_RESULT(ic)) &&
398 opIsGptr(IC_RIGHT(ic)) &&
399 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
401 pic16_aopPut(AOP(IC_RESULT(ic)),
402 pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
406 if (opIsGptr(IC_RESULT(ic)) &&
407 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
408 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
409 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
410 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
412 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
413 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
418 /*-----------------------------------------------------------------*/
419 /* genAddlit - generates code for addition */
420 /*-----------------------------------------------------------------*/
421 static void genAddLit2byte (operand *result, int offr, int lit)
428 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
431 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
434 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
435 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
440 static void emitMOVWF(operand *reg, int offset)
445 if (AOP_TYPE(reg) == AOP_ACC) {
446 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
450 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
454 static void genAddLit (iCode *ic, int lit)
463 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
467 result = IC_RESULT(ic);
468 same = pic16_sameRegs(AOP(left), AOP(result));
469 size = pic16_getDataSize(result);
473 /* Handle special cases first */
475 genAddLit2byte (result, 0, lit);
478 int hi = 0xff & (lit >> 8);
485 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
490 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
492 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
495 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
496 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
497 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
501 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
502 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
504 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
512 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
515 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
518 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
519 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
521 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
523 case 0xff: /* 0x01ff */
524 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
525 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
526 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
527 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
532 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
536 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
539 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
540 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
542 /* case 0xff: * 0xffff *
543 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
544 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
545 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
549 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
550 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
552 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
559 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
564 genAddLit2byte (result, MSB16, hi);
567 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1)&0xff));
568 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
569 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
570 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
572 /* case 0xff: * 0xHHff *
573 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
574 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
575 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
576 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
578 */ default: /* 0xHHLL */
579 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
580 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
581 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
583 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1) & 0xff));
584 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
593 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
596 lo = BYTEofLONG(lit,0);
604 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
607 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
608 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(1));
609 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
611 default: /* carry_info = 3 */
613 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
619 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
624 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
627 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
632 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo+1));
633 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
638 /* no carry info from previous step */
639 /* this means this is the first time to add */
644 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
648 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
649 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
651 carry_info = 3; /* Were adding only one byte and propogating the carry */
662 lo = BYTEofLONG(lit,0);
667 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
670 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
671 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
674 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
676 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
678 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
688 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
692 if(AOP_TYPE(left) == AOP_ACC) {
693 /* left addend is already in accumulator */
696 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
700 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
701 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
705 /* left addend is in a register */
708 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
709 emitMOVWF(result, 0);
710 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
714 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
715 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
719 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
720 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
724 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
725 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
726 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
734 /* left is not the accumulator */
736 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
737 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
739 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
740 /* We don't know the state of the carry bit at this point */
743 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
750 /* The ls byte of the lit must've been zero - that
751 means we don't have to deal with carry */
753 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
754 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
755 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),offset));
760 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
761 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset,FALSE,FALSE));
762 emitMOVWF(result,offset);
763 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
765 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
766 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
770 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
771 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset));
772 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
773 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
781 /*-----------------------------------------------------------------*/
782 /* pic16_genPlus - generates code for addition */
783 /*-----------------------------------------------------------------*/
784 void pic16_genPlus (iCode *ic)
786 int size, offset = 0;
787 operand *result, *left, *right;
789 /* special cases :- */
790 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
794 result = IC_RESULT(ic);
796 right = IC_RIGHT(ic);
797 pic16_aopOp (left,ic,FALSE);
798 pic16_aopOp (right,ic,FALSE);
799 pic16_aopOp (result,ic,TRUE);
800 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
803 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
804 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
805 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
806 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
810 /* if literal, literal on the right or
811 if left requires ACC or right is already
814 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
815 operand *t = IC_RIGHT(ic);
816 IC_RIGHT(ic) = IC_LEFT(ic);
820 /* if both left & right are in bit space */
821 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
822 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
823 pic16_genPlusBits (ic);
827 /* if left in bit space & right literal */
828 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
829 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
830 /* if result in bit space */
831 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
832 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
833 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
834 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
835 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
836 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
839 size = pic16_getDataSize(IC_RESULT(ic));
841 MOVA(pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
842 pic16_emitcode("addc","a,#00 ;%d",__LINE__);
843 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
849 /* if I can do an increment instead
850 of add then GOOD for ME */
851 if (pic16_genPlusIncr (ic) == TRUE)
854 size = pic16_getDataSize(IC_RESULT(ic));
856 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
857 /* Add a literal to something else */
859 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
863 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
868 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
870 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
871 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
872 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
874 /* here we are adding a bit to a char or int */
876 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
878 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
879 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
881 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
882 AOP(IC_RIGHT(ic))->aopu.aop_dir,
883 AOP(IC_RIGHT(ic))->aopu.aop_dir);
884 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
887 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
888 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
889 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
891 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
892 AOP(IC_RIGHT(ic))->aopu.aop_dir,
893 AOP(IC_RIGHT(ic))->aopu.aop_dir);
894 pic16_emitcode(" xorlw","1");
896 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
897 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
898 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
900 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
901 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
902 AOP(IC_RIGHT(ic))->aopu.aop_dir,
903 AOP(IC_RIGHT(ic))->aopu.aop_dir);
904 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
907 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
909 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
910 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
911 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
913 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
915 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
916 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
923 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
924 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
926 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
927 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
929 pic16_emitcode("clrz","");
931 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
932 AOP(IC_RIGHT(ic))->aopu.aop_dir,
933 AOP(IC_RIGHT(ic))->aopu.aop_dir);
934 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
938 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
939 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
940 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
941 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
942 emitMOVWF(IC_RIGHT(ic),0);
944 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
945 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
946 AOP(IC_RIGHT(ic))->aopu.aop_dir,
947 AOP(IC_RIGHT(ic))->aopu.aop_dir);
948 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
949 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
955 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
956 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
962 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
964 /* Add the first bytes */
966 if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
967 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
968 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
971 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
972 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
973 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
974 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
977 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
979 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
980 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
982 PIC_OPCODE poc = POC_ADDFW;
984 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
985 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
986 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
988 pic16_emitpcode(poc, pic16_popGet(AOP(IC_LEFT(ic)),0));
989 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
990 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
995 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1000 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1001 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1002 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1004 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1005 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1008 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1010 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1011 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1014 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1016 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1017 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1025 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1026 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1027 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1030 /* Need to extend result to higher bytes */
1031 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1033 /* First grab the carry from the lower bytes */
1034 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1035 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1039 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1042 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1043 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1044 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1045 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1047 /* if chars or ints or being signed extended to longs: */
1049 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1050 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1051 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1059 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1061 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1068 //adjustArithmeticResult(ic);
1071 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1072 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1073 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1076 /*-----------------------------------------------------------------*/
1077 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1078 /*-----------------------------------------------------------------*/
1079 bool pic16_genMinusDec (iCode *ic)
1081 unsigned int icount ;
1082 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1084 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1085 /* will try to generate an increment */
1086 /* if the right side is not a literal
1088 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1089 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1090 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1093 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1095 /* if the literal value of the right hand side
1096 is greater than 4 then it is not worth it */
1097 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1100 /* if decrement 16 bits in register */
1101 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1106 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1107 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1108 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1109 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1111 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1112 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1113 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1115 /* size is 3 or 4 */
1116 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1117 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1119 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1121 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1123 pic16_emitcode("movlw","0xff");
1124 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1127 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1129 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1133 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1135 pic16_emitcode("skpnc","");
1137 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1146 /* if the sizes are greater than 1 then we cannot */
1147 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1148 AOP_SIZE(IC_LEFT(ic)) > 1 )
1151 /* we can if the aops of the left & result match or
1152 if they are in registers and the registers are the
1154 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1157 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1159 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1164 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1165 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1166 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1169 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1170 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1172 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1173 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1181 /*-----------------------------------------------------------------*/
1182 /* pic16_addSign - propogate sign bit to higher bytes */
1183 /*-----------------------------------------------------------------*/
1184 void pic16_addSign(operand *result, int offset, int sign)
1186 int size = (pic16_getDataSize(result) - offset);
1187 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1190 if(sign && offset) {
1193 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1194 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1195 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1198 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1199 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1200 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1202 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),size));
1207 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1211 /*-----------------------------------------------------------------*/
1212 /* pic16_genMinusBits - generates code for subtraction of two bits */
1213 /*-----------------------------------------------------------------*/
1214 void pic16_genMinusBits (iCode *ic)
1216 symbol *lbl = newiTempLabel(NULL);
1217 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1218 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1219 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1220 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1221 pic16_emitcode("cpl","c");
1222 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1223 pic16_outBitC(IC_RESULT(ic));
1226 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1227 pic16_emitcode("subb","a,acc");
1228 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1229 pic16_emitcode("inc","a");
1230 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1231 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1232 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1236 /*-----------------------------------------------------------------*/
1237 /* pic16_genMinus - generates code for subtraction */
1238 /*-----------------------------------------------------------------*/
1239 void pic16_genMinus (iCode *ic)
1241 int size, offset = 0, same=0;
1242 unsigned long lit = 0L;
1244 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1245 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1246 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1247 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1249 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1250 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1251 operand *t = IC_RIGHT(ic);
1252 IC_RIGHT(ic) = IC_LEFT(ic);
1256 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1257 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1258 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1259 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1261 /* special cases :- */
1262 /* if both left & right are in bit space */
1263 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1264 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1265 pic16_genPlusBits (ic);
1269 /* if I can do an decrement instead
1270 of subtract then GOOD for ME */
1271 // if (pic16_genMinusDec (ic) == TRUE)
1274 size = pic16_getDataSize(IC_RESULT(ic));
1275 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1277 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1278 /* Add a literal to something else */
1280 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1283 genAddLit ( ic, lit);
1286 /* add the first byte: */
1287 pic16_emitcode("movlw","0x%x", lit & 0xff);
1288 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1289 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1290 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1302 if((lit & 0xff) == 0xff) {
1303 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1305 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1307 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1309 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1310 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1314 /* do the rlf known zero trick here */
1315 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1317 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1322 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1325 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1326 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1327 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1329 /* here we are subtracting a bit from a char or int */
1331 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1333 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1334 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1336 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1337 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1338 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1339 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1342 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1343 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1344 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1345 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1346 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1348 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1350 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1351 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1353 pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1354 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1357 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1359 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1361 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1362 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1366 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1367 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1368 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1369 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1374 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1375 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1376 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1379 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1381 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1384 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1386 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1388 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1395 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1396 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1397 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1399 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1400 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1401 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1402 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1403 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1406 if( (size == 1) && ((lit & 0xff) == 0) ) {
1407 /* res = 0 - right */
1408 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1409 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1410 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1412 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1413 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1414 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1419 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1420 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1421 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1429 /* This is the last byte in a multibyte subtraction
1430 * There are a couple of tricks we can do by not worrying about
1431 * propogating the carry */
1433 /* 0xff - x == ~x */
1435 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1437 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1439 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1440 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1442 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1445 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1447 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1448 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1449 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1458 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1460 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
1461 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1464 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1470 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1471 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1473 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1475 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1477 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1478 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1485 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1486 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1487 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1488 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1490 if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1491 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1492 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1493 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1494 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1497 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1498 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1499 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1500 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1501 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1504 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1505 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1506 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1508 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1509 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1511 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1512 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1513 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1515 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1517 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1518 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1519 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1521 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1523 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1530 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1532 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1533 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1535 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1536 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1543 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1544 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1545 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1547 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1549 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1550 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1558 // adjustArithmeticResult(ic);
1561 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1562 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1563 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1565 /*-----------------------------------------------------------------*
1566 * pic_genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1569 *-----------------------------------------------------------------*/
1570 void pic16_genUMult8XLit_16 (operand *left,
1573 pCodeOpReg *result_hi)
1578 unsigned int i,have_first_bit;
1582 if (AOP_TYPE(right) != AOP_LIT){
1583 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1589 result_hi = PCOR(pic16_popGet(AOP(result),1));
1592 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1594 pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1596 same = pic16_sameRegs(AOP(left), AOP(result));
1601 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(left),0));
1604 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1605 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1608 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1609 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1610 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1613 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1614 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1615 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1616 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1619 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1620 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1621 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1622 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1625 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1626 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1627 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1628 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1629 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1632 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1633 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1634 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1635 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1636 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 7*F
1639 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1640 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1641 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1642 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1643 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
1646 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1647 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1648 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1649 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1650 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1651 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1654 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1655 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1656 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1657 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1658 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1659 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1662 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1663 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1664 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1665 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1666 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
1667 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 11*F
1670 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1671 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1672 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1673 pic16_emitpcode(POC_MOVFW, 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));
1679 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1680 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1681 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1682 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1683 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
1684 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 13*F
1687 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1688 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1689 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1690 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1691 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
1692 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 11*F
1693 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 14*F
1696 temp = pic16_popGetTempReg();
1698 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1701 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1702 pic16_emitpcode(POC_MOVWF, temp);
1703 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1704 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1705 pic16_emitpcode(POC_SWAPFW, temp);
1706 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(left),0));
1707 pic16_popReleaseTempReg(temp);
1710 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1711 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1712 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1715 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1716 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1717 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1720 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
1721 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
1722 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xe0));
1723 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1726 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
1727 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1728 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
1729 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xc0));
1730 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1733 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
1734 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(left),0));
1735 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),0));
1743 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1744 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1747 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1748 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1749 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
1750 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1751 pic16_emitpcode(POC_RLCF, pic16_popCopyReg(result_hi));
1757 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1758 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1759 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1762 for(i=0; i<8; i++) {
1765 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1769 if(have_first_bit) {
1770 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1771 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1779 /*-----------------------------------------------------------------*
1780 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1783 *-----------------------------------------------------------------*/
1784 void pic16_genUMult8X8_16 (operand *left,
1787 pCodeOpReg *result_hi)
1795 result_hi = PCOR(pic16_popGet(AOP(result),1));
1798 if (AOP_TYPE(right) == AOP_LIT) {
1799 pic16_genUMult8XLit_16(left,right,result,result_hi);
1804 pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1806 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1807 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1808 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1811 for(i=0; i<8; i++) {
1812 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),i,0));
1813 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1814 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1815 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1820 Here's another version that does the same thing and takes the
1821 same number of instructions. The one above is slightly better
1822 because the entry instructions have a higher probability of
1823 being optimized out.
1826 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1827 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
1828 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1829 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1831 for(i=0; i<8; i++) {
1833 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1834 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1835 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1840 symbol *tlbl = newiTempLabel(NULL);
1844 pic16_emitcode(";","Looped 8 X 8 multiplication");
1846 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1847 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1849 pic16_emitpcode(POC_BSF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),0,FALSE,FALSE),7,0));
1851 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1853 temp = pic16_popGetTempReg();
1854 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(PCOR(temp)));
1856 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1858 pic16_emitpLabel(tlbl->key);
1860 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(PCOR(temp)));
1862 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1864 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1865 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1868 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl->key));
1870 pic16_popReleaseTempReg(temp);
1875 /*-----------------------------------------------------------------*
1876 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1878 * this routine will call the unsigned multiply routine and then
1879 * post-fix the sign bit.
1880 *-----------------------------------------------------------------*/
1881 void pic16_genSMult8X8_16 (operand *left,
1884 pCodeOpReg *result_hi)
1888 result_hi = PCOR(pic16_popGet(AOP(result),1));
1891 pic16_genUMult8X8_16(left,right,result,result_hi);
1893 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0));
1894 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
1895 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1896 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0));
1897 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
1901 /*-----------------------------------------------------------------*
1902 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers
1904 * this routine will call the unsigned multiply 8X8=>16 routine and
1905 * then throw away the high byte of the result.
1907 *-----------------------------------------------------------------*/
1908 void pic16_genMult8X8_8 (operand *left,
1912 pCodeOp *result_hi = pic16_popGetTempReg();
1914 if (AOP_TYPE(right) == AOP_LIT)
1915 pic16_genUMult8XLit_16(left,right,result,PCOR(result_hi));
1917 pic16_genUMult8X8_16(left,right,result,PCOR(result_hi));
1919 pic16_popReleaseTempReg(result_hi);
1922 /*-----------------------------------------------------------------*/
1923 /* constMult - generates code for multiplication by a constant */
1924 /*-----------------------------------------------------------------*/
1925 void genMultConst(unsigned C)
1929 unsigned sr3; // Shift right 3
1935 Convert a string of 3 binary 1's in the lit into
1939 mask = 7 << ( (size*8) - 3);
1943 while(mask < (1<<size*8)) {
1945 if( (mask & lit) == lit) {
1948 /* We found 3 (or more) consecutive 1's */
1950 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1952 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1954 lit ^= consecutive_bits;
1958 sr3 |= (consecutive + lsb);