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)) > 2)
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*/
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;
787 /* special cases :- */
788 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
790 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
791 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
792 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
794 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
796 /* if literal, literal on the right or
797 if left requires ACC or right is already
800 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
801 operand *t = IC_RIGHT(ic);
802 IC_RIGHT(ic) = IC_LEFT(ic);
806 /* if both left & right are in bit space */
807 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
808 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
809 pic16_genPlusBits (ic);
813 /* if left in bit space & right literal */
814 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
815 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
816 /* if result in bit space */
817 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
818 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
819 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
820 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
821 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
822 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
825 size = pic16_getDataSize(IC_RESULT(ic));
827 MOVA(pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
828 pic16_emitcode("addc","a,#00 ;%d",__LINE__);
829 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
835 /* if I can do an increment instead
836 of add then GOOD for ME */
837 if (pic16_genPlusIncr (ic) == TRUE)
840 size = pic16_getDataSize(IC_RESULT(ic));
842 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
843 /* Add a literal to something else */
845 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
849 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
854 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
856 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
857 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
858 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
860 /* here we are adding a bit to a char or int */
862 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
864 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
865 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
867 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
868 AOP(IC_RIGHT(ic))->aopu.aop_dir,
869 AOP(IC_RIGHT(ic))->aopu.aop_dir);
870 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
873 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
874 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
875 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
877 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
878 AOP(IC_RIGHT(ic))->aopu.aop_dir,
879 AOP(IC_RIGHT(ic))->aopu.aop_dir);
880 pic16_emitcode(" xorlw","1");
882 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
883 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
884 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
886 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
887 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
888 AOP(IC_RIGHT(ic))->aopu.aop_dir,
889 AOP(IC_RIGHT(ic))->aopu.aop_dir);
890 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
893 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
895 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
896 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
897 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
899 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
901 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
902 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
909 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
910 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
912 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
913 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
915 pic16_emitcode("clrz","");
917 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
918 AOP(IC_RIGHT(ic))->aopu.aop_dir,
919 AOP(IC_RIGHT(ic))->aopu.aop_dir);
920 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
924 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
925 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
926 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
927 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
928 emitMOVWF(IC_RIGHT(ic),0);
930 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
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,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
935 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
941 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
942 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
948 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
950 /* Add the first bytes */
952 if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
953 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
954 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
957 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
958 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
959 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
960 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
963 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
965 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
966 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
968 PIC_OPCODE poc = POC_ADDFW;
970 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
971 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
972 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
974 pic16_emitpcode(poc, pic16_popGet(AOP(IC_LEFT(ic)),0));
975 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
976 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
981 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
986 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
987 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
988 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
990 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
991 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
994 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
996 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
997 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1000 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1002 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1003 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1011 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1012 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1013 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1016 /* Need to extend result to higher bytes */
1017 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1019 /* First grab the carry from the lower bytes */
1020 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1021 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1025 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1028 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1029 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1030 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1031 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1033 /* if chars or ints or being signed extended to longs: */
1035 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1036 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1037 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1045 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1047 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1054 //adjustArithmeticResult(ic);
1057 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1058 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1059 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1062 /*-----------------------------------------------------------------*/
1063 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1064 /*-----------------------------------------------------------------*/
1065 bool pic16_genMinusDec (iCode *ic)
1067 unsigned int icount ;
1068 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1070 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1071 /* will try to generate an increment */
1072 /* if the right side is not a literal
1074 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1075 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1076 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1079 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1081 /* if the literal value of the right hand side
1082 is greater than 4 then it is not worth it */
1083 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1086 /* if decrement 16 bits in register */
1087 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1092 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1093 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1094 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1095 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1097 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1098 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1099 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1101 /* size is 3 or 4 */
1102 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1103 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1105 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1107 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1109 pic16_emitcode("movlw","0xff");
1110 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1113 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1115 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1119 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1121 pic16_emitcode("skpnc","");
1123 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1132 /* if the sizes are greater than 1 then we cannot */
1133 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1134 AOP_SIZE(IC_LEFT(ic)) > 1 )
1137 /* we can if the aops of the left & result match or
1138 if they are in registers and the registers are the
1140 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1143 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1145 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1150 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1151 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1152 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1155 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1156 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1158 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1159 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1167 /*-----------------------------------------------------------------*/
1168 /* pic16_addSign - propogate sign bit to higher bytes */
1169 /*-----------------------------------------------------------------*/
1170 void pic16_addSign(operand *result, int offset, int sign)
1172 int size = (pic16_getDataSize(result) - offset);
1173 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1176 if(sign && offset) {
1179 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1180 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1181 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1184 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1185 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1186 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1188 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),size));
1193 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1197 /*-----------------------------------------------------------------*/
1198 /* pic16_genMinusBits - generates code for subtraction of two bits */
1199 /*-----------------------------------------------------------------*/
1200 void pic16_genMinusBits (iCode *ic)
1202 symbol *lbl = newiTempLabel(NULL);
1203 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1204 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1205 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1206 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1207 pic16_emitcode("cpl","c");
1208 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1209 pic16_outBitC(IC_RESULT(ic));
1212 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1213 pic16_emitcode("subb","a,acc");
1214 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1215 pic16_emitcode("inc","a");
1216 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1217 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1218 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1222 /*-----------------------------------------------------------------*/
1223 /* pic16_genMinus - generates code for subtraction */
1224 /*-----------------------------------------------------------------*/
1225 void pic16_genMinus (iCode *ic)
1227 int size, offset = 0, same=0;
1228 unsigned long lit = 0L;
1230 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1231 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1232 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1233 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1235 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1236 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1237 operand *t = IC_RIGHT(ic);
1238 IC_RIGHT(ic) = IC_LEFT(ic);
1242 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1243 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1244 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1245 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1247 /* special cases :- */
1248 /* if both left & right are in bit space */
1249 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1250 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1251 pic16_genPlusBits (ic);
1255 /* if I can do an decrement instead
1256 of subtract then GOOD for ME */
1257 // if (pic16_genMinusDec (ic) == TRUE)
1260 size = pic16_getDataSize(IC_RESULT(ic));
1261 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1263 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1264 /* Add a literal to something else */
1266 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1269 genAddLit ( ic, lit);
1272 /* add the first byte: */
1273 pic16_emitcode("movlw","0x%x", lit & 0xff);
1274 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1275 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1276 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1288 if((lit & 0xff) == 0xff) {
1289 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1291 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1293 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1295 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1296 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1300 /* do the rlf known zero trick here */
1301 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1303 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1308 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1311 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1312 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1313 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1315 /* here we are subtracting a bit from a char or int */
1317 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1319 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1320 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1322 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1323 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1324 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1325 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1328 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1329 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1330 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1331 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1332 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1334 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1336 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1337 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1339 pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1340 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1343 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1345 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1347 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1348 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1352 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1353 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1354 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1355 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1360 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1361 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1362 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1365 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1367 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1370 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1372 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1374 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1381 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1382 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1383 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1385 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1386 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1387 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1388 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1389 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1392 if( (size == 1) && ((lit & 0xff) == 0) ) {
1393 /* res = 0 - right */
1394 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1395 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1396 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1398 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1399 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1400 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1405 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1406 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1407 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1415 /* This is the last byte in a multibyte subtraction
1416 * There are a couple of tricks we can do by not worrying about
1417 * propogating the carry */
1419 /* 0xff - x == ~x */
1421 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1423 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1425 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1426 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1428 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1431 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1433 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1434 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1435 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1444 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1446 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
1447 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1450 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1456 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1457 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1459 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1461 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1463 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1464 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1471 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1472 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1473 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1474 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1476 if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1477 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1478 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1479 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1480 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1483 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1484 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1485 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1486 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1487 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1490 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1491 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1492 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1494 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1495 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1497 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1498 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1499 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1501 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1503 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1504 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1505 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1507 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1509 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1516 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1518 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1519 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1521 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1522 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1529 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1530 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1531 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1533 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1535 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1536 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1544 // adjustArithmeticResult(ic);
1547 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1548 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1549 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1551 /*-----------------------------------------------------------------*
1552 * pic_genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1555 *-----------------------------------------------------------------*/
1556 void pic16_genUMult8XLit_16 (operand *left,
1559 pCodeOpReg *result_hi)
1564 unsigned int i,have_first_bit;
1568 if (AOP_TYPE(right) != AOP_LIT){
1569 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1575 result_hi = PCOR(pic16_popGet(AOP(result),1));
1578 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1580 pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1582 same = pic16_sameRegs(AOP(left), AOP(result));
1587 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(left),0));
1590 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1591 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1594 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1595 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1596 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1599 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1600 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1601 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1602 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1605 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1606 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1607 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1608 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1611 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1612 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1613 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1614 pic16_emitpcode(POC_MOVFW, 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
1622 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 7*F
1625 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1626 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1627 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1628 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1629 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
1632 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1633 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1634 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1635 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1636 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1637 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1640 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1641 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1642 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1643 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1644 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1645 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1648 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1649 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1650 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1651 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1652 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
1653 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 11*F
1656 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1657 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1658 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1659 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1660 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1661 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1662 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1665 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1666 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1667 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1668 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1669 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
1670 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 13*F
1673 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1674 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1675 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1676 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1677 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
1678 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 11*F
1679 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 14*F
1682 temp = pic16_popGetTempReg();
1684 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1687 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1688 pic16_emitpcode(POC_MOVWF, temp);
1689 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1690 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1691 pic16_emitpcode(POC_SWAPFW, temp);
1692 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(left),0));
1693 pic16_popReleaseTempReg(temp);
1696 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1697 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1698 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1701 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1702 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1703 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1706 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
1707 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
1708 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xe0));
1709 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1712 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
1713 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1714 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
1715 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xc0));
1716 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1719 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
1720 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(left),0));
1721 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),0));
1729 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1730 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1733 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1734 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1735 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
1736 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1737 pic16_emitpcode(POC_RLCF, pic16_popCopyReg(result_hi));
1743 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1744 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1745 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1748 for(i=0; i<8; i++) {
1751 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1755 if(have_first_bit) {
1756 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1757 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1765 /*-----------------------------------------------------------------*
1766 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1769 *-----------------------------------------------------------------*/
1770 void pic16_genUMult8X8_16 (operand *left,
1773 pCodeOpReg *result_hi)
1781 result_hi = PCOR(pic16_popGet(AOP(result),1));
1784 if (AOP_TYPE(right) == AOP_LIT) {
1785 pic16_genUMult8XLit_16(left,right,result,result_hi);
1790 pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1792 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1793 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1794 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1797 for(i=0; i<8; i++) {
1798 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),i,0));
1799 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1800 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1801 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1806 Here's another version that does the same thing and takes the
1807 same number of instructions. The one above is slightly better
1808 because the entry instructions have a higher probability of
1809 being optimized out.
1812 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1813 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
1814 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1815 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1817 for(i=0; i<8; i++) {
1819 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1820 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1821 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1826 symbol *tlbl = newiTempLabel(NULL);
1830 pic16_emitcode(";","Looped 8 X 8 multiplication");
1832 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1833 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1835 pic16_emitpcode(POC_BSF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),0,FALSE,FALSE),7,0));
1837 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1839 temp = pic16_popGetTempReg();
1840 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(PCOR(temp)));
1842 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1844 pic16_emitpLabel(tlbl->key);
1846 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(PCOR(temp)));
1848 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1850 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1851 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1854 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl->key));
1856 pic16_popReleaseTempReg(temp);
1861 /*-----------------------------------------------------------------*
1862 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1864 * this routine will call the unsigned multiply routine and then
1865 * post-fix the sign bit.
1866 *-----------------------------------------------------------------*/
1867 void pic16_genSMult8X8_16 (operand *left,
1870 pCodeOpReg *result_hi)
1874 result_hi = PCOR(pic16_popGet(AOP(result),1));
1877 pic16_genUMult8X8_16(left,right,result,result_hi);
1879 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0));
1880 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
1881 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1882 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0));
1883 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
1887 /*-----------------------------------------------------------------*
1888 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers
1890 * this routine will call the unsigned multiply 8X8=>16 routine and
1891 * then throw away the high byte of the result.
1893 *-----------------------------------------------------------------*/
1894 void pic16_genMult8X8_8 (operand *left,
1898 pCodeOp *result_hi = pic16_popGetTempReg();
1900 if (AOP_TYPE(right) == AOP_LIT)
1901 pic16_genUMult8XLit_16(left,right,result,PCOR(result_hi));
1903 pic16_genUMult8X8_16(left,right,result,PCOR(result_hi));
1905 pic16_popReleaseTempReg(result_hi);
1908 /*-----------------------------------------------------------------*/
1909 /* constMult - generates code for multiplication by a constant */
1910 /*-----------------------------------------------------------------*/
1911 void genMultConst(unsigned C)
1915 unsigned sr3; // Shift right 3
1921 Convert a string of 3 binary 1's in the lit into
1925 mask = 7 << ( (size*8) - 3);
1929 while(mask < (1<<size*8)) {
1931 if( (mask & lit) == lit) {
1934 /* We found 3 (or more) consecutive 1's */
1936 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1938 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1940 lit ^= consecutive_bits;
1944 sr3 |= (consecutive + lsb);