1 /*-------------------------------------------------------------------------
3 genarith.c - source file for code generation - arithmetic
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 and - Jean-Louis VERN.jlvern@writeme.com (1999)
7 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
8 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2, or (at your option) any
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 In other words, you are welcome to use, share and improve this program.
26 You are forbidden to forbid anyone else to use, share and improve
27 what you give them. Help stamp out software-hoarding!
30 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
31 Made everything static
32 -------------------------------------------------------------------------*/
38 #include "SDCCglobl.h"
41 #if defined(_MSC_VER) && (_MSC_VER < 1300)
42 #define __FUNCTION__ __FILE__
46 #include "SDCCpeeph.h"
52 #define pic16_emitcode DEBUGpic16_emitcode
55 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
56 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
57 void pic16_emitpcomment(char *, ...);
58 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst);
59 const char *pic16_AopType(short type)
62 case AOP_LIT: return "AOP_LIT";
63 case AOP_REG: return "AOP_REG";
64 case AOP_DIR: return "AOP_DIR";
65 case AOP_DPTR: return "AOP_DPTR";
66 case AOP_DPTR2: return "AOP_DPTR2";
67 case AOP_FSR0: return "AOP_FSR0";
68 case AOP_FSR2: return "AOP_FSR2";
69 case AOP_R0: return "AOP_R0";
70 case AOP_R1: return "AOP_R1";
71 case AOP_STK: return "AOP_STK";
72 case AOP_IMMD: return "AOP_IMMD";
73 case AOP_STR: return "AOP_STR";
74 case AOP_CRY: return "AOP_CRY";
75 case AOP_ACC: return "AOP_ACC";
76 case AOP_PCODE: return "AOP_PCODE";
77 case AOP_STA: return "AOP_STA";
83 const char *pic16_pCodeOpType(pCodeOp *pcop)
90 case PO_NONE: return "PO_NONE";
91 case PO_W: return "PO_W";
92 case PO_WREG: return "PO_WREG";
93 case PO_STATUS: return "PO_STATUS";
94 case PO_BSR: return "PO_BSR";
95 case PO_FSR0: return "PO_FSR0";
96 case PO_INDF0: return "PO_INDF0";
97 case PO_INTCON: return "PO_INTCON";
98 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
99 case PO_GPR_BIT: return "PO_GPR_BIT";
100 case PO_GPR_TEMP: return "PO_GPR_TEMP";
101 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
102 case PO_PCL: return "PO_PCL";
103 case PO_PCLATH: return "PO_PCLATH";
104 case PO_PCLATU: return "PO_PCLATU";
105 case PO_PRODL: return "PO_PRODL";
106 case PO_PRODH: return "PO_PRODH";
107 case PO_LITERAL: return "PO_LITERAL";
108 case PO_REL_ADDR: return "PO_REL_ADDR";
109 case PO_IMMEDIATE: return "PO_IMMEDIATE";
110 case PO_DIR: return "PO_DIR";
111 case PO_CRY: return "PO_CRY";
112 case PO_BIT: return "PO_BIT";
113 case PO_STR: return "PO_STR";
114 case PO_LABEL: return "PO_LABEL";
115 case PO_WILD: return "PO_WILD";
119 return "BAD PO_TYPE";
122 const char *pic16_pCodeOpSubType(pCodeOp *pcop)
125 if(pcop && (pcop->type == PO_GPR_BIT)) {
127 switch(PCORB(pcop)->subtype) {
129 case PO_NONE: return "PO_NONE";
130 case PO_W: return "PO_W";
131 case PO_WREG: return "PO_WREG";
132 case PO_STATUS: return "PO_STATUS";
133 case PO_BSR: return "PO_BSR";
134 case PO_FSR0: return "PO_FSR0";
135 case PO_INDF0: return "PO_INDF0";
136 case PO_INTCON: return "PO_INTCON";
137 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
138 case PO_GPR_BIT: return "PO_GPR_BIT";
139 case PO_GPR_TEMP: return "PO_GPR_TEMP";
140 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
141 case PO_PCL: return "PO_PCL";
142 case PO_PCLATH: return "PO_PCLATH";
143 case PO_PCLATU: return "PO_PCLATU";
144 case PO_PRODL: return "PO_PRODL";
145 case PO_PRODH: return "PO_PRODH";
146 case PO_LITERAL: return "PO_LITERAL";
147 case PO_REL_ADDR: return "PO_REL_ADDR";
148 case PO_IMMEDIATE: return "PO_IMMEDIATE";
149 case PO_DIR: return "PO_DIR";
150 case PO_CRY: return "PO_CRY";
151 case PO_BIT: return "PO_BIT";
152 case PO_STR: return "PO_STR";
153 case PO_LABEL: return "PO_LABEL";
154 case PO_WILD: return "PO_WILD";
158 return "BAD PO_TYPE";
161 /*-----------------------------------------------------------------*/
162 /* pic16_genPlusIncr :- does addition with increment if possible */
163 /*-----------------------------------------------------------------*/
164 bool pic16_genPlusIncr (iCode *ic)
166 unsigned int icount ;
167 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
171 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
172 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
173 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
174 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
176 /* will try to generate an increment */
177 /* if the right side is not a literal
179 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
182 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
183 /* if the literal value of the right hand side
184 is greater than 2 then it is faster to add */
185 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
188 /* if increment 16 bits in register */
189 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
194 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
195 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
199 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
200 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
206 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
207 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
208 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
209 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
211 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
212 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
213 AOP(IC_RESULT(ic))->aopu.aop_dir,
214 AOP(IC_RESULT(ic))->aopu.aop_dir);
216 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
217 //pic16_emitcode("xorlw","1");
219 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
220 //pic16_emitcode("andlw","1");
223 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
224 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
225 AOP(IC_RESULT(ic))->aopu.aop_dir,
226 AOP(IC_RESULT(ic))->aopu.aop_dir);
232 /* if the sizes are greater than 1 then we cannot */
233 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
234 AOP_SIZE(IC_LEFT(ic)) > 1 )
237 /* If we are incrementing the same register by two: */
239 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
242 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
243 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
248 DEBUGpic16_emitcode ("; ","couldn't increment ");
253 /*-----------------------------------------------------------------*/
254 /* pic16_outBitAcc - output a bit in acc */
255 /*-----------------------------------------------------------------*/
256 void pic16_outBitAcc(operand *result)
258 symbol *tlbl = newiTempLabel(NULL);
259 /* if the result is a bit */
260 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
262 assert(0); // not implemented for PIC16?
264 if (AOP_TYPE(result) == AOP_CRY){
265 pic16_aopPut(AOP(result),"a",0);
268 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
269 pic16_emitcode("mov","a,#01");
270 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
271 pic16_outAcc(result);
275 /*-----------------------------------------------------------------*/
276 /* pic16_genPlusBits - generates code for addition of two bits */
277 /*-----------------------------------------------------------------*/
278 void pic16_genPlusBits (iCode *ic)
282 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
283 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
284 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
285 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
287 The following block of code will add two bits.
288 Note that it'll even work if the destination is
289 the carry (C in the status register).
290 It won't work if the 'Z' bit is a source or destination.
293 /* If the result is stored in the accumulator (w) */
294 //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
295 switch(AOP_TYPE(IC_RESULT(ic))) {
297 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
298 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
299 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
300 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
301 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
303 pic16_emitcode("clrw","");
304 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
305 AOP(IC_RIGHT(ic))->aopu.aop_dir,
306 AOP(IC_RIGHT(ic))->aopu.aop_dir);
307 pic16_emitcode("xorlw","1");
308 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
309 AOP(IC_LEFT(ic))->aopu.aop_dir,
310 AOP(IC_LEFT(ic))->aopu.aop_dir);
311 pic16_emitcode("xorlw","1");
314 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
315 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
316 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
317 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
318 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
319 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
322 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
323 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
324 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
325 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
326 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
327 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
329 pic16_emitcode("movlw","(1 << (%s & 7))",
330 AOP(IC_RESULT(ic))->aopu.aop_dir,
331 AOP(IC_RESULT(ic))->aopu.aop_dir);
332 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
333 AOP(IC_RESULT(ic))->aopu.aop_dir,
334 AOP(IC_RESULT(ic))->aopu.aop_dir);
335 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
336 AOP(IC_RIGHT(ic))->aopu.aop_dir,
337 AOP(IC_RIGHT(ic))->aopu.aop_dir);
338 pic16_emitcode("xorwf","(%s >>3),f",
339 AOP(IC_RESULT(ic))->aopu.aop_dir);
340 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
341 AOP(IC_LEFT(ic))->aopu.aop_dir,
342 AOP(IC_LEFT(ic))->aopu.aop_dir);
343 pic16_emitcode("xorwf","(%s>>3),f",
344 AOP(IC_RESULT(ic))->aopu.aop_dir);
351 /* This is the original version of this code.
353 * This is being kept around for reference,
354 * because I am not entirely sure I got it right...
356 static void adjustArithmeticResult(iCode *ic)
358 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
359 AOP_SIZE(IC_LEFT(ic)) == 3 &&
360 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
361 pic16_aopPut(AOP(IC_RESULT(ic)),
362 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
365 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
366 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
367 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
368 pic16_aopPut(AOP(IC_RESULT(ic)),
369 pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
372 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
373 AOP_SIZE(IC_LEFT(ic)) < 3 &&
374 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
375 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
376 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
378 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
379 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
383 /* This is the pure and virtuous version of this code.
384 * I'm pretty certain it's right, but not enough to toss the old
387 static void adjustArithmeticResult(iCode *ic)
389 if (opIsGptr(IC_RESULT(ic)) &&
390 opIsGptr(IC_LEFT(ic)) &&
391 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
393 pic16_aopPut(AOP(IC_RESULT(ic)),
394 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
398 if (opIsGptr(IC_RESULT(ic)) &&
399 opIsGptr(IC_RIGHT(ic)) &&
400 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
402 pic16_aopPut(AOP(IC_RESULT(ic)),
403 pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
407 if (opIsGptr(IC_RESULT(ic)) &&
408 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
409 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
410 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
411 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
413 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
414 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
420 /*-----------------------------------------------------------------*/
421 /* genAddlit - generates code for addition */
422 /*-----------------------------------------------------------------*/
423 static void genAddLit2byte (operand *result, int offr, int lit)
431 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
434 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
437 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
438 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
444 static void emitMOVWF(operand *reg, int offset)
449 if (AOP_TYPE(reg) == AOP_ACC) {
450 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
454 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
458 static void genAddLit (iCode *ic, int lit)
472 lleft = operandType (left);
473 result = IC_RESULT(ic);
474 same = pic16_sameRegs(AOP(left), AOP(result));
475 size = pic16_getDataSize(result);
476 sizeL = pic16_getDataSize(left);
479 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
480 /* move left to result -- possibly sign extend */
481 for (i=0; i < MIN(size, sizeL); i++) {
482 pic16_mov2f (AOP(result), AOP(left), i);
486 /* extend to result size */
487 if (IS_UNSIGNED(lleft)) {
489 for (i = sizeL; i < size; i++) {
490 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
494 if (size == sizeL + 1) {
495 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), sizeL));
496 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
497 pic16_emitpcode (POC_SETF, pic16_popGet (AOP(result), sizeL));
499 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
500 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
501 pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
503 for (i=sizeL; i < size; i++) {
504 pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(result), i));
512 } else if (lit == 1) {
518 pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(result), 0));
522 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), 0));
523 for (i=1; i < size-1; i++) {
524 emitSKPNC; /* a jump here saves up to 2(size-2)cycles */
525 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), i));
531 pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1));
535 /* add literal to result */
536 for (i=0; i < size; i++) {
537 pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit));
538 llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */
539 pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC,
540 pic16_popGet (AOP(result), i));
548 /* Handle special cases first */
550 genAddLit2byte (result, 0, lit);
553 int hi = 0xff & (lit >> 8);
560 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
565 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
567 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
570 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
571 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
572 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
576 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
577 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
579 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
587 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
590 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
593 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
594 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
596 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
598 case 0xff: /* 0x01ff */
599 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
600 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
601 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
602 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
604 default: /* 0x01LL */
605 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
606 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
608 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
609 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
614 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
618 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
621 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
622 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
624 /* case 0xff: * 0xffff *
625 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
626 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
627 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
631 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
632 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
634 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
641 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
646 genAddLit2byte (result, MSB16, hi);
649 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
650 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
651 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
653 /* case 0xff: * 0xHHff *
654 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
655 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
656 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
657 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
659 */ default: /* 0xHHLL */
660 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
661 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
662 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
663 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
672 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
675 lo = BYTEofLONG(lit,0);
678 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
679 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
681 /* no carry info from previous step */
682 /* this means this is the first time to add */
687 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
691 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
692 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
694 carry_info = 3; /* Were adding only one byte and propogating the carry */
705 lo = BYTEofLONG(lit,0);
710 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
713 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
714 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
717 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
719 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
721 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
731 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
735 if(AOP_TYPE(left) == AOP_ACC) {
736 /* left addend is already in accumulator */
739 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
743 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
744 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
748 /* left addend is in a register */
751 pic16_mov2w(AOP(left),0);
752 emitMOVWF(result, 0);
755 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
756 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
760 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
761 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
765 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
766 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
767 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
775 /* left is not the accumulator */
777 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
778 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
780 pic16_mov2w(AOP(left),0);
781 /* We don't know the state of the carry bit at this point */
784 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
791 /* The ls byte of the lit must've been zero - that
792 means we don't have to deal with carry */
794 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
795 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
796 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
801 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
802 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
803 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
807 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
808 pic16_mov2w(AOP(left),offset);
809 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
818 /*-----------------------------------------------------------------*/
819 /* pic16_genPlus - generates code for addition */
820 /*-----------------------------------------------------------------*/
821 void pic16_genPlus (iCode *ic)
823 int i, size, offset = 0;
824 operand *result, *left, *right;
828 /* special cases :- */
829 result = IC_RESULT(ic);
831 right = IC_RIGHT(ic);
832 pic16_aopOp (left,ic,FALSE);
833 pic16_aopOp (right,ic,FALSE);
834 pic16_aopOp (result,ic,TRUE);
835 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
836 // pic16_DumpOp("(left)",left);
838 /* if literal, literal on the right or
839 if left requires ACC or right is already
842 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
844 right = IC_RIGHT(ic) = left;
845 left = IC_LEFT(ic) = t;
848 /* if both left & right are in bit space */
849 if (AOP_TYPE(left) == AOP_CRY &&
850 AOP_TYPE(right) == AOP_CRY) {
851 pic16_genPlusBits (ic);
855 /* if left in bit space & right literal */
856 if (AOP_TYPE(left) == AOP_CRY &&
857 AOP_TYPE(right) == AOP_LIT) {
858 /* if result in bit space */
859 if(AOP_TYPE(result) == AOP_CRY){
860 if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
861 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
862 if (!pic16_sameRegs(AOP(left), AOP(result)) )
863 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
864 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
867 unsigned long lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
868 size = pic16_getDataSize(result);
870 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
871 pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
872 pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
873 //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
874 //pic16_emitcode("addc","a,#00 ;%d",__LINE__);
875 //pic16_aopPut(AOP(result),"a",offset++);
881 /* if I can do an increment instead
882 of add then GOOD for ME */
883 if (pic16_genPlusIncr (ic) == TRUE)
886 size = pic16_getDataSize(result);
888 if(AOP(right)->type == AOP_LIT) {
889 /* Add a literal to something else */
891 unsigned lit = (unsigned) floatFromVal(AOP(right)->aopu.aop_lit);
895 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
900 } else if(AOP_TYPE(right) == AOP_CRY) {
902 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
903 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
904 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
906 /* here we are adding a bit to a char or int */
908 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
910 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
911 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0));
913 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
914 AOP(right)->aopu.aop_dir,
915 AOP(right)->aopu.aop_dir);
916 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
919 if(AOP_TYPE(left) == AOP_ACC) {
920 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
921 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
923 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
924 AOP(right)->aopu.aop_dir,
925 AOP(right)->aopu.aop_dir);
926 pic16_emitcode(" xorlw","1");
928 pic16_mov2w(AOP(left),0);
929 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
930 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
932 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
933 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
934 AOP(right)->aopu.aop_dir,
935 AOP(right)->aopu.aop_dir);
936 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
939 if(AOP_TYPE(result) != AOP_ACC) {
941 if(AOP_TYPE(result) == AOP_CRY) {
942 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
943 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0));
945 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0));
947 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0));
948 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
955 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
956 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
958 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
959 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
961 pic16_emitcode("clrz","");
963 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
964 AOP(right)->aopu.aop_dir,
965 AOP(right)->aopu.aop_dir);
966 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
969 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
970 pic16_mov2w(AOP(left),0);
971 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
972 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
973 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
976 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
977 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
978 AOP(right)->aopu.aop_dir,
979 AOP(right)->aopu.aop_dir);
980 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
981 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
987 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++));
988 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE));
996 // Note: the following is an example of WISC code, eg.
997 // it's supposed to run on a Weird Instruction Set Computer :o)
999 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1001 if ( AOP_TYPE(left) == AOP_ACC) {
1002 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1003 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
1004 if ( AOP_TYPE(result) != AOP_ACC)
1005 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1006 goto release; // we're done, since WREG is 1 byte
1010 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1012 size = min( AOP_SIZE(result), AOP_SIZE(right) );
1013 size = min( size, AOP_SIZE(left) );
1016 if(pic16_debug_verbose) {
1017 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
1018 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
1019 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
1024 if ((AOP_TYPE(left) == AOP_PCODE) && (
1025 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
1026 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
1027 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
1029 // add to literal operand
1032 for(i=0; i<size; i++) {
1033 if (AOP_TYPE(right) == AOP_ACC) {
1034 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1036 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1037 if(i) { // add with carry
1038 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1039 } else { // add without
1040 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1043 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1046 DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
1048 // add leftover bytes
1049 if (SPEC_USIGN(getSpec(operandType(right)))) {
1050 // right is unsigned
1051 for(i=size; i< AOP_SIZE(result); i++) {
1052 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1053 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1054 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1058 // right is signed, oh dear ...
1059 for(i=size; i< AOP_SIZE(result); i++) {
1060 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1061 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1062 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
1063 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1064 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1074 for(i=0; i<size; i++) {
1075 if (AOP_TYPE(right) != AOP_ACC)
1076 pic16_mov2w(AOP(right),i);
1077 if (pic16_sameRegs(AOP(left), AOP(result)))
1079 if(i) { // add with carry
1080 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1081 } else { // add without
1082 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1084 } else { // not same
1085 if(i) { // add with carry
1086 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1087 } else { // add without
1088 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1090 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1094 // add leftover bytes
1095 // either left or right is too short
1096 for (i=size; i < AOP_SIZE(result); i++) {
1097 // get right operand into WREG
1098 if (i < AOP_SIZE(right)) {
1099 pic16_mov2w (AOP(right), i);
1101 // right is too short
1102 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1103 if (!SPEC_USIGN(getSpec(operandType(right)))) {
1104 // right operand is signed
1105 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1106 pic16_emitpcode(POC_COMF, pic16_popCopyReg (&pic16_pc_wreg));
1110 // get left+WREG+CARRY into result
1111 if (i < AOP_SIZE(left)) {
1112 if (pic16_sameRegs (AOP(left), AOP(result))) {
1113 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1115 pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
1116 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1119 // left is too short
1120 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
1121 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1122 // left operand is signed
1123 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1124 pic16_emitpcode(POC_COMF, pic16_popGet (AOP(result), i));
1126 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1132 // add leftover bytes
1133 if (SPEC_USIGN(getSpec(operandType(right)))) {
1134 // right is unsigned
1135 for(i=size; i< AOP_SIZE(result); i++) {
1136 if (pic16_sameRegs(AOP(left), AOP(result)))
1138 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1139 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1140 } else { // not same
1141 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1142 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1143 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1148 for(i=size; i< AOP_SIZE(result); i++) {
1149 if(size < AOP_SIZE(left)) {
1150 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1151 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1152 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1153 if (pic16_sameRegs(AOP(left), AOP(result)))
1155 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1156 } else { // not same
1157 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1158 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1161 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1162 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1173 // TODO: anything from here to before "release:" is probably obsolete and should be removed
1174 // when the regression tests are stable
1176 if (AOP_SIZE(result) > AOP_SIZE(right)) {
1177 int sign = !(SPEC_USIGN(getSpec(operandType(left))) |
1178 SPEC_USIGN(getSpec(operandType(right))) );
1181 /* Need to extend result to higher bytes */
1182 size = AOP_SIZE(result) - AOP_SIZE(right) - 1;
1184 /* First grab the carry from the lower bytes */
1185 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
1186 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset));
1190 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1193 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1194 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1195 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1196 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1198 /* if chars or ints or being signed extended to longs: */
1200 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1201 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1202 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1210 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1212 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
1219 //adjustArithmeticResult(ic);
1222 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1223 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1224 pic16_freeAsmop(result,NULL,ic,TRUE);
1227 /*-----------------------------------------------------------------*/
1228 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1229 /*-----------------------------------------------------------------*/
1230 bool pic16_genMinusDec (iCode *ic)
1232 unsigned int icount ;
1233 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1236 /* will try to generate an increment */
1237 /* if the right side is not a literal
1239 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1240 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1241 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1244 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1246 /* if the literal value of the right hand side
1247 is greater than 4 then it is not worth it */
1248 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1251 /* if decrement 16 bits in register */
1252 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1257 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1259 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1261 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1262 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1263 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1265 /* size is 3 or 4 */
1266 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1267 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1268 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1269 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1271 pic16_emitcode("movlw","0xff");
1272 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1275 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1277 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1280 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1282 pic16_emitcode("skpnc","");
1284 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1293 /* if the sizes are greater than 1 then we cannot */
1294 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1295 AOP_SIZE(IC_LEFT(ic)) > 1 )
1298 /* we can if the aops of the left & result match or
1299 if they are in registers and the registers are the
1301 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1304 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1306 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1311 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1312 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1313 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1316 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1317 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1319 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1320 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1328 /*-----------------------------------------------------------------*/
1329 /* pic16_addSign - propogate sign bit to higher bytes */
1330 /*-----------------------------------------------------------------*/
1331 void pic16_addSign(operand *result, int offset, int sign)
1333 int size = (pic16_getDataSize(result) - offset);
1334 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1337 if(sign && offset) {
1340 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1341 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1342 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1345 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1346 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1347 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1349 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1354 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1358 /*-----------------------------------------------------------------*/
1359 /* pic16_genMinusBits - generates code for subtraction of two bits */
1360 /*-----------------------------------------------------------------*/
1361 void pic16_genMinusBits (iCode *ic)
1363 symbol *lbl = newiTempLabel(NULL);
1366 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1367 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1368 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1369 pic16_emitcode("cpl","c");
1370 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1371 pic16_outBitC(IC_RESULT(ic));
1374 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1375 pic16_emitcode("subb","a,acc");
1376 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1377 pic16_emitcode("inc","a");
1378 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1379 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1380 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1384 /*-----------------------------------------------------------------*/
1385 /* pic16_genMinus - generates code for subtraction */
1386 /*-----------------------------------------------------------------*/
1387 void pic16_genMinus (iCode *ic)
1389 int size, offset = 0, same=0;
1390 unsigned long lit = 0L;
1393 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1394 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1395 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1397 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1398 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1399 operand *t = IC_RIGHT(ic);
1400 IC_RIGHT(ic) = IC_LEFT(ic);
1404 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1405 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1406 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1407 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1409 /* special cases :- */
1410 /* if both left & right are in bit space */
1411 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1412 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1413 pic16_genPlusBits (ic);
1417 /* if I can do an decrement instead
1418 of subtract then GOOD for ME */
1419 // if (pic16_genMinusDec (ic) == TRUE)
1422 size = pic16_getDataSize(IC_RESULT(ic));
1423 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1425 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1426 /* Add a literal to something else */
1428 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1431 genAddLit ( ic, lit);
1434 /* add the first byte: */
1435 pic16_emitcode("movlw","0x%x", lit & 0xff);
1436 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1437 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1438 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1450 if((lit & 0xff) == 0xff) {
1451 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1453 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1455 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1457 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1458 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1462 /* do the rlf known zero trick here */
1463 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1465 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1470 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1473 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1474 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1475 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1477 /* here we are subtracting a bit from a char or int */
1479 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1481 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1482 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1484 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1485 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1486 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1487 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1490 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1491 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1492 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1493 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1494 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1496 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1498 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1499 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1501 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1502 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1505 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1507 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1509 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1510 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1514 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1515 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1516 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1517 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1522 pic16_mov2w(AOP(IC_LEFT(ic)),0);
1523 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1524 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1527 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1529 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1532 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1534 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1536 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1543 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1544 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1545 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1547 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1548 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1549 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1550 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1551 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1554 if( (size == 1) && ((lit & 0xff) == 0) ) {
1555 /* res = 0 - right */
1556 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1557 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1559 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1560 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1561 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1566 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1567 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1568 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1576 // here we have x = lit - x for sizeof(x)>1
1577 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1578 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1580 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1581 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1582 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1589 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1590 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1591 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1592 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1594 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1595 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1596 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1597 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1598 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1599 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1602 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1603 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1604 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1606 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1607 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1609 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1610 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1611 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1613 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1615 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1616 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1617 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1619 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1621 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1627 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1629 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1630 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1632 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1633 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1640 if (offset < AOP_SIZE(IC_RIGHT(ic)))
1641 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1643 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1644 if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
1645 // signed -- sign extend the right operand
1646 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),AOP_SIZE(IC_RIGHT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1647 pic16_emitpcode (POC_COMF, pic16_popCopyReg (&pic16_pc_wreg));
1650 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1651 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1653 if (offset < AOP_SIZE(IC_LEFT(ic))) {
1654 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1655 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1657 // zero extend the left operand
1658 pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
1659 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
1660 // signed -- sign extend the left operand
1661 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),AOP_SIZE(IC_LEFT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1662 pic16_emitpcode (POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
1664 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1673 // adjustArithmeticResult(ic);
1676 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1677 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1678 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1682 /*-----------------------------------------------------------------*
1683 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1686 *-----------------------------------------------------------------*/
1687 void pic16_genUMult8XLit_8 (operand *left,
1693 int size = AOP_SIZE(result);
1697 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1699 if (AOP_TYPE(right) != AOP_LIT){
1700 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1704 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1706 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1707 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1709 same = pic16_sameRegs(AOP(left), AOP(result));
1714 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1718 // its faster to left shift
1719 for (i=1; i < size; i++) {
1720 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1723 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1725 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1729 if(AOP_TYPE(left) != AOP_ACC)
1730 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1731 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1732 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1733 pic16_popGet(AOP(result), 0)));
1735 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1736 pic16_popGet(AOP(result), 1)));
1737 for (i=2; i < size; i++) {
1738 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1744 // operands different
1748 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1752 for (i=1; i < size; i++) {
1753 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1756 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1757 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1759 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1762 if(AOP_TYPE(left) != AOP_ACC)
1763 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1764 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1765 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1766 pic16_popGet(AOP(result), 0)));
1769 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1770 pic16_popGet(AOP(result), 1)));
1771 for (i=2; i < size; i++) {
1772 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1780 /*-----------------------------------------------------------------------*
1781 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1782 *-----------------------------------------------------------------------*/
1783 void pic16_genUMult16XLit_16 (operand *left,
1787 pCodeOp *pct1, *pct2, *pct3, *pct4;
1794 if (AOP_TYPE(right) != AOP_LIT){
1795 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1799 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1802 same = pic16_sameRegs(AOP(left), AOP(result));
1806 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1807 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1810 // its faster to left shift
1812 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1813 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1817 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1819 pct1 = pic16_popGetTempReg(1);
1820 pct2 = pic16_popGetTempReg(1);
1821 pct3 = pic16_popGetTempReg(1);
1822 pct4 = pic16_popGetTempReg(1);
1824 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1825 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1826 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1827 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1828 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1829 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1831 /* WREG still holds the low literal */
1832 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1833 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1834 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1836 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1837 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1838 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1839 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1842 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1843 pct1, pic16_popGet(AOP(result), 0)));
1844 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1845 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1846 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1847 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1849 pic16_popReleaseTempReg(pct4,1);
1850 pic16_popReleaseTempReg(pct3,1);
1851 pic16_popReleaseTempReg(pct2,1);
1852 pic16_popReleaseTempReg(pct1,1);
1856 // operands different
1859 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1860 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1864 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1865 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1866 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1867 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1871 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1872 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1873 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1874 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1875 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1876 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1878 /* WREG still holds the low literal */
1879 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1880 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1881 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1883 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1884 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1885 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1886 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1894 /*-----------------------------------------------------------------*
1895 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1898 *-----------------------------------------------------------------*/
1899 void pic16_genUMult8X8_8 (operand *left,
1907 if (AOP_TYPE(right) == AOP_LIT) {
1908 pic16_genUMult8XLit_8(left,right,result);
1918 /* if result == right then exchange left and right */
1919 if(pic16_sameRegs(AOP(result), AOP(right))) {
1926 if(AOP_TYPE(left) != AOP_ACC) {
1928 if(AOP_TYPE(right) != AOP_ACC) {
1929 pic16_mov2w(AOP(left), 0);
1930 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1932 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1935 // left is WREG, right cannot be WREG (or can?!)
1936 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1939 /* result is in PRODL:PRODH */
1940 if(AOP_TYPE(result) != AOP_ACC) {
1941 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1942 pic16_popGet(AOP(result), 0)));
1945 if(AOP_SIZE(result)>1) {
1948 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1949 pic16_popGet(AOP(result), 1)));
1951 for(i=2;i<AOP_SIZE(result);i++)
1952 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1955 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1959 /*------------------------------------------------------------------*
1960 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1961 *------------------------------------------------------------------*/
1962 void pic16_genUMult16X16_16 (operand *left,
1967 pCodeOp *pct1, *pct2, *pct3, *pct4;
1972 if (AOP_TYPE(right) == AOP_LIT) {
1973 pic16_genUMult8XLit_8(left,right,result);
1981 /* if result == right then exchange left and right */
1982 if(pic16_sameRegs(AOP(result), AOP(right))) {
1990 if(pic16_sameRegs(AOP(result), AOP(left))) {
1992 pct1 = pic16_popGetTempReg(1);
1993 pct2 = pic16_popGetTempReg(1);
1994 pct3 = pic16_popGetTempReg(1);
1995 pct4 = pic16_popGetTempReg(1);
1997 pic16_mov2w(AOP(left), 0);
1998 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1999 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2000 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2001 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2002 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2004 /* WREG still holds the lower left */
2005 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2006 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2007 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2009 pic16_mov2w(AOP(left), 1);
2010 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2011 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2012 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2015 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2016 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2017 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2018 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2019 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2020 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2022 pic16_popReleaseTempReg( pct4, 1 );
2023 pic16_popReleaseTempReg( pct3, 1 );
2024 pic16_popReleaseTempReg( pct2, 1 );
2025 pic16_popReleaseTempReg( pct1, 1 );
2029 pic16_mov2w(AOP(left), 0);
2030 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2031 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2032 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2033 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2034 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2036 /* WREG still holds the lower left */
2037 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2038 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2039 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2041 pic16_mov2w(AOP(left), 1);
2042 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2043 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2044 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2049 void pic16_genSMult16X16_16(operand *left,
2057 /*-----------------------------------------------------------------*
2058 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
2060 * this routine will call the unsigned multiply routine and then
2061 * post-fix the sign bit.
2062 *-----------------------------------------------------------------*/
2063 void pic16_genSMult8X8_8 (operand *left,
2066 pCodeOpReg *result_hi)
2068 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2072 result_hi = PCOR(pic16_popGet(AOP(result),1));
2076 pic16_genUMult8X8_8(left,right,result);
2080 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2081 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2082 pic16_mov2w(AOP(left),0);
2083 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2084 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2089 /*-----------------------------------------------------------------*
2090 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
2091 *-----------------------------------------------------------------*/
2092 void pic16_genMult8X8_8 (operand *left,
2098 if(AOP_TYPE(right) == AOP_LIT)
2099 pic16_genUMult8XLit_8(left,right,result);
2101 pic16_genUMult8X8_8(left,right,result);
2105 /*-----------------------------------------------------------------*
2106 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
2107 *-----------------------------------------------------------------*/
2108 void pic16_genMult16X16_16 (operand *left,
2114 if (AOP_TYPE(right) == AOP_LIT)
2115 pic16_genUMult16XLit_16(left,right,result);
2117 pic16_genUMult16X16_16(left,right,result);
2123 /*-----------------------------------------------------------------------*
2124 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2125 *-----------------------------------------------------------------------*/
2126 void pic16_genUMult32XLit_32 (operand *left,
2130 pCodeOp *pct1, *pct2, *pct3, *pct4;
2137 if (AOP_TYPE(right) != AOP_LIT){
2138 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2142 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2145 same = pic16_sameRegs(AOP(left), AOP(result));
2149 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2150 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2153 // its faster to left shift
2155 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2156 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2160 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2162 pct1 = pic16_popGetTempReg(1);
2163 pct2 = pic16_popGetTempReg(1);
2164 pct3 = pic16_popGetTempReg(1);
2165 pct4 = pic16_popGetTempReg(1);
2167 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2168 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2169 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2170 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2171 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2172 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2174 /* WREG still holds the low literal */
2175 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2176 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2177 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2179 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2180 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2181 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2182 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2185 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2186 pct1, pic16_popGet(AOP(result), 0)));
2187 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2188 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2189 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2190 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2192 pic16_popReleaseTempReg( pct4, 1 );
2193 pic16_popReleaseTempReg( pct3, 1 );
2194 pic16_popReleaseTempReg( pct2, 1 );
2195 pic16_popReleaseTempReg( pct1, 1 );
2199 // operands different
2202 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2203 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2207 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2208 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2209 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2210 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2214 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2215 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2216 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2217 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2218 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2219 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2221 /* WREG still holds the low literal */
2222 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2223 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2224 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2226 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2227 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2228 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2229 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2237 /*------------------------------------------------------------------*
2238 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2239 *------------------------------------------------------------------*/
2240 void pic16_genUMult32X32_32 (operand *left,
2245 pCodeOp *pct1, *pct2, *pct3, *pct4;
2249 if (AOP_TYPE(right) == AOP_LIT) {
2250 pic16_genUMult8XLit_8(left,right,result);
2258 /* if result == right then exchange left and right */
2259 if(pic16_sameRegs(AOP(result), AOP(right))) {
2267 if(pic16_sameRegs(AOP(result), AOP(left))) {
2269 pct1 = pic16_popGetTempReg(1);
2270 pct2 = pic16_popGetTempReg(1);
2271 pct3 = pic16_popGetTempReg(1);
2272 pct4 = pic16_popGetTempReg(1);
2274 pic16_mov2w(AOP(left), 0);
2275 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2276 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2277 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2278 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2279 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2281 /* WREG still holds the lower left */
2282 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2283 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2284 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2286 pic16_mov2w(AOP(left), 1);
2287 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2288 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2289 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2292 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2293 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2294 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2295 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2296 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2297 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2299 pic16_popReleaseTempReg( pct4, 1 );
2300 pic16_popReleaseTempReg( pct3, 1 );
2301 pic16_popReleaseTempReg( pct2, 1 );
2302 pic16_popReleaseTempReg( pct1, 1 );
2306 pic16_mov2w(AOP(left), 0);
2307 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2308 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2309 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2310 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2311 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2313 /* WREG still holds the lower left */
2314 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2315 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2316 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2318 pic16_mov2w(AOP(left), 1);
2319 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2320 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2321 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2326 /*-----------------------------------------------------------------*
2327 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2328 *-----------------------------------------------------------------*/
2329 void pic16_genMult32X32_32 (operand *left,
2335 if (AOP_TYPE(right) == AOP_LIT)
2336 pic16_genUMult32XLit_32(left,right,result);
2338 pic16_genUMult32X32_32(left,right,result);
2348 /*-----------------------------------------------------------------*/
2349 /* constMult - generates code for multiplication by a constant */
2350 /*-----------------------------------------------------------------*/
2351 void genMultConst(unsigned C)
2355 unsigned sr3; // Shift right 3
2361 Convert a string of 3 binary 1's in the lit into
2365 mask = 7 << ( (size*8) - 3);
2369 while(mask < (1<<size*8)) {
2371 if( (mask & lit) == lit) {
2374 /* We found 3 (or more) consecutive 1's */
2376 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2378 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2380 lit ^= consecutive_bits;
2384 sr3 |= (consecutive + lsb);