1 /*-------------------------------------------------------------------------
3 genarith.c - source file for code generation - arithmetic
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 and - Jean-Louis VERN.jlvern@writeme.com (1999)
7 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
8 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2, or (at your option) any
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 In other words, you are welcome to use, share and improve this program.
26 You are forbidden to forbid anyone else to use, share and improve
27 what you give them. Help stamp out software-hoarding!
30 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
31 Made everything static
32 -------------------------------------------------------------------------*/
38 #include "SDCCglobl.h"
41 #if defined(_MSC_VER) && (_MSC_VER < 1300)
42 #define __FUNCTION__ __FILE__
46 #include "SDCCpeeph.h"
52 #define pic16_emitcode DEBUGpic16_emitcode
55 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
56 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
57 void pic16_emitpcomment(char *, ...);
58 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst);
59 const char *pic16_AopType(short type)
62 case AOP_LIT: return "AOP_LIT";
63 case AOP_REG: return "AOP_REG";
64 case AOP_DIR: return "AOP_DIR";
65 case AOP_DPTR: return "AOP_DPTR";
66 case AOP_DPTR2: return "AOP_DPTR2";
67 case AOP_FSR0: return "AOP_FSR0";
68 case AOP_FSR2: return "AOP_FSR2";
69 case AOP_R0: return "AOP_R0";
70 case AOP_R1: return "AOP_R1";
71 case AOP_STK: return "AOP_STK";
72 case AOP_IMMD: return "AOP_IMMD";
73 case AOP_STR: return "AOP_STR";
74 case AOP_CRY: return "AOP_CRY";
75 case AOP_ACC: return "AOP_ACC";
76 case AOP_PCODE: return "AOP_PCODE";
77 case AOP_STA: return "AOP_STA";
83 const char *pic16_pCodeOpType(pCodeOp *pcop)
90 case PO_NONE: return "PO_NONE";
91 case PO_W: return "PO_W";
92 case PO_WREG: return "PO_WREG";
93 case PO_STATUS: return "PO_STATUS";
94 case PO_BSR: return "PO_BSR";
95 case PO_FSR0: return "PO_FSR0";
96 case PO_INDF0: return "PO_INDF0";
97 case PO_INTCON: return "PO_INTCON";
98 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
99 case PO_GPR_BIT: return "PO_GPR_BIT";
100 case PO_GPR_TEMP: return "PO_GPR_TEMP";
101 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
102 case PO_PCL: return "PO_PCL";
103 case PO_PCLATH: return "PO_PCLATH";
104 case PO_PCLATU: return "PO_PCLATU";
105 case PO_PRODL: return "PO_PRODL";
106 case PO_PRODH: return "PO_PRODH";
107 case PO_LITERAL: return "PO_LITERAL";
108 case PO_REL_ADDR: return "PO_REL_ADDR";
109 case PO_IMMEDIATE: return "PO_IMMEDIATE";
110 case PO_DIR: return "PO_DIR";
111 case PO_CRY: return "PO_CRY";
112 case PO_BIT: return "PO_BIT";
113 case PO_STR: return "PO_STR";
114 case PO_LABEL: return "PO_LABEL";
115 case PO_WILD: return "PO_WILD";
116 case PO_TWO_OPS: return "PO_TWO_OPS";
120 return "BAD PO_TYPE";
123 const char *pic16_pCodeOpSubType(pCodeOp *pcop)
126 if(pcop && (pcop->type == PO_GPR_BIT)) {
128 switch(PCORB(pcop)->subtype) {
130 case PO_NONE: return "PO_NONE";
131 case PO_W: return "PO_W";
132 case PO_WREG: return "PO_WREG";
133 case PO_STATUS: return "PO_STATUS";
134 case PO_BSR: return "PO_BSR";
135 case PO_FSR0: return "PO_FSR0";
136 case PO_INDF0: return "PO_INDF0";
137 case PO_INTCON: return "PO_INTCON";
138 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
139 case PO_GPR_BIT: return "PO_GPR_BIT";
140 case PO_GPR_TEMP: return "PO_GPR_TEMP";
141 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
142 case PO_PCL: return "PO_PCL";
143 case PO_PCLATH: return "PO_PCLATH";
144 case PO_PCLATU: return "PO_PCLATU";
145 case PO_PRODL: return "PO_PRODL";
146 case PO_PRODH: return "PO_PRODH";
147 case PO_LITERAL: return "PO_LITERAL";
148 case PO_REL_ADDR: return "PO_REL_ADDR";
149 case PO_IMMEDIATE: return "PO_IMMEDIATE";
150 case PO_DIR: return "PO_DIR";
151 case PO_CRY: return "PO_CRY";
152 case PO_BIT: return "PO_BIT";
153 case PO_STR: return "PO_STR";
154 case PO_LABEL: return "PO_LABEL";
155 case PO_WILD: return "PO_WILD";
156 case PO_TWO_OPS: return "PO_TWO_OPS";
160 return "BAD PO_TYPE";
163 /*-----------------------------------------------------------------*/
164 /* pic16_genPlusIncr :- does addition with increment if possible */
165 /*-----------------------------------------------------------------*/
166 bool pic16_genPlusIncr (iCode *ic)
168 unsigned int icount ;
169 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
173 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
174 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
175 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
176 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
178 /* will try to generate an increment */
179 /* if the right side is not a literal
181 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
184 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
185 /* if the literal value of the right hand side
186 is greater than 2 then it is faster to add */
187 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
190 /* if increment 16 bits in register */
191 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
196 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
197 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
201 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
202 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
208 // DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
209 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
210 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
211 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
213 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
214 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
215 AOP(IC_RESULT(ic))->aopu.aop_dir,
216 AOP(IC_RESULT(ic))->aopu.aop_dir);
218 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
219 //pic16_emitcode("xorlw","1");
221 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
222 //pic16_emitcode("andlw","1");
225 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
226 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
227 AOP(IC_RESULT(ic))->aopu.aop_dir,
228 AOP(IC_RESULT(ic))->aopu.aop_dir);
234 /* if the sizes are greater than 1 then we cannot */
235 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
236 AOP_SIZE(IC_LEFT(ic)) > 1 )
239 /* If we are incrementing the same register by two: */
241 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
244 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
245 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
250 DEBUGpic16_emitcode ("; ","couldn't increment ");
255 /*-----------------------------------------------------------------*/
256 /* pic16_outBitAcc - output a bit in acc */
257 /*-----------------------------------------------------------------*/
258 void pic16_outBitAcc(operand *result)
260 symbol *tlbl = newiTempLabel(NULL);
261 /* if the result is a bit */
262 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
264 assert(0); // not implemented for PIC16?
266 if (AOP_TYPE(result) == AOP_CRY){
267 pic16_aopPut(AOP(result),"a",0);
270 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
271 pic16_emitcode("mov","a,#01");
272 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
273 pic16_outAcc(result);
277 /*-----------------------------------------------------------------*/
278 /* pic16_genPlusBits - generates code for addition of two bits */
279 /*-----------------------------------------------------------------*/
280 void pic16_genPlusBits (iCode *ic)
284 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
285 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
286 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
287 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
289 The following block of code will add two bits.
290 Note that it'll even work if the destination is
291 the carry (C in the status register).
292 It won't work if the 'Z' bit is a source or destination.
295 /* If the result is stored in the accumulator (w) */
296 //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
297 switch(AOP_TYPE(IC_RESULT(ic))) {
299 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
300 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
301 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
302 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
303 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
305 pic16_emitcode("clrw","");
306 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
307 AOP(IC_RIGHT(ic))->aopu.aop_dir,
308 AOP(IC_RIGHT(ic))->aopu.aop_dir);
309 pic16_emitcode("xorlw","1");
310 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
311 AOP(IC_LEFT(ic))->aopu.aop_dir,
312 AOP(IC_LEFT(ic))->aopu.aop_dir);
313 pic16_emitcode("xorlw","1");
316 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
317 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
318 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
319 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
320 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
321 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
324 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
325 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
326 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
327 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
328 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
329 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
331 pic16_emitcode("movlw","(1 << (%s & 7))",
332 AOP(IC_RESULT(ic))->aopu.aop_dir,
333 AOP(IC_RESULT(ic))->aopu.aop_dir);
334 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
335 AOP(IC_RESULT(ic))->aopu.aop_dir,
336 AOP(IC_RESULT(ic))->aopu.aop_dir);
337 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
338 AOP(IC_RIGHT(ic))->aopu.aop_dir,
339 AOP(IC_RIGHT(ic))->aopu.aop_dir);
340 pic16_emitcode("xorwf","(%s >>3),f",
341 AOP(IC_RESULT(ic))->aopu.aop_dir);
342 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
343 AOP(IC_LEFT(ic))->aopu.aop_dir,
344 AOP(IC_LEFT(ic))->aopu.aop_dir);
345 pic16_emitcode("xorwf","(%s>>3),f",
346 AOP(IC_RESULT(ic))->aopu.aop_dir);
353 /* This is the original version of this code.
355 * This is being kept around for reference,
356 * because I am not entirely sure I got it right...
358 static void adjustArithmeticResult(iCode *ic)
360 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
361 AOP_SIZE(IC_LEFT(ic)) == 3 &&
362 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
363 pic16_aopPut(AOP(IC_RESULT(ic)),
364 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
367 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
368 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
369 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
370 pic16_aopPut(AOP(IC_RESULT(ic)),
371 pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
374 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
375 AOP_SIZE(IC_LEFT(ic)) < 3 &&
376 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
377 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
378 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
380 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
381 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
385 /* This is the pure and virtuous version of this code.
386 * I'm pretty certain it's right, but not enough to toss the old
389 static void adjustArithmeticResult(iCode *ic)
391 if (opIsGptr(IC_RESULT(ic)) &&
392 opIsGptr(IC_LEFT(ic)) &&
393 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
395 pic16_aopPut(AOP(IC_RESULT(ic)),
396 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
400 if (opIsGptr(IC_RESULT(ic)) &&
401 opIsGptr(IC_RIGHT(ic)) &&
402 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
404 pic16_aopPut(AOP(IC_RESULT(ic)),
405 pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
409 if (opIsGptr(IC_RESULT(ic)) &&
410 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
411 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
412 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
413 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
415 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
416 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
422 /*-----------------------------------------------------------------*/
423 /* genAddlit - generates code for addition */
424 /*-----------------------------------------------------------------*/
425 static void genAddLit2byte (operand *result, int offr, int lit)
433 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
436 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
439 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
440 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
446 static void emitMOVWF(operand *reg, int offset)
451 if (AOP_TYPE(reg) == AOP_ACC) {
452 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
456 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
463 static void genAddLit (iCode *ic, int lit)
476 result = IC_RESULT(ic);
477 same = pic16_sameRegs(AOP(left), AOP(result));
478 size = pic16_getDataSize(result);
482 /* Handle special cases first */
484 genAddLit2byte (result, 0, lit);
487 int hi = 0xff & (lit >> 8);
494 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
499 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
501 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
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));
510 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
511 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
513 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
521 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
524 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
527 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
528 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
530 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
532 case 0xff: /* 0x01ff */
533 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
534 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
535 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
536 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
538 default: /* 0x01LL */
539 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
540 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
542 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
543 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
548 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
552 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
555 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
556 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
558 /* case 0xff: * 0xffff *
559 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
560 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
561 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
565 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
566 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
568 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
575 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
580 genAddLit2byte (result, MSB16, hi);
583 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
584 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
585 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
587 /* case 0xff: * 0xHHff *
588 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
589 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
590 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
591 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
593 */ default: /* 0xHHLL */
594 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
595 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
596 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
597 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
606 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
609 lo = BYTEofLONG(lit,0);
612 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
613 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
615 /* no carry info from previous step */
616 /* this means this is the first time to add */
621 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
625 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
626 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
628 carry_info = 3; /* Were adding only one byte and propogating the carry */
639 lo = BYTEofLONG(lit,0);
644 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
647 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
648 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
651 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
653 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
655 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
664 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
668 if(AOP_TYPE(left) == AOP_ACC) {
669 /* left addend is already in accumulator */
672 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
676 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
677 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
681 /* left addend is in a register */
684 pic16_mov2w(AOP(left),0);
685 emitMOVWF(result, 0);
688 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
689 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
693 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
694 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
698 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
699 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
700 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
708 /* left is not the accumulator */
710 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
711 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
713 pic16_mov2w(AOP(left),0);
714 /* We don't know the state of the carry bit at this point */
717 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
721 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
722 if (offset < AOP_SIZE(left)) {
723 pic16_emitpcode(clear_carry ? POC_ADDFW : POC_ADDFWC, pic16_popGet(AOP(left),offset));
724 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
726 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
727 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
728 /* sign-extend left (in result) */
729 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left),AOP_SIZE(left)-1,7));
730 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
732 pic16_emitpcode(clear_carry ? POC_ADDWF : POC_ADDWFC, pic16_popGet(AOP(result),offset));
742 /* this fails when result is an SFR because value is written there
743 * during addition and not at the end */
745 static void genAddLit (iCode *ic, int lit)
759 lleft = operandType (left);
760 result = IC_RESULT(ic);
761 same = pic16_sameRegs(AOP(left), AOP(result));
762 size = pic16_getDataSize(result);
763 sizeL = pic16_getDataSize(left);
766 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
767 /* move left to result -- possibly sign extend */
768 for (i=0; i < MIN(size, sizeL); i++) {
769 pic16_mov2f (AOP(result), AOP(left), i);
773 /* extend to result size */
774 if (IS_UNSIGNED(lleft)) {
776 for (i = sizeL; i < size; i++) {
777 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
781 if (size == sizeL + 1) {
782 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), sizeL));
783 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
784 pic16_emitpcode (POC_SETF, pic16_popGet (AOP(result), sizeL));
786 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
787 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
788 pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
790 for (i=sizeL; i < size; i++) {
791 pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(result), i));
799 } else if (lit == 1) {
805 pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(result), 0));
809 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), 0));
810 for (i=1; i < size-1; i++) {
811 emitSKPNC; /* a jump here saves up to 2(size-2)cycles */
812 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), i));
818 pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1));
822 /* add literal to result */
823 for (i=0; i < size; i++) {
824 pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit));
825 llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */
826 pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC,
827 pic16_popGet (AOP(result), i));
835 /* Handle special cases first */
837 genAddLit2byte (result, 0, lit);
840 int hi = 0xff & (lit >> 8);
847 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
852 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
854 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
857 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
858 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
859 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
863 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
864 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
866 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
874 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
877 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
880 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
881 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
883 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
885 case 0xff: /* 0x01ff */
886 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
887 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
888 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
889 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
891 default: /* 0x01LL */
892 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
893 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
895 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
896 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
901 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
905 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
908 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
909 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
911 /* case 0xff: * 0xffff *
912 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
913 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
914 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
918 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
919 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
921 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
928 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
933 genAddLit2byte (result, MSB16, hi);
936 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
937 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
938 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
940 /* case 0xff: * 0xHHff *
941 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
942 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
943 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
944 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
946 */ default: /* 0xHHLL */
947 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
948 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
949 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
950 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
959 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
962 lo = BYTEofLONG(lit,0);
965 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
966 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
968 /* no carry info from previous step */
969 /* this means this is the first time to add */
974 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
978 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
979 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
981 carry_info = 3; /* Were adding only one byte and propogating the carry */
992 lo = BYTEofLONG(lit,0);
997 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1000 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
1001 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1004 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
1006 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
1008 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
1017 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
1021 if(AOP_TYPE(left) == AOP_ACC) {
1022 /* left addend is already in accumulator */
1023 switch(lit & 0xff) {
1025 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1026 emitMOVWF(result,0);
1029 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
1030 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1031 emitMOVWF(result,0);
1034 /* left addend is in a register */
1035 switch(lit & 0xff) {
1037 pic16_mov2w(AOP(left),0);
1038 emitMOVWF(result, 0);
1041 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1042 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1043 emitMOVWF(result,0);
1046 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
1047 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1048 emitMOVWF(result,0);
1051 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1052 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1053 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1054 emitMOVWF(result,0);
1061 /* left is not the accumulator */
1063 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1064 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1066 pic16_mov2w(AOP(left),0);
1067 /* We don't know the state of the carry bit at this point */
1070 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1071 emitMOVWF(result,0);
1077 /* The ls byte of the lit must've been zero - that
1078 means we don't have to deal with carry */
1080 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1081 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
1082 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1087 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1088 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
1089 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1093 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
1094 pic16_mov2w(AOP(left),offset);
1095 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
1106 /*-----------------------------------------------------------------*/
1107 /* pic16_genPlus - generates code for addition */
1108 /*-----------------------------------------------------------------*/
1109 void pic16_genPlus (iCode *ic)
1111 int i, size, offset = 0;
1112 operand *result, *left, *right;
1116 /* special cases :- */
1117 result = IC_RESULT(ic);
1119 right = IC_RIGHT(ic);
1120 pic16_aopOp (left,ic,FALSE);
1121 pic16_aopOp (right,ic,FALSE);
1122 pic16_aopOp (result,ic,TRUE);
1123 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
1124 // pic16_DumpOp("(left)",left);
1126 /* if literal, literal on the right or
1127 if left requires ACC or right is already
1130 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
1132 right = IC_RIGHT(ic) = left;
1133 left = IC_LEFT(ic) = t;
1136 /* if both left & right are in bit space */
1137 if (AOP_TYPE(left) == AOP_CRY &&
1138 AOP_TYPE(right) == AOP_CRY) {
1139 pic16_genPlusBits (ic);
1143 /* if left in bit space & right literal */
1144 if (AOP_TYPE(left) == AOP_CRY &&
1145 AOP_TYPE(right) == AOP_LIT) {
1146 /* if result in bit space */
1147 if(AOP_TYPE(result) == AOP_CRY){
1148 if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
1149 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
1150 if (!pic16_sameRegs(AOP(left), AOP(result)) )
1151 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
1152 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
1155 unsigned long lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
1156 size = pic16_getDataSize(result);
1158 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
1159 pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
1160 pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
1161 //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
1162 //pic16_emitcode("addc","a,#00 ;%d",__LINE__);
1163 //pic16_aopPut(AOP(result),"a",offset++);
1169 /* if I can do an increment instead
1170 of add then GOOD for ME */
1171 if (pic16_genPlusIncr (ic) == TRUE)
1174 size = pic16_getDataSize(result);
1176 if(AOP(right)->type == AOP_LIT) {
1177 /* Add a literal to something else */
1179 unsigned lit = (unsigned) floatFromVal(AOP(right)->aopu.aop_lit);
1183 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
1185 genAddLit (ic, lit);
1188 } else if(AOP_TYPE(right) == AOP_CRY) {
1190 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
1191 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
1192 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
1194 /* here we are adding a bit to a char or int */
1196 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1198 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1199 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0));
1201 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1202 AOP(right)->aopu.aop_dir,
1203 AOP(right)->aopu.aop_dir);
1204 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1205 } else { // not same
1207 if(AOP_TYPE(left) == AOP_ACC) {
1208 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1209 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1211 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1212 AOP(right)->aopu.aop_dir,
1213 AOP(right)->aopu.aop_dir);
1214 pic16_emitcode(" xorlw","1");
1216 pic16_mov2w(AOP(left),0);
1217 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1218 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
1220 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1221 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1222 AOP(right)->aopu.aop_dir,
1223 AOP(right)->aopu.aop_dir);
1224 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1227 if(AOP_TYPE(result) != AOP_ACC) {
1229 if(AOP_TYPE(result) == AOP_CRY) {
1230 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1231 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0));
1233 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0));
1235 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0));
1236 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1243 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1244 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1246 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1247 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
1249 pic16_emitcode("clrz","");
1251 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1252 AOP(right)->aopu.aop_dir,
1253 AOP(right)->aopu.aop_dir);
1254 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1257 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
1258 pic16_mov2w(AOP(left),0);
1259 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1260 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1261 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
1264 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1265 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1266 AOP(right)->aopu.aop_dir,
1267 AOP(right)->aopu.aop_dir);
1268 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1269 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1275 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++));
1276 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE));
1284 // Note: the following is an example of WISC code, eg.
1285 // it's supposed to run on a Weird Instruction Set Computer :o)
1287 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1289 if ( AOP_TYPE(left) == AOP_ACC) {
1290 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1291 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
1292 if ( AOP_TYPE(result) != AOP_ACC)
1293 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1294 goto release; // we're done, since WREG is 1 byte
1298 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1300 size = min( AOP_SIZE(result), AOP_SIZE(right) );
1301 size = min( size, AOP_SIZE(left) );
1304 if(pic16_debug_verbose) {
1305 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
1306 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
1307 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
1312 if ((AOP_TYPE(left) == AOP_PCODE) && (
1313 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
1314 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
1315 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
1317 // add to literal operand
1320 for(i=0; i<size; i++) {
1321 if (AOP_TYPE(right) == AOP_ACC) {
1322 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1324 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1325 if(i) { // add with carry
1326 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1327 } else { // add without
1328 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1331 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1334 DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
1336 // add leftover bytes
1337 if (SPEC_USIGN(getSpec(operandType(right)))) {
1338 // right is unsigned
1339 for(i=size; i< AOP_SIZE(result); i++) {
1340 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1341 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1342 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1346 // right is signed, oh dear ...
1347 for(i=size; i< AOP_SIZE(result); i++) {
1348 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1349 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1350 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),i));
1351 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1352 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1362 for(i=0; i<size; i++) {
1363 if (AOP_TYPE(right) != AOP_ACC)
1364 pic16_mov2w(AOP(right),i);
1365 if (pic16_sameRegs(AOP(left), AOP(result)))
1367 if(i) { // add with carry
1368 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1369 } else { // add without
1370 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1372 } else { // not same
1373 if(i) { // add with carry
1374 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1375 } else { // add without
1376 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1378 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1382 // add leftover bytes
1383 // either left or right is too short
1384 for (i=size; i < AOP_SIZE(result); i++) {
1385 // get right operand into WREG
1386 if (i < AOP_SIZE(right)) {
1387 pic16_mov2w (AOP(right), i);
1389 // right is too short
1390 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1391 if (!SPEC_USIGN(getSpec(operandType(right)))) {
1392 // right operand is signed
1393 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1394 pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1398 // get left+WREG+CARRY into result
1399 if (i < AOP_SIZE(left)) {
1400 if (pic16_sameRegs (AOP(left), AOP(result))) {
1401 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1403 pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
1404 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1407 // left is too short
1408 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
1409 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1410 // left operand is signed
1411 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1412 pic16_emitpcode(POC_SETF, pic16_popGet (AOP(result), i));
1414 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1425 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1426 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1427 pic16_freeAsmop(result,NULL,ic,TRUE);
1430 /*-----------------------------------------------------------------*/
1431 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1432 /*-----------------------------------------------------------------*/
1433 bool pic16_genMinusDec (iCode *ic)
1435 unsigned int icount ;
1436 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1439 /* will try to generate an increment */
1440 /* if the right side is not a literal
1442 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1443 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1444 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1447 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1449 /* if the literal value of the right hand side
1450 is greater than 4 then it is not worth it */
1451 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1454 /* if decrement 16 bits in register */
1455 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1460 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1462 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1464 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1465 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1466 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1468 /* size is 3 or 4 */
1469 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1470 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1471 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1472 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1474 pic16_emitcode("movlw","0xff");
1475 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1478 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1480 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1483 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1485 pic16_emitcode("skpnc","");
1487 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1496 /* if the sizes are greater than 1 then we cannot */
1497 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1498 AOP_SIZE(IC_LEFT(ic)) > 1 )
1501 /* we can if the aops of the left & result match or
1502 if they are in registers and the registers are the
1504 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1507 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1509 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1514 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1515 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1516 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1519 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1520 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1522 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1523 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1531 /*-----------------------------------------------------------------*/
1532 /* pic16_addSign - propogate sign bit to higher bytes */
1533 /*-----------------------------------------------------------------*/
1534 void pic16_addSign(operand *result, int offset, int sign)
1536 int size = (pic16_getDataSize(result) - offset);
1537 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1540 if(sign && offset) {
1543 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1544 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1545 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
1548 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1549 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1550 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1552 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1557 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1561 /*-----------------------------------------------------------------*/
1562 /* pic16_genMinusBits - generates code for subtraction of two bits */
1563 /*-----------------------------------------------------------------*/
1564 void pic16_genMinusBits (iCode *ic)
1566 symbol *lbl = newiTempLabel(NULL);
1569 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1570 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1571 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1572 pic16_emitcode("cpl","c");
1573 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1574 pic16_outBitC(IC_RESULT(ic));
1577 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1578 pic16_emitcode("subb","a,acc");
1579 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1580 pic16_emitcode("inc","a");
1581 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1582 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1583 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1587 /*-----------------------------------------------------------------*/
1588 /* pic16_genMinus - generates code for subtraction */
1589 /*-----------------------------------------------------------------*/
1590 void pic16_genMinus (iCode *ic)
1592 int size, offset = 0, same=0;
1593 unsigned long lit = 0L;
1596 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1597 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1598 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1600 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1601 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1602 operand *t = IC_RIGHT(ic);
1603 IC_RIGHT(ic) = IC_LEFT(ic);
1607 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1608 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1609 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1610 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1612 /* special cases :- */
1613 /* if both left & right are in bit space */
1614 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1615 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1616 pic16_genPlusBits (ic);
1620 /* if I can do an decrement instead
1621 of subtract then GOOD for ME */
1622 // if (pic16_genMinusDec (ic) == TRUE)
1625 size = pic16_getDataSize(IC_RESULT(ic));
1626 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1628 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1629 /* Add a literal to something else */
1631 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1634 genAddLit ( ic, lit);
1637 /* add the first byte: */
1638 pic16_emitcode("movlw","0x%x", lit & 0xff);
1639 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1640 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1641 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1653 if((lit & 0xff) == 0xff) {
1654 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1656 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1658 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1660 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1661 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1665 /* do the rlf known zero trick here */
1666 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1668 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1673 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1676 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1677 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1678 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1680 /* here we are subtracting a bit from a char or int */
1682 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1684 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1685 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1687 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1688 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1689 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1690 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1693 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1694 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1695 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1696 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1697 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1699 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1701 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1702 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1704 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1705 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1708 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1710 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1712 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1713 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1717 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1718 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1719 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1720 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1725 pic16_mov2w(AOP(IC_LEFT(ic)),0);
1726 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1727 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1730 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1732 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1735 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1737 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1739 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1746 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1747 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1748 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1750 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1751 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1752 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1753 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1754 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1757 if( (size == 1) && ((lit & 0xff) == 0) ) {
1758 /* res = 0 - right */
1759 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1760 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1762 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1763 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1764 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1769 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1770 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1771 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1779 // here we have x = lit - x for sizeof(x)>1
1780 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1781 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1783 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1784 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1785 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1792 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1793 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1794 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1795 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1797 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1798 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1799 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1800 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1801 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1802 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1805 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1806 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1807 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1809 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1810 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1812 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1813 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1814 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1816 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1818 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1819 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1820 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1822 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1824 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1830 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1832 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1833 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1835 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1836 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1843 if (offset < AOP_SIZE(IC_RIGHT(ic)))
1844 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1846 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1847 if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
1848 // signed -- sign extend the right operand
1849 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));
1850 pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1853 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1854 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1856 if (offset < AOP_SIZE(IC_LEFT(ic))) {
1857 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1858 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1860 // zero extend the left operand
1861 pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
1862 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
1863 // signed -- sign extend the left operand
1864 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));
1865 pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
1867 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1876 // adjustArithmeticResult(ic);
1879 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1880 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1881 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1885 /*-----------------------------------------------------------------*
1886 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1889 *-----------------------------------------------------------------*/
1890 void pic16_genUMult8XLit_8 (operand *left,
1896 int size = AOP_SIZE(result);
1900 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1902 if (AOP_TYPE(right) != AOP_LIT){
1903 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1907 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1909 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1910 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1912 same = pic16_sameRegs(AOP(left), AOP(result));
1917 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1921 // its faster to left shift
1922 for (i=1; i < size; i++) {
1923 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1926 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1928 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1932 if(AOP_TYPE(left) != AOP_ACC)
1933 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1934 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1935 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1936 pic16_popGet(AOP(result), 0)));
1938 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1939 pic16_popGet(AOP(result), 1)));
1940 for (i=2; i < size; i++) {
1941 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1947 // operands different
1951 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1955 for (i=1; i < size; i++) {
1956 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1959 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1960 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1962 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1965 if(AOP_TYPE(left) != AOP_ACC)
1966 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1967 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1968 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1969 pic16_popGet(AOP(result), 0)));
1972 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1973 pic16_popGet(AOP(result), 1)));
1974 for (i=2; i < size; i++) {
1975 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1983 /*-----------------------------------------------------------------------*
1984 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1985 *-----------------------------------------------------------------------*/
1986 void pic16_genUMult16XLit_16 (operand *left,
1990 pCodeOp *pct1, *pct2, *pct3, *pct4;
1997 if (AOP_TYPE(right) != AOP_LIT){
1998 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2002 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2005 same = pic16_sameRegs(AOP(left), AOP(result));
2009 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2010 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2013 // its faster to left shift
2015 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2016 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2020 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2022 pct1 = pic16_popGetTempReg(1);
2023 pct2 = pic16_popGetTempReg(1);
2024 pct3 = pic16_popGetTempReg(1);
2025 pct4 = pic16_popGetTempReg(1);
2027 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2028 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2029 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2030 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2031 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2032 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2034 /* WREG still holds the low literal */
2035 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2036 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2037 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2039 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2040 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2041 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2042 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2045 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2046 pct1, pic16_popGet(AOP(result), 0)));
2047 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2048 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2049 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2050 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2052 pic16_popReleaseTempReg(pct4,1);
2053 pic16_popReleaseTempReg(pct3,1);
2054 pic16_popReleaseTempReg(pct2,1);
2055 pic16_popReleaseTempReg(pct1,1);
2059 // operands different
2062 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2063 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2067 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2068 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2069 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2070 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2074 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2075 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2076 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2077 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2078 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2079 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2081 /* WREG still holds the low literal */
2082 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2083 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2084 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2086 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2087 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2088 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2089 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2097 /*-----------------------------------------------------------------*
2098 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
2101 *-----------------------------------------------------------------*/
2102 void pic16_genUMult8X8_8 (operand *left,
2110 if (AOP_TYPE(right) == AOP_LIT) {
2111 pic16_genUMult8XLit_8(left,right,result);
2121 /* if result == right then exchange left and right */
2122 if(pic16_sameRegs(AOP(result), AOP(right))) {
2129 if(AOP_TYPE(left) != AOP_ACC) {
2131 if(AOP_TYPE(right) != AOP_ACC) {
2132 pic16_mov2w(AOP(left), 0);
2133 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2135 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2138 // left is WREG, right cannot be WREG (or can?!)
2139 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
2142 /* result is in PRODL:PRODH */
2143 if(AOP_TYPE(result) != AOP_ACC) {
2144 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
2145 pic16_popGet(AOP(result), 0)));
2148 if(AOP_SIZE(result)>1) {
2151 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
2152 pic16_popGet(AOP(result), 1)));
2154 for(i=2;i<AOP_SIZE(result);i++)
2155 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
2158 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2162 /*------------------------------------------------------------------*
2163 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
2164 *------------------------------------------------------------------*/
2165 void pic16_genUMult16X16_16 (operand *left,
2170 pCodeOp *pct1, *pct2, *pct3, *pct4;
2175 if (AOP_TYPE(right) == AOP_LIT) {
2176 pic16_genUMult8XLit_8(left,right,result);
2184 /* if result == right then exchange left and right */
2185 if(pic16_sameRegs(AOP(result), AOP(right))) {
2193 if(pic16_sameRegs(AOP(result), AOP(left))) {
2195 pct1 = pic16_popGetTempReg(1);
2196 pct2 = pic16_popGetTempReg(1);
2197 pct3 = pic16_popGetTempReg(1);
2198 pct4 = pic16_popGetTempReg(1);
2200 pic16_mov2w(AOP(left), 0);
2201 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2202 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2203 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2204 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2205 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2207 /* WREG still holds the lower left */
2208 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2209 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2210 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2212 pic16_mov2w(AOP(left), 1);
2213 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2214 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2215 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2218 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2219 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2220 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2221 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2222 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2223 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2225 pic16_popReleaseTempReg( pct4, 1 );
2226 pic16_popReleaseTempReg( pct3, 1 );
2227 pic16_popReleaseTempReg( pct2, 1 );
2228 pic16_popReleaseTempReg( pct1, 1 );
2232 pic16_mov2w(AOP(left), 0);
2233 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2234 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2235 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2236 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2237 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2239 /* WREG still holds the lower left */
2240 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2241 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2242 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2244 pic16_mov2w(AOP(left), 1);
2245 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2246 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2247 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2252 void pic16_genSMult16X16_16(operand *left,
2260 /*-----------------------------------------------------------------*
2261 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
2263 * this routine will call the unsigned multiply routine and then
2264 * post-fix the sign bit.
2265 *-----------------------------------------------------------------*/
2266 void pic16_genSMult8X8_8 (operand *left,
2269 pCodeOpReg *result_hi)
2271 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2275 result_hi = PCOR(pic16_popGet(AOP(result),1));
2279 pic16_genUMult8X8_8(left,right,result);
2283 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2284 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2285 pic16_mov2w(AOP(left),0);
2286 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2287 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2292 /*-----------------------------------------------------------------*
2293 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
2294 *-----------------------------------------------------------------*/
2295 void pic16_genMult8X8_8 (operand *left,
2301 if(AOP_TYPE(right) == AOP_LIT)
2302 pic16_genUMult8XLit_8(left,right,result);
2304 pic16_genUMult8X8_8(left,right,result);
2308 /*-----------------------------------------------------------------*
2309 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
2310 *-----------------------------------------------------------------*/
2311 void pic16_genMult16X16_16 (operand *left,
2317 if (AOP_TYPE(right) == AOP_LIT)
2318 pic16_genUMult16XLit_16(left,right,result);
2320 pic16_genUMult16X16_16(left,right,result);
2326 /*-----------------------------------------------------------------------*
2327 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2328 *-----------------------------------------------------------------------*/
2329 void pic16_genUMult32XLit_32 (operand *left,
2333 pCodeOp *pct1, *pct2, *pct3, *pct4;
2340 if (AOP_TYPE(right) != AOP_LIT){
2341 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2345 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2348 same = pic16_sameRegs(AOP(left), AOP(result));
2352 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2353 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2356 // its faster to left shift
2358 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2359 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2363 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2365 pct1 = pic16_popGetTempReg(1);
2366 pct2 = pic16_popGetTempReg(1);
2367 pct3 = pic16_popGetTempReg(1);
2368 pct4 = pic16_popGetTempReg(1);
2370 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2371 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2372 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2373 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2374 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2375 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2377 /* WREG still holds the low literal */
2378 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2379 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2380 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2382 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2383 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2384 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2385 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2388 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2389 pct1, pic16_popGet(AOP(result), 0)));
2390 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2391 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2392 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2393 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2395 pic16_popReleaseTempReg( pct4, 1 );
2396 pic16_popReleaseTempReg( pct3, 1 );
2397 pic16_popReleaseTempReg( pct2, 1 );
2398 pic16_popReleaseTempReg( pct1, 1 );
2402 // operands different
2405 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2406 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2410 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2411 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2412 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2413 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2417 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2418 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2419 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2420 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2421 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2422 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2424 /* WREG still holds the low literal */
2425 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2426 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2427 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2429 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2430 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2431 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2432 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2440 /*------------------------------------------------------------------*
2441 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2442 *------------------------------------------------------------------*/
2443 void pic16_genUMult32X32_32 (operand *left,
2448 pCodeOp *pct1, *pct2, *pct3, *pct4;
2452 if (AOP_TYPE(right) == AOP_LIT) {
2453 pic16_genUMult8XLit_8(left,right,result);
2461 /* if result == right then exchange left and right */
2462 if(pic16_sameRegs(AOP(result), AOP(right))) {
2470 if(pic16_sameRegs(AOP(result), AOP(left))) {
2472 pct1 = pic16_popGetTempReg(1);
2473 pct2 = pic16_popGetTempReg(1);
2474 pct3 = pic16_popGetTempReg(1);
2475 pct4 = pic16_popGetTempReg(1);
2477 pic16_mov2w(AOP(left), 0);
2478 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2479 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2480 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2481 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2482 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2484 /* WREG still holds the lower left */
2485 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2486 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2487 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2489 pic16_mov2w(AOP(left), 1);
2490 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2491 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2492 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2495 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2496 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2497 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2498 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2499 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2500 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2502 pic16_popReleaseTempReg( pct4, 1 );
2503 pic16_popReleaseTempReg( pct3, 1 );
2504 pic16_popReleaseTempReg( pct2, 1 );
2505 pic16_popReleaseTempReg( pct1, 1 );
2509 pic16_mov2w(AOP(left), 0);
2510 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2511 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2512 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2513 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2514 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2516 /* WREG still holds the lower left */
2517 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2518 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2519 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2521 pic16_mov2w(AOP(left), 1);
2522 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2523 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2524 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2529 /*-----------------------------------------------------------------*
2530 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2531 *-----------------------------------------------------------------*/
2532 void pic16_genMult32X32_32 (operand *left,
2538 if (AOP_TYPE(right) == AOP_LIT)
2539 pic16_genUMult32XLit_32(left,right,result);
2541 pic16_genUMult32X32_32(left,right,result);
2551 /*-----------------------------------------------------------------*/
2552 /* constMult - generates code for multiplication by a constant */
2553 /*-----------------------------------------------------------------*/
2554 void genMultConst(unsigned C)
2558 unsigned sr3; // Shift right 3
2564 Convert a string of 3 binary 1's in the lit into
2568 mask = 7 << ( (size*8) - 3);
2572 while(mask < (1<<size*8)) {
2574 if( (mask & lit) == lit) {
2577 /* We found 3 (or more) consecutive 1's */
2579 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2581 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2583 lit ^= consecutive_bits;
2587 sr3 |= (consecutive + lsb);