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)
435 result = IC_RESULT(ic);
436 same = pic16_sameRegs(AOP(left), AOP(result));
437 size = pic16_getDataSize(result);
439 if ((AOP_PCODE == AOP_TYPE(left))
440 && (PO_IMMEDIATE == AOP(left)->aopu.pcop->type))
442 /* see #1888004 for an example case for this */
443 for (offset = 0; offset < size; offset++) {
444 pic16_emitpcode(POC_MOVLW, pic16_newpCodeOpImmd(AOP(left)->aopu.pcop->name,
445 offset, PCOI(AOP(left)->aopu.pcop)->index + lit, 0));
446 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
453 /* Handle special cases first */
455 genAddLit2byte (result, 0, lit);
458 int hi = 0xff & (lit >> 8);
465 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
470 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
472 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
475 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
476 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
477 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
481 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
482 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
484 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
492 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
495 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
498 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
499 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
501 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
503 case 0xff: /* 0x01ff */
504 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
505 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
506 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
507 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
509 default: /* 0x01LL */
510 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
511 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
513 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
514 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
519 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
523 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
526 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
527 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
529 /* case 0xff: * 0xffff *
530 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
531 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
532 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
536 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
537 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
539 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
546 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
551 genAddLit2byte (result, MSB16, hi);
554 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
555 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
556 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
558 /* case 0xff: * 0xHHff *
559 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
560 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
561 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
562 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
564 */ default: /* 0xHHLL */
565 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
566 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
567 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
568 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
577 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
580 lo = BYTEofLONG(lit,0);
583 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
584 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
586 /* no carry info from previous step */
587 /* this means this is the first time to add */
592 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
596 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
597 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
599 carry_info = 3; /* Were adding only one byte and propogating the carry */
610 lo = BYTEofLONG(lit,0);
615 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
618 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
619 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
622 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
624 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
626 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
635 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
639 if(AOP_TYPE(left) == AOP_ACC) {
640 /* left addend is already in accumulator */
643 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
647 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
648 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
652 /* left addend is in a register */
655 pic16_mov2w(AOP(left),0);
656 emitMOVWF(result, 0);
659 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
660 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
664 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
665 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
669 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
670 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
671 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
676 // } else if (pic16_isLitAop(AOP(left))) {
677 // // adding two literals
678 // assert ( !"adding two literals is not yet supported" );
682 /* left is not the accumulator */
684 pic16_mov2w(AOP(left),0);
685 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
687 pic16_mov2w(AOP(left),0);
688 /* We don't know the state of the carry bit at this point */
691 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
695 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
696 if (offset < AOP_SIZE(left)) {
697 pic16_emitpcode(clear_carry ? POC_ADDFW : POC_ADDFWC, pic16_popGet(AOP(left),offset));
698 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
700 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
701 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
702 /* sign-extend left (in result) */
703 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left),AOP_SIZE(left)-1,7));
704 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
706 pic16_emitpcode(clear_carry ? POC_ADDWF : POC_ADDWFC, pic16_popGet(AOP(result),offset));
716 /* this fails when result is an SFR because value is written there
717 * during addition and not at the end */
719 static void genAddLit (iCode *ic, int lit)
732 result = IC_RESULT(ic);
733 same = pic16_sameRegs(AOP(left), AOP(result));
734 size = pic16_getDataSize(result);
735 sizeL = pic16_getDataSize(left);
738 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
739 /* move left to result -- possibly sign extend */
740 for (i=0; i < MIN(size, sizeL); i++) {
741 pic16_mov2f (AOP(result), AOP(left), i);
745 /* extend to result size */
746 pic16_addSign(result, sizeL, !IS_UNSIGNED(operandType(left)));
751 } else if (lit == 1) {
757 pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(result), 0));
761 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), 0));
762 for (i=1; i < size-1; i++) {
763 emitSKPNC; /* a jump here saves up to 2(size-2)cycles */
764 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), i));
770 pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1));
774 /* add literal to result */
775 for (i=0; i < size; i++) {
776 pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit));
777 llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */
778 pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC,
779 pic16_popGet (AOP(result), i));
787 /* Handle special cases first */
789 genAddLit2byte (result, 0, lit);
792 int hi = 0xff & (lit >> 8);
799 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
804 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
806 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
809 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
810 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
811 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
815 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
816 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
818 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
826 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
829 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
832 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
833 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
835 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
837 case 0xff: /* 0x01ff */
838 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
839 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
840 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
841 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
843 default: /* 0x01LL */
844 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
845 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
847 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
848 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
853 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
857 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
860 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
861 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
863 /* case 0xff: * 0xffff *
864 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
865 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
866 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
870 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
871 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
873 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
880 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
885 genAddLit2byte (result, MSB16, hi);
888 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
889 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
890 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
892 /* case 0xff: * 0xHHff *
893 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
894 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
895 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
896 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
898 */ default: /* 0xHHLL */
899 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
900 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
901 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
902 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
911 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
914 lo = BYTEofLONG(lit,0);
917 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
918 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
920 /* no carry info from previous step */
921 /* this means this is the first time to add */
926 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
930 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
931 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
933 carry_info = 3; /* Were adding only one byte and propogating the carry */
944 lo = BYTEofLONG(lit,0);
949 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
952 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
953 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
956 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
958 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
960 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
969 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
973 if(AOP_TYPE(left) == AOP_ACC) {
974 /* left addend is already in accumulator */
977 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
981 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
982 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
986 /* left addend is in a register */
989 pic16_mov2w(AOP(left),0);
990 emitMOVWF(result, 0);
993 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
994 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
998 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
999 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1000 emitMOVWF(result,0);
1003 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1004 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1005 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1006 emitMOVWF(result,0);
1013 /* left is not the accumulator */
1015 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1016 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1018 pic16_mov2w(AOP(left),0);
1019 /* We don't know the state of the carry bit at this point */
1022 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1023 emitMOVWF(result,0);
1029 /* The ls byte of the lit must've been zero - that
1030 means we don't have to deal with carry */
1032 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1033 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
1034 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1039 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1040 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
1041 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1045 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
1046 pic16_mov2w(AOP(left),offset);
1047 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
1058 /*-----------------------------------------------------------------*/
1059 /* pic16_genPlus - generates code for addition */
1060 /*-----------------------------------------------------------------*/
1061 void pic16_genPlus (iCode *ic)
1063 int i, size, offset = 0;
1064 operand *result, *left, *right;
1068 /* special cases :- */
1069 result = IC_RESULT(ic);
1071 right = IC_RIGHT(ic);
1072 pic16_aopOp (left,ic,FALSE);
1073 pic16_aopOp (right,ic,FALSE);
1074 pic16_aopOp (result,ic,TRUE);
1075 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
1076 // pic16_DumpOp("(left)",left);
1078 /* if literal, literal on the right or
1079 if left requires ACC or right is already
1082 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
1084 right = IC_RIGHT(ic) = left;
1085 left = IC_LEFT(ic) = t;
1088 /* if both left & right are in bit space */
1089 if (AOP_TYPE(left) == AOP_CRY &&
1090 AOP_TYPE(right) == AOP_CRY) {
1091 pic16_genPlusBits (ic);
1095 /* if left in bit space & right literal */
1096 if (AOP_TYPE(left) == AOP_CRY &&
1097 AOP_TYPE(right) == AOP_LIT) {
1098 /* if result in bit space */
1099 if(AOP_TYPE(result) == AOP_CRY){
1100 if(ulFromVal (AOP(right)->aopu.aop_lit) != 0L) {
1101 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
1102 if (!pic16_sameRegs(AOP(left), AOP(result)) )
1103 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
1104 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
1107 unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit);
1108 size = pic16_getDataSize(result);
1110 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
1111 pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
1112 pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
1113 //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
1114 //pic16_emitcode("addc","a,#00 ;%d",__LINE__);
1115 //pic16_aopPut(AOP(result),"a",offset++);
1121 /* if I can do an increment instead
1122 of add then GOOD for ME */
1123 if (pic16_genPlusIncr (ic) == TRUE)
1126 size = pic16_getDataSize(result);
1128 if(AOP(right)->type == AOP_LIT) {
1129 /* Add a literal to something else */
1131 unsigned lit = (unsigned) ulFromVal (AOP(right)->aopu.aop_lit);
1135 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
1137 genAddLit (ic, lit);
1140 } else if(AOP_TYPE(right) == AOP_CRY) {
1142 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
1143 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
1144 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
1146 /* here we are adding a bit to a char or int */
1148 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1150 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1151 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0));
1152 } else { // not same
1154 if(AOP_TYPE(left) == AOP_ACC) {
1155 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1156 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1158 pic16_mov2w(AOP(left),0);
1159 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1160 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
1163 if(AOP_TYPE(result) != AOP_ACC) {
1165 if(AOP_TYPE(result) == AOP_CRY) {
1166 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1167 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0));
1169 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0));
1171 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0));
1178 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1179 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1181 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1182 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
1184 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
1185 pic16_mov2w(AOP(left),0);
1186 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1187 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1193 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++));
1201 // Note: the following is an example of WISC code, eg.
1202 // it's supposed to run on a Weird Instruction Set Computer :o)
1204 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1206 if ( AOP_TYPE(left) == AOP_ACC) {
1207 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1208 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
1209 if ( AOP_TYPE(result) != AOP_ACC)
1210 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1211 goto release; // we're done, since WREG is 1 byte
1215 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1217 size = min( AOP_SIZE(result), AOP_SIZE(right) );
1218 size = min( size, AOP_SIZE(left) );
1221 if(pic16_debug_verbose) {
1222 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
1223 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
1224 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
1229 if ((AOP_TYPE(left) == AOP_PCODE) && (
1230 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
1231 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
1232 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
1234 // add to literal operand
1237 for(i=0; i<size; i++) {
1238 if (AOP_TYPE(right) == AOP_ACC) {
1239 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1241 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1242 if(i) { // add with carry
1243 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1244 } else { // add without
1245 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1248 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1251 DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
1253 // add leftover bytes
1254 if (SPEC_USIGN(getSpec(operandType(right)))) {
1255 // right is unsigned
1256 for(i=size; i< AOP_SIZE(result); i++) {
1257 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1258 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1259 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1263 // right is signed, oh dear ...
1264 for(i=size; i< AOP_SIZE(result); i++) {
1265 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1266 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1267 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),i));
1268 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1269 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1278 if (pic16_sameRegs(AOP(left), AOP(result))
1279 && (AOP_SIZE(left) < AOP_SIZE(result)))
1281 // extend left operand, sign-bit still intact
1282 pic16_addSign (result, AOP_SIZE(left), !SPEC_USIGN(getSpec(operandType(left))));
1286 for(i=0; i<size; i++) {
1287 if (AOP_TYPE(right) != AOP_ACC)
1288 pic16_mov2w(AOP(right),i);
1289 if (pic16_sameRegs(AOP(left), AOP(result)))
1291 if(i) { // add with carry
1292 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1293 } else { // add without
1294 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1296 } else { // not same
1297 if(i) { // add with carry
1298 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1299 } else { // add without
1300 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1302 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1306 // add leftover bytes
1307 // either left or right is too short
1308 for (i=size; i < AOP_SIZE(result); i++) {
1309 // get right operand into WREG
1310 if (i < AOP_SIZE(right)) {
1311 pic16_mov2w (AOP(right), i);
1313 // right is too short, not overwritten with result
1314 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1315 if (!SPEC_USIGN(getSpec(operandType(right)))) {
1316 // right operand is signed
1317 // Make sure that right's sign is not yet overwritten
1318 assert (!pic16_sameRegs (AOP(right), AOP(result)));
1319 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1320 pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1324 // get left+WREG+CARRY into result
1325 if (pic16_sameRegs (AOP(left), AOP(result))) {
1326 // left might have been extended in result above
1327 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1328 } else if (i < AOP_SIZE(left)) {
1329 pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
1330 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1332 // left is too short, not overwritten with result
1333 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
1334 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1335 // left operand is signed
1336 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1337 pic16_emitpcode(POC_SETF, pic16_popGet (AOP(result), i));
1339 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1350 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1351 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1352 pic16_freeAsmop(result,NULL,ic,TRUE);
1355 /*-----------------------------------------------------------------*/
1356 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1357 /*-----------------------------------------------------------------*/
1358 bool pic16_genMinusDec (iCode *ic)
1360 unsigned int icount ;
1361 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1364 /* will try to generate an increment */
1365 /* if the right side is not a literal
1367 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1368 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1369 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1372 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1374 /* if the literal value of the right hand side
1375 is greater than 4 then it is not worth it */
1376 if ((icount = (unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1379 /* if decrement 16 bits in register */
1380 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1385 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1387 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1389 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1390 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1391 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1393 /* size is 3 or 4 */
1394 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1395 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1396 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1397 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1399 pic16_emitcode("movlw","0xff");
1400 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1403 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1405 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1408 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1410 pic16_emitcode("skpnc","");
1412 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1421 /* if the sizes are greater than 1 then we cannot */
1422 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1423 AOP_SIZE(IC_LEFT(ic)) > 1 )
1426 /* we can if the aops of the left & result match or
1427 if they are in registers and the registers are the
1429 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1432 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1434 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1439 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1440 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1441 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1444 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1445 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1447 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1448 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1456 /*-----------------------------------------------------------------*/
1457 /* pic16_addSign - propogate sign bit to higher bytes */
1458 /*-----------------------------------------------------------------*/
1459 void pic16_addSign(operand *result, int offset, int sign)
1461 int size = (pic16_getDataSize(result) - offset);
1462 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1465 if(sign && offset) {
1468 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1469 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1470 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
1473 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1474 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1475 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1477 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1482 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1486 /*-----------------------------------------------------------------*/
1487 /* pic16_genMinus - generates code for subtraction */
1488 /*-----------------------------------------------------------------*/
1489 void pic16_genMinus (iCode *ic)
1491 int size, offset = 0, same=0;
1492 unsigned long lit = 0L;
1495 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1496 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1497 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1499 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1500 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1501 operand *t = IC_RIGHT(ic);
1502 IC_RIGHT(ic) = IC_LEFT(ic);
1506 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1507 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1508 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1509 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1511 /* special cases :- */
1512 /* if both left & right are in bit space */
1513 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1514 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1515 pic16_genPlusBits (ic);
1519 /* if I can do an decrement instead
1520 of subtract then GOOD for ME */
1521 // if (pic16_genMinusDec (ic) == TRUE)
1524 size = pic16_getDataSize(IC_RESULT(ic));
1525 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1527 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1528 /* Add a literal to something else */
1530 lit = ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
1533 genAddLit ( ic, lit);
1534 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1537 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1538 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1539 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1541 /* here we are subtracting a bit from a char or int */
1543 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1545 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1546 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1549 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1550 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1551 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1552 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1554 lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
1556 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1557 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1559 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1560 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1563 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1565 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1567 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1568 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1572 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1573 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1574 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1575 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1580 pic16_mov2w(AOP(IC_LEFT(ic)),0);
1581 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1582 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1585 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1587 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1590 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1592 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1594 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1601 } else if((AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1602 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1604 lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
1605 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1606 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1607 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1608 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1611 if( (size == 1) && ((lit & 0xff) == 0) ) {
1612 /* res = 0 - right */
1613 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1614 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1616 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1617 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1618 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1623 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1624 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1625 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1633 // here we have x = lit - x for sizeof(x)>1
1634 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1635 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1637 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1638 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1639 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1646 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1647 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1648 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1649 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1651 if ((AOP_SIZE(IC_LEFT(ic)) < AOP_SIZE(IC_RESULT(ic)))
1652 && pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1653 // extend left in result
1654 pic16_addSign (IC_RESULT(ic), AOP_SIZE(IC_LEFT(ic)), !SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))));
1657 if ((AOP_SIZE(IC_RIGHT(ic)) < AOP_SIZE(IC_RESULT(ic)))
1658 && pic16_sameRegs (AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1659 // extend right in result---fails if left resides in result as well...
1660 assert ((IC_LEFT(ic) == IC_RIGHT(ic)) || !pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))));
1661 pic16_addSign (IC_RESULT(ic), AOP_SIZE(IC_RIGHT(ic)), !SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))));
1664 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1665 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1666 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1667 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1668 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1669 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1672 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1673 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1674 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1676 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1677 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1679 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1680 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1682 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1684 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1685 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1686 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1688 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1690 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1696 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1698 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1699 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1701 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1702 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1709 if (pic16_sameRegs (AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1710 pic16_mov2w (AOP(IC_RESULT(ic)), offset);
1711 } else if (offset < AOP_SIZE(IC_RIGHT(ic)))
1712 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1714 // right operand is too short, not overwritten with result
1715 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1716 if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
1717 // signed -- sign extend the right operand
1718 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));
1719 pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1722 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1723 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1724 } else if (offset < AOP_SIZE(IC_LEFT(ic))) {
1725 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1726 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1728 // left operand is too short, not overwritten with result
1729 pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
1730 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
1731 // signed -- sign extend the left operand
1732 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));
1733 pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
1735 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1741 // adjustArithmeticResult(ic);
1744 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1745 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1746 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1750 /*-----------------------------------------------------------------*
1751 * pic_genMult8XLit_n - multiplication of two 8-bit numbers.
1754 *-----------------------------------------------------------------*/
1755 void pic16_genMult8XLit_n (operand *left,
1761 int size = AOP_SIZE(result);
1765 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1767 if (AOP_TYPE(right) != AOP_LIT){
1768 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1772 lit = (int) ulFromVal (AOP(right)->aopu.aop_lit);
1773 assert( (lit >= -128) && (lit < 256) );
1774 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1775 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1777 same = pic16_sameRegs(AOP(left), AOP(result));
1779 switch(lit & 0x00ff) {
1782 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1787 /* sign extend left in result */
1788 pic16_addSign(result, 1, !IS_UNSIGNED(operandType(left)));
1789 // its faster to left shift
1791 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1793 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1797 if(AOP_TYPE(left) != AOP_ACC)
1798 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1799 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit & 0x00ff));
1800 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1801 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1802 /* Adjust result's high bytes below! */
1805 // operands different
1806 switch(lit & 0x00ff) {
1809 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1814 if (IS_UNSIGNED(operandType(result))) {
1815 for (i=1; i < size; i++) {
1816 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1819 /* sign extend left to result */
1820 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1821 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
1822 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1823 for (i=1; i < size; i++) {
1824 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1828 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1829 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1831 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1835 if(AOP_TYPE(left) != AOP_ACC)
1836 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1837 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1838 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1839 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1840 /* Adjust result's high bytes below! */
1845 /* We need to fix PRODH for
1846 * (a) literals < 0 and
1847 * (b) signed register operands < 0.
1849 //printf( "%s: lit %d, left unsigned: %d\n", __FUNCTION__, lit, SPEC_USIGN(getSpec(operandType(left))));
1851 /* literal negative (i.e. in [-128..-1]), high byte == -1 */
1852 pic16_mov2w(AOP(left), 0);
1853 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
1856 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1857 /* register operand signed, determine signedness of high byte */
1858 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0x00ff));
1859 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
1860 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
1863 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1864 &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1866 /* Need to sign-extend here. */
1867 pic16_addSign(result, 2, !IS_UNSIGNED(operandType(result)));
1872 /*-----------------------------------------------------------------------*
1873 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1874 *-----------------------------------------------------------------------*/
1875 void pic16_genUMult16XLit_16 (operand *left,
1879 pCodeOp *pct1, *pct2, *pct3, *pct4;
1886 if (AOP_TYPE(right) != AOP_LIT){
1887 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1891 lit = (unsigned int) ulFromVal (AOP(right)->aopu.aop_lit);
1894 same = pic16_sameRegs(AOP(left), AOP(result));
1898 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1899 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1902 // its faster to left shift
1904 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1905 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1909 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1911 pct1 = pic16_popGetTempReg(1);
1912 pct2 = pic16_popGetTempReg(1);
1913 pct3 = pic16_popGetTempReg(1);
1914 pct4 = pic16_popGetTempReg(1);
1916 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1917 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1918 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1919 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1920 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1921 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1923 /* WREG still holds the low literal */
1924 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1925 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1926 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1928 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1929 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1930 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1931 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1934 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1935 pct1, pic16_popGet(AOP(result), 0)));
1936 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1937 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1938 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1939 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1941 pic16_popReleaseTempReg(pct4,1);
1942 pic16_popReleaseTempReg(pct3,1);
1943 pic16_popReleaseTempReg(pct2,1);
1944 pic16_popReleaseTempReg(pct1,1);
1948 // operands different
1951 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1952 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1956 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1957 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1958 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1959 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1963 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1964 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1965 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1966 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1967 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1968 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1970 /* WREG still holds the low literal */
1971 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1972 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1973 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1975 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1976 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1977 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1978 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1987 /*-----------------------------------------------------------------*
1988 * genMult8X8_n - multiplication of two 8-bit numbers.
1991 *-----------------------------------------------------------------*/
1992 void pic16_genMult8X8_n (operand *left, operand *right, operand *result)
1998 if (AOP_TYPE(right) == AOP_LIT) {
1999 pic16_genMult8XLit_n(left,right,result);
2009 /* if result == right then exchange left and right */
2010 if(pic16_sameRegs(AOP(result), AOP(right))) {
2017 if(AOP_TYPE(left) != AOP_ACC) {
2019 if(AOP_TYPE(right) != AOP_ACC) {
2020 pic16_mov2w(AOP(left), 0);
2021 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2023 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2026 // left is WREG, right cannot be WREG (or can?!)
2027 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
2030 /* result is in PRODL:PRODH */
2031 if(AOP_TYPE(result) != AOP_ACC) {
2032 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
2033 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2036 if(AOP_SIZE(result)>1) {
2038 /* If s8 x s8 --> s16 multiplication was called for, fixup high byte.
2039 * (left=a1a0, right=b1b0, X1: high byte, X0: low byte)
2046 * a0b0 a1= 0, b1= 0 (both unsigned)
2047 * -b0 a0b0 a1=-1, b1= 0 (a signed and < 0, b unsigned or >= 0)
2048 * -a0 a0b0 a1= 0, b1=-1 (b signed and < 0, a unsigned or >= 0)
2049 * -(a0+b0) a0b0 a1=-1, b1=-1 (a and b signed and < 0)
2051 * Currently, PRODH:PRODL holds a0b0 as 16 bit value; we need to
2052 * subtract a0 and/or b0 from PRODH. */
2053 if (!IS_UNSIGNED(operandType(right))) {
2054 /* right operand (b1) signed and < 0, then subtract left op (a0) */
2055 pic16_mov2w( AOP(left), 0 );
2056 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
2057 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
2060 if (!IS_UNSIGNED(getSpec(operandType(left)))) {
2061 /* left operand (a1) signed and < 0, then subtract right op (b0) */
2062 pic16_mov2w( AOP(right), 0 );
2063 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
2064 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
2067 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
2068 &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2070 /* Must sign-extend here. */
2071 pic16_addSign(result, 2, !IS_UNSIGNED(operandType(left)));
2074 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2079 /*------------------------------------------------------------------*
2080 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
2081 *------------------------------------------------------------------*/
2082 void pic16_genUMult16X16_16 (operand *left,
2087 pCodeOp *pct1, *pct2, *pct3, *pct4;
2092 if (AOP_TYPE(right) == AOP_LIT) {
2093 pic16_genMult8XLit_n(left,right,result);
2101 /* if result == right then exchange left and right */
2102 if(pic16_sameRegs(AOP(result), AOP(right))) {
2110 if(pic16_sameRegs(AOP(result), AOP(left))) {
2112 pct1 = pic16_popGetTempReg(1);
2113 pct2 = pic16_popGetTempReg(1);
2114 pct3 = pic16_popGetTempReg(1);
2115 pct4 = pic16_popGetTempReg(1);
2117 pic16_mov2w(AOP(left), 0);
2118 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2119 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2120 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2121 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2122 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2124 /* WREG still holds the lower left */
2125 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2126 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2127 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2129 pic16_mov2w(AOP(left), 1);
2130 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2131 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2132 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2135 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2136 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2137 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2138 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2139 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2140 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2142 pic16_popReleaseTempReg( pct4, 1 );
2143 pic16_popReleaseTempReg( pct3, 1 );
2144 pic16_popReleaseTempReg( pct2, 1 );
2145 pic16_popReleaseTempReg( pct1, 1 );
2149 pic16_mov2w(AOP(left), 0);
2150 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2151 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2152 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2153 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2154 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2156 /* WREG still holds the lower left */
2157 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2158 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2159 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2161 pic16_mov2w(AOP(left), 1);
2162 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2163 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2164 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2170 void pic16_genSMult16X16_16(operand *left,
2179 /*-----------------------------------------------------------------*
2180 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
2182 * this routine will call the unsigned multiply routine and then
2183 * post-fix the sign bit.
2184 *-----------------------------------------------------------------*/
2185 void pic16_genSMult8X8_8 (operand *left,
2188 pCodeOpReg *result_hi)
2190 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2194 result_hi = PCOR(pic16_popGet(AOP(result),1));
2198 pic16_genUMult8X8_8(left,right,result);
2202 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2203 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2204 pic16_mov2w(AOP(left),0);
2205 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2206 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2211 /*-----------------------------------------------------------------*
2212 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
2213 *-----------------------------------------------------------------*/
2214 void pic16_genMult8X8_8 (operand *left,
2220 if(AOP_TYPE(right) == AOP_LIT)
2221 pic16_genMult8XLit_n(left,right,result);
2223 pic16_genMult8X8_n(left,right,result);
2228 /*-----------------------------------------------------------------*
2229 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
2230 *-----------------------------------------------------------------*/
2231 void pic16_genMult16X16_16 (operand *left,
2237 if (AOP_TYPE(right) == AOP_LIT)
2238 pic16_genUMult16XLit_16(left,right,result);
2240 pic16_genUMult16X16_16(left,right,result);
2246 /*-----------------------------------------------------------------------*
2247 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2248 *-----------------------------------------------------------------------*/
2249 void pic16_genUMult32XLit_32 (operand *left,
2253 pCodeOp *pct1, *pct2, *pct3, *pct4;
2260 if (AOP_TYPE(right) != AOP_LIT){
2261 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2265 lit = (unsigned int) ulFromVal (AOP(right)->aopu.aop_lit);
2268 same = pic16_sameRegs(AOP(left), AOP(result));
2272 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2273 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2276 // its faster to left shift
2278 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2279 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2283 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2285 pct1 = pic16_popGetTempReg(1);
2286 pct2 = pic16_popGetTempReg(1);
2287 pct3 = pic16_popGetTempReg(1);
2288 pct4 = pic16_popGetTempReg(1);
2290 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2291 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2292 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2293 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2294 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2295 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2297 /* WREG still holds the low literal */
2298 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2299 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2300 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2302 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2303 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2304 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2305 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2308 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2309 pct1, pic16_popGet(AOP(result), 0)));
2310 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2311 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2312 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2313 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2315 pic16_popReleaseTempReg( pct4, 1 );
2316 pic16_popReleaseTempReg( pct3, 1 );
2317 pic16_popReleaseTempReg( pct2, 1 );
2318 pic16_popReleaseTempReg( pct1, 1 );
2322 // operands different
2325 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2326 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2330 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2331 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2332 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2333 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2337 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2338 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2339 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2340 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2341 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2342 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2344 /* WREG still holds the low literal */
2345 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2346 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2347 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2349 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2350 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2351 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2352 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2361 /*------------------------------------------------------------------*
2362 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2363 *------------------------------------------------------------------*/
2364 void pic16_genUMult32X32_32 (operand *left,
2369 pCodeOp *pct1, *pct2, *pct3, *pct4;
2373 if (AOP_TYPE(right) == AOP_LIT) {
2374 pic16_genMult8XLit_n(left,right,result);
2382 /* if result == right then exchange left and right */
2383 if(pic16_sameRegs(AOP(result), AOP(right))) {
2391 if(pic16_sameRegs(AOP(result), AOP(left))) {
2393 pct1 = pic16_popGetTempReg(1);
2394 pct2 = pic16_popGetTempReg(1);
2395 pct3 = pic16_popGetTempReg(1);
2396 pct4 = pic16_popGetTempReg(1);
2398 pic16_mov2w(AOP(left), 0);
2399 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2400 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2401 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2402 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2403 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2405 /* WREG still holds the lower left */
2406 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2407 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2408 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2410 pic16_mov2w(AOP(left), 1);
2411 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2412 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2413 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2416 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2417 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2418 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2419 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2420 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2421 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2423 pic16_popReleaseTempReg( pct4, 1 );
2424 pic16_popReleaseTempReg( pct3, 1 );
2425 pic16_popReleaseTempReg( pct2, 1 );
2426 pic16_popReleaseTempReg( pct1, 1 );
2430 pic16_mov2w(AOP(left), 0);
2431 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2432 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2433 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2434 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2435 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2437 /* WREG still holds the lower left */
2438 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2439 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2440 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2442 pic16_mov2w(AOP(left), 1);
2443 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2444 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2445 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2452 /*-----------------------------------------------------------------*
2453 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2454 *-----------------------------------------------------------------*/
2455 void pic16_genMult32X32_32 (operand *left,
2461 if (AOP_TYPE(right) == AOP_LIT)
2462 pic16_genUMult32XLit_32(left,right,result);
2464 pic16_genUMult32X32_32(left,right,result);
2475 /*-----------------------------------------------------------------*/
2476 /* constMult - generates code for multiplication by a constant */
2477 /*-----------------------------------------------------------------*/
2478 void genMultConst(unsigned C)
2482 unsigned sr3; // Shift right 3
2488 Convert a string of 3 binary 1's in the lit into
2492 mask = 7 << ( (size*8) - 3);
2496 while(mask < (1<<size*8)) {
2498 if( (mask & lit) == lit) {
2501 /* We found 3 (or more) consecutive 1's */
2503 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2505 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2507 lit ^= consecutive_bits;
2511 sr3 |= (consecutive + lsb);