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";
82 const char *pic16_pCodeOpType(pCodeOp *pcop)
89 case PO_NONE: return "PO_NONE";
90 case PO_W: return "PO_W";
91 case PO_WREG: return "PO_WREG";
92 case PO_STATUS: return "PO_STATUS";
93 case PO_BSR: return "PO_BSR";
94 case PO_FSR0: return "PO_FSR0";
95 case PO_INDF0: return "PO_INDF0";
96 case PO_INTCON: return "PO_INTCON";
97 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
98 case PO_GPR_BIT: return "PO_GPR_BIT";
99 case PO_GPR_TEMP: return "PO_GPR_TEMP";
100 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
101 case PO_PCL: return "PO_PCL";
102 case PO_PCLATH: return "PO_PCLATH";
103 case PO_PCLATU: return "PO_PCLATU";
104 case PO_PRODL: return "PO_PRODL";
105 case PO_PRODH: return "PO_PRODH";
106 case PO_LITERAL: return "PO_LITERAL";
107 case PO_REL_ADDR: return "PO_REL_ADDR";
108 case PO_IMMEDIATE: return "PO_IMMEDIATE";
109 case PO_DIR: return "PO_DIR";
110 case PO_CRY: return "PO_CRY";
111 case PO_BIT: return "PO_BIT";
112 case PO_STR: return "PO_STR";
113 case PO_LABEL: return "PO_LABEL";
114 case PO_WILD: return "PO_WILD";
118 return "BAD PO_TYPE";
121 const char *pic16_pCodeOpSubType(pCodeOp *pcop)
124 if(pcop && (pcop->type == PO_GPR_BIT)) {
126 switch(PCORB(pcop)->subtype) {
128 case PO_NONE: return "PO_NONE";
129 case PO_W: return "PO_W";
130 case PO_WREG: return "PO_WREG";
131 case PO_STATUS: return "PO_STATUS";
132 case PO_BSR: return "PO_BSR";
133 case PO_FSR0: return "PO_FSR0";
134 case PO_INDF0: return "PO_INDF0";
135 case PO_INTCON: return "PO_INTCON";
136 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
137 case PO_GPR_BIT: return "PO_GPR_BIT";
138 case PO_GPR_TEMP: return "PO_GPR_TEMP";
139 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
140 case PO_PCL: return "PO_PCL";
141 case PO_PCLATH: return "PO_PCLATH";
142 case PO_PCLATU: return "PO_PCLATU";
143 case PO_PRODL: return "PO_PRODL";
144 case PO_PRODH: return "PO_PRODH";
145 case PO_LITERAL: return "PO_LITERAL";
146 case PO_REL_ADDR: return "PO_REL_ADDR";
147 case PO_IMMEDIATE: return "PO_IMMEDIATE";
148 case PO_DIR: return "PO_DIR";
149 case PO_CRY: return "PO_CRY";
150 case PO_BIT: return "PO_BIT";
151 case PO_STR: return "PO_STR";
152 case PO_LABEL: return "PO_LABEL";
153 case PO_WILD: return "PO_WILD";
157 return "BAD PO_TYPE";
160 /*-----------------------------------------------------------------*/
161 /* pic16_genPlusIncr :- does addition with increment if possible */
162 /*-----------------------------------------------------------------*/
163 bool pic16_genPlusIncr (iCode *ic)
165 unsigned int icount ;
166 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
168 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
169 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
170 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
171 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
172 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
174 /* will try to generate an increment */
175 /* if the right side is not a literal
177 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
180 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
181 /* if the literal value of the right hand side
182 is greater than 2 then it is faster to add */
183 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
186 /* if increment 16 bits in register */
187 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
192 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
193 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
197 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
198 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
204 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
205 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
206 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
207 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
209 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
210 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
211 AOP(IC_RESULT(ic))->aopu.aop_dir,
212 AOP(IC_RESULT(ic))->aopu.aop_dir);
214 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
215 //pic16_emitcode("xorlw","1");
217 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
218 //pic16_emitcode("andlw","1");
221 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
222 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
223 AOP(IC_RESULT(ic))->aopu.aop_dir,
224 AOP(IC_RESULT(ic))->aopu.aop_dir);
230 /* if the sizes are greater than 1 then we cannot */
231 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
232 AOP_SIZE(IC_LEFT(ic)) > 1 )
235 /* If we are incrementing the same register by two: */
237 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
240 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
241 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
246 DEBUGpic16_emitcode ("; ","couldn't increment ");
251 /*-----------------------------------------------------------------*/
252 /* pic16_outBitAcc - output a bit in acc */
253 /*-----------------------------------------------------------------*/
254 void pic16_outBitAcc(operand *result)
256 symbol *tlbl = newiTempLabel(NULL);
257 /* if the result is a bit */
258 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
260 if (AOP_TYPE(result) == AOP_CRY){
261 pic16_aopPut(AOP(result),"a",0);
264 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
265 pic16_emitcode("mov","a,#01");
266 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
267 pic16_outAcc(result);
271 /*-----------------------------------------------------------------*/
272 /* pic16_genPlusBits - generates code for addition of two bits */
273 /*-----------------------------------------------------------------*/
274 void pic16_genPlusBits (iCode *ic)
277 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
279 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
280 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
281 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
282 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
284 The following block of code will add two bits.
285 Note that it'll even work if the destination is
286 the carry (C in the status register).
287 It won't work if the 'Z' bit is a source or destination.
290 /* If the result is stored in the accumulator (w) */
291 //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
292 switch(AOP_TYPE(IC_RESULT(ic))) {
294 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
295 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
296 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
297 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
298 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
300 pic16_emitcode("clrw","");
301 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
302 AOP(IC_RIGHT(ic))->aopu.aop_dir,
303 AOP(IC_RIGHT(ic))->aopu.aop_dir);
304 pic16_emitcode("xorlw","1");
305 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
306 AOP(IC_LEFT(ic))->aopu.aop_dir,
307 AOP(IC_LEFT(ic))->aopu.aop_dir);
308 pic16_emitcode("xorlw","1");
311 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
312 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
313 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
314 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
315 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
316 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
319 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
320 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
321 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
322 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
323 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
324 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
326 pic16_emitcode("movlw","(1 << (%s & 7))",
327 AOP(IC_RESULT(ic))->aopu.aop_dir,
328 AOP(IC_RESULT(ic))->aopu.aop_dir);
329 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
330 AOP(IC_RESULT(ic))->aopu.aop_dir,
331 AOP(IC_RESULT(ic))->aopu.aop_dir);
332 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
333 AOP(IC_RIGHT(ic))->aopu.aop_dir,
334 AOP(IC_RIGHT(ic))->aopu.aop_dir);
335 pic16_emitcode("xorwf","(%s >>3),f",
336 AOP(IC_RESULT(ic))->aopu.aop_dir);
337 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
338 AOP(IC_LEFT(ic))->aopu.aop_dir,
339 AOP(IC_LEFT(ic))->aopu.aop_dir);
340 pic16_emitcode("xorwf","(%s>>3),f",
341 AOP(IC_RESULT(ic))->aopu.aop_dir);
348 /* This is the original version of this code.
350 * This is being kept around for reference,
351 * because I am not entirely sure I got it right...
353 static void adjustArithmeticResult(iCode *ic)
355 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
356 AOP_SIZE(IC_LEFT(ic)) == 3 &&
357 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
358 pic16_aopPut(AOP(IC_RESULT(ic)),
359 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
362 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
363 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
364 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
365 pic16_aopPut(AOP(IC_RESULT(ic)),
366 pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
369 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
370 AOP_SIZE(IC_LEFT(ic)) < 3 &&
371 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
372 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
373 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
375 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
376 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
380 /* This is the pure and virtuous version of this code.
381 * I'm pretty certain it's right, but not enough to toss the old
384 static void adjustArithmeticResult(iCode *ic)
386 if (opIsGptr(IC_RESULT(ic)) &&
387 opIsGptr(IC_LEFT(ic)) &&
388 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
390 pic16_aopPut(AOP(IC_RESULT(ic)),
391 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
395 if (opIsGptr(IC_RESULT(ic)) &&
396 opIsGptr(IC_RIGHT(ic)) &&
397 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
399 pic16_aopPut(AOP(IC_RESULT(ic)),
400 pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
404 if (opIsGptr(IC_RESULT(ic)) &&
405 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
406 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
407 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
408 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
410 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
411 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
416 /*-----------------------------------------------------------------*/
417 /* genAddlit - generates code for addition */
418 /*-----------------------------------------------------------------*/
419 static void genAddLit2byte (operand *result, int offr, int lit)
426 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
429 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
432 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
433 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
438 static void emitMOVWF(operand *reg, int offset)
443 if (AOP_TYPE(reg) == AOP_ACC) {
444 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
448 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
452 static void genAddLit (iCode *ic, int lit)
461 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
465 result = IC_RESULT(ic);
466 same = pic16_sameRegs(AOP(left), AOP(result));
467 size = pic16_getDataSize(result);
471 /* Handle special cases first */
473 genAddLit2byte (result, 0, lit);
476 int hi = 0xff & (lit >> 8);
483 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
488 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
490 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
493 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
494 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
495 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
499 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
500 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
502 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
510 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
513 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
516 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
517 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
519 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
521 case 0xff: /* 0x01ff */
522 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
523 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
524 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
525 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
530 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
534 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
537 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
538 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
540 /* case 0xff: * 0xffff *
541 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
542 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
543 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
547 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
548 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
550 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
557 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
562 genAddLit2byte (result, MSB16, hi);
565 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1)&0xff));
566 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
567 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
568 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
570 /* case 0xff: * 0xHHff *
571 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
572 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
573 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
574 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
576 */ default: /* 0xHHLL */
577 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
578 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
579 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
581 pic16_emitpcode(POC_MOVLW,pic16_popGetLit((hi+1) & 0xff));
582 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16));
591 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
594 lo = BYTEofLONG(lit,0);
602 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
605 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
606 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(1));
607 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
609 default: /* carry_info = 3 */
611 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
617 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
622 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
625 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
630 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo+1));
631 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
636 /* no carry info from previous step */
637 /* this means this is the first time to add */
642 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
646 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
647 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
649 carry_info = 3; /* Were adding only one byte and propogating the carry */
660 lo = BYTEofLONG(lit,0);
665 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
668 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
669 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
672 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
674 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
676 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
686 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
690 if(AOP_TYPE(left) == AOP_ACC) {
691 /* left addend is already in accumulator */
694 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
698 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
699 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
703 /* left addend is in a register */
706 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
707 emitMOVWF(result, 0);
708 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
712 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
713 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
717 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
718 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
722 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
723 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
724 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
732 /* left is not the accumulator */
734 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
735 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
737 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
738 /* We don't know the state of the carry bit at this point */
741 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
748 /* The ls byte of the lit must've been zero - that
749 means we don't have to deal with carry */
751 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
752 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
753 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(left),offset));
758 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
759 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset,FALSE,FALSE));
760 emitMOVWF(result,offset);
761 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
763 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
764 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
768 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
769 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset));
770 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
771 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
779 /*-----------------------------------------------------------------*/
780 /* pic16_genPlus - generates code for addition */
781 /*-----------------------------------------------------------------*/
782 void pic16_genPlus (iCode *ic)
784 int i, size, offset = 0;
785 operand *result, *left, *right;
787 /* special cases :- */
788 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
791 result = IC_RESULT(ic);
793 right = IC_RIGHT(ic);
794 pic16_aopOp (left,ic,FALSE);
795 pic16_aopOp (right,ic,FALSE);
796 pic16_aopOp (result,ic,TRUE);
797 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
798 // pic16_DumpOp("(left)",left);
800 /* if literal, literal on the right or
801 if left requires ACC or right is already
804 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
810 /* if both left & right are in bit space */
811 if (AOP_TYPE(left) == AOP_CRY &&
812 AOP_TYPE(right) == AOP_CRY) {
813 pic16_genPlusBits (ic);
817 /* if left in bit space & right literal */
818 if (AOP_TYPE(left) == AOP_CRY &&
819 AOP_TYPE(right) == AOP_LIT) {
820 /* if result in bit space */
821 if(AOP_TYPE(result) == AOP_CRY){
822 if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
823 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
824 if (!pic16_sameRegs(AOP(left), AOP(result)) )
825 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
826 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
829 size = pic16_getDataSize(result);
831 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
832 pic16_emitcode("addc","a,#00 ;%d",__LINE__);
833 pic16_aopPut(AOP(result),"a",offset++);
839 /* if I can do an increment instead
840 of add then GOOD for ME */
841 if (pic16_genPlusIncr (ic) == TRUE)
844 size = pic16_getDataSize(IC_RESULT(ic));
846 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
847 /* Add a literal to something else */
849 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
853 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
858 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
860 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
861 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
862 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
864 /* here we are adding a bit to a char or int */
866 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
868 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
869 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
871 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
872 AOP(IC_RIGHT(ic))->aopu.aop_dir,
873 AOP(IC_RIGHT(ic))->aopu.aop_dir);
874 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
877 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
878 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
879 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
881 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
882 AOP(IC_RIGHT(ic))->aopu.aop_dir,
883 AOP(IC_RIGHT(ic))->aopu.aop_dir);
884 pic16_emitcode(" xorlw","1");
886 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
887 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
888 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
890 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
891 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
892 AOP(IC_RIGHT(ic))->aopu.aop_dir,
893 AOP(IC_RIGHT(ic))->aopu.aop_dir);
894 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
897 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
899 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
900 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
901 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
903 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
905 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
906 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
913 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
914 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
916 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
917 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
919 pic16_emitcode("clrz","");
921 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
922 AOP(IC_RIGHT(ic))->aopu.aop_dir,
923 AOP(IC_RIGHT(ic))->aopu.aop_dir);
924 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
928 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
929 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
930 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
931 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
932 emitMOVWF(IC_RIGHT(ic),0);
934 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
935 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
936 AOP(IC_RIGHT(ic))->aopu.aop_dir,
937 AOP(IC_RIGHT(ic))->aopu.aop_dir);
938 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
939 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
945 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
946 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
954 // Note: the following is an example of WISC code, eg.
955 // it's supposed to run on a Weird Instruction Set Computer :o)
957 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
959 if ( AOP_TYPE(left) == AOP_ACC) {
960 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
961 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
962 if ( AOP_TYPE(result) != AOP_ACC)
963 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
964 goto release; // we're done, since WREG is 1 byte
968 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
970 size = min( AOP_SIZE(result), AOP_SIZE(right) );
971 size = min( size, AOP_SIZE(left) );
974 if(pic16_debug_verbose) {
975 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
976 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
977 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
982 if ((AOP_TYPE(left) == AOP_PCODE) && (
983 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
984 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
985 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
987 // add to literal operand
990 for(i=0; i<size; i++) {
991 if (AOP_TYPE(right) == AOP_ACC) {
992 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
994 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
995 if(i) { // add with carry
996 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
997 } else { // add without
998 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1001 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1004 // add leftover bytes
1005 if (SPEC_USIGN(getSpec(operandType(right)))) {
1006 // right is unsigned
1007 for(i=size; i< AOP_SIZE(result); i++) {
1008 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1009 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1010 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1014 // right is signed, oh dear ...
1015 for(i=size; i< AOP_SIZE(result); i++) {
1016 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1017 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1018 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
1019 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1020 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1030 for(i=0; i<size; i++) {
1031 if (AOP_TYPE(right) != AOP_ACC)
1032 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),i));
1033 if (pic16_sameRegs(AOP(left), AOP(result)))
1035 if(i) { // add with carry
1036 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1037 } else { // add without
1038 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1040 } else { // not same
1041 if(i) { // add with carry
1042 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1043 } else { // add without
1044 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1046 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1050 // add leftover bytes
1051 if (SPEC_USIGN(getSpec(operandType(right)))) {
1052 // right is unsigned
1053 for(i=size; i< AOP_SIZE(result); i++) {
1054 if (pic16_sameRegs(AOP(left), AOP(result)))
1056 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1057 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1058 } else { // not same
1059 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),i));
1060 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1065 for(i=size; i< AOP_SIZE(result); i++) {
1066 if(size < AOP_SIZE(left)) {
1067 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1068 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1069 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1070 if (pic16_sameRegs(AOP(left), AOP(result)))
1072 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1073 } else { // not same
1074 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1075 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1078 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1079 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1089 // TODO: anything from here to before "release:" is probably obsolete and should be removed
1090 // when the regression tests are stable
1092 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1093 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1094 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1097 /* Need to extend result to higher bytes */
1098 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1100 /* First grab the carry from the lower bytes */
1101 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1102 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1106 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1109 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1110 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1111 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1112 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1114 /* if chars or ints or being signed extended to longs: */
1116 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1117 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1118 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1126 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1128 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1135 //adjustArithmeticResult(ic);
1138 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1139 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1140 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1143 /*-----------------------------------------------------------------*/
1144 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1145 /*-----------------------------------------------------------------*/
1146 bool pic16_genMinusDec (iCode *ic)
1148 unsigned int icount ;
1149 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1151 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1152 /* will try to generate an increment */
1153 /* if the right side is not a literal
1155 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1156 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1157 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1160 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1162 /* if the literal value of the right hand side
1163 is greater than 4 then it is not worth it */
1164 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1167 /* if decrement 16 bits in register */
1168 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1173 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1174 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1175 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1176 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1178 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1179 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1180 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1182 /* size is 3 or 4 */
1183 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1184 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1186 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1188 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1190 pic16_emitcode("movlw","0xff");
1191 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1194 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1196 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1200 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1202 pic16_emitcode("skpnc","");
1204 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1213 /* if the sizes are greater than 1 then we cannot */
1214 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1215 AOP_SIZE(IC_LEFT(ic)) > 1 )
1218 /* we can if the aops of the left & result match or
1219 if they are in registers and the registers are the
1221 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1224 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1226 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1231 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1232 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1233 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1236 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1237 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1239 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1240 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1248 /*-----------------------------------------------------------------*/
1249 /* pic16_addSign - propogate sign bit to higher bytes */
1250 /*-----------------------------------------------------------------*/
1251 void pic16_addSign(operand *result, int offset, int sign)
1253 int size = (pic16_getDataSize(result) - offset);
1254 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1257 if(sign && offset) {
1260 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1261 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1262 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1265 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1266 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1267 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1269 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1274 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1278 /*-----------------------------------------------------------------*/
1279 /* pic16_genMinusBits - generates code for subtraction of two bits */
1280 /*-----------------------------------------------------------------*/
1281 void pic16_genMinusBits (iCode *ic)
1283 symbol *lbl = newiTempLabel(NULL);
1284 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1285 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1286 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1287 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1288 pic16_emitcode("cpl","c");
1289 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1290 pic16_outBitC(IC_RESULT(ic));
1293 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1294 pic16_emitcode("subb","a,acc");
1295 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1296 pic16_emitcode("inc","a");
1297 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1298 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1299 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1303 /*-----------------------------------------------------------------*/
1304 /* pic16_genMinus - generates code for subtraction */
1305 /*-----------------------------------------------------------------*/
1306 void pic16_genMinus (iCode *ic)
1308 int size, offset = 0, same=0;
1309 unsigned long lit = 0L;
1311 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1312 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1313 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1314 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1316 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1317 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1318 operand *t = IC_RIGHT(ic);
1319 IC_RIGHT(ic) = IC_LEFT(ic);
1323 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1324 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1325 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1326 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1328 /* special cases :- */
1329 /* if both left & right are in bit space */
1330 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1331 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1332 pic16_genPlusBits (ic);
1336 /* if I can do an decrement instead
1337 of subtract then GOOD for ME */
1338 // if (pic16_genMinusDec (ic) == TRUE)
1341 size = pic16_getDataSize(IC_RESULT(ic));
1342 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1344 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1345 /* Add a literal to something else */
1347 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1350 genAddLit ( ic, lit);
1353 /* add the first byte: */
1354 pic16_emitcode("movlw","0x%x", lit & 0xff);
1355 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1356 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1357 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1369 if((lit & 0xff) == 0xff) {
1370 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1372 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1374 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1376 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1377 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1381 /* do the rlf known zero trick here */
1382 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1384 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1389 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1392 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1393 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1394 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1396 /* here we are subtracting a bit from a char or int */
1398 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1400 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1401 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1403 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1404 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1405 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1406 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1409 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1410 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1411 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1412 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1413 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1415 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1417 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1418 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1420 pic16_emitpcode(POC_MOVLW , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1421 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1424 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1426 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1428 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1429 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1433 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1434 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1435 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1436 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1441 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1442 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1443 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1446 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1448 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1451 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1453 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1455 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1462 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1463 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1464 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1466 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1467 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1468 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1469 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1470 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1473 if( (size == 1) && ((lit & 0xff) == 0) ) {
1474 /* res = 0 - right */
1475 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1476 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1477 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1479 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1480 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1481 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1486 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1487 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1488 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1496 /* This is the last byte in a multibyte subtraction
1497 * There are a couple of tricks we can do by not worrying about
1498 * propogating the carry */
1500 /* 0xff - x == ~x */
1502 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1504 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1506 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1507 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1509 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1512 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1514 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1515 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1516 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1525 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1527 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & 0xff)-1));
1528 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1531 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1537 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1538 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1540 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1542 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1544 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1545 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1552 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1553 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1554 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1555 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1557 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1558 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1559 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1560 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1561 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1564 if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1565 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1566 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1567 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1568 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1571 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1572 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1573 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1575 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1576 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1578 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1579 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1580 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1582 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1584 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1585 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1586 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1588 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1590 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1597 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1599 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1600 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1602 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1603 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1610 if (!pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1611 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1612 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1614 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1616 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1617 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1625 // adjustArithmeticResult(ic);
1628 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1629 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1630 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1634 /*-----------------------------------------------------------------*
1635 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1638 *-----------------------------------------------------------------*/
1639 void pic16_genUMult8XLit_8 (operand *left,
1647 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1648 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1650 if (AOP_TYPE(right) != AOP_LIT){
1651 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1655 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1657 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1658 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1660 same = pic16_sameRegs(AOP(left), AOP(result));
1664 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1667 // its faster to left shift
1669 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1673 if(AOP_TYPE(left) != AOP_ACC)
1674 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1675 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1676 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1677 pic16_popGet(AOP(result), 0)));
1681 // operands different
1684 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1688 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1689 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1692 if(AOP_TYPE(left) != AOP_ACC)
1693 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1694 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1695 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1696 pic16_popGet(AOP(result), 0)));
1702 /*-----------------------------------------------------------------------*
1703 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1704 *-----------------------------------------------------------------------*/
1705 void pic16_genUMult16XLit_16 (operand *left,
1709 pCodeOp *pct1, *pct2, *pct3, *pct4;
1714 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1716 if (AOP_TYPE(right) != AOP_LIT){
1717 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1721 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1724 same = pic16_sameRegs(AOP(left), AOP(result));
1728 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1729 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1732 // its faster to left shift
1734 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1735 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1739 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1741 pct1 = pic16_popGetTempReg();
1742 pct2 = pic16_popGetTempReg();
1743 pct3 = pic16_popGetTempReg();
1744 pct4 = pic16_popGetTempReg();
1746 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1747 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1748 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1749 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1750 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1751 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1753 /* WREG still holds the low literal */
1754 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1755 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1756 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1758 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1759 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1760 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1761 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1764 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1765 pct1, pic16_popGet(AOP(result), 0)));
1766 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1767 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1768 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1769 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1771 pic16_popReleaseTempReg( pct4 );
1772 pic16_popReleaseTempReg( pct3 );
1773 pic16_popReleaseTempReg( pct2 );
1774 pic16_popReleaseTempReg( pct1 );
1778 // operands different
1781 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1782 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1786 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1787 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1788 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1789 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1793 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1794 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1795 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1796 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1797 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1798 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1800 /* WREG still holds the low literal */
1801 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1802 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1803 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1805 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1806 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1807 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1808 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1816 /*-----------------------------------------------------------------*
1817 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1820 *-----------------------------------------------------------------*/
1821 void pic16_genUMult8X8_8 (operand *left,
1826 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1829 if (AOP_TYPE(right) == AOP_LIT) {
1830 pic16_genUMult8XLit_8(left,right,result);
1840 /* if result == right then exchange left and right */
1841 if(pic16_sameRegs(AOP(result), AOP(right))) {
1848 if(AOP_TYPE(left) != AOP_ACC) {
1850 if(AOP_TYPE(right) != AOP_ACC) {
1851 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1852 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1854 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1857 // left is WREG, right cannot be WREG (or can?!)
1858 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1861 /* result is in PRODL:PRODH */
1862 if(AOP_TYPE(result) != AOP_ACC) {
1863 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1864 pic16_popGet(AOP(result), 0)));
1867 if(AOP_SIZE(result)>1) {
1870 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1871 pic16_popGet(AOP(result), 1)));
1873 for(i=2;i<AOP_SIZE(result);i++)
1874 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1877 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1881 /*------------------------------------------------------------------*
1882 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1883 *------------------------------------------------------------------*/
1884 void pic16_genUMult16X16_16 (operand *left,
1889 pCodeOp *pct1, *pct2, *pct3, *pct4;
1891 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1894 if (AOP_TYPE(right) == AOP_LIT) {
1895 pic16_genUMult8XLit_8(left,right,result);
1903 /* if result == right then exchange left and right */
1904 if(pic16_sameRegs(AOP(result), AOP(right))) {
1912 if(pic16_sameRegs(AOP(result), AOP(left))) {
1914 pct1 = pic16_popGetTempReg();
1915 pct2 = pic16_popGetTempReg();
1916 pct3 = pic16_popGetTempReg();
1917 pct4 = pic16_popGetTempReg();
1919 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1920 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1921 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1922 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1923 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1924 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1926 /* WREG still holds the lower left */
1927 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1928 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1929 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1931 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1932 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1933 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1934 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1937 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1938 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
1939 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
1940 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1941 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1942 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1944 pic16_popReleaseTempReg( pct4 );
1945 pic16_popReleaseTempReg( pct3 );
1946 pic16_popReleaseTempReg( pct2 );
1947 pic16_popReleaseTempReg( pct1 );
1951 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1952 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1953 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1954 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1955 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1956 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1958 /* WREG still holds the lower left */
1959 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1960 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1961 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1963 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1964 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1965 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1966 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1971 void pic16_genSMult16X16_16(operand *left,
1979 /*-----------------------------------------------------------------*
1980 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1982 * this routine will call the unsigned multiply routine and then
1983 * post-fix the sign bit.
1984 *-----------------------------------------------------------------*/
1985 void pic16_genSMult8X8_8 (operand *left,
1988 pCodeOpReg *result_hi)
1990 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1994 result_hi = PCOR(pic16_popGet(AOP(result),1));
1998 pic16_genUMult8X8_8(left,right,result);
2002 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2003 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2004 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
2005 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2006 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2011 /*-----------------------------------------------------------------*
2012 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
2013 *-----------------------------------------------------------------*/
2014 void pic16_genMult8X8_8 (operand *left,
2018 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2020 if(AOP_TYPE(right) == AOP_LIT)
2021 pic16_genUMult8XLit_8(left,right,result);
2023 pic16_genUMult8X8_8(left,right,result);
2027 /*-----------------------------------------------------------------*
2028 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
2029 *-----------------------------------------------------------------*/
2030 void pic16_genMult16X16_16 (operand *left,
2034 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2036 if (AOP_TYPE(right) == AOP_LIT)
2037 pic16_genUMult16XLit_16(left,right,result);
2039 pic16_genUMult16X16_16(left,right,result);
2046 /*-----------------------------------------------------------------------*
2047 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2048 *-----------------------------------------------------------------------*/
2049 void pic16_genUMult32XLit_32 (operand *left,
2053 pCodeOp *pct1, *pct2, *pct3, *pct4;
2058 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2060 if (AOP_TYPE(right) != AOP_LIT){
2061 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2065 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2068 same = pic16_sameRegs(AOP(left), AOP(result));
2072 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2073 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2076 // its faster to left shift
2078 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2079 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2083 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2085 pct1 = pic16_popGetTempReg();
2086 pct2 = pic16_popGetTempReg();
2087 pct3 = pic16_popGetTempReg();
2088 pct4 = pic16_popGetTempReg();
2090 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2091 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2092 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2093 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2094 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2095 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2097 /* WREG still holds the low literal */
2098 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2099 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2100 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2102 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2103 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2104 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2105 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2108 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2109 pct1, pic16_popGet(AOP(result), 0)));
2110 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2111 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2112 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2113 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2115 pic16_popReleaseTempReg( pct4 );
2116 pic16_popReleaseTempReg( pct3 );
2117 pic16_popReleaseTempReg( pct2 );
2118 pic16_popReleaseTempReg( pct1 );
2122 // operands different
2125 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2126 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2130 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2131 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2132 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2133 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2137 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2138 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2139 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2140 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2141 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2142 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2144 /* WREG still holds the low literal */
2145 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2146 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2147 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2149 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2150 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2151 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2152 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2160 /*------------------------------------------------------------------*
2161 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2162 *------------------------------------------------------------------*/
2163 void pic16_genUMult32X32_32 (operand *left,
2168 pCodeOp *pct1, *pct2, *pct3, *pct4;
2170 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2173 if (AOP_TYPE(right) == AOP_LIT) {
2174 pic16_genUMult8XLit_8(left,right,result);
2182 /* if result == right then exchange left and right */
2183 if(pic16_sameRegs(AOP(result), AOP(right))) {
2191 if(pic16_sameRegs(AOP(result), AOP(left))) {
2193 pct1 = pic16_popGetTempReg();
2194 pct2 = pic16_popGetTempReg();
2195 pct3 = pic16_popGetTempReg();
2196 pct4 = pic16_popGetTempReg();
2198 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2199 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2200 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2201 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2202 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2203 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2205 /* WREG still holds the lower left */
2206 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2207 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2208 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2210 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2211 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2212 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2213 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2216 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2217 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2218 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2219 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2220 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2221 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2223 pic16_popReleaseTempReg( pct4 );
2224 pic16_popReleaseTempReg( pct3 );
2225 pic16_popReleaseTempReg( pct2 );
2226 pic16_popReleaseTempReg( pct1 );
2230 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2231 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2232 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2233 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2234 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2235 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2237 /* WREG still holds the lower left */
2238 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2239 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2240 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2242 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2243 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2244 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2245 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2250 /*-----------------------------------------------------------------*
2251 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2252 *-----------------------------------------------------------------*/
2253 void pic16_genMult32X32_32 (operand *left,
2257 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2259 if (AOP_TYPE(right) == AOP_LIT)
2260 pic16_genUMult32XLit_32(left,right,result);
2262 pic16_genUMult32X32_32(left,right,result);
2273 /*-----------------------------------------------------------------*/
2274 /* constMult - generates code for multiplication by a constant */
2275 /*-----------------------------------------------------------------*/
2276 void genMultConst(unsigned C)
2280 unsigned sr3; // Shift right 3
2286 Convert a string of 3 binary 1's in the lit into
2290 mask = 7 << ( (size*8) - 3);
2294 while(mask < (1<<size*8)) {
2296 if( (mask & lit) == lit) {
2299 /* We found 3 (or more) consecutive 1's */
2301 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2303 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2305 lit ^= consecutive_bits;
2309 sr3 |= (consecutive + lsb);