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)
758 result = IC_RESULT(ic);
759 same = pic16_sameRegs(AOP(left), AOP(result));
760 size = pic16_getDataSize(result);
761 sizeL = pic16_getDataSize(left);
764 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
765 /* move left to result -- possibly sign extend */
766 for (i=0; i < MIN(size, sizeL); i++) {
767 pic16_mov2f (AOP(result), AOP(left), i);
771 /* extend to result size */
772 pic16_addSign(result, sizeL, !IS_UNSIGNED(operandType(left)));
777 } else if (lit == 1) {
783 pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(result), 0));
787 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), 0));
788 for (i=1; i < size-1; i++) {
789 emitSKPNC; /* a jump here saves up to 2(size-2)cycles */
790 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), i));
796 pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1));
800 /* add literal to result */
801 for (i=0; i < size; i++) {
802 pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit));
803 llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */
804 pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC,
805 pic16_popGet (AOP(result), i));
813 /* Handle special cases first */
815 genAddLit2byte (result, 0, lit);
818 int hi = 0xff & (lit >> 8);
825 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
830 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
832 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
835 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
836 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
837 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
841 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
842 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
844 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
852 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
855 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
858 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
859 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
861 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
863 case 0xff: /* 0x01ff */
864 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
865 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
866 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
867 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
869 default: /* 0x01LL */
870 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
871 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
873 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
874 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
879 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
883 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
886 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
887 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
889 /* case 0xff: * 0xffff *
890 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
891 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
892 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
896 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
897 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
899 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
906 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
911 genAddLit2byte (result, MSB16, hi);
914 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
915 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
916 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
918 /* case 0xff: * 0xHHff *
919 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
920 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
921 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
922 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
924 */ default: /* 0xHHLL */
925 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
926 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
927 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
928 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
937 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
940 lo = BYTEofLONG(lit,0);
943 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
944 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
946 /* no carry info from previous step */
947 /* this means this is the first time to add */
952 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
956 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
957 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
959 carry_info = 3; /* Were adding only one byte and propogating the carry */
970 lo = BYTEofLONG(lit,0);
975 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
978 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
979 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
982 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
984 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
986 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
995 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
999 if(AOP_TYPE(left) == AOP_ACC) {
1000 /* left addend is already in accumulator */
1001 switch(lit & 0xff) {
1003 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1004 emitMOVWF(result,0);
1007 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
1008 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1009 emitMOVWF(result,0);
1012 /* left addend is in a register */
1013 switch(lit & 0xff) {
1015 pic16_mov2w(AOP(left),0);
1016 emitMOVWF(result, 0);
1019 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1020 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1021 emitMOVWF(result,0);
1024 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
1025 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1026 emitMOVWF(result,0);
1029 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1030 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1031 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1032 emitMOVWF(result,0);
1039 /* left is not the accumulator */
1041 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1042 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1044 pic16_mov2w(AOP(left),0);
1045 /* We don't know the state of the carry bit at this point */
1048 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1049 emitMOVWF(result,0);
1055 /* The ls byte of the lit must've been zero - that
1056 means we don't have to deal with carry */
1058 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1059 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
1060 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1065 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1066 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
1067 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1071 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
1072 pic16_mov2w(AOP(left),offset);
1073 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
1084 /*-----------------------------------------------------------------*/
1085 /* pic16_genPlus - generates code for addition */
1086 /*-----------------------------------------------------------------*/
1087 void pic16_genPlus (iCode *ic)
1089 int i, size, offset = 0;
1090 operand *result, *left, *right;
1094 /* special cases :- */
1095 result = IC_RESULT(ic);
1097 right = IC_RIGHT(ic);
1098 pic16_aopOp (left,ic,FALSE);
1099 pic16_aopOp (right,ic,FALSE);
1100 pic16_aopOp (result,ic,TRUE);
1101 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
1102 // pic16_DumpOp("(left)",left);
1104 /* if literal, literal on the right or
1105 if left requires ACC or right is already
1108 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
1110 right = IC_RIGHT(ic) = left;
1111 left = IC_LEFT(ic) = t;
1114 /* if both left & right are in bit space */
1115 if (AOP_TYPE(left) == AOP_CRY &&
1116 AOP_TYPE(right) == AOP_CRY) {
1117 pic16_genPlusBits (ic);
1121 /* if left in bit space & right literal */
1122 if (AOP_TYPE(left) == AOP_CRY &&
1123 AOP_TYPE(right) == AOP_LIT) {
1124 /* if result in bit space */
1125 if(AOP_TYPE(result) == AOP_CRY){
1126 if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
1127 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
1128 if (!pic16_sameRegs(AOP(left), AOP(result)) )
1129 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
1130 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
1133 unsigned long lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
1134 size = pic16_getDataSize(result);
1136 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
1137 pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
1138 pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
1139 //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
1140 //pic16_emitcode("addc","a,#00 ;%d",__LINE__);
1141 //pic16_aopPut(AOP(result),"a",offset++);
1147 /* if I can do an increment instead
1148 of add then GOOD for ME */
1149 if (pic16_genPlusIncr (ic) == TRUE)
1152 size = pic16_getDataSize(result);
1154 if(AOP(right)->type == AOP_LIT) {
1155 /* Add a literal to something else */
1157 unsigned lit = (unsigned) floatFromVal(AOP(right)->aopu.aop_lit);
1161 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
1163 genAddLit (ic, lit);
1166 } else if(AOP_TYPE(right) == AOP_CRY) {
1168 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
1169 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
1170 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
1172 /* here we are adding a bit to a char or int */
1174 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1176 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1177 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0));
1179 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1180 AOP(right)->aopu.aop_dir,
1181 AOP(right)->aopu.aop_dir);
1182 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1183 } else { // not same
1185 if(AOP_TYPE(left) == AOP_ACC) {
1186 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1187 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1189 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1190 AOP(right)->aopu.aop_dir,
1191 AOP(right)->aopu.aop_dir);
1192 pic16_emitcode(" xorlw","1");
1194 pic16_mov2w(AOP(left),0);
1195 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1196 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
1198 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1199 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1200 AOP(right)->aopu.aop_dir,
1201 AOP(right)->aopu.aop_dir);
1202 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1205 if(AOP_TYPE(result) != AOP_ACC) {
1207 if(AOP_TYPE(result) == AOP_CRY) {
1208 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1209 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0));
1211 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0));
1213 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0));
1214 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1221 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1222 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1224 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1225 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
1227 pic16_emitcode("clrz","");
1229 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1230 AOP(right)->aopu.aop_dir,
1231 AOP(right)->aopu.aop_dir);
1232 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1235 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
1236 pic16_mov2w(AOP(left),0);
1237 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1238 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1239 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
1242 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1243 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1244 AOP(right)->aopu.aop_dir,
1245 AOP(right)->aopu.aop_dir);
1246 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1247 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1253 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++));
1254 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE));
1262 // Note: the following is an example of WISC code, eg.
1263 // it's supposed to run on a Weird Instruction Set Computer :o)
1265 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1267 if ( AOP_TYPE(left) == AOP_ACC) {
1268 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1269 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
1270 if ( AOP_TYPE(result) != AOP_ACC)
1271 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1272 goto release; // we're done, since WREG is 1 byte
1276 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1278 size = min( AOP_SIZE(result), AOP_SIZE(right) );
1279 size = min( size, AOP_SIZE(left) );
1282 if(pic16_debug_verbose) {
1283 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
1284 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
1285 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
1290 if ((AOP_TYPE(left) == AOP_PCODE) && (
1291 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
1292 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
1293 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
1295 // add to literal operand
1298 for(i=0; i<size; i++) {
1299 if (AOP_TYPE(right) == AOP_ACC) {
1300 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1302 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1303 if(i) { // add with carry
1304 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1305 } else { // add without
1306 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1309 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1312 DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
1314 // add leftover bytes
1315 if (SPEC_USIGN(getSpec(operandType(right)))) {
1316 // right is unsigned
1317 for(i=size; i< AOP_SIZE(result); i++) {
1318 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1319 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1320 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1324 // right is signed, oh dear ...
1325 for(i=size; i< AOP_SIZE(result); i++) {
1326 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1327 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1328 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),i));
1329 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1330 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1340 for(i=0; i<size; i++) {
1341 if (AOP_TYPE(right) != AOP_ACC)
1342 pic16_mov2w(AOP(right),i);
1343 if (pic16_sameRegs(AOP(left), AOP(result)))
1345 if(i) { // add with carry
1346 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1347 } else { // add without
1348 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1350 } else { // not same
1351 if(i) { // add with carry
1352 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1353 } else { // add without
1354 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1356 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1360 // add leftover bytes
1361 // either left or right is too short
1362 for (i=size; i < AOP_SIZE(result); i++) {
1363 // get right operand into WREG
1364 if (i < AOP_SIZE(right)) {
1365 pic16_mov2w (AOP(right), i);
1367 // right is too short
1368 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1369 if (!SPEC_USIGN(getSpec(operandType(right)))) {
1370 // right operand is signed
1371 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1372 pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1376 // get left+WREG+CARRY into result
1377 if (i < AOP_SIZE(left)) {
1378 if (pic16_sameRegs (AOP(left), AOP(result))) {
1379 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1381 pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
1382 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1385 // left is too short
1386 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
1387 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1388 // left operand is signed
1389 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1390 pic16_emitpcode(POC_SETF, pic16_popGet (AOP(result), i));
1392 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1403 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1404 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1405 pic16_freeAsmop(result,NULL,ic,TRUE);
1408 /*-----------------------------------------------------------------*/
1409 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1410 /*-----------------------------------------------------------------*/
1411 bool pic16_genMinusDec (iCode *ic)
1413 unsigned int icount ;
1414 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1417 /* will try to generate an increment */
1418 /* if the right side is not a literal
1420 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1421 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1422 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1425 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1427 /* if the literal value of the right hand side
1428 is greater than 4 then it is not worth it */
1429 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1432 /* if decrement 16 bits in register */
1433 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1438 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1440 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1442 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1443 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1444 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1446 /* size is 3 or 4 */
1447 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1448 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1449 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1450 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1452 pic16_emitcode("movlw","0xff");
1453 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1456 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1458 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1461 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1463 pic16_emitcode("skpnc","");
1465 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1474 /* if the sizes are greater than 1 then we cannot */
1475 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1476 AOP_SIZE(IC_LEFT(ic)) > 1 )
1479 /* we can if the aops of the left & result match or
1480 if they are in registers and the registers are the
1482 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1485 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1487 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1492 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1493 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1494 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1497 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1498 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1500 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1501 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1509 /*-----------------------------------------------------------------*/
1510 /* pic16_addSign - propogate sign bit to higher bytes */
1511 /*-----------------------------------------------------------------*/
1512 void pic16_addSign(operand *result, int offset, int sign)
1514 int size = (pic16_getDataSize(result) - offset);
1515 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1518 if(sign && offset) {
1521 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1522 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1523 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
1526 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1527 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1528 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1530 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1535 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1539 /*-----------------------------------------------------------------*/
1540 /* pic16_genMinusBits - generates code for subtraction of two bits */
1541 /*-----------------------------------------------------------------*/
1542 void pic16_genMinusBits (iCode *ic)
1544 symbol *lbl = newiTempLabel(NULL);
1547 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1548 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1549 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1550 pic16_emitcode("cpl","c");
1551 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1552 pic16_outBitC(IC_RESULT(ic));
1555 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1556 pic16_emitcode("subb","a,acc");
1557 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1558 pic16_emitcode("inc","a");
1559 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1560 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1561 pic16_addSign(IC_RESULT(ic), MSB16, !IS_UNSIGNED(operandType(IC_RESULT(ic))));
1565 /*-----------------------------------------------------------------*/
1566 /* pic16_genMinus - generates code for subtraction */
1567 /*-----------------------------------------------------------------*/
1568 void pic16_genMinus (iCode *ic)
1570 int size, offset = 0, same=0;
1571 unsigned long lit = 0L;
1574 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1575 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1576 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1578 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1579 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1580 operand *t = IC_RIGHT(ic);
1581 IC_RIGHT(ic) = IC_LEFT(ic);
1585 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1586 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1587 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1588 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1590 /* special cases :- */
1591 /* if both left & right are in bit space */
1592 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1593 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1594 pic16_genPlusBits (ic);
1598 /* if I can do an decrement instead
1599 of subtract then GOOD for ME */
1600 // if (pic16_genMinusDec (ic) == TRUE)
1603 size = pic16_getDataSize(IC_RESULT(ic));
1604 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1606 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1607 /* Add a literal to something else */
1609 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1612 genAddLit ( ic, lit);
1615 /* add the first byte: */
1616 pic16_emitcode("movlw","0x%x", lit & 0xff);
1617 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1618 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1619 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1631 if((lit & 0xff) == 0xff) {
1632 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1634 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1636 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1638 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1639 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1643 /* do the rlf known zero trick here */
1644 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1646 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1651 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1654 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1655 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1656 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1658 /* here we are subtracting a bit from a char or int */
1660 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1662 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1663 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1665 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1666 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1667 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1668 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1671 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1672 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1673 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1674 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1675 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1677 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1679 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1680 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1682 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1683 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1686 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1688 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1690 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1691 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1695 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1696 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1697 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1698 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1703 pic16_mov2w(AOP(IC_LEFT(ic)),0);
1704 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1705 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1708 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1710 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1713 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1715 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1717 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1724 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1725 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1726 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1728 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1729 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1730 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1731 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1732 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1735 if( (size == 1) && ((lit & 0xff) == 0) ) {
1736 /* res = 0 - right */
1737 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1738 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1740 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1741 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1742 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1747 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1748 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1749 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1757 // here we have x = lit - x for sizeof(x)>1
1758 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1759 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1761 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1762 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1763 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1770 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1771 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1772 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1773 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1775 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1776 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1777 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1778 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1779 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1780 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1783 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1784 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1785 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1787 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1788 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1790 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1791 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1792 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1794 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1796 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1797 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1798 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1800 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1802 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1808 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1810 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1811 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1813 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1814 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1821 if (offset < AOP_SIZE(IC_RIGHT(ic)))
1822 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1824 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1825 if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
1826 // signed -- sign extend the right operand
1827 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));
1828 pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1831 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1832 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1834 if (offset < AOP_SIZE(IC_LEFT(ic))) {
1835 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1836 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1838 // zero extend the left operand
1839 pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
1840 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
1841 // signed -- sign extend the left operand
1842 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));
1843 pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
1845 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1854 // adjustArithmeticResult(ic);
1857 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1858 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1859 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1863 /*-----------------------------------------------------------------*
1864 * pic_genMult8XLit_n - multiplication of two 8-bit numbers.
1867 *-----------------------------------------------------------------*/
1868 void pic16_genMult8XLit_n (operand *left,
1874 int size = AOP_SIZE(result);
1878 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1880 if (AOP_TYPE(right) != AOP_LIT){
1881 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1885 lit = (int)floatFromVal(AOP(right)->aopu.aop_lit);
1886 assert( (lit >= -128) && (lit < 256) );
1887 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1888 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1890 same = pic16_sameRegs(AOP(left), AOP(result));
1892 switch(lit & 0x00ff) {
1895 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1900 /* sign extend left in result */
1901 pic16_addSign(result, 1, !IS_UNSIGNED(operandType(left)));
1902 // its faster to left shift
1904 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1906 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1910 if(AOP_TYPE(left) != AOP_ACC)
1911 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1912 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit & 0x00ff));
1913 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1914 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1915 /* Adjust result's high bytes below! */
1918 // operands different
1919 switch(lit & 0x00ff) {
1922 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1927 if (IS_UNSIGNED(operandType(result))) {
1928 for (i=1; i < size; i++) {
1929 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1932 /* sign extend left to result */
1933 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1934 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
1935 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1936 for (i=1; i < size; i++) {
1937 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1941 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1942 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1944 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1948 if(AOP_TYPE(left) != AOP_ACC)
1949 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1950 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1951 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1952 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1953 /* Adjust result's high bytes below! */
1958 /* We need to fix PRODH for
1959 * (a) literals < 0 and
1960 * (b) signed register operands < 0.
1962 //printf( "%s: lit %d, left unsigned: %d\n", __FUNCTION__, lit, SPEC_USIGN(getSpec(operandType(left))));
1964 /* literal negative (i.e. in [-128..-1]), high byte == -1 */
1965 pic16_mov2w(AOP(left), 0);
1966 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
1969 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1970 /* register operand signed, determine signedness of high byte */
1971 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0x00ff));
1972 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
1973 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
1976 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1977 &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1979 /* Need to sign-extend here. */
1980 pic16_addSign(result, 2, !IS_UNSIGNED(operandType(result)));
1985 /*-----------------------------------------------------------------------*
1986 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1987 *-----------------------------------------------------------------------*/
1988 void pic16_genUMult16XLit_16 (operand *left,
1992 pCodeOp *pct1, *pct2, *pct3, *pct4;
1999 if (AOP_TYPE(right) != AOP_LIT){
2000 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2004 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2007 same = pic16_sameRegs(AOP(left), AOP(result));
2011 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2012 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2015 // its faster to left shift
2017 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2018 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2022 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2024 pct1 = pic16_popGetTempReg(1);
2025 pct2 = pic16_popGetTempReg(1);
2026 pct3 = pic16_popGetTempReg(1);
2027 pct4 = pic16_popGetTempReg(1);
2029 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2030 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2031 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2032 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2033 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2034 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2036 /* WREG still holds the low literal */
2037 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2038 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2039 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2041 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2042 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2043 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2044 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2047 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2048 pct1, pic16_popGet(AOP(result), 0)));
2049 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2050 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2051 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2052 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2054 pic16_popReleaseTempReg(pct4,1);
2055 pic16_popReleaseTempReg(pct3,1);
2056 pic16_popReleaseTempReg(pct2,1);
2057 pic16_popReleaseTempReg(pct1,1);
2061 // operands different
2064 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2065 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2069 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2070 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2071 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2072 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2076 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2077 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2078 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2079 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2080 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2081 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2083 /* WREG still holds the low literal */
2084 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2085 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2086 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2088 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2089 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2090 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2091 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2100 /*-----------------------------------------------------------------*
2101 * genMult8X8_n - multiplication of two 8-bit numbers.
2104 *-----------------------------------------------------------------*/
2105 void pic16_genMult8X8_n (operand *left, operand *right, operand *result)
2111 if (AOP_TYPE(right) == AOP_LIT) {
2112 pic16_genMult8XLit_n(left,right,result);
2122 /* if result == right then exchange left and right */
2123 if(pic16_sameRegs(AOP(result), AOP(right))) {
2130 if(AOP_TYPE(left) != AOP_ACC) {
2132 if(AOP_TYPE(right) != AOP_ACC) {
2133 pic16_mov2w(AOP(left), 0);
2134 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2136 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2139 // left is WREG, right cannot be WREG (or can?!)
2140 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
2143 /* result is in PRODL:PRODH */
2144 if(AOP_TYPE(result) != AOP_ACC) {
2145 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
2146 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2149 if(AOP_SIZE(result)>1) {
2151 /* If s8 x s8 --> s16 multiplication was called for, fixup high byte.
2152 * (left=a1a0, right=b1b0, X1: high byte, X0: low byte)
2159 * a0b0 a1= 0, b1= 0 (both unsigned)
2160 * -b0 a0b0 a1=-1, b1= 0 (a signed and < 0, b unsigned or >= 0)
2161 * -a0 a0b0 a1= 0, b1=-1 (b signed and < 0, a unsigned or >= 0)
2162 * -(a0+b0) a0b0 a1=-1, b1=-1 (a and b signed and < 0)
2164 * Currently, PRODH:PRODL holds a0b0 as 16 bit value; we need to
2165 * subtract a0 and/or b0 from PRODH. */
2166 if (!IS_UNSIGNED(operandType(right))) {
2167 /* right operand (b1) signed and < 0, then subtract left op (a0) */
2168 pic16_mov2w( AOP(left), 0 );
2169 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
2170 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
2173 if (!IS_UNSIGNED(getSpec(operandType(left)))) {
2174 /* left operand (a1) signed and < 0, then subtract right op (b0) */
2175 pic16_mov2w( AOP(right), 0 );
2176 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
2177 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
2180 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
2181 &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2183 /* Must sign-extend here. */
2184 pic16_addSign(result, 2, !IS_UNSIGNED(operandType(left)));
2187 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2192 /*------------------------------------------------------------------*
2193 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
2194 *------------------------------------------------------------------*/
2195 void pic16_genUMult16X16_16 (operand *left,
2200 pCodeOp *pct1, *pct2, *pct3, *pct4;
2205 if (AOP_TYPE(right) == AOP_LIT) {
2206 pic16_genMult8XLit_n(left,right,result);
2214 /* if result == right then exchange left and right */
2215 if(pic16_sameRegs(AOP(result), AOP(right))) {
2223 if(pic16_sameRegs(AOP(result), AOP(left))) {
2225 pct1 = pic16_popGetTempReg(1);
2226 pct2 = pic16_popGetTempReg(1);
2227 pct3 = pic16_popGetTempReg(1);
2228 pct4 = pic16_popGetTempReg(1);
2230 pic16_mov2w(AOP(left), 0);
2231 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2232 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2233 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2234 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2235 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2237 /* WREG still holds the lower left */
2238 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2239 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2240 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2242 pic16_mov2w(AOP(left), 1);
2243 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2244 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2245 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2248 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2249 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2250 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2251 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2252 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2253 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2255 pic16_popReleaseTempReg( pct4, 1 );
2256 pic16_popReleaseTempReg( pct3, 1 );
2257 pic16_popReleaseTempReg( pct2, 1 );
2258 pic16_popReleaseTempReg( pct1, 1 );
2262 pic16_mov2w(AOP(left), 0);
2263 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2264 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2265 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2266 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2267 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2269 /* WREG still holds the lower left */
2270 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2271 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2272 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2274 pic16_mov2w(AOP(left), 1);
2275 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2276 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2277 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2283 void pic16_genSMult16X16_16(operand *left,
2292 /*-----------------------------------------------------------------*
2293 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
2295 * this routine will call the unsigned multiply routine and then
2296 * post-fix the sign bit.
2297 *-----------------------------------------------------------------*/
2298 void pic16_genSMult8X8_8 (operand *left,
2301 pCodeOpReg *result_hi)
2303 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2307 result_hi = PCOR(pic16_popGet(AOP(result),1));
2311 pic16_genUMult8X8_8(left,right,result);
2315 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2316 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2317 pic16_mov2w(AOP(left),0);
2318 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2319 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2324 /*-----------------------------------------------------------------*
2325 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
2326 *-----------------------------------------------------------------*/
2327 void pic16_genMult8X8_8 (operand *left,
2333 if(AOP_TYPE(right) == AOP_LIT)
2334 pic16_genMult8XLit_n(left,right,result);
2336 pic16_genMult8X8_n(left,right,result);
2341 /*-----------------------------------------------------------------*
2342 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
2343 *-----------------------------------------------------------------*/
2344 void pic16_genMult16X16_16 (operand *left,
2350 if (AOP_TYPE(right) == AOP_LIT)
2351 pic16_genUMult16XLit_16(left,right,result);
2353 pic16_genUMult16X16_16(left,right,result);
2359 /*-----------------------------------------------------------------------*
2360 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2361 *-----------------------------------------------------------------------*/
2362 void pic16_genUMult32XLit_32 (operand *left,
2366 pCodeOp *pct1, *pct2, *pct3, *pct4;
2373 if (AOP_TYPE(right) != AOP_LIT){
2374 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2378 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2381 same = pic16_sameRegs(AOP(left), AOP(result));
2385 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2386 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2389 // its faster to left shift
2391 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2392 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2396 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2398 pct1 = pic16_popGetTempReg(1);
2399 pct2 = pic16_popGetTempReg(1);
2400 pct3 = pic16_popGetTempReg(1);
2401 pct4 = pic16_popGetTempReg(1);
2403 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2404 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2405 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2406 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2407 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2408 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2410 /* WREG still holds the low literal */
2411 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2412 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2413 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2415 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2416 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2417 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2418 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2421 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2422 pct1, pic16_popGet(AOP(result), 0)));
2423 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2424 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2425 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2426 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2428 pic16_popReleaseTempReg( pct4, 1 );
2429 pic16_popReleaseTempReg( pct3, 1 );
2430 pic16_popReleaseTempReg( pct2, 1 );
2431 pic16_popReleaseTempReg( pct1, 1 );
2435 // operands different
2438 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2439 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2443 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2444 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2445 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2446 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2450 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2451 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2452 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2453 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2454 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2455 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2457 /* WREG still holds the low literal */
2458 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2459 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2460 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2462 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2463 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2464 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2465 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2474 /*------------------------------------------------------------------*
2475 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2476 *------------------------------------------------------------------*/
2477 void pic16_genUMult32X32_32 (operand *left,
2482 pCodeOp *pct1, *pct2, *pct3, *pct4;
2486 if (AOP_TYPE(right) == AOP_LIT) {
2487 pic16_genMult8XLit_n(left,right,result);
2495 /* if result == right then exchange left and right */
2496 if(pic16_sameRegs(AOP(result), AOP(right))) {
2504 if(pic16_sameRegs(AOP(result), AOP(left))) {
2506 pct1 = pic16_popGetTempReg(1);
2507 pct2 = pic16_popGetTempReg(1);
2508 pct3 = pic16_popGetTempReg(1);
2509 pct4 = pic16_popGetTempReg(1);
2511 pic16_mov2w(AOP(left), 0);
2512 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2513 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2514 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2515 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2516 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2518 /* WREG still holds the lower left */
2519 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2520 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2521 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2523 pic16_mov2w(AOP(left), 1);
2524 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2525 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2526 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2529 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2530 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2531 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2532 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2533 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2534 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2536 pic16_popReleaseTempReg( pct4, 1 );
2537 pic16_popReleaseTempReg( pct3, 1 );
2538 pic16_popReleaseTempReg( pct2, 1 );
2539 pic16_popReleaseTempReg( pct1, 1 );
2543 pic16_mov2w(AOP(left), 0);
2544 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2545 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2546 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2547 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2548 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2550 /* WREG still holds the lower left */
2551 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2552 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2553 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2555 pic16_mov2w(AOP(left), 1);
2556 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2557 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2558 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2565 /*-----------------------------------------------------------------*
2566 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2567 *-----------------------------------------------------------------*/
2568 void pic16_genMult32X32_32 (operand *left,
2574 if (AOP_TYPE(right) == AOP_LIT)
2575 pic16_genUMult32XLit_32(left,right,result);
2577 pic16_genUMult32X32_32(left,right,result);
2588 /*-----------------------------------------------------------------*/
2589 /* constMult - generates code for multiplication by a constant */
2590 /*-----------------------------------------------------------------*/
2591 void genMultConst(unsigned C)
2595 unsigned sr3; // Shift right 3
2601 Convert a string of 3 binary 1's in the lit into
2605 mask = 7 << ( (size*8) - 3);
2609 while(mask < (1<<size*8)) {
2611 if( (mask & lit) == lit) {
2614 /* We found 3 (or more) consecutive 1's */
2616 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2618 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2620 lit ^= consecutive_bits;
2624 sr3 |= (consecutive + lsb);