1 /*-------------------------------------------------------------------------
2 genarith.c - source file for code generation - arithmetic
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
8 PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
10 This program is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 In other words, you are welcome to use, share and improve this program.
25 You are forbidden to forbid anyone else to use, share and improve
26 what you give them. Help stamp out software-hoarding!
29 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
30 Made everything static
31 -------------------------------------------------------------------------*/
37 #include "SDCCglobl.h"
40 #if defined(_MSC_VER) && (_MSC_VER < 1300)
41 #define __FUNCTION__ __FILE__
45 #include "SDCCpeeph.h"
51 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
52 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
54 const char *pic16_AopType(short type)
101 const char *pic16_pCodeOpType( pCodeOp *pcop)
124 case PO_GPR_REGISTER:
125 return "PO_GPR_REGISTER";
129 return "PO_GPR_TEMP";
130 case PO_SFR_REGISTER:
131 return "PO_SFR_REGISTER";
139 return "PO_REL_ADDR";
141 return "PO_IMMEDIATE";
157 return "BAD PO_TYPE";
160 /*-----------------------------------------------------------------*/
161 /* pic16_genPlusIncr :- does addition with increment if possible */
162 /*-----------------------------------------------------------------*/
163 bool pic16_genPlusIncr (iCode *ic)
165 unsigned int icount ;
166 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
168 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
169 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
170 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
171 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
172 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
174 /* will try to generate an increment */
175 /* if the right side is not a literal
177 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
180 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
181 /* if the literal value of the right hand side
182 is greater than 1 then it is faster to add */
183 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 1) // this was > 2 why? VR
186 /* if increment 16 bits in register */
187 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
192 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
193 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
197 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
198 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
204 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
205 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
206 if( strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
207 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
209 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
210 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
211 AOP(IC_RESULT(ic))->aopu.aop_dir,
212 AOP(IC_RESULT(ic))->aopu.aop_dir);
214 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
215 //pic16_emitcode("xorlw","1");
217 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
218 //pic16_emitcode("andlw","1");
221 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
222 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
223 AOP(IC_RESULT(ic))->aopu.aop_dir,
224 AOP(IC_RESULT(ic))->aopu.aop_dir);
231 /* if the sizes are greater than 1 then we cannot */
232 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
233 AOP_SIZE(IC_LEFT(ic)) > 1 )
236 /* If we are incrementing the same register by two: */
238 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
241 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
242 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
247 DEBUGpic16_emitcode ("; ","couldn't increment ");
252 /*-----------------------------------------------------------------*/
253 /* pic16_outBitAcc - output a bit in acc */
254 /*-----------------------------------------------------------------*/
255 void pic16_outBitAcc(operand *result)
257 symbol *tlbl = newiTempLabel(NULL);
258 /* if the result is a bit */
259 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
261 if (AOP_TYPE(result) == AOP_CRY){
262 pic16_aopPut(AOP(result),"a",0);
265 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
266 pic16_emitcode("mov","a,#01");
267 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
268 pic16_outAcc(result);
272 /*-----------------------------------------------------------------*/
273 /* pic16_genPlusBits - generates code for addition of two bits */
274 /*-----------------------------------------------------------------*/
275 void pic16_genPlusBits (iCode *ic)
278 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
280 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
281 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
282 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
283 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
285 The following block of code will add two bits.
286 Note that it'll even work if the destination is
287 the carry (C in the status register).
288 It won't work if the 'Z' bit is a source or destination.
291 /* If the result is stored in the accumulator (w) */
292 //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
293 switch(AOP_TYPE(IC_RESULT(ic))) {
295 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
296 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
297 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
298 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
299 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
301 pic16_emitcode("clrw","");
302 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
303 AOP(IC_RIGHT(ic))->aopu.aop_dir,
304 AOP(IC_RIGHT(ic))->aopu.aop_dir);
305 pic16_emitcode("xorlw","1");
306 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
307 AOP(IC_LEFT(ic))->aopu.aop_dir,
308 AOP(IC_LEFT(ic))->aopu.aop_dir);
309 pic16_emitcode("xorlw","1");
312 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
313 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
314 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
315 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
316 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
317 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
320 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
321 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
322 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
323 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
324 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
325 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
327 pic16_emitcode("movlw","(1 << (%s & 7))",
328 AOP(IC_RESULT(ic))->aopu.aop_dir,
329 AOP(IC_RESULT(ic))->aopu.aop_dir);
330 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
331 AOP(IC_RESULT(ic))->aopu.aop_dir,
332 AOP(IC_RESULT(ic))->aopu.aop_dir);
333 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
334 AOP(IC_RIGHT(ic))->aopu.aop_dir,
335 AOP(IC_RIGHT(ic))->aopu.aop_dir);
336 pic16_emitcode("xorwf","(%s >>3),f",
337 AOP(IC_RESULT(ic))->aopu.aop_dir);
338 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
339 AOP(IC_LEFT(ic))->aopu.aop_dir,
340 AOP(IC_LEFT(ic))->aopu.aop_dir);
341 pic16_emitcode("xorwf","(%s>>3),f",
342 AOP(IC_RESULT(ic))->aopu.aop_dir);
349 /* This is the original version of this code.
351 * This is being kept around for reference,
352 * because I am not entirely sure I got it right...
354 static void adjustArithmeticResult(iCode *ic)
356 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
357 AOP_SIZE(IC_LEFT(ic)) == 3 &&
358 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
359 pic16_aopPut(AOP(IC_RESULT(ic)),
360 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
363 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
364 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
365 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
366 pic16_aopPut(AOP(IC_RESULT(ic)),
367 pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
370 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
371 AOP_SIZE(IC_LEFT(ic)) < 3 &&
372 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
373 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
374 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
376 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
377 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
381 /* This is the pure and virtuous version of this code.
382 * I'm pretty certain it's right, but not enough to toss the old
385 static void adjustArithmeticResult(iCode *ic)
387 if (opIsGptr(IC_RESULT(ic)) &&
388 opIsGptr(IC_LEFT(ic)) &&
389 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
391 pic16_aopPut(AOP(IC_RESULT(ic)),
392 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
396 if (opIsGptr(IC_RESULT(ic)) &&
397 opIsGptr(IC_RIGHT(ic)) &&
398 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
400 pic16_aopPut(AOP(IC_RESULT(ic)),
401 pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
405 if (opIsGptr(IC_RESULT(ic)) &&
406 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
407 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
408 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
409 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
411 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
412 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
417 /*-----------------------------------------------------------------*/
418 /* genAddlit - generates code for addition */
419 /*-----------------------------------------------------------------*/
420 static void genAddLit2byte (operand *result, int offr, int lit)
427 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
430 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
433 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
434 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
439 static void emitMOVWF(operand *reg, int offset)
444 if (AOP_TYPE(reg) == AOP_ACC) {
445 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
449 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
453 static void genAddLit (iCode *ic, int lit)
462 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
466 result = IC_RESULT(ic);
467 same = pic16_sameRegs(AOP(left), AOP(result));
468 size = pic16_getDataSize(result);
472 /* Handle special cases first */
474 genAddLit2byte (result, 0, lit);
477 int hi = 0xff & (lit >> 8);
484 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
489 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
491 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
494 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
495 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
496 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
500 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
501 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
503 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
511 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
514 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
517 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
518 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
520 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
522 case 0xff: /* 0x01ff */
523 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
524 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
525 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
526 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
531 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
535 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
538 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
539 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
541 /* case 0xff: * 0xffff *
542 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
543 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
544 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
548 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
549 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
551 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
558 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
563 genAddLit2byte (result, MSB16, hi);
566 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1)&0xff));
567 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
568 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
569 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
571 /* case 0xff: * 0xHHff *
572 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
573 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
574 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
575 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
577 */ default: /* 0xHHLL */
578 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
579 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
580 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
582 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1) & 0xff));
583 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
592 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
595 lo = BYTEofLONG(lit,0);
603 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
606 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
607 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(1));
608 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
610 default: /* carry_info = 3 */
612 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
618 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
623 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
626 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
631 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo+1));
632 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
637 /* no carry info from previous step */
638 /* this means this is the first time to add */
643 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
647 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
648 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
650 carry_info = 3; /* Were adding only one byte and propogating the carry */
661 lo = BYTEofLONG(lit,0);
666 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
669 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
670 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
673 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
675 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
677 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
687 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
691 if(AOP_TYPE(left) == AOP_ACC) {
692 /* left addend is already in accumulator */
695 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
699 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
700 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
704 /* left addend is in a register */
707 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
708 emitMOVWF(result, 0);
709 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
713 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
714 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
718 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
719 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
723 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
724 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
725 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
733 /* left is not the accumulator */
735 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
736 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
738 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
739 /* We don't know the state of the carry bit at this point */
742 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
749 /* The ls byte of the lit must've been zero - that
750 means we don't have to deal with carry */
752 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
753 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
754 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),offset));
759 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
760 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset,FALSE,FALSE));
761 emitMOVWF(result,offset);
762 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
764 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
765 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
769 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
770 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset));
771 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
772 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
780 /*-----------------------------------------------------------------*/
781 /* pic16_genPlus - generates code for addition */
782 /*-----------------------------------------------------------------*/
783 void pic16_genPlus (iCode *ic)
785 int size, offset = 0;
786 operand *result, *left, *right;
788 /* special cases :- */
789 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
793 result = IC_RESULT(ic);
795 right = IC_RIGHT(ic);
796 pic16_aopOp (left,ic,FALSE);
797 pic16_aopOp (right,ic,FALSE);
798 pic16_aopOp (result,ic,TRUE);
799 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
802 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
803 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
804 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
805 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
809 /* if literal, literal on the right or
810 if left requires ACC or right is already
813 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
814 operand *t = IC_RIGHT(ic);
815 IC_RIGHT(ic) = IC_LEFT(ic);
819 /* if both left & right are in bit space */
820 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
821 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
822 pic16_genPlusBits (ic);
826 /* if left in bit space & right literal */
827 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
828 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
829 /* if result in bit space */
830 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
831 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
832 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
833 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
834 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
835 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
838 size = pic16_getDataSize(IC_RESULT(ic));
840 MOVA(pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
841 pic16_emitcode("addc","a,#00 ;%d",__LINE__);
842 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
848 /* if I can do an increment instead
849 of add then GOOD for ME */
850 if (pic16_genPlusIncr (ic) == TRUE)
853 size = pic16_getDataSize(IC_RESULT(ic));
855 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
856 /* Add a literal to something else */
858 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
862 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
867 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
869 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
870 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
871 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
873 /* here we are adding a bit to a char or int */
875 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
877 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
878 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
880 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
881 AOP(IC_RIGHT(ic))->aopu.aop_dir,
882 AOP(IC_RIGHT(ic))->aopu.aop_dir);
883 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
886 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
887 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
888 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
890 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
891 AOP(IC_RIGHT(ic))->aopu.aop_dir,
892 AOP(IC_RIGHT(ic))->aopu.aop_dir);
893 pic16_emitcode(" xorlw","1");
895 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
896 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
897 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
899 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
900 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
901 AOP(IC_RIGHT(ic))->aopu.aop_dir,
902 AOP(IC_RIGHT(ic))->aopu.aop_dir);
903 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
906 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
908 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
909 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
910 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
912 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
914 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
915 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
922 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
923 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
925 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
926 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
928 pic16_emitcode("clrz","");
930 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
931 AOP(IC_RIGHT(ic))->aopu.aop_dir,
932 AOP(IC_RIGHT(ic))->aopu.aop_dir);
933 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
937 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
938 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
939 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
940 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
941 emitMOVWF(IC_RIGHT(ic),0);
943 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
944 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
945 AOP(IC_RIGHT(ic))->aopu.aop_dir,
946 AOP(IC_RIGHT(ic))->aopu.aop_dir);
947 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
948 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
954 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
955 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
961 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
963 /* Add the first bytes */
965 if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
966 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
967 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
970 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
971 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
972 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
973 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
976 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
978 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
979 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
981 PIC_OPCODE poc = POC_ADDFW;
983 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
984 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
985 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
987 pic16_emitpcode(poc, pic16_popGet(AOP(IC_LEFT(ic)),0));
988 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
989 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
994 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
999 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1000 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1001 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1003 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1004 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1007 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1009 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1010 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1013 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1015 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1016 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1024 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1025 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1026 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1029 /* Need to extend result to higher bytes */
1030 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1032 /* First grab the carry from the lower bytes */
1033 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1034 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1038 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1041 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1042 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1043 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1044 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1046 /* if chars or ints or being signed extended to longs: */
1048 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1049 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1050 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1058 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1060 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1067 //adjustArithmeticResult(ic);
1070 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1071 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1072 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1075 /*-----------------------------------------------------------------*/
1076 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1077 /*-----------------------------------------------------------------*/
1078 bool pic16_genMinusDec (iCode *ic)
1080 unsigned int icount ;
1081 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1083 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1084 /* will try to generate an increment */
1085 /* if the right side is not a literal
1087 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1088 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1089 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1092 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1094 /* if the literal value of the right hand side
1095 is greater than 4 then it is not worth it */
1096 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1099 /* if decrement 16 bits in register */
1100 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1105 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1106 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1107 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1108 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1110 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1111 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1112 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1114 /* size is 3 or 4 */
1115 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1116 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1118 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1120 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1122 pic16_emitcode("movlw","0xff");
1123 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1126 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1128 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1132 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1134 pic16_emitcode("skpnc","");
1136 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1145 /* if the sizes are greater than 1 then we cannot */
1146 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1147 AOP_SIZE(IC_LEFT(ic)) > 1 )
1150 /* we can if the aops of the left & result match or
1151 if they are in registers and the registers are the
1153 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1156 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1158 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1163 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1164 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1165 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1168 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1169 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1171 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1172 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1180 /*-----------------------------------------------------------------*/
1181 /* pic16_addSign - propogate sign bit to higher bytes */
1182 /*-----------------------------------------------------------------*/
1183 void pic16_addSign(operand *result, int offset, int sign)
1185 int size = (pic16_getDataSize(result) - offset);
1186 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1189 if(sign && offset) {
1192 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1193 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1194 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1197 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1198 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1199 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1201 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),size));
1206 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1210 /*-----------------------------------------------------------------*/
1211 /* pic16_genMinusBits - generates code for subtraction of two bits */
1212 /*-----------------------------------------------------------------*/
1213 void pic16_genMinusBits (iCode *ic)
1215 symbol *lbl = newiTempLabel(NULL);
1216 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1217 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1218 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1219 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1220 pic16_emitcode("cpl","c");
1221 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1222 pic16_outBitC(IC_RESULT(ic));
1225 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1226 pic16_emitcode("subb","a,acc");
1227 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1228 pic16_emitcode("inc","a");
1229 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1230 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1231 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1235 /*-----------------------------------------------------------------*/
1236 /* pic16_genMinus - generates code for subtraction */
1237 /*-----------------------------------------------------------------*/
1238 void pic16_genMinus (iCode *ic)
1240 int size, offset = 0, same=0;
1241 unsigned long lit = 0L;
1243 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1244 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1245 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1246 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1248 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1249 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1250 operand *t = IC_RIGHT(ic);
1251 IC_RIGHT(ic) = IC_LEFT(ic);
1255 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1256 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1257 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1258 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1260 /* special cases :- */
1261 /* if both left & right are in bit space */
1262 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1263 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1264 pic16_genPlusBits (ic);
1268 /* if I can do an decrement instead
1269 of subtract then GOOD for ME */
1270 // if (pic16_genMinusDec (ic) == TRUE)
1273 size = pic16_getDataSize(IC_RESULT(ic));
1274 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1276 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1277 /* Add a literal to something else */
1279 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1282 genAddLit ( ic, lit);
1285 /* add the first byte: */
1286 pic16_emitcode("movlw","0x%x", lit & 0xff);
1287 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1288 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1289 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1301 if((lit & 0xff) == 0xff) {
1302 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1304 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1306 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1308 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1309 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1313 /* do the rlf known zero trick here */
1314 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1316 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1321 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1324 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1325 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1326 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1328 /* here we are subtracting a bit from a char or int */
1330 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1332 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1333 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1335 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1336 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1337 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1338 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1341 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1342 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1343 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1344 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1345 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1347 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1349 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1350 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1352 pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1353 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1356 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1358 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1360 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1361 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1365 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1366 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1367 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1368 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1373 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1374 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1375 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1378 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1380 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1383 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1385 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1387 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1394 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1395 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1396 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1398 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1399 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1400 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1401 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1402 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1405 if( (size == 1) && ((lit & 0xff) == 0) ) {
1406 /* res = 0 - right */
1407 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1408 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1409 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1411 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1412 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1413 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1418 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1419 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1420 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1428 /* This is the last byte in a multibyte subtraction
1429 * There are a couple of tricks we can do by not worrying about
1430 * propogating the carry */
1432 /* 0xff - x == ~x */
1434 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1436 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1438 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1439 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1441 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1444 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1446 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1447 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1448 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1457 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1459 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
1460 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1463 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1469 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1470 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1472 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1474 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1476 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1477 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1484 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1485 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1486 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1487 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1489 if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1490 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1491 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1492 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1493 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1496 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1497 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1498 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1499 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1500 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1503 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1504 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1505 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1507 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1508 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1510 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1511 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1512 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1514 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1516 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1517 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1518 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1520 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1522 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1529 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1531 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1532 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1534 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1535 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1542 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1543 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1544 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1546 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1548 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1549 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1557 // adjustArithmeticResult(ic);
1560 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1561 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1562 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1564 /*-----------------------------------------------------------------*
1565 * pic_genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1568 *-----------------------------------------------------------------*/
1569 void pic16_genUMult8XLit_16 (operand *left,
1572 pCodeOpReg *result_hi)
1577 unsigned int i,have_first_bit;
1581 if (AOP_TYPE(right) != AOP_LIT){
1582 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1588 result_hi = PCOR(pic16_popGet(AOP(result),1));
1591 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1593 pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1595 same = pic16_sameRegs(AOP(left), AOP(result));
1600 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(left),0));
1603 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1604 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1607 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1608 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1609 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1612 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1613 pic16_emitpcode(POC_ADDWF, 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));
1618 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1619 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1620 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1621 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1624 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1625 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1626 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1627 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1628 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1631 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1632 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1633 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1634 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1635 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 7*F
1638 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1639 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1640 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1641 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1642 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
1645 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1646 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1647 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
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));
1653 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1654 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1655 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1656 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1657 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1658 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1661 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1662 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1663 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1664 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1665 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
1666 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 11*F
1669 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1670 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1671 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1672 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1673 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1674 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1675 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1678 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1679 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1680 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1681 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1682 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
1683 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 13*F
1686 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1687 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1688 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1689 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1690 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
1691 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 11*F
1692 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 14*F
1695 temp = pic16_popGetTempReg();
1697 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1700 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1701 pic16_emitpcode(POC_MOVWF, temp);
1702 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1703 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1704 pic16_emitpcode(POC_SWAPFW, temp);
1705 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(left),0));
1706 pic16_popReleaseTempReg(temp);
1709 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1710 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1711 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1714 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1715 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1716 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1719 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
1720 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
1721 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xe0));
1722 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1725 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
1726 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1727 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
1728 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xc0));
1729 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1732 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
1733 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(left),0));
1734 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),0));
1742 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1743 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1746 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1747 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1748 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
1749 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1750 pic16_emitpcode(POC_RLCF, pic16_popCopyReg(result_hi));
1756 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1757 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1758 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1761 for(i=0; i<8; i++) {
1764 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1768 if(have_first_bit) {
1769 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1770 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1778 /*-----------------------------------------------------------------*
1779 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1782 *-----------------------------------------------------------------*/
1783 void pic16_genUMult8X8_16 (operand *left,
1786 pCodeOpReg *result_hi)
1794 result_hi = PCOR(pic16_popGet(AOP(result),1));
1797 if (AOP_TYPE(right) == AOP_LIT) {
1798 pic16_genUMult8XLit_16(left,right,result,result_hi);
1803 pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1805 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1806 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1807 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1810 for(i=0; i<8; i++) {
1811 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),i,0));
1812 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1813 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1814 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1819 Here's another version that does the same thing and takes the
1820 same number of instructions. The one above is slightly better
1821 because the entry instructions have a higher probability of
1822 being optimized out.
1825 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1826 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
1827 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1828 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1830 for(i=0; i<8; i++) {
1832 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1833 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1834 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1839 symbol *tlbl = newiTempLabel(NULL);
1843 pic16_emitcode(";","Looped 8 X 8 multiplication");
1845 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1846 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1848 pic16_emitpcode(POC_BSF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),0,FALSE,FALSE),7,0));
1850 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1852 temp = pic16_popGetTempReg();
1853 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(PCOR(temp)));
1855 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1857 pic16_emitpLabel(tlbl->key);
1859 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(PCOR(temp)));
1861 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1863 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1864 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1867 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl->key));
1869 pic16_popReleaseTempReg(temp);
1874 /*-----------------------------------------------------------------*
1875 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1877 * this routine will call the unsigned multiply routine and then
1878 * post-fix the sign bit.
1879 *-----------------------------------------------------------------*/
1880 void pic16_genSMult8X8_16 (operand *left,
1883 pCodeOpReg *result_hi)
1887 result_hi = PCOR(pic16_popGet(AOP(result),1));
1890 pic16_genUMult8X8_16(left,right,result,result_hi);
1892 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0));
1893 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
1894 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1895 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0));
1896 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
1900 /*-----------------------------------------------------------------*
1901 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers
1903 * this routine will call the unsigned multiply 8X8=>16 routine and
1904 * then throw away the high byte of the result.
1906 *-----------------------------------------------------------------*/
1907 void pic16_genMult8X8_8 (operand *left,
1911 pCodeOp *result_hi = pic16_popGetTempReg();
1913 if (AOP_TYPE(right) == AOP_LIT)
1914 pic16_genUMult8XLit_16(left,right,result,PCOR(result_hi));
1916 pic16_genUMult8X8_16(left,right,result,PCOR(result_hi));
1918 pic16_popReleaseTempReg(result_hi);
1921 /*-----------------------------------------------------------------*/
1922 /* constMult - generates code for multiplication by a constant */
1923 /*-----------------------------------------------------------------*/
1924 void genMultConst(unsigned C)
1928 unsigned sr3; // Shift right 3
1934 Convert a string of 3 binary 1's in the lit into
1938 mask = 7 << ( (size*8) - 3);
1942 while(mask < (1<<size*8)) {
1944 if( (mask & lit) == lit) {
1947 /* We found 3 (or more) consecutive 1's */
1949 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1951 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1953 lit ^= consecutive_bits;
1957 sr3 |= (consecutive + lsb);