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_STK: return "AOP_STK";
66 case AOP_STR: return "AOP_STR";
67 case AOP_CRY: return "AOP_CRY";
68 case AOP_ACC: return "AOP_ACC";
69 case AOP_PCODE: return "AOP_PCODE";
70 case AOP_STA: return "AOP_STA";
76 const char *pic16_pCodeOpType(pCodeOp *pcop)
83 case PO_NONE: return "PO_NONE";
84 case PO_W: return "PO_W";
85 case PO_WREG: return "PO_WREG";
86 case PO_STATUS: return "PO_STATUS";
87 case PO_BSR: return "PO_BSR";
88 case PO_FSR0: return "PO_FSR0";
89 case PO_INDF0: return "PO_INDF0";
90 case PO_INTCON: return "PO_INTCON";
91 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
92 case PO_GPR_BIT: return "PO_GPR_BIT";
93 case PO_GPR_TEMP: return "PO_GPR_TEMP";
94 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
95 case PO_PCL: return "PO_PCL";
96 case PO_PCLATH: return "PO_PCLATH";
97 case PO_PCLATU: return "PO_PCLATU";
98 case PO_PRODL: return "PO_PRODL";
99 case PO_PRODH: return "PO_PRODH";
100 case PO_LITERAL: return "PO_LITERAL";
101 case PO_REL_ADDR: return "PO_REL_ADDR";
102 case PO_IMMEDIATE: return "PO_IMMEDIATE";
103 case PO_DIR: return "PO_DIR";
104 case PO_CRY: return "PO_CRY";
105 case PO_BIT: return "PO_BIT";
106 case PO_STR: return "PO_STR";
107 case PO_LABEL: return "PO_LABEL";
108 case PO_WILD: return "PO_WILD";
109 case PO_TWO_OPS: return "PO_TWO_OPS";
113 return "BAD PO_TYPE";
116 const char *pic16_pCodeOpSubType(pCodeOp *pcop)
119 if(pcop && (pcop->type == PO_GPR_BIT)) {
121 switch(PCORB(pcop)->subtype) {
123 case PO_NONE: return "PO_NONE";
124 case PO_W: return "PO_W";
125 case PO_WREG: return "PO_WREG";
126 case PO_STATUS: return "PO_STATUS";
127 case PO_BSR: return "PO_BSR";
128 case PO_FSR0: return "PO_FSR0";
129 case PO_INDF0: return "PO_INDF0";
130 case PO_INTCON: return "PO_INTCON";
131 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
132 case PO_GPR_BIT: return "PO_GPR_BIT";
133 case PO_GPR_TEMP: return "PO_GPR_TEMP";
134 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
135 case PO_PCL: return "PO_PCL";
136 case PO_PCLATH: return "PO_PCLATH";
137 case PO_PCLATU: return "PO_PCLATU";
138 case PO_PRODL: return "PO_PRODL";
139 case PO_PRODH: return "PO_PRODH";
140 case PO_LITERAL: return "PO_LITERAL";
141 case PO_REL_ADDR: return "PO_REL_ADDR";
142 case PO_IMMEDIATE: return "PO_IMMEDIATE";
143 case PO_DIR: return "PO_DIR";
144 case PO_CRY: return "PO_CRY";
145 case PO_BIT: return "PO_BIT";
146 case PO_STR: return "PO_STR";
147 case PO_LABEL: return "PO_LABEL";
148 case PO_WILD: return "PO_WILD";
149 case PO_TWO_OPS: return "PO_TWO_OPS";
153 return "BAD PO_TYPE";
156 /*-----------------------------------------------------------------*/
157 /* pic16_genPlusIncr :- does addition with increment if possible */
158 /*-----------------------------------------------------------------*/
159 bool pic16_genPlusIncr (iCode *ic)
161 unsigned int icount ;
162 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
166 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
167 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
168 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
169 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
171 /* will try to generate an increment */
172 /* if the right side is not a literal
174 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
177 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
178 /* if the literal value of the right hand side
179 is greater than 2 then it is faster to add */
180 if ((icount = (unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
183 /* if increment 16 bits in register */
184 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
189 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
190 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
194 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
195 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
201 // DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
202 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
203 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
204 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
206 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
208 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
209 //pic16_emitcode("xorlw","1");
211 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
212 //pic16_emitcode("andlw","1");
215 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
221 /* if the sizes are greater than 1 then we cannot */
222 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
223 AOP_SIZE(IC_LEFT(ic)) > 1 )
226 /* If we are incrementing the same register by two: */
228 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
231 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
232 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
237 DEBUGpic16_emitcode ("; ","couldn't increment ");
242 /*-----------------------------------------------------------------*/
243 /* pic16_outBitAcc - output a bit in acc */
244 /*-----------------------------------------------------------------*/
245 void pic16_outBitAcc(operand *result)
247 symbol *tlbl = newiTempLabel(NULL);
248 /* if the result is a bit */
249 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
251 assert(0); // not implemented for PIC16?
253 if (AOP_TYPE(result) == AOP_CRY){
254 pic16_aopPut(AOP(result),"a",0);
257 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
258 pic16_emitcode("mov","a,#01");
259 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
260 pic16_outAcc(result);
264 /*-----------------------------------------------------------------*/
265 /* pic16_genPlusBits - generates code for addition of two bits */
266 /*-----------------------------------------------------------------*/
267 void pic16_genPlusBits (iCode *ic)
271 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
272 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
273 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
274 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
276 The following block of code will add two bits.
277 Note that it'll even work if the destination is
278 the carry (C in the status register).
279 It won't work if the 'Z' bit is a source or destination.
282 /* If the result is stored in the accumulator (w) */
283 //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
284 switch(AOP_TYPE(IC_RESULT(ic))) {
286 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
287 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
288 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
289 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
290 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
293 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
294 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
295 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
296 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
297 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
298 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
301 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
302 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
303 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
304 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
305 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
306 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
313 /* This is the original version of this code.
315 * This is being kept around for reference,
316 * because I am not entirely sure I got it right...
318 static void adjustArithmeticResult(iCode *ic)
320 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
321 AOP_SIZE(IC_LEFT(ic)) == 3 &&
322 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
323 pic16_aopPut(AOP(IC_RESULT(ic)),
324 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
327 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
328 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
329 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
330 pic16_aopPut(AOP(IC_RESULT(ic)),
331 pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
334 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
335 AOP_SIZE(IC_LEFT(ic)) < 3 &&
336 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
337 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
338 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
340 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
341 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
345 /* This is the pure and virtuous version of this code.
346 * I'm pretty certain it's right, but not enough to toss the old
349 static void adjustArithmeticResult(iCode *ic)
351 if (opIsGptr(IC_RESULT(ic)) &&
352 opIsGptr(IC_LEFT(ic)) &&
353 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
355 pic16_aopPut(AOP(IC_RESULT(ic)),
356 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
360 if (opIsGptr(IC_RESULT(ic)) &&
361 opIsGptr(IC_RIGHT(ic)) &&
362 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
364 pic16_aopPut(AOP(IC_RESULT(ic)),
365 pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
369 if (opIsGptr(IC_RESULT(ic)) &&
370 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
371 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
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,GPTRSIZE - 1);
382 /*-----------------------------------------------------------------*/
383 /* genAddlit - generates code for addition */
384 /*-----------------------------------------------------------------*/
385 static void genAddLit2byte (operand *result, int offr, int lit)
393 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
396 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
399 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
400 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
406 static void emitMOVWF(operand *reg, int offset)
411 if (AOP_TYPE(reg) == AOP_ACC) {
412 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
416 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
423 static void genAddLit (iCode *ic, int lit)
436 result = IC_RESULT(ic);
437 same = pic16_sameRegs(AOP(left), AOP(result));
438 size = pic16_getDataSize(result);
442 /* Handle special cases first */
444 genAddLit2byte (result, 0, lit);
447 int hi = 0xff & (lit >> 8);
454 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
459 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
461 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
464 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
465 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
466 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
470 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
471 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
473 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
481 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
484 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
487 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
488 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
490 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
492 case 0xff: /* 0x01ff */
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));
496 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
498 default: /* 0x01LL */
499 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
500 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
502 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
503 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
508 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
512 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
515 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
516 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
518 /* case 0xff: * 0xffff *
519 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
520 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
521 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
525 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
526 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
528 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
535 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
540 genAddLit2byte (result, MSB16, hi);
543 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
544 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
545 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
547 /* case 0xff: * 0xHHff *
548 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
549 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
550 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
551 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
553 */ default: /* 0xHHLL */
554 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
555 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
556 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
557 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
566 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
569 lo = BYTEofLONG(lit,0);
572 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
573 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
575 /* no carry info from previous step */
576 /* this means this is the first time to add */
581 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
585 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
586 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
588 carry_info = 3; /* Were adding only one byte and propogating the carry */
599 lo = BYTEofLONG(lit,0);
604 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
607 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
608 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
611 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
613 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
615 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
624 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
628 if(AOP_TYPE(left) == AOP_ACC) {
629 /* left addend is already in accumulator */
632 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
636 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
637 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
641 /* left addend is in a register */
644 pic16_mov2w(AOP(left),0);
645 emitMOVWF(result, 0);
648 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
649 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
653 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
654 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
658 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
659 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
660 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
665 // } else if (pic16_isLitAop(AOP(left))) {
666 // // adding two literals
667 // assert ( !"adding two literals is not yet supported" );
671 /* left is not the accumulator */
673 pic16_mov2w(AOP(left),0);
674 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
676 pic16_mov2w(AOP(left),0);
677 /* We don't know the state of the carry bit at this point */
680 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
684 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
685 if (offset < AOP_SIZE(left)) {
686 pic16_emitpcode(clear_carry ? POC_ADDFW : POC_ADDFWC, pic16_popGet(AOP(left),offset));
687 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
689 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
690 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
691 /* sign-extend left (in result) */
692 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left),AOP_SIZE(left)-1,7));
693 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
695 pic16_emitpcode(clear_carry ? POC_ADDWF : POC_ADDWFC, pic16_popGet(AOP(result),offset));
705 /* this fails when result is an SFR because value is written there
706 * during addition and not at the end */
708 static void genAddLit (iCode *ic, int lit)
721 result = IC_RESULT(ic);
722 same = pic16_sameRegs(AOP(left), AOP(result));
723 size = pic16_getDataSize(result);
724 sizeL = pic16_getDataSize(left);
727 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
728 /* move left to result -- possibly sign extend */
729 for (i=0; i < MIN(size, sizeL); i++) {
730 pic16_mov2f (AOP(result), AOP(left), i);
734 /* extend to result size */
735 pic16_addSign(result, sizeL, !IS_UNSIGNED(operandType(left)));
740 } else if (lit == 1) {
746 pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(result), 0));
750 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), 0));
751 for (i=1; i < size-1; i++) {
752 emitSKPNC; /* a jump here saves up to 2(size-2)cycles */
753 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), i));
759 pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1));
763 /* add literal to result */
764 for (i=0; i < size; i++) {
765 pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit));
766 llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */
767 pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC,
768 pic16_popGet (AOP(result), i));
776 /* Handle special cases first */
778 genAddLit2byte (result, 0, lit);
781 int hi = 0xff & (lit >> 8);
788 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
793 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
795 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
798 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
799 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
800 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
804 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
805 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
807 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
815 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
818 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
821 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
822 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
824 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
826 case 0xff: /* 0x01ff */
827 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
828 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
829 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
830 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
832 default: /* 0x01LL */
833 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
834 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
836 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
837 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
842 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
846 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
849 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
850 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
852 /* case 0xff: * 0xffff *
853 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
854 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
855 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
859 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
860 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
862 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
869 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
874 genAddLit2byte (result, MSB16, hi);
877 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
878 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
879 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
881 /* case 0xff: * 0xHHff *
882 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
883 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
884 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
885 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
887 */ default: /* 0xHHLL */
888 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
889 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
890 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
891 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
900 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
903 lo = BYTEofLONG(lit,0);
906 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
907 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
909 /* no carry info from previous step */
910 /* this means this is the first time to add */
915 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
919 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
920 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
922 carry_info = 3; /* Were adding only one byte and propogating the carry */
933 lo = BYTEofLONG(lit,0);
938 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
941 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
942 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
945 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
947 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
949 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
958 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
962 if(AOP_TYPE(left) == AOP_ACC) {
963 /* left addend is already in accumulator */
966 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
970 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
971 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
975 /* left addend is in a register */
978 pic16_mov2w(AOP(left),0);
979 emitMOVWF(result, 0);
982 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
983 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
987 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
988 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
992 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
993 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
994 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1002 /* left is not the accumulator */
1004 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1005 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1007 pic16_mov2w(AOP(left),0);
1008 /* We don't know the state of the carry bit at this point */
1011 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1012 emitMOVWF(result,0);
1018 /* The ls byte of the lit must've been zero - that
1019 means we don't have to deal with carry */
1021 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1022 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
1023 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1028 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1029 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
1030 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1034 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
1035 pic16_mov2w(AOP(left),offset);
1036 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
1047 /*-----------------------------------------------------------------*/
1048 /* pic16_genPlus - generates code for addition */
1049 /*-----------------------------------------------------------------*/
1050 void pic16_genPlus (iCode *ic)
1052 int i, size, offset = 0;
1053 operand *result, *left, *right;
1057 /* special cases :- */
1058 result = IC_RESULT(ic);
1060 right = IC_RIGHT(ic);
1061 pic16_aopOp (left,ic,FALSE);
1062 pic16_aopOp (right,ic,FALSE);
1063 pic16_aopOp (result,ic,TRUE);
1064 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
1065 // pic16_DumpOp("(left)",left);
1067 /* if literal, literal on the right or
1068 if left requires ACC or right is already
1071 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
1073 right = IC_RIGHT(ic) = left;
1074 left = IC_LEFT(ic) = t;
1077 /* if both left & right are in bit space */
1078 if (AOP_TYPE(left) == AOP_CRY &&
1079 AOP_TYPE(right) == AOP_CRY) {
1080 pic16_genPlusBits (ic);
1084 /* if left in bit space & right literal */
1085 if (AOP_TYPE(left) == AOP_CRY &&
1086 AOP_TYPE(right) == AOP_LIT) {
1087 /* if result in bit space */
1088 if(AOP_TYPE(result) == AOP_CRY){
1089 if(ulFromVal (AOP(right)->aopu.aop_lit) != 0L) {
1090 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
1091 if (!pic16_sameRegs(AOP(left), AOP(result)) )
1092 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
1093 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
1096 unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit);
1097 size = pic16_getDataSize(result);
1099 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
1100 pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
1101 pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
1102 //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
1103 //pic16_emitcode("addc","a,#00 ;%d",__LINE__);
1104 //pic16_aopPut(AOP(result),"a",offset++);
1110 /* if I can do an increment instead
1111 of add then GOOD for ME */
1112 if (pic16_genPlusIncr (ic) == TRUE)
1115 size = pic16_getDataSize(result);
1117 if(AOP(right)->type == AOP_LIT) {
1118 /* Add a literal to something else */
1120 unsigned lit = (unsigned) ulFromVal (AOP(right)->aopu.aop_lit);
1124 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
1126 genAddLit (ic, lit);
1129 } else if(AOP_TYPE(right) == AOP_CRY) {
1131 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
1132 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
1133 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
1135 /* here we are adding a bit to a char or int */
1137 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1139 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1140 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0));
1141 } else { // not same
1143 if(AOP_TYPE(left) == AOP_ACC) {
1144 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1145 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1147 pic16_mov2w(AOP(left),0);
1148 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1149 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
1152 if(AOP_TYPE(result) != AOP_ACC) {
1154 if(AOP_TYPE(result) == AOP_CRY) {
1155 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1156 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0));
1158 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0));
1160 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0));
1167 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1168 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1170 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1171 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
1173 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
1174 pic16_mov2w(AOP(left),0);
1175 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1176 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1182 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++));
1190 // Note: the following is an example of WISC code, eg.
1191 // it's supposed to run on a Weird Instruction Set Computer :o)
1193 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1195 if ( AOP_TYPE(left) == AOP_ACC) {
1196 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1197 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
1198 if ( AOP_TYPE(result) != AOP_ACC)
1199 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1200 goto release; // we're done, since WREG is 1 byte
1204 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1206 size = min( AOP_SIZE(result), AOP_SIZE(right) );
1207 size = min( size, AOP_SIZE(left) );
1210 if(pic16_debug_verbose) {
1211 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
1212 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
1213 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
1218 if ((AOP_TYPE(left) == AOP_PCODE) && (
1219 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
1220 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
1221 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
1223 // add to literal operand
1226 for(i=0; i<size; i++) {
1227 if (AOP_TYPE(right) == AOP_ACC) {
1228 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1230 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1231 if(i) { // add with carry
1232 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1233 } else { // add without
1234 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1237 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1240 DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
1242 // add leftover bytes
1243 if (SPEC_USIGN(getSpec(operandType(right)))) {
1244 // right is unsigned
1245 for(i=size; i< AOP_SIZE(result); i++) {
1246 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1247 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1248 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1252 // right is signed, oh dear ...
1253 for(i=size; i< AOP_SIZE(result); i++) {
1254 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1255 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1256 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),i));
1257 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1258 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1267 if (pic16_sameRegs(AOP(left), AOP(result))
1268 && (AOP_SIZE(left) < AOP_SIZE(result)))
1270 // extend left operand, sign-bit still intact
1271 pic16_addSign (result, AOP_SIZE(left), !SPEC_USIGN(getSpec(operandType(left))));
1275 for(i=0; i<size; i++) {
1276 if (AOP_TYPE(right) != AOP_ACC)
1277 pic16_mov2w(AOP(right),i);
1278 if (pic16_sameRegs(AOP(left), AOP(result)))
1280 if(i) { // add with carry
1281 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1282 } else { // add without
1283 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1285 } else { // not same
1286 if(i) { // add with carry
1287 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1288 } else { // add without
1289 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1291 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1295 // add leftover bytes
1296 // either left or right is too short
1297 for (i=size; i < AOP_SIZE(result); i++) {
1298 // get right operand into WREG
1299 if (i < AOP_SIZE(right)) {
1300 pic16_mov2w (AOP(right), i);
1302 // right is too short, not overwritten with result
1303 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1304 if (!SPEC_USIGN(getSpec(operandType(right)))) {
1305 // right operand is signed
1306 // Make sure that right's sign is not yet overwritten
1307 assert (!pic16_sameRegs (AOP(right), AOP(result)));
1308 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1309 pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1313 // get left+WREG+CARRY into result
1314 if (pic16_sameRegs (AOP(left), AOP(result))) {
1315 // left might have been extended in result above
1316 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1317 } else if (i < AOP_SIZE(left)) {
1318 pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
1319 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1321 // left is too short, not overwritten with result
1322 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
1323 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1324 // left operand is signed
1325 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1326 pic16_emitpcode(POC_SETF, pic16_popGet (AOP(result), i));
1328 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1339 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1340 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1341 pic16_freeAsmop(result,NULL,ic,TRUE);
1344 /*-----------------------------------------------------------------*/
1345 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1346 /*-----------------------------------------------------------------*/
1347 bool pic16_genMinusDec (iCode *ic)
1349 unsigned int icount ;
1350 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1353 /* will try to generate an increment */
1354 /* if the right side is not a literal
1356 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1357 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1358 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1361 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1363 /* if the literal value of the right hand side
1364 is greater than 4 then it is not worth it */
1365 if ((icount = (unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1368 /* if decrement 16 bits in register */
1369 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1374 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1376 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1378 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1379 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1380 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1382 /* size is 3 or 4 */
1383 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1384 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1385 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1386 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1388 pic16_emitcode("movlw","0xff");
1389 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1392 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1394 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1397 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1399 pic16_emitcode("skpnc","");
1401 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1410 /* if the sizes are greater than 1 then we cannot */
1411 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1412 AOP_SIZE(IC_LEFT(ic)) > 1 )
1415 /* we can if the aops of the left & result match or
1416 if they are in registers and the registers are the
1418 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1421 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1423 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1428 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1429 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1430 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1433 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1434 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1436 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1437 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1445 /*-----------------------------------------------------------------*/
1446 /* pic16_addSign - propogate sign bit to higher bytes */
1447 /*-----------------------------------------------------------------*/
1448 void pic16_addSign(operand *result, int offset, int sign)
1450 int size = (pic16_getDataSize(result) - offset);
1451 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1454 if(sign && offset) {
1457 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1458 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1459 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
1462 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1463 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1464 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1466 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1471 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1475 /*-----------------------------------------------------------------*/
1476 /* pic16_genMinus - generates code for subtraction */
1477 /*-----------------------------------------------------------------*/
1478 void pic16_genMinus (iCode *ic)
1480 int size, offset = 0, same=0;
1481 unsigned long lit = 0L;
1484 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1485 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1486 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1488 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1489 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1490 operand *t = IC_RIGHT(ic);
1491 IC_RIGHT(ic) = IC_LEFT(ic);
1495 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1496 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1497 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1498 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1500 /* special cases :- */
1501 /* if both left & right are in bit space */
1502 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1503 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1504 pic16_genPlusBits (ic);
1508 /* if I can do an decrement instead
1509 of subtract then GOOD for ME */
1510 // if (pic16_genMinusDec (ic) == TRUE)
1513 size = pic16_getDataSize(IC_RESULT(ic));
1514 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1516 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1517 /* Add a literal to something else */
1519 lit = ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
1522 genAddLit ( ic, lit);
1523 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1526 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1527 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1528 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1530 /* here we are subtracting a bit from a char or int */
1532 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1534 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1535 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1538 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1539 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1540 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1541 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1543 lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
1545 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1546 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1548 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1549 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1552 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1554 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1556 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1557 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1561 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1562 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1563 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1564 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1569 pic16_mov2w(AOP(IC_LEFT(ic)),0);
1570 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1571 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1574 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1576 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1579 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1581 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1583 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1590 } else if((AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1591 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1593 lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
1594 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1595 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1596 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1597 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1600 if( (size == 1) && ((lit & 0xff) == 0) ) {
1601 /* res = 0 - right */
1602 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1603 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1605 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1606 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1607 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1612 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1613 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1614 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1622 // here we have x = lit - x for sizeof(x)>1
1623 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1624 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1626 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1627 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1628 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1635 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1636 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1637 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1638 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1640 if ((AOP_SIZE(IC_LEFT(ic)) < AOP_SIZE(IC_RESULT(ic)))
1641 && pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1642 // extend left in result
1643 pic16_addSign (IC_RESULT(ic), AOP_SIZE(IC_LEFT(ic)), !SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))));
1646 if ((AOP_SIZE(IC_RIGHT(ic)) < AOP_SIZE(IC_RESULT(ic)))
1647 && pic16_sameRegs (AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1648 // extend right in result---fails if left resides in result as well...
1649 assert ((IC_LEFT(ic) == IC_RIGHT(ic)) || !pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))));
1650 pic16_addSign (IC_RESULT(ic), AOP_SIZE(IC_RIGHT(ic)), !SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))));
1653 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1654 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1655 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1656 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1657 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1658 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1661 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1662 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1663 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1665 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1666 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1668 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1669 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1671 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1673 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1674 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1675 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1677 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1679 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1685 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1687 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1688 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1690 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1691 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1698 if (pic16_sameRegs (AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1699 pic16_mov2w (AOP(IC_RESULT(ic)), offset);
1700 } else if (offset < AOP_SIZE(IC_RIGHT(ic)))
1701 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1703 // right operand is too short, not overwritten with result
1704 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1705 if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
1706 // signed -- sign extend the right operand
1707 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));
1708 pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1711 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1712 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1713 } else if (offset < AOP_SIZE(IC_LEFT(ic))) {
1714 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1715 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1717 // left operand is too short, not overwritten with result
1718 pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
1719 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
1720 // signed -- sign extend the left operand
1721 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));
1722 pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
1724 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1730 // adjustArithmeticResult(ic);
1733 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1734 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1735 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1739 /*-----------------------------------------------------------------*
1740 * pic_genMult8XLit_n - multiplication of two 8-bit numbers.
1743 *-----------------------------------------------------------------*/
1744 void pic16_genMult8XLit_n (operand *left,
1750 int size = AOP_SIZE(result);
1754 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1756 if (AOP_TYPE(right) != AOP_LIT){
1757 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1761 lit = (int) ulFromVal (AOP(right)->aopu.aop_lit);
1762 assert( (lit >= -128) && (lit < 256) );
1763 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1764 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1766 same = pic16_sameRegs(AOP(left), AOP(result));
1768 switch(lit & 0x00ff) {
1771 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1776 /* sign extend left in result */
1777 pic16_addSign(result, 1, !IS_UNSIGNED(operandType(left)));
1778 // its faster to left shift
1780 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1782 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1786 if(AOP_TYPE(left) != AOP_ACC)
1787 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1788 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit & 0x00ff));
1789 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1790 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1791 /* Adjust result's high bytes below! */
1794 // operands different
1795 switch(lit & 0x00ff) {
1798 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1803 if (IS_UNSIGNED(operandType(result))) {
1804 for (i=1; i < size; i++) {
1805 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1808 /* sign extend left to result */
1809 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1810 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
1811 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1812 for (i=1; i < size; i++) {
1813 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1817 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1818 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1820 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1824 if(AOP_TYPE(left) != AOP_ACC)
1825 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1826 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1827 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1828 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1829 /* Adjust result's high bytes below! */
1834 /* We need to fix PRODH for
1835 * (a) literals < 0 and
1836 * (b) signed register operands < 0.
1838 //printf( "%s: lit %d, left unsigned: %d\n", __FUNCTION__, lit, SPEC_USIGN(getSpec(operandType(left))));
1840 /* literal negative (i.e. in [-128..-1]), high byte == -1 */
1841 pic16_mov2w(AOP(left), 0);
1842 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
1845 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1846 /* register operand signed, determine signedness of high byte */
1847 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0x00ff));
1848 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
1849 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
1852 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1853 &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1855 /* Need to sign-extend here. */
1856 pic16_addSign(result, 2, !IS_UNSIGNED(operandType(result)));
1861 /*-----------------------------------------------------------------------*
1862 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1863 *-----------------------------------------------------------------------*/
1864 void pic16_genUMult16XLit_16 (operand *left,
1868 pCodeOp *pct1, *pct2, *pct3, *pct4;
1875 if (AOP_TYPE(right) != AOP_LIT){
1876 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1880 lit = (unsigned int) ulFromVal (AOP(right)->aopu.aop_lit);
1883 same = pic16_sameRegs(AOP(left), AOP(result));
1887 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1888 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1891 // its faster to left shift
1893 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1894 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1898 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1900 pct1 = pic16_popGetTempReg(1);
1901 pct2 = pic16_popGetTempReg(1);
1902 pct3 = pic16_popGetTempReg(1);
1903 pct4 = pic16_popGetTempReg(1);
1905 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1906 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1907 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1908 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1909 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1910 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1912 /* WREG still holds the low literal */
1913 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1914 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1915 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1917 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1918 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1919 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1920 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1923 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1924 pct1, pic16_popGet(AOP(result), 0)));
1925 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1926 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1927 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1928 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1930 pic16_popReleaseTempReg(pct4,1);
1931 pic16_popReleaseTempReg(pct3,1);
1932 pic16_popReleaseTempReg(pct2,1);
1933 pic16_popReleaseTempReg(pct1,1);
1937 // operands different
1940 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1941 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1945 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1946 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1947 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1948 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1952 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1953 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1954 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1955 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1956 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1957 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1959 /* WREG still holds the low literal */
1960 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1961 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1962 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1964 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1965 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1966 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1967 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1976 /*-----------------------------------------------------------------*
1977 * genMult8X8_n - multiplication of two 8-bit numbers.
1980 *-----------------------------------------------------------------*/
1981 void pic16_genMult8X8_n (operand *left, operand *right, operand *result)
1987 if (AOP_TYPE(right) == AOP_LIT) {
1988 pic16_genMult8XLit_n(left,right,result);
1998 /* if result == right then exchange left and right */
1999 if(pic16_sameRegs(AOP(result), AOP(right))) {
2006 if(AOP_TYPE(left) != AOP_ACC) {
2008 if(AOP_TYPE(right) != AOP_ACC) {
2009 pic16_mov2w(AOP(left), 0);
2010 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2012 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2015 // left is WREG, right cannot be WREG (or can?!)
2016 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
2019 /* result is in PRODL:PRODH */
2020 if(AOP_TYPE(result) != AOP_ACC) {
2021 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
2022 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2025 if(AOP_SIZE(result)>1) {
2027 /* If s8 x s8 --> s16 multiplication was called for, fixup high byte.
2028 * (left=a1a0, right=b1b0, X1: high byte, X0: low byte)
2035 * a0b0 a1= 0, b1= 0 (both unsigned)
2036 * -b0 a0b0 a1=-1, b1= 0 (a signed and < 0, b unsigned or >= 0)
2037 * -a0 a0b0 a1= 0, b1=-1 (b signed and < 0, a unsigned or >= 0)
2038 * -(a0+b0) a0b0 a1=-1, b1=-1 (a and b signed and < 0)
2040 * Currently, PRODH:PRODL holds a0b0 as 16 bit value; we need to
2041 * subtract a0 and/or b0 from PRODH. */
2042 if (!IS_UNSIGNED(operandType(right))) {
2043 /* right operand (b1) signed and < 0, then subtract left op (a0) */
2044 pic16_mov2w( AOP(left), 0 );
2045 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
2046 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
2049 if (!IS_UNSIGNED(getSpec(operandType(left)))) {
2050 /* left operand (a1) signed and < 0, then subtract right op (b0) */
2051 pic16_mov2w( AOP(right), 0 );
2052 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
2053 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
2056 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
2057 &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2059 /* Must sign-extend here. */
2060 pic16_addSign(result, 2, !IS_UNSIGNED(operandType(left)));
2063 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2068 /*------------------------------------------------------------------*
2069 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
2070 *------------------------------------------------------------------*/
2071 void pic16_genUMult16X16_16 (operand *left,
2076 pCodeOp *pct1, *pct2, *pct3, *pct4;
2081 if (AOP_TYPE(right) == AOP_LIT) {
2082 pic16_genMult8XLit_n(left,right,result);
2090 /* if result == right then exchange left and right */
2091 if(pic16_sameRegs(AOP(result), AOP(right))) {
2099 if(pic16_sameRegs(AOP(result), AOP(left))) {
2101 pct1 = pic16_popGetTempReg(1);
2102 pct2 = pic16_popGetTempReg(1);
2103 pct3 = pic16_popGetTempReg(1);
2104 pct4 = pic16_popGetTempReg(1);
2106 pic16_mov2w(AOP(left), 0);
2107 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2108 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2109 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2110 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2111 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2113 /* WREG still holds the lower left */
2114 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2115 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2116 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2118 pic16_mov2w(AOP(left), 1);
2119 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2120 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2121 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2124 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2125 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2126 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2127 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2128 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2129 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2131 pic16_popReleaseTempReg( pct4, 1 );
2132 pic16_popReleaseTempReg( pct3, 1 );
2133 pic16_popReleaseTempReg( pct2, 1 );
2134 pic16_popReleaseTempReg( pct1, 1 );
2138 pic16_mov2w(AOP(left), 0);
2139 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2140 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2141 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2142 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2143 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2145 /* WREG still holds the lower left */
2146 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2147 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2148 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2150 pic16_mov2w(AOP(left), 1);
2151 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2152 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2153 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2159 void pic16_genSMult16X16_16(operand *left,
2168 /*-----------------------------------------------------------------*
2169 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
2171 * this routine will call the unsigned multiply routine and then
2172 * post-fix the sign bit.
2173 *-----------------------------------------------------------------*/
2174 void pic16_genSMult8X8_8 (operand *left,
2177 pCodeOpReg *result_hi)
2179 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2183 result_hi = PCOR(pic16_popGet(AOP(result),1));
2187 pic16_genUMult8X8_8(left,right,result);
2191 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2192 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2193 pic16_mov2w(AOP(left),0);
2194 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2195 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2200 /*-----------------------------------------------------------------*
2201 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
2202 *-----------------------------------------------------------------*/
2203 void pic16_genMult8X8_8 (operand *left,
2209 if(AOP_TYPE(right) == AOP_LIT)
2210 pic16_genMult8XLit_n(left,right,result);
2212 pic16_genMult8X8_n(left,right,result);
2217 /*-----------------------------------------------------------------*
2218 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
2219 *-----------------------------------------------------------------*/
2220 void pic16_genMult16X16_16 (operand *left,
2226 if (AOP_TYPE(right) == AOP_LIT)
2227 pic16_genUMult16XLit_16(left,right,result);
2229 pic16_genUMult16X16_16(left,right,result);
2235 /*-----------------------------------------------------------------------*
2236 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2237 *-----------------------------------------------------------------------*/
2238 void pic16_genUMult32XLit_32 (operand *left,
2242 pCodeOp *pct1, *pct2, *pct3, *pct4;
2249 if (AOP_TYPE(right) != AOP_LIT){
2250 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2254 lit = (unsigned int) ulFromVal (AOP(right)->aopu.aop_lit);
2257 same = pic16_sameRegs(AOP(left), AOP(result));
2261 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2262 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2265 // its faster to left shift
2267 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2268 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2272 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2274 pct1 = pic16_popGetTempReg(1);
2275 pct2 = pic16_popGetTempReg(1);
2276 pct3 = pic16_popGetTempReg(1);
2277 pct4 = pic16_popGetTempReg(1);
2279 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2280 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2281 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2282 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2283 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2284 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2286 /* WREG still holds the low literal */
2287 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2288 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2289 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2291 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2292 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2293 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2294 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2297 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2298 pct1, pic16_popGet(AOP(result), 0)));
2299 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2300 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2301 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2302 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2304 pic16_popReleaseTempReg( pct4, 1 );
2305 pic16_popReleaseTempReg( pct3, 1 );
2306 pic16_popReleaseTempReg( pct2, 1 );
2307 pic16_popReleaseTempReg( pct1, 1 );
2311 // operands different
2314 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2315 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2319 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2320 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2321 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2322 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2326 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2327 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2328 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2329 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2330 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2331 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2333 /* WREG still holds the low literal */
2334 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2335 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2336 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2338 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2339 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2340 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2341 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2350 /*------------------------------------------------------------------*
2351 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2352 *------------------------------------------------------------------*/
2353 void pic16_genUMult32X32_32 (operand *left,
2358 pCodeOp *pct1, *pct2, *pct3, *pct4;
2362 if (AOP_TYPE(right) == AOP_LIT) {
2363 pic16_genMult8XLit_n(left,right,result);
2371 /* if result == right then exchange left and right */
2372 if(pic16_sameRegs(AOP(result), AOP(right))) {
2380 if(pic16_sameRegs(AOP(result), AOP(left))) {
2382 pct1 = pic16_popGetTempReg(1);
2383 pct2 = pic16_popGetTempReg(1);
2384 pct3 = pic16_popGetTempReg(1);
2385 pct4 = pic16_popGetTempReg(1);
2387 pic16_mov2w(AOP(left), 0);
2388 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2389 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2390 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2391 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2392 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2394 /* WREG still holds the lower left */
2395 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2396 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2397 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2399 pic16_mov2w(AOP(left), 1);
2400 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2401 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2402 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2405 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2406 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2407 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2408 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2409 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2410 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2412 pic16_popReleaseTempReg( pct4, 1 );
2413 pic16_popReleaseTempReg( pct3, 1 );
2414 pic16_popReleaseTempReg( pct2, 1 );
2415 pic16_popReleaseTempReg( pct1, 1 );
2419 pic16_mov2w(AOP(left), 0);
2420 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2421 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2422 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2423 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2424 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2426 /* WREG still holds the lower left */
2427 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2428 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2429 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2431 pic16_mov2w(AOP(left), 1);
2432 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2433 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2434 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2441 /*-----------------------------------------------------------------*
2442 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2443 *-----------------------------------------------------------------*/
2444 void pic16_genMult32X32_32 (operand *left,
2450 if (AOP_TYPE(right) == AOP_LIT)
2451 pic16_genUMult32XLit_32(left,right,result);
2453 pic16_genUMult32X32_32(left,right,result);
2464 /*-----------------------------------------------------------------*/
2465 /* constMult - generates code for multiplication by a constant */
2466 /*-----------------------------------------------------------------*/
2467 void genMultConst(unsigned C)
2471 unsigned sr3; // Shift right 3
2477 Convert a string of 3 binary 1's in the lit into
2481 mask = 7 << ( (size*8) - 3);
2485 while(mask < (1<<size*8)) {
2487 if( (mask & lit) == lit) {
2490 /* We found 3 (or more) consecutive 1's */
2492 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2494 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2496 lit ^= consecutive_bits;
2500 sr3 |= (consecutive + lsb);