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__
44 #ifdef HAVE_SYS_ISA_DEFS_H
45 #include <sys/isa_defs.h>
47 #ifdef HAVE_MACHINE_ENDIAN_H
48 #include <machine/endian.h>
53 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
54 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
55 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
62 #include "SDCCpeeph.h"
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
69 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
71 const char *pic16_AopType(short type)
118 const char *pic16_pCodeOpType( pCodeOp *pcop)
141 case PO_GPR_REGISTER:
142 return "PO_GPR_REGISTER";
146 return "PO_GPR_TEMP";
147 case PO_SFR_REGISTER:
148 return "PO_SFR_REGISTER";
156 return "PO_REL_ADDR";
158 return "PO_IMMEDIATE";
174 return "BAD PO_TYPE";
177 /*-----------------------------------------------------------------*/
178 /* pic16_genPlusIncr :- does addition with increment if possible */
179 /*-----------------------------------------------------------------*/
180 bool pic16_genPlusIncr (iCode *ic)
182 unsigned int icount ;
183 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
185 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
186 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
187 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
188 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
189 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
191 /* will try to generate an increment */
192 /* if the right side is not a literal
194 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
197 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
198 /* if the literal value of the right hand side
199 is greater than 1 then it is faster to add */
200 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
203 /* if increment 16 bits in register */
204 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
209 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
210 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
214 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
215 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
221 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
222 /* if left is in accumulator - probably a bit operation*/
223 if( strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
224 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
226 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
227 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
228 AOP(IC_RESULT(ic))->aopu.aop_dir,
229 AOP(IC_RESULT(ic))->aopu.aop_dir);
231 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
232 //pic16_emitcode("xorlw","1");
234 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
235 //pic16_emitcode("andlw","1");
238 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
239 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
240 AOP(IC_RESULT(ic))->aopu.aop_dir,
241 AOP(IC_RESULT(ic))->aopu.aop_dir);
248 /* if the sizes are greater than 1 then we cannot */
249 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
250 AOP_SIZE(IC_LEFT(ic)) > 1 )
253 /* If we are incrementing the same register by two: */
255 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
258 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
259 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
264 DEBUGpic16_emitcode ("; ","couldn't increment ");
269 /*-----------------------------------------------------------------*/
270 /* pic16_outBitAcc - output a bit in acc */
271 /*-----------------------------------------------------------------*/
272 void pic16_outBitAcc(operand *result)
274 symbol *tlbl = newiTempLabel(NULL);
275 /* if the result is a bit */
276 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
278 if (AOP_TYPE(result) == AOP_CRY){
279 pic16_aopPut(AOP(result),"a",0);
282 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
283 pic16_emitcode("mov","a,#01");
284 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
285 pic16_outAcc(result);
289 /*-----------------------------------------------------------------*/
290 /* pic16_genPlusBits - generates code for addition of two bits */
291 /*-----------------------------------------------------------------*/
292 void pic16_genPlusBits (iCode *ic)
295 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
297 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
298 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
299 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
300 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
302 The following block of code will add two bits.
303 Note that it'll even work if the destination is
304 the carry (C in the status register).
305 It won't work if the 'Z' bit is a source or destination.
308 /* If the result is stored in the accumulator (w) */
309 //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
310 switch(AOP_TYPE(IC_RESULT(ic))) {
312 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
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));
318 pic16_emitcode("clrw","");
319 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
320 AOP(IC_RIGHT(ic))->aopu.aop_dir,
321 AOP(IC_RIGHT(ic))->aopu.aop_dir);
322 pic16_emitcode("xorlw","1");
323 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
324 AOP(IC_LEFT(ic))->aopu.aop_dir,
325 AOP(IC_LEFT(ic))->aopu.aop_dir);
326 pic16_emitcode("xorlw","1");
329 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
330 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
331 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
332 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
333 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
334 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
337 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
338 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
339 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
340 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
341 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
342 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
344 pic16_emitcode("movlw","(1 << (%s & 7))",
345 AOP(IC_RESULT(ic))->aopu.aop_dir,
346 AOP(IC_RESULT(ic))->aopu.aop_dir);
347 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
348 AOP(IC_RESULT(ic))->aopu.aop_dir,
349 AOP(IC_RESULT(ic))->aopu.aop_dir);
350 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
351 AOP(IC_RIGHT(ic))->aopu.aop_dir,
352 AOP(IC_RIGHT(ic))->aopu.aop_dir);
353 pic16_emitcode("xorwf","(%s >>3),f",
354 AOP(IC_RESULT(ic))->aopu.aop_dir);
355 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
356 AOP(IC_LEFT(ic))->aopu.aop_dir,
357 AOP(IC_LEFT(ic))->aopu.aop_dir);
358 pic16_emitcode("xorwf","(%s>>3),f",
359 AOP(IC_RESULT(ic))->aopu.aop_dir);
366 /* This is the original version of this code.
368 * This is being kept around for reference,
369 * because I am not entirely sure I got it right...
371 static void adjustArithmeticResult(iCode *ic)
373 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
374 AOP_SIZE(IC_LEFT(ic)) == 3 &&
375 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
376 pic16_aopPut(AOP(IC_RESULT(ic)),
377 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
380 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
381 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
382 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
383 pic16_aopPut(AOP(IC_RESULT(ic)),
384 pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
387 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
388 AOP_SIZE(IC_LEFT(ic)) < 3 &&
389 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
390 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
391 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
393 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
394 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
398 /* This is the pure and virtuous version of this code.
399 * I'm pretty certain it's right, but not enough to toss the old
402 static void adjustArithmeticResult(iCode *ic)
404 if (opIsGptr(IC_RESULT(ic)) &&
405 opIsGptr(IC_LEFT(ic)) &&
406 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
408 pic16_aopPut(AOP(IC_RESULT(ic)),
409 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
413 if (opIsGptr(IC_RESULT(ic)) &&
414 opIsGptr(IC_RIGHT(ic)) &&
415 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
417 pic16_aopPut(AOP(IC_RESULT(ic)),
418 pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
422 if (opIsGptr(IC_RESULT(ic)) &&
423 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
424 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
425 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
426 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
428 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
429 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
434 /*-----------------------------------------------------------------*/
435 /* genAddlit - generates code for addition */
436 /*-----------------------------------------------------------------*/
437 static void genAddLit2byte (operand *result, int offr, int lit)
444 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
447 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
450 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
451 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
456 static void emitMOVWF(operand *reg, int offset)
461 if (AOP_TYPE(reg) == AOP_ACC) {
462 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
466 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
470 static void genAddLit (iCode *ic, int lit)
479 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
483 result = IC_RESULT(ic);
484 same = pic16_sameRegs(AOP(left), AOP(result));
485 size = pic16_getDataSize(result);
489 /* Handle special cases first */
491 genAddLit2byte (result, 0, lit);
494 int hi = 0xff & (lit >> 8);
501 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
506 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
508 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
511 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
512 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
513 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
517 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
518 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
520 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
528 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
531 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
534 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
535 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
537 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
539 case 0xff: /* 0x01ff */
540 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
541 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
542 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
543 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
548 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
552 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
555 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
556 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
558 /* case 0xff: * 0xffff *
559 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
560 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
561 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
565 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
566 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
568 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
575 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
580 genAddLit2byte (result, MSB16, hi);
583 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1)&0xff));
584 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
585 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
586 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
588 /* case 0xff: * 0xHHff *
589 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
590 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
591 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
592 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
594 */ default: /* 0xHHLL */
595 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
596 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
597 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
599 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1) & 0xff));
600 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
609 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
612 lo = BYTEofLONG(lit,0);
620 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
623 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
624 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(1));
625 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
627 default: /* carry_info = 3 */
629 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
635 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
640 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
643 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
648 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo+1));
649 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
654 /* no carry info from previous step */
655 /* this means this is the first time to add */
660 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
664 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
665 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
667 carry_info = 3; /* Were adding only one byte and propogating the carry */
678 lo = BYTEofLONG(lit,0);
683 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
686 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
687 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
690 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
692 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
694 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
704 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
708 if(AOP_TYPE(left) == AOP_ACC) {
709 /* left addend is already in accumulator */
712 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
716 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
717 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
721 /* left addend is in a register */
724 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
725 emitMOVWF(result, 0);
726 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
730 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
731 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
735 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
736 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
740 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
741 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
742 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
750 /* left is not the accumulator */
752 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
753 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
755 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
756 /* We don't know the state of the carry bit at this point */
759 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
766 /* The ls byte of the lit must've been zero - that
767 means we don't have to deal with carry */
769 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
770 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
771 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),offset));
776 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
777 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset,FALSE,FALSE));
778 emitMOVWF(result,offset);
779 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
781 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
782 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
786 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
787 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset));
788 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
789 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
797 /*-----------------------------------------------------------------*/
798 /* pic16_genPlus - generates code for addition */
799 /*-----------------------------------------------------------------*/
800 void pic16_genPlus (iCode *ic)
802 int size, offset = 0;
804 /* special cases :- */
805 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
807 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
808 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
809 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
811 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
813 /* if literal, literal on the right or
814 if left requires ACC or right is already
817 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
818 operand *t = IC_RIGHT(ic);
819 IC_RIGHT(ic) = IC_LEFT(ic);
823 /* if both left & right are in bit space */
824 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
825 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
826 pic16_genPlusBits (ic);
830 /* if left in bit space & right literal */
831 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
832 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
833 /* if result in bit space */
834 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
835 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
836 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
837 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
838 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
839 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
842 size = pic16_getDataSize(IC_RESULT(ic));
844 MOVA(pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
845 pic16_emitcode("addc","a,#00 ;%d",__LINE__);
846 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
852 /* if I can do an increment instead
853 of add then GOOD for ME */
854 if (pic16_genPlusIncr (ic) == TRUE)
857 size = pic16_getDataSize(IC_RESULT(ic));
859 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
860 /* Add a literal to something else */
862 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
866 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
871 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
873 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
874 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
875 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
877 /* here we are adding a bit to a char or int */
879 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
881 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
882 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
884 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
885 AOP(IC_RIGHT(ic))->aopu.aop_dir,
886 AOP(IC_RIGHT(ic))->aopu.aop_dir);
887 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
890 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
891 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
892 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
894 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
895 AOP(IC_RIGHT(ic))->aopu.aop_dir,
896 AOP(IC_RIGHT(ic))->aopu.aop_dir);
897 pic16_emitcode(" xorlw","1");
899 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
900 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
901 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
903 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
904 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
905 AOP(IC_RIGHT(ic))->aopu.aop_dir,
906 AOP(IC_RIGHT(ic))->aopu.aop_dir);
907 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
910 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
912 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
913 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
914 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
916 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
918 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
919 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
926 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
927 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
929 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
930 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
932 pic16_emitcode("clrz","");
934 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
935 AOP(IC_RIGHT(ic))->aopu.aop_dir,
936 AOP(IC_RIGHT(ic))->aopu.aop_dir);
937 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
941 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
942 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
943 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
944 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
945 emitMOVWF(IC_RIGHT(ic),0);
947 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
948 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
949 AOP(IC_RIGHT(ic))->aopu.aop_dir,
950 AOP(IC_RIGHT(ic))->aopu.aop_dir);
951 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
952 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
958 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
959 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
965 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
967 /* Add the first bytes */
969 if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
970 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
971 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
974 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
975 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
976 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
977 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
980 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
982 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
983 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
985 PIC_OPCODE poc = POC_ADDFW;
987 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
988 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
989 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
991 pic16_emitpcode(poc, pic16_popGet(AOP(IC_LEFT(ic)),0));
992 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
993 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
998 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
1003 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1004 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1005 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1007 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1008 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1011 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1013 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1014 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1017 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1019 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1020 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1028 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1029 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1030 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1033 /* Need to extend result to higher bytes */
1034 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1036 /* First grab the carry from the lower bytes */
1037 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1038 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1042 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1045 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1046 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1047 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1048 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1050 /* if chars or ints or being signed extended to longs: */
1052 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1053 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1054 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1062 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1064 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1071 //adjustArithmeticResult(ic);
1074 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1075 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1076 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1079 /*-----------------------------------------------------------------*/
1080 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1081 /*-----------------------------------------------------------------*/
1082 bool pic16_genMinusDec (iCode *ic)
1084 unsigned int icount ;
1085 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1087 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1088 /* will try to generate an increment */
1089 /* if the right side is not a literal
1091 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1092 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1093 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1096 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1098 /* if the literal value of the right hand side
1099 is greater than 4 then it is not worth it */
1100 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1103 /* if decrement 16 bits in register */
1104 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1109 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1110 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1111 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1112 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1114 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1115 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1116 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1118 /* size is 3 or 4 */
1119 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1120 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1122 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1124 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1126 pic16_emitcode("movlw","0xff");
1127 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1130 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1132 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1136 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1138 pic16_emitcode("skpnc","");
1140 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1149 /* if the sizes are greater than 1 then we cannot */
1150 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1151 AOP_SIZE(IC_LEFT(ic)) > 1 )
1154 /* we can if the aops of the left & result match or
1155 if they are in registers and the registers are the
1157 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1160 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1162 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1167 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1168 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1169 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1172 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1173 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1175 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1176 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1184 /*-----------------------------------------------------------------*/
1185 /* pic16_addSign - propogate sign bit to higher bytes */
1186 /*-----------------------------------------------------------------*/
1187 void pic16_addSign(operand *result, int offset, int sign)
1189 int size = (pic16_getDataSize(result) - offset);
1190 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1193 if(sign && offset) {
1196 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1197 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1198 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1201 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1202 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1203 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1205 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),size));
1210 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1214 /*-----------------------------------------------------------------*/
1215 /* pic16_genMinusBits - generates code for subtraction of two bits */
1216 /*-----------------------------------------------------------------*/
1217 void pic16_genMinusBits (iCode *ic)
1219 symbol *lbl = newiTempLabel(NULL);
1220 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1221 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1222 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1223 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1224 pic16_emitcode("cpl","c");
1225 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1226 pic16_outBitC(IC_RESULT(ic));
1229 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1230 pic16_emitcode("subb","a,acc");
1231 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1232 pic16_emitcode("inc","a");
1233 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1234 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1235 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1239 /*-----------------------------------------------------------------*/
1240 /* pic16_genMinus - generates code for subtraction */
1241 /*-----------------------------------------------------------------*/
1242 void pic16_genMinus (iCode *ic)
1244 int size, offset = 0, same=0;
1245 unsigned long lit = 0L;
1247 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1248 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1249 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1250 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1252 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1253 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1254 operand *t = IC_RIGHT(ic);
1255 IC_RIGHT(ic) = IC_LEFT(ic);
1259 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1260 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1261 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1262 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1264 /* special cases :- */
1265 /* if both left & right are in bit space */
1266 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1267 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1268 pic16_genPlusBits (ic);
1272 /* if I can do an decrement instead
1273 of subtract then GOOD for ME */
1274 // if (pic16_genMinusDec (ic) == TRUE)
1277 size = pic16_getDataSize(IC_RESULT(ic));
1278 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1280 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1281 /* Add a literal to something else */
1283 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1286 genAddLit ( ic, lit);
1289 /* add the first byte: */
1290 pic16_emitcode("movlw","0x%x", lit & 0xff);
1291 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1292 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1293 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1305 if((lit & 0xff) == 0xff) {
1306 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1308 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1310 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1312 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1313 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1317 /* do the rlf known zero trick here */
1318 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1320 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1325 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1328 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1329 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1330 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1332 /* here we are subtracting a bit from a char or int */
1334 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1336 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1337 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1339 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1340 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1341 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1342 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1345 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1346 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1347 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1348 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1349 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1351 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1353 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1354 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1356 pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1357 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1360 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1362 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1364 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1365 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1369 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1370 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1371 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1372 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1377 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1378 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1379 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1382 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1384 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1387 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1389 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1391 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1398 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1399 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1400 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1402 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1403 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1404 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1405 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1406 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1409 if( (size == 1) && ((lit & 0xff) == 0) ) {
1410 /* res = 0 - right */
1411 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1412 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1413 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1415 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1416 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1417 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1422 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1423 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1424 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1432 /* This is the last byte in a multibyte subtraction
1433 * There are a couple of tricks we can do by not worrying about
1434 * propogating the carry */
1436 /* 0xff - x == ~x */
1438 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1440 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1442 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1443 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1445 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1448 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1450 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1451 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1452 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1461 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1463 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
1464 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1467 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1473 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1474 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1476 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1478 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1480 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1481 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1488 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1489 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1490 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1491 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1493 if(strcmp(pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1494 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1495 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1496 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1497 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1500 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1501 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1502 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1503 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1504 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1507 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1508 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1509 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1511 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1512 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1514 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1515 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1516 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1518 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1520 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1521 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1522 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1524 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1526 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1533 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1535 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1536 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1538 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1539 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1546 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1547 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1548 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1550 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1552 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1553 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1561 // adjustArithmeticResult(ic);
1564 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1565 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1566 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1568 /*-----------------------------------------------------------------*
1569 * pic_genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1572 *-----------------------------------------------------------------*/
1573 void pic16_genUMult8XLit_16 (operand *left,
1576 pCodeOpReg *result_hi)
1581 unsigned int i,have_first_bit;
1585 if (AOP_TYPE(right) != AOP_LIT){
1586 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1592 result_hi = PCOR(pic16_popGet(AOP(result),1));
1595 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1597 pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1599 same = pic16_sameRegs(AOP(left), AOP(result));
1604 pic16_emitpcode(POC_CLRF, 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));
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));
1616 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1617 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1618 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1619 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1622 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1623 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1624 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1625 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1628 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1629 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1630 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1631 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1632 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1635 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1636 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1637 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1638 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
1639 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 7*F
1642 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1643 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1644 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1645 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1646 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
1649 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1650 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1651 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1652 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1653 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1654 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1657 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1658 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1659 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1660 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 5*F
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_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
1670 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 11*F
1673 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1674 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1675 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1676 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1677 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1678 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1679 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1682 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1683 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1684 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1685 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1686 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 8*F
1687 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 13*F
1690 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1691 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 2*F
1692 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 3*F
1693 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 5*F
1694 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 8*F
1695 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); // W = 11*F
1696 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0)); // F = 14*F
1699 temp = pic16_popGetTempReg();
1701 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1704 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1705 pic16_emitpcode(POC_MOVWF, temp);
1706 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1707 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1708 pic16_emitpcode(POC_SWAPFW, temp);
1709 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(left),0));
1710 pic16_popReleaseTempReg(temp);
1713 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1714 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1715 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1718 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
1719 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
1720 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
1723 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
1724 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
1725 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xe0));
1726 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1729 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(left),0));
1730 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1731 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),0));
1732 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xc0));
1733 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),0));
1736 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
1737 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(left),0));
1738 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),0));
1746 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1747 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1750 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1751 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1752 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
1753 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1754 pic16_emitpcode(POC_RLCF, pic16_popCopyReg(result_hi));
1760 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1761 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1762 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1765 for(i=0; i<8; i++) {
1768 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1772 if(have_first_bit) {
1773 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1774 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1782 /*-----------------------------------------------------------------*
1783 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1786 *-----------------------------------------------------------------*/
1787 void pic16_genUMult8X8_16 (operand *left,
1790 pCodeOpReg *result_hi)
1798 result_hi = PCOR(pic16_popGet(AOP(result),1));
1801 if (AOP_TYPE(right) == AOP_LIT) {
1802 pic16_genUMult8XLit_16(left,right,result,result_hi);
1807 pic16_emitcode(";","Unrolled 8 X 8 multiplication");
1809 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1810 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1811 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1814 for(i=0; i<8; i++) {
1815 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),i,0));
1816 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1817 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1818 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1823 Here's another version that does the same thing and takes the
1824 same number of instructions. The one above is slightly better
1825 because the entry instructions have a higher probability of
1826 being optimized out.
1829 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1830 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
1831 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
1832 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1834 for(i=0; i<8; i++) {
1836 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1837 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1838 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1843 symbol *tlbl = newiTempLabel(NULL);
1847 pic16_emitcode(";","Looped 8 X 8 multiplication");
1849 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1850 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(result_hi));
1852 pic16_emitpcode(POC_BSF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),0,FALSE,FALSE),7,0));
1854 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
1856 temp = pic16_popGetTempReg();
1857 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(PCOR(temp)));
1859 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1861 pic16_emitpLabel(tlbl->key);
1863 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(PCOR(temp)));
1865 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
1867 pic16_emitpcode(POC_RRCF, pic16_popCopyReg(result_hi));
1868 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
1871 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl->key));
1873 pic16_popReleaseTempReg(temp);
1878 /*-----------------------------------------------------------------*
1879 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1881 * this routine will call the unsigned multiply routine and then
1882 * post-fix the sign bit.
1883 *-----------------------------------------------------------------*/
1884 void pic16_genSMult8X8_16 (operand *left,
1887 pCodeOpReg *result_hi)
1891 result_hi = PCOR(pic16_popGet(AOP(result),1));
1894 pic16_genUMult8X8_16(left,right,result,result_hi);
1896 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0));
1897 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
1898 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1899 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0));
1900 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
1904 /*-----------------------------------------------------------------*
1905 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers
1907 * this routine will call the unsigned multiply 8X8=>16 routine and
1908 * then throw away the high byte of the result.
1910 *-----------------------------------------------------------------*/
1911 void pic16_genMult8X8_8 (operand *left,
1915 pCodeOp *result_hi = pic16_popGetTempReg();
1917 if (AOP_TYPE(right) == AOP_LIT)
1918 pic16_genUMult8XLit_16(left,right,result,PCOR(result_hi));
1920 pic16_genUMult8X8_16(left,right,result,PCOR(result_hi));
1922 pic16_popReleaseTempReg(result_hi);
1925 /*-----------------------------------------------------------------*/
1926 /* constMult - generates code for multiplication by a constant */
1927 /*-----------------------------------------------------------------*/
1928 void genMultConst(unsigned C)
1932 unsigned sr3; // Shift right 3
1938 Convert a string of 3 binary 1's in the lit into
1942 mask = 7 << ( (size*8) - 3);
1946 while(mask < (1<<size*8)) {
1948 if( (mask & lit) == lit) {
1951 /* We found 3 (or more) consecutive 1's */
1953 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1955 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1957 lit ^= consecutive_bits;
1961 sr3 |= (consecutive + lsb);