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)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
39 #if defined(_MSC_VER) && (_MSC_VER < 1300)
40 #define __FUNCTION__ __FILE__
43 #ifdef HAVE_SYS_ISA_DEFS_H
44 #include <sys/isa_defs.h>
46 #ifdef HAVE_MACHINE_ENDIAN_H
47 #include <machine/endian.h>
52 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
53 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
54 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
61 #include "SDCCpeeph.h"
67 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
68 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result);
70 const char *AopType(short type)
117 const char *pCodeOpType( pCodeOp *pcop)
136 case PO_GPR_REGISTER:
137 return "PO_GPR_REGISTER";
141 return "PO_GPR_TEMP";
142 case PO_SFR_REGISTER:
143 return "PO_SFR_REGISTER";
151 return "PO_IMMEDIATE";
167 return "BAD PO_TYPE";
170 /*-----------------------------------------------------------------*/
171 /* genPlusIncr :- does addition with increment if possible */
172 /*-----------------------------------------------------------------*/
173 bool genPlusIncr (iCode *ic)
175 unsigned int icount ;
176 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
178 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
179 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
180 AopType(AOP_TYPE(IC_RESULT(ic))),
181 AopType(AOP_TYPE(IC_LEFT(ic))),
182 AopType(AOP_TYPE(IC_RIGHT(ic))));
184 /* will try to generate an increment */
185 /* if the right side is not a literal
187 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
190 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
191 /* if the literal value of the right hand side
192 is greater than 1 then it is faster to add */
193 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
196 /* if increment 16 bits in register */
197 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
202 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB));
203 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
207 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
208 //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
214 DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
215 /* if left is in accumulator - probably a bit operation*/
216 if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
217 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
219 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
220 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
221 AOP(IC_RESULT(ic))->aopu.aop_dir,
222 AOP(IC_RESULT(ic))->aopu.aop_dir);
224 emitpcode(POC_XORLW,popGetLit(1));
225 //pic14_emitcode("xorlw","1");
227 emitpcode(POC_ANDLW,popGetLit(1));
228 //pic14_emitcode("andlw","1");
231 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
232 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
233 AOP(IC_RESULT(ic))->aopu.aop_dir,
234 AOP(IC_RESULT(ic))->aopu.aop_dir);
241 /* if the sizes are greater than 1 then we cannot */
242 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
243 AOP_SIZE(IC_LEFT(ic)) > 1 )
246 /* If we are incrementing the same register by two: */
248 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
251 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
252 //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
257 DEBUGpic14_emitcode ("; ","couldn't increment ");
262 /*-----------------------------------------------------------------*/
263 /* pic14_outBitAcc - output a bit in acc */
264 /*-----------------------------------------------------------------*/
265 void pic14_outBitAcc(operand *result)
267 symbol *tlbl = newiTempLabel(NULL);
268 /* if the result is a bit */
269 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
271 if (AOP_TYPE(result) == AOP_CRY){
272 aopPut(AOP(result),"a",0);
275 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
276 pic14_emitcode("mov","a,#01");
277 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
278 pic14_outAcc(result);
282 /*-----------------------------------------------------------------*/
283 /* genPlusBits - generates code for addition of two bits */
284 /*-----------------------------------------------------------------*/
285 void genPlusBits (iCode *ic)
288 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
290 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
291 AopType(AOP_TYPE(IC_RESULT(ic))),
292 AopType(AOP_TYPE(IC_LEFT(ic))),
293 AopType(AOP_TYPE(IC_RIGHT(ic))));
295 The following block of code will add two bits.
296 Note that it'll even work if the destination is
297 the carry (C in the status register).
298 It won't work if the 'Z' bit is a source or destination.
301 /* If the result is stored in the accumulator (w) */
302 //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
303 switch(AOP_TYPE(IC_RESULT(ic))) {
305 emitpcode(POC_CLRW, NULL);
306 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
307 emitpcode(POC_XORLW, popGetLit(1));
308 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
309 emitpcode(POC_XORLW, popGetLit(1));
311 pic14_emitcode("clrw","");
312 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
313 AOP(IC_RIGHT(ic))->aopu.aop_dir,
314 AOP(IC_RIGHT(ic))->aopu.aop_dir);
315 pic14_emitcode("xorlw","1");
316 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
317 AOP(IC_LEFT(ic))->aopu.aop_dir,
318 AOP(IC_LEFT(ic))->aopu.aop_dir);
319 pic14_emitcode("xorlw","1");
322 emitpcode(POC_MOVLW, popGetLit(0));
323 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
324 emitpcode(POC_XORLW, popGetLit(1));
325 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
326 emitpcode(POC_XORLW, popGetLit(1));
327 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
330 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
331 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
332 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
333 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
334 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
335 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
337 pic14_emitcode("movlw","(1 << (%s & 7))",
338 AOP(IC_RESULT(ic))->aopu.aop_dir,
339 AOP(IC_RESULT(ic))->aopu.aop_dir);
340 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
341 AOP(IC_RESULT(ic))->aopu.aop_dir,
342 AOP(IC_RESULT(ic))->aopu.aop_dir);
343 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
344 AOP(IC_RIGHT(ic))->aopu.aop_dir,
345 AOP(IC_RIGHT(ic))->aopu.aop_dir);
346 pic14_emitcode("xorwf","(%s >>3),f",
347 AOP(IC_RESULT(ic))->aopu.aop_dir);
348 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
349 AOP(IC_LEFT(ic))->aopu.aop_dir,
350 AOP(IC_LEFT(ic))->aopu.aop_dir);
351 pic14_emitcode("xorwf","(%s>>3),f",
352 AOP(IC_RESULT(ic))->aopu.aop_dir);
359 /* This is the original version of this code.
361 * This is being kept around for reference,
362 * because I am not entirely sure I got it right...
364 static void adjustArithmeticResult(iCode *ic)
366 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
367 AOP_SIZE(IC_LEFT(ic)) == 3 &&
368 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
369 aopPut(AOP(IC_RESULT(ic)),
370 aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
373 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
374 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
375 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
376 aopPut(AOP(IC_RESULT(ic)),
377 aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
380 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
381 AOP_SIZE(IC_LEFT(ic)) < 3 &&
382 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
383 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
384 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
386 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
387 aopPut(AOP(IC_RESULT(ic)),buffer,2);
391 /* This is the pure and virtuous version of this code.
392 * I'm pretty certain it's right, but not enough to toss the old
395 static void adjustArithmeticResult(iCode *ic)
397 if (opIsGptr(IC_RESULT(ic)) &&
398 opIsGptr(IC_LEFT(ic)) &&
399 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
401 aopPut(AOP(IC_RESULT(ic)),
402 aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
406 if (opIsGptr(IC_RESULT(ic)) &&
407 opIsGptr(IC_RIGHT(ic)) &&
408 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
410 aopPut(AOP(IC_RESULT(ic)),
411 aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
415 if (opIsGptr(IC_RESULT(ic)) &&
416 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
417 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
418 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
419 !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
421 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
422 aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
427 /*-----------------------------------------------------------------*/
428 /* genAddlit - generates code for addition */
429 /*-----------------------------------------------------------------*/
430 static void genAddLit2byte (operand *result, int offr, int lit)
437 emitpcode(POC_INCF, popGet(AOP(result),offr));
440 emitpcode(POC_DECF, popGet(AOP(result),offr));
443 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
444 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
449 static void emitMOVWF(operand *reg, int offset)
454 if (AOP_TYPE(reg) == AOP_ACC) {
455 DEBUGpic14_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
459 emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
463 static void genAddLit (iCode *ic, int lit)
472 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
476 result = IC_RESULT(ic);
477 same = pic14_sameRegs(AOP(left), AOP(result));
478 size = pic14_getDataSize(result);
482 /* Handle special cases first */
484 genAddLit2byte (result, 0, lit);
487 int hi = 0xff & (lit >> 8);
494 DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
499 emitpcode(POC_INCF, popGet(AOP(result),0));
501 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
504 emitpcode(POC_DECF, popGet(AOP(result),0));
505 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
506 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
510 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
511 emitpcode(POC_ADDWF,popGet(AOP(result),0));
513 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
521 DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
524 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
527 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
528 emitpcode(POC_INCF, popGet(AOP(result),0));
530 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
532 case 0xff: /* 0x01ff */
533 emitpcode(POC_DECF, popGet(AOP(result),0));
534 emitpcode(POC_INCFSZW, popGet(AOP(result),0));
535 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
536 emitpcode(POC_INCF, popGet(AOP(result),MSB16));
541 DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
545 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
548 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
549 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
551 /* case 0xff: * 0xffff *
552 emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
553 emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
554 emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
558 emitpcode(POC_MOVLW,popGetLit(lo));
559 emitpcode(POC_ADDWF,popGet(AOP(result),0));
561 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
568 DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
573 genAddLit2byte (result, MSB16, hi);
576 emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
577 emitpcode(POC_INCFSZ, popGet(AOP(result),0));
578 emitpcode(POC_MOVLW,popGetLit(hi));
579 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
581 /* case 0xff: * 0xHHff *
582 emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
583 emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
584 emitpcode(POC_MOVLW,popGetLit(hi));
585 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
587 */ default: /* 0xHHLL */
588 emitpcode(POC_MOVLW,popGetLit(lo));
589 emitpcode(POC_ADDWF, popGet(AOP(result),0));
590 emitpcode(POC_MOVLW,popGetLit(hi));
592 emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
593 emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
602 DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
605 lo = BYTEofLONG(lit,0);
613 emitpcode(POC_INCF, popGet(AOP(result),offset));
616 emitpcode(POC_RLFW, popGet(AOP(result),offset));
617 emitpcode(POC_ANDLW,popGetLit(1));
618 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
620 default: /* carry_info = 3 */
622 emitpcode(POC_INCF, popGet(AOP(result),offset));
628 emitpcode(POC_MOVLW,popGetLit(lo));
633 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
636 emitpcode(POC_MOVLW,popGetLit(lo));
641 emitpcode(POC_MOVLW,popGetLit(lo+1));
642 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
647 /* no carry info from previous step */
648 /* this means this is the first time to add */
653 emitpcode(POC_INCF, popGet(AOP(result),offset));
657 emitpcode(POC_MOVLW,popGetLit(lo));
658 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
660 carry_info = 3; /* Were adding only one byte and propogating the carry */
671 lo = BYTEofLONG(lit,0);
676 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
679 emitpcode(POC_MOVLW,popGetLit(lo));
680 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
683 emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
685 emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
687 emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
697 DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
701 if(AOP_TYPE(left) == AOP_ACC) {
702 /* left addend is already in accumulator */
705 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
709 emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
710 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
714 /* left addend is in a register */
717 emitpcode(POC_MOVFW, popGet(AOP(left),0));
718 emitMOVWF(result, 0);
719 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
723 emitpcode(POC_INCFW, popGet(AOP(left),0));
724 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
728 emitpcode(POC_DECFW, popGet(AOP(left),0));
729 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
733 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
734 emitpcode(POC_ADDFW, popGet(AOP(left),0));
735 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
743 /* left is not the accumulator */
745 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
746 emitpcode(POC_ADDFW, popGet(AOP(left),0));
748 emitpcode(POC_MOVFW, popGet(AOP(left),0));
749 /* We don't know the state of the carry bit at this point */
752 //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
759 /* The ls byte of the lit must've been zero - that
760 means we don't have to deal with carry */
762 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
763 emitpcode(POC_ADDFW, popGet(AOP(left),offset));
764 emitpcode(POC_MOVWF, popGet(AOP(left),offset));
769 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
770 //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
771 emitMOVWF(result,offset);
772 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
774 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
775 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
779 emitpcode(POC_CLRF, popGet(AOP(result),offset));
780 emitpcode(POC_RLF, popGet(AOP(result),offset));
781 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
782 emitpcode(POC_ADDWF, popGet(AOP(result),offset));
790 /*-----------------------------------------------------------------*/
791 /* genPlus - generates code for addition */
792 /*-----------------------------------------------------------------*/
793 void genPlus (iCode *ic)
795 int size, offset = 0;
797 /* special cases :- */
798 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
800 aopOp (IC_LEFT(ic),ic,FALSE);
801 aopOp (IC_RIGHT(ic),ic,FALSE);
802 aopOp (IC_RESULT(ic),ic,TRUE);
804 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
806 /* if literal, literal on the right or
807 if left requires ACC or right is already
810 if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
811 operand *t = IC_RIGHT(ic);
812 IC_RIGHT(ic) = IC_LEFT(ic);
816 /* if both left & right are in bit space */
817 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
818 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
823 /* if left in bit space & right literal */
824 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
825 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
826 /* if result in bit space */
827 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
828 if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
829 emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
830 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
831 emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
832 emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
835 size = pic14_getDataSize(IC_RESULT(ic));
837 MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
838 pic14_emitcode("addc","a,#00 ;%d",__LINE__);
839 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
845 /* if I can do an increment instead
846 of add then GOOD for ME */
847 if (genPlusIncr (ic) == TRUE)
850 size = pic14_getDataSize(IC_RESULT(ic));
852 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
853 /* Add a literal to something else */
855 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
859 DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
864 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
866 pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
867 pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
868 pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
870 /* here we are adding a bit to a char or int */
872 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
874 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
875 emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
877 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
878 AOP(IC_RIGHT(ic))->aopu.aop_dir,
879 AOP(IC_RIGHT(ic))->aopu.aop_dir);
880 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
883 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
884 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
885 emitpcode(POC_XORLW , popGetLit(1));
887 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
888 AOP(IC_RIGHT(ic))->aopu.aop_dir,
889 AOP(IC_RIGHT(ic))->aopu.aop_dir);
890 pic14_emitcode(" xorlw","1");
892 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
893 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
894 emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
896 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
897 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
898 AOP(IC_RIGHT(ic))->aopu.aop_dir,
899 AOP(IC_RIGHT(ic))->aopu.aop_dir);
900 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
903 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
905 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
906 emitpcode(POC_ANDLW , popGetLit(1));
907 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
909 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
911 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
912 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
919 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
920 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
922 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
923 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
925 pic14_emitcode("clrz","");
927 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
928 AOP(IC_RIGHT(ic))->aopu.aop_dir,
929 AOP(IC_RIGHT(ic))->aopu.aop_dir);
930 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
934 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
935 emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
936 emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
937 //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
938 emitMOVWF(IC_RIGHT(ic),0);
940 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
941 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
942 AOP(IC_RIGHT(ic))->aopu.aop_dir,
943 AOP(IC_RIGHT(ic))->aopu.aop_dir);
944 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
945 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
951 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
952 //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
958 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
960 /* Add the first bytes */
962 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
963 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
964 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
967 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
968 emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
969 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
970 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
973 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
975 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
976 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
978 PIC_OPCODE poc = POC_ADDFW;
980 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
981 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) ||
982 (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
984 emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0));
985 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
986 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
991 size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
996 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
997 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
998 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1000 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
1001 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1004 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1006 emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
1007 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
1010 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1012 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
1013 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE));
1021 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1022 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1023 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1026 /* Need to extend result to higher bytes */
1027 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1029 /* First grab the carry from the lower bytes */
1030 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1031 emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
1035 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1038 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
1039 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1040 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
1041 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1043 /* if chars or ints or being signed extended to longs: */
1045 emitpcode(POC_MOVLW, popGetLit(0));
1046 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
1047 emitpcode(POC_MOVLW, popGetLit(0xff));
1055 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1057 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1064 //adjustArithmeticResult(ic);
1067 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1068 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1069 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1072 /*-----------------------------------------------------------------*/
1073 /* genMinusDec :- does subtraction with decrement if possible */
1074 /*-----------------------------------------------------------------*/
1075 bool genMinusDec (iCode *ic)
1077 unsigned int icount ;
1078 unsigned int size = pic14_getDataSize(IC_RESULT(ic));
1080 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1081 /* will try to generate an increment */
1082 /* if the right side is not a literal
1084 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1085 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1086 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1089 DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1091 /* if the literal value of the right hand side
1092 is greater than 4 then it is not worth it */
1093 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1096 /* if decrement 16 bits in register */
1097 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1102 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
1103 emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
1104 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
1105 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
1107 pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1108 pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1109 pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1111 /* size is 3 or 4 */
1112 emitpcode(POC_MOVLW, popGetLit(0xff));
1113 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
1115 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
1117 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
1119 pic14_emitcode("movlw","0xff");
1120 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1123 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1125 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1129 emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
1131 pic14_emitcode("skpnc","");
1133 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1142 /* if the sizes are greater than 1 then we cannot */
1143 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1144 AOP_SIZE(IC_LEFT(ic)) > 1 )
1147 /* we can if the aops of the left & result match or
1148 if they are in registers and the registers are the
1150 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1153 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
1155 //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1160 DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
1161 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1162 aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1165 pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1166 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1168 emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
1169 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1177 /*-----------------------------------------------------------------*/
1178 /* addSign - propogate sign bit to higher bytes */
1179 /*-----------------------------------------------------------------*/
1180 void addSign(operand *result, int offset, int sign)
1182 int size = (pic14_getDataSize(result) - offset);
1183 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1186 if(sign && offset) {
1189 emitpcode(POC_CLRF,popGet(AOP(result),offset));
1190 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1191 emitpcode(POC_DECF, popGet(AOP(result),offset));
1194 emitpcode(POC_MOVLW, popGetLit(0));
1195 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
1196 emitpcode(POC_MOVLW, popGetLit(0xff));
1198 emitpcode(POC_MOVWF, popGet(AOP(result),size));
1203 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1207 /*-----------------------------------------------------------------*/
1208 /* genMinusBits - generates code for subtraction of two bits */
1209 /*-----------------------------------------------------------------*/
1210 void genMinusBits (iCode *ic)
1212 symbol *lbl = newiTempLabel(NULL);
1213 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1214 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1215 pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1216 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1217 pic14_emitcode("cpl","c");
1218 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1219 pic14_outBitC(IC_RESULT(ic));
1222 pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1223 pic14_emitcode("subb","a,acc");
1224 pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1225 pic14_emitcode("inc","a");
1226 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
1227 aopPut(AOP(IC_RESULT(ic)),"a",0);
1228 addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1232 /*-----------------------------------------------------------------*/
1233 /* genMinus - generates code for subtraction */
1234 /*-----------------------------------------------------------------*/
1235 void genMinus (iCode *ic)
1237 int size, offset = 0, same=0;
1238 unsigned long lit = 0L;
1240 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1241 aopOp (IC_LEFT(ic),ic,FALSE);
1242 aopOp (IC_RIGHT(ic),ic,FALSE);
1243 aopOp (IC_RESULT(ic),ic,TRUE);
1245 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1246 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1247 operand *t = IC_RIGHT(ic);
1248 IC_RIGHT(ic) = IC_LEFT(ic);
1252 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
1253 AopType(AOP_TYPE(IC_RESULT(ic))),
1254 AopType(AOP_TYPE(IC_LEFT(ic))),
1255 AopType(AOP_TYPE(IC_RIGHT(ic))));
1257 /* special cases :- */
1258 /* if both left & right are in bit space */
1259 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1260 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1265 /* if I can do an decrement instead
1266 of subtract then GOOD for ME */
1267 // if (genMinusDec (ic) == TRUE)
1270 size = pic14_getDataSize(IC_RESULT(ic));
1271 same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1273 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1274 /* Add a literal to something else */
1276 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1279 genAddLit ( ic, lit);
1282 /* add the first byte: */
1283 pic14_emitcode("movlw","0x%x", lit & 0xff);
1284 pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1285 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1286 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
1298 if((lit & 0xff) == 0xff) {
1299 emitpcode(POC_MOVLW, popGetLit(0xff));
1301 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1303 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1305 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
1306 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1310 /* do the rlf known zero trick here */
1311 emitpcode(POC_MOVLW, popGetLit(1));
1313 emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
1318 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1321 pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1322 pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1323 pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1325 /* here we are subtracting a bit from a char or int */
1327 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1329 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1330 emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
1332 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
1333 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1334 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1335 pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1338 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1339 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1340 emitpcode(POC_XORLW , popGetLit(1));
1341 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1342 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1344 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1346 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1347 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1349 emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
1350 emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
1353 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1355 emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
1357 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1358 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1362 emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
1363 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1364 emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
1365 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1370 emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
1371 emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
1372 emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
1375 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1377 emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
1380 emitpcode(POC_ANDLW , popGetLit(1));
1382 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1384 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1391 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1392 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1393 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1395 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1396 DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1397 AopType(AOP_TYPE(IC_RESULT(ic))),
1398 AopType(AOP_TYPE(IC_LEFT(ic))),
1399 AopType(AOP_TYPE(IC_RIGHT(ic))));
1402 if( (size == 1) && ((lit & 0xff) == 0) ) {
1403 /* res = 0 - right */
1404 if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1405 emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
1406 emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
1408 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
1409 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
1410 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1415 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
1416 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1417 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1425 /* This is the last byte in a multibyte subtraction
1426 * There are a couple of tricks we can do by not worrying about
1427 * propogating the carry */
1429 /* 0xff - x == ~x */
1431 emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
1433 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1435 emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
1436 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1438 emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
1441 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1443 emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
1444 emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
1445 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1454 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1456 emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
1457 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1460 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1466 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
1467 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1469 emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
1471 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1473 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1474 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1481 DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1482 AopType(AOP_TYPE(IC_RESULT(ic))),
1483 AopType(AOP_TYPE(IC_LEFT(ic))),
1484 AopType(AOP_TYPE(IC_RIGHT(ic))));
1486 if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
1487 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1488 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1489 emitpcode(POC_SUBLW, popGetLit(0));
1490 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1493 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1494 emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
1495 emitpcode(POC_SUBLW, popGetLit(0));
1496 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1497 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1500 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1501 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1502 emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
1504 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1505 emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
1507 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1508 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1509 emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
1511 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
1513 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1514 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1515 emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
1517 emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
1519 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1526 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1528 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1529 emitpcode(POC_SUBFW, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1531 emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1532 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1539 if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1540 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
1541 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
1543 emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
1545 emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
1546 emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
1554 // adjustArithmeticResult(ic);
1557 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1558 freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1559 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1561 /*-----------------------------------------------------------------*
1562 * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
1565 *-----------------------------------------------------------------*/
1566 void genUMult8XLit_16 (operand *left,
1569 pCodeOpReg *result_hi)
1574 unsigned int i,have_first_bit;
1578 if (AOP_TYPE(right) != AOP_LIT){
1579 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1585 result_hi = PCOR(popGet(AOP(result),1));
1588 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1590 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1592 same = pic14_sameRegs(AOP(left), AOP(result));
1597 emitpcode(POC_CLRF, popGet(AOP(left),0));
1600 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1601 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1604 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1605 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1606 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1609 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1610 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1611 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1612 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1615 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1616 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1617 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1618 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1621 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1622 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1623 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1624 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1625 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1628 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1629 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1630 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1631 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1632 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F
1635 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1636 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1637 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1638 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1639 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1642 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1643 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1644 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1645 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1646 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1647 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1650 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1651 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1652 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1653 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
1654 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1655 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1658 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1659 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1660 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1661 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1662 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1663 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F
1666 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1667 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1668 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1669 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1670 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1671 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1672 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1675 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1676 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1677 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1678 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1679 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
1680 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*F
1683 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1684 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
1685 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
1686 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
1687 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
1688 emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F
1689 emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F
1692 temp = popGetTempReg();
1694 fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
1697 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1698 emitpcode(POC_MOVWF, temp);
1699 emitpcode(POC_ANDLW, popGetLit(0xf0));
1700 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1701 emitpcode(POC_SWAPFW, temp);
1702 emitpcode(POC_SUBWF, popGet(AOP(left),0));
1703 popReleaseTempReg(temp);
1706 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1707 emitpcode(POC_ANDLW, popGetLit(0xf0));
1708 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1711 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
1712 emitpcode(POC_ANDLW, popGetLit(0xf0));
1713 emitpcode(POC_ADDWF, popGet(AOP(left),0));
1716 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1717 emitpcode(POC_RLFW, popGet(AOP(left),0));
1718 emitpcode(POC_ANDLW, popGetLit(0xe0));
1719 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1722 emitpcode(POC_SWAPF, popGet(AOP(left),0));
1723 emitpcode(POC_RLF, popGet(AOP(left),0));
1724 emitpcode(POC_RLFW, popGet(AOP(left),0));
1725 emitpcode(POC_ANDLW, popGetLit(0xc0));
1726 emitpcode(POC_MOVWF, popGet(AOP(left),0));
1729 emitpcode(POC_RRFW, popGet(AOP(left),0));
1730 emitpcode(POC_CLRF, popGet(AOP(left),0));
1731 emitpcode(POC_RRF, popGet(AOP(left),0));
1739 emitpcode(POC_CLRF, popGet(AOP(result),0));
1740 emitpcode(POC_CLRF, popCopyReg(result_hi));
1743 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1744 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1745 emitpcode(POC_ADDWF, popGet(AOP(result),0));
1746 emitpcode(POC_CLRF, popCopyReg(result_hi));
1747 emitpcode(POC_RLF, popCopyReg(result_hi));
1753 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1754 emitpcode(POC_CLRF, popGet(AOP(result),0));
1755 emitpcode(POC_CLRF, popCopyReg(result_hi));
1758 for(i=0; i<8; i++) {
1761 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1765 if(have_first_bit) {
1766 emitpcode(POC_RRF, popCopyReg(result_hi));
1767 emitpcode(POC_RRF, popGet(AOP(result),0));
1775 /*-----------------------------------------------------------------*
1776 * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
1779 *-----------------------------------------------------------------*/
1780 void genUMult8X8_16 (operand *left,
1783 pCodeOpReg *result_hi)
1791 result_hi = PCOR(popGet(AOP(result),1));
1794 if (AOP_TYPE(right) == AOP_LIT) {
1795 genUMult8XLit_16(left,right,result,result_hi);
1800 pic14_emitcode(";","Unrolled 8 X 8 multiplication");
1802 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1803 emitpcode(POC_CLRF, popGet(AOP(result),0));
1804 emitpcode(POC_CLRF, popCopyReg(result_hi));
1807 for(i=0; i<8; i++) {
1808 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
1809 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1810 emitpcode(POC_RRF, popCopyReg(result_hi));
1811 emitpcode(POC_RRF, popGet(AOP(result),0));
1816 Here's another version that does the same thing and takes the
1817 same number of instructions. The one above is slightly better
1818 because the entry instructions have a higher probability of
1819 being optimized out.
1822 emitpcode(POC_CLRF, popCopyReg(result_hi));
1823 emitpcode(POC_RRFW, popGet(AOP(left),0));
1824 emitpcode(POC_MOVWF, popGet(AOP(result),0));
1825 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1827 for(i=0; i<8; i++) {
1829 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1830 emitpcode(POC_RRF, popCopyReg(result_hi));
1831 emitpcode(POC_RRF, popGet(AOP(result),0));
1836 symbol *tlbl = newiTempLabel(NULL);
1840 pic14_emitcode(";","Looped 8 X 8 multiplication");
1842 emitpcode(POC_CLRF, popGet(AOP(result),0));
1843 emitpcode(POC_CLRF, popCopyReg(result_hi));
1845 emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
1847 emitpcode(POC_MOVFW, popGet(AOP(right),0));
1849 temp = popGetTempReg();
1850 emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
1852 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1854 emitpLabel(tlbl->key);
1856 emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
1858 emitpcode(POC_ADDWF, popCopyReg(result_hi));
1860 emitpcode(POC_RRF, popCopyReg(result_hi));
1861 emitpcode(POC_RRF, popGet(AOP(result),0));
1864 emitpcode(POC_GOTO, popGetLabel(tlbl->key));
1866 popReleaseTempReg(temp);
1871 /*-----------------------------------------------------------------*
1872 * genSMult8X8_16 - signed multiplication of two 8-bit numbers
1874 * this routine will call the unsigned multiply routine and then
1875 * post-fix the sign bit.
1876 *-----------------------------------------------------------------*/
1877 void genSMult8X8_16 (operand *left,
1880 pCodeOpReg *result_hi)
1884 result_hi = PCOR(popGet(AOP(result),1));
1887 genUMult8X8_16(left,right,result,result_hi);
1889 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
1890 emitpcode(POC_SUBWF, popCopyReg(result_hi));
1891 emitpcode(POC_MOVFW, popGet(AOP(left),0));
1892 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
1893 emitpcode(POC_SUBWF, popGet(AOP(result),1));
1897 /*-----------------------------------------------------------------*
1898 * genMult8X8_8 - multiplication of two 8-bit numbers
1900 * this routine will call the unsigned multiply 8X8=>16 routine and
1901 * then throw away the high byte of the result.
1903 *-----------------------------------------------------------------*/
1904 void genMult8X8_8 (operand *left,
1908 pCodeOp *result_hi = popGetTempReg();
1910 if (AOP_TYPE(right) == AOP_LIT)
1911 genUMult8XLit_16(left,right,result,PCOR(result_hi));
1913 genUMult8X8_16(left,right,result,PCOR(result_hi));
1915 popReleaseTempReg(result_hi);
1918 /*-----------------------------------------------------------------*/
1919 /* constMult - generates code for multiplication by a constant */
1920 /*-----------------------------------------------------------------*/
1921 void genMultConst(unsigned C)
1925 unsigned sr3; // Shift right 3
1931 Convert a string of 3 binary 1's in the lit into
1935 mask = 7 << ( (size*8) - 3);
1939 while(mask < (1<<size*8)) {
1941 if( (mask & lit) == lit) {
1944 /* We found 3 (or more) consecutive 1's */
1946 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
1948 consecutive_bits = ((lit + lsb) & lit) ^ lit;
1950 lit ^= consecutive_bits;
1954 sr3 |= (consecutive + lsb);