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";
119 return "BAD PO_TYPE";
122 const char *pic16_pCodeOpSubType(pCodeOp *pcop)
125 if(pcop && (pcop->type == PO_GPR_BIT)) {
127 switch(PCORB(pcop)->subtype) {
129 case PO_NONE: return "PO_NONE";
130 case PO_W: return "PO_W";
131 case PO_WREG: return "PO_WREG";
132 case PO_STATUS: return "PO_STATUS";
133 case PO_BSR: return "PO_BSR";
134 case PO_FSR0: return "PO_FSR0";
135 case PO_INDF0: return "PO_INDF0";
136 case PO_INTCON: return "PO_INTCON";
137 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
138 case PO_GPR_BIT: return "PO_GPR_BIT";
139 case PO_GPR_TEMP: return "PO_GPR_TEMP";
140 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
141 case PO_PCL: return "PO_PCL";
142 case PO_PCLATH: return "PO_PCLATH";
143 case PO_PCLATU: return "PO_PCLATU";
144 case PO_PRODL: return "PO_PRODL";
145 case PO_PRODH: return "PO_PRODH";
146 case PO_LITERAL: return "PO_LITERAL";
147 case PO_REL_ADDR: return "PO_REL_ADDR";
148 case PO_IMMEDIATE: return "PO_IMMEDIATE";
149 case PO_DIR: return "PO_DIR";
150 case PO_CRY: return "PO_CRY";
151 case PO_BIT: return "PO_BIT";
152 case PO_STR: return "PO_STR";
153 case PO_LABEL: return "PO_LABEL";
154 case PO_WILD: return "PO_WILD";
158 return "BAD PO_TYPE";
161 /*-----------------------------------------------------------------*/
162 /* pic16_genPlusIncr :- does addition with increment if possible */
163 /*-----------------------------------------------------------------*/
164 bool pic16_genPlusIncr (iCode *ic)
166 unsigned int icount ;
167 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
171 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
172 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
173 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
174 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
176 /* will try to generate an increment */
177 /* if the right side is not a literal
179 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
182 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
183 /* if the literal value of the right hand side
184 is greater than 2 then it is faster to add */
185 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
188 /* if increment 16 bits in register */
189 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
194 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
195 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
199 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
200 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
206 // DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
207 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
208 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
209 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
211 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
212 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
213 AOP(IC_RESULT(ic))->aopu.aop_dir,
214 AOP(IC_RESULT(ic))->aopu.aop_dir);
216 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
217 //pic16_emitcode("xorlw","1");
219 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
220 //pic16_emitcode("andlw","1");
223 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
224 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
225 AOP(IC_RESULT(ic))->aopu.aop_dir,
226 AOP(IC_RESULT(ic))->aopu.aop_dir);
232 /* if the sizes are greater than 1 then we cannot */
233 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
234 AOP_SIZE(IC_LEFT(ic)) > 1 )
237 /* If we are incrementing the same register by two: */
239 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
242 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
243 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
248 DEBUGpic16_emitcode ("; ","couldn't increment ");
253 /*-----------------------------------------------------------------*/
254 /* pic16_outBitAcc - output a bit in acc */
255 /*-----------------------------------------------------------------*/
256 void pic16_outBitAcc(operand *result)
258 symbol *tlbl = newiTempLabel(NULL);
259 /* if the result is a bit */
260 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
262 assert(0); // not implemented for PIC16?
264 if (AOP_TYPE(result) == AOP_CRY){
265 pic16_aopPut(AOP(result),"a",0);
268 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
269 pic16_emitcode("mov","a,#01");
270 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
271 pic16_outAcc(result);
275 /*-----------------------------------------------------------------*/
276 /* pic16_genPlusBits - generates code for addition of two bits */
277 /*-----------------------------------------------------------------*/
278 void pic16_genPlusBits (iCode *ic)
282 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
283 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
284 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
285 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
287 The following block of code will add two bits.
288 Note that it'll even work if the destination is
289 the carry (C in the status register).
290 It won't work if the 'Z' bit is a source or destination.
293 /* If the result is stored in the accumulator (w) */
294 //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
295 switch(AOP_TYPE(IC_RESULT(ic))) {
297 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
298 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
299 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
300 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
301 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
303 pic16_emitcode("clrw","");
304 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
305 AOP(IC_RIGHT(ic))->aopu.aop_dir,
306 AOP(IC_RIGHT(ic))->aopu.aop_dir);
307 pic16_emitcode("xorlw","1");
308 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
309 AOP(IC_LEFT(ic))->aopu.aop_dir,
310 AOP(IC_LEFT(ic))->aopu.aop_dir);
311 pic16_emitcode("xorlw","1");
314 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
315 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
316 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
317 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
318 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
319 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
322 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
323 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
324 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
325 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
326 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
327 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
329 pic16_emitcode("movlw","(1 << (%s & 7))",
330 AOP(IC_RESULT(ic))->aopu.aop_dir,
331 AOP(IC_RESULT(ic))->aopu.aop_dir);
332 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
333 AOP(IC_RESULT(ic))->aopu.aop_dir,
334 AOP(IC_RESULT(ic))->aopu.aop_dir);
335 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
336 AOP(IC_RIGHT(ic))->aopu.aop_dir,
337 AOP(IC_RIGHT(ic))->aopu.aop_dir);
338 pic16_emitcode("xorwf","(%s >>3),f",
339 AOP(IC_RESULT(ic))->aopu.aop_dir);
340 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
341 AOP(IC_LEFT(ic))->aopu.aop_dir,
342 AOP(IC_LEFT(ic))->aopu.aop_dir);
343 pic16_emitcode("xorwf","(%s>>3),f",
344 AOP(IC_RESULT(ic))->aopu.aop_dir);
351 /* This is the original version of this code.
353 * This is being kept around for reference,
354 * because I am not entirely sure I got it right...
356 static void adjustArithmeticResult(iCode *ic)
358 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
359 AOP_SIZE(IC_LEFT(ic)) == 3 &&
360 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
361 pic16_aopPut(AOP(IC_RESULT(ic)),
362 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
365 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
366 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
367 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
368 pic16_aopPut(AOP(IC_RESULT(ic)),
369 pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
372 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
373 AOP_SIZE(IC_LEFT(ic)) < 3 &&
374 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
375 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
376 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
378 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
379 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
383 /* This is the pure and virtuous version of this code.
384 * I'm pretty certain it's right, but not enough to toss the old
387 static void adjustArithmeticResult(iCode *ic)
389 if (opIsGptr(IC_RESULT(ic)) &&
390 opIsGptr(IC_LEFT(ic)) &&
391 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
393 pic16_aopPut(AOP(IC_RESULT(ic)),
394 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
398 if (opIsGptr(IC_RESULT(ic)) &&
399 opIsGptr(IC_RIGHT(ic)) &&
400 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
402 pic16_aopPut(AOP(IC_RESULT(ic)),
403 pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
407 if (opIsGptr(IC_RESULT(ic)) &&
408 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
409 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
410 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
411 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
413 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
414 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
420 /*-----------------------------------------------------------------*/
421 /* genAddlit - generates code for addition */
422 /*-----------------------------------------------------------------*/
423 static void genAddLit2byte (operand *result, int offr, int lit)
431 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
434 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
437 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
438 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
444 static void emitMOVWF(operand *reg, int offset)
449 if (AOP_TYPE(reg) == AOP_ACC) {
450 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
454 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
461 static void genAddLit (iCode *ic, int lit)
474 result = IC_RESULT(ic);
475 same = pic16_sameRegs(AOP(left), AOP(result));
476 size = pic16_getDataSize(result);
480 /* Handle special cases first */
482 genAddLit2byte (result, 0, lit);
485 int hi = 0xff & (lit >> 8);
492 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
497 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
499 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
502 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
503 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
504 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
508 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
509 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
511 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
519 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
522 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
525 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
526 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
528 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
530 case 0xff: /* 0x01ff */
531 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
532 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
533 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
534 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
536 default: /* 0x01LL */
537 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
538 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
540 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
541 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
546 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
550 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
553 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
554 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
556 /* case 0xff: * 0xffff *
557 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
558 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
559 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
563 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
564 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
566 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
573 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
578 genAddLit2byte (result, MSB16, hi);
581 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
582 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
583 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
585 /* case 0xff: * 0xHHff *
586 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
587 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
588 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
589 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
591 */ default: /* 0xHHLL */
592 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
593 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
594 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
595 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
604 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
607 lo = BYTEofLONG(lit,0);
610 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
611 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
613 /* no carry info from previous step */
614 /* this means this is the first time to add */
619 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
623 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
624 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
626 carry_info = 3; /* Were adding only one byte and propogating the carry */
637 lo = BYTEofLONG(lit,0);
642 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
645 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
646 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
649 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
651 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
653 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
662 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
666 if(AOP_TYPE(left) == AOP_ACC) {
667 /* left addend is already in accumulator */
670 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
674 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
675 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
679 /* left addend is in a register */
682 pic16_mov2w(AOP(left),0);
683 emitMOVWF(result, 0);
686 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
687 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
691 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
692 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
696 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
697 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
698 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
706 /* left is not the accumulator */
708 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
709 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
711 pic16_mov2w(AOP(left),0);
712 /* We don't know the state of the carry bit at this point */
715 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
719 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
720 if (offset < AOP_SIZE(left)) {
721 pic16_emitpcode(clear_carry ? POC_ADDFW : POC_ADDFWC, pic16_popGet(AOP(left),offset));
722 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
724 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
725 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
726 /* sign-extend left (in result) */
727 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left),AOP_SIZE(left)-1,7));
728 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
730 pic16_emitpcode(clear_carry ? POC_ADDWF : POC_ADDWFC, pic16_popGet(AOP(result),offset));
740 /* this fails when result is an SFR because value is written there
741 * during addition and not at the end */
743 static void genAddLit (iCode *ic, int lit)
757 lleft = operandType (left);
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 if (IS_UNSIGNED(lleft)) {
774 for (i = sizeL; i < size; i++) {
775 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
779 if (size == sizeL + 1) {
780 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), sizeL));
781 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
782 pic16_emitpcode (POC_SETF, pic16_popGet (AOP(result), sizeL));
784 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
785 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
786 pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
788 for (i=sizeL; i < size; i++) {
789 pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(result), i));
797 } else if (lit == 1) {
803 pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(result), 0));
807 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), 0));
808 for (i=1; i < size-1; i++) {
809 emitSKPNC; /* a jump here saves up to 2(size-2)cycles */
810 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), i));
816 pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1));
820 /* add literal to result */
821 for (i=0; i < size; i++) {
822 pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit));
823 llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */
824 pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC,
825 pic16_popGet (AOP(result), i));
833 /* Handle special cases first */
835 genAddLit2byte (result, 0, lit);
838 int hi = 0xff & (lit >> 8);
845 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
850 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
852 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
855 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
856 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
857 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
861 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
862 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
864 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
872 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
875 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
878 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
879 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
881 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
883 case 0xff: /* 0x01ff */
884 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
885 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
886 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
887 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
889 default: /* 0x01LL */
890 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
891 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
893 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
894 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
899 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
903 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
906 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
907 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
909 /* case 0xff: * 0xffff *
910 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
911 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
912 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
916 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
917 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
919 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
926 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
931 genAddLit2byte (result, MSB16, hi);
934 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
935 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
936 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
938 /* case 0xff: * 0xHHff *
939 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
940 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
941 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
942 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
944 */ default: /* 0xHHLL */
945 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
946 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
947 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
948 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
957 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
960 lo = BYTEofLONG(lit,0);
963 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
964 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
966 /* no carry info from previous step */
967 /* this means this is the first time to add */
972 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
976 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
977 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
979 carry_info = 3; /* Were adding only one byte and propogating the carry */
990 lo = BYTEofLONG(lit,0);
995 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
998 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
999 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1002 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
1004 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
1006 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
1015 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
1019 if(AOP_TYPE(left) == AOP_ACC) {
1020 /* left addend is already in accumulator */
1021 switch(lit & 0xff) {
1023 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1024 emitMOVWF(result,0);
1027 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
1028 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1029 emitMOVWF(result,0);
1032 /* left addend is in a register */
1033 switch(lit & 0xff) {
1035 pic16_mov2w(AOP(left),0);
1036 emitMOVWF(result, 0);
1039 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1040 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1041 emitMOVWF(result,0);
1044 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
1045 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1046 emitMOVWF(result,0);
1049 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1050 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1051 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1052 emitMOVWF(result,0);
1059 /* left is not the accumulator */
1061 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1062 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1064 pic16_mov2w(AOP(left),0);
1065 /* We don't know the state of the carry bit at this point */
1068 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1069 emitMOVWF(result,0);
1075 /* The ls byte of the lit must've been zero - that
1076 means we don't have to deal with carry */
1078 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1079 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
1080 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1085 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1086 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
1087 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1091 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
1092 pic16_mov2w(AOP(left),offset);
1093 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
1104 /*-----------------------------------------------------------------*/
1105 /* pic16_genPlus - generates code for addition */
1106 /*-----------------------------------------------------------------*/
1107 void pic16_genPlus (iCode *ic)
1109 int i, size, offset = 0;
1110 operand *result, *left, *right;
1114 /* special cases :- */
1115 result = IC_RESULT(ic);
1117 right = IC_RIGHT(ic);
1118 pic16_aopOp (left,ic,FALSE);
1119 pic16_aopOp (right,ic,FALSE);
1120 pic16_aopOp (result,ic,TRUE);
1121 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
1122 // pic16_DumpOp("(left)",left);
1124 /* if literal, literal on the right or
1125 if left requires ACC or right is already
1128 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
1130 right = IC_RIGHT(ic) = left;
1131 left = IC_LEFT(ic) = t;
1134 /* if both left & right are in bit space */
1135 if (AOP_TYPE(left) == AOP_CRY &&
1136 AOP_TYPE(right) == AOP_CRY) {
1137 pic16_genPlusBits (ic);
1141 /* if left in bit space & right literal */
1142 if (AOP_TYPE(left) == AOP_CRY &&
1143 AOP_TYPE(right) == AOP_LIT) {
1144 /* if result in bit space */
1145 if(AOP_TYPE(result) == AOP_CRY){
1146 if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
1147 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
1148 if (!pic16_sameRegs(AOP(left), AOP(result)) )
1149 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
1150 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
1153 unsigned long lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
1154 size = pic16_getDataSize(result);
1156 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
1157 pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
1158 pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
1159 //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
1160 //pic16_emitcode("addc","a,#00 ;%d",__LINE__);
1161 //pic16_aopPut(AOP(result),"a",offset++);
1167 /* if I can do an increment instead
1168 of add then GOOD for ME */
1169 if (pic16_genPlusIncr (ic) == TRUE)
1172 size = pic16_getDataSize(result);
1174 if(AOP(right)->type == AOP_LIT) {
1175 /* Add a literal to something else */
1177 unsigned lit = (unsigned) floatFromVal(AOP(right)->aopu.aop_lit);
1181 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
1183 genAddLit (ic, lit);
1186 } else if(AOP_TYPE(right) == AOP_CRY) {
1188 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
1189 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
1190 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
1192 /* here we are adding a bit to a char or int */
1194 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1196 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1197 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0));
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,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1203 } else { // not same
1205 if(AOP_TYPE(left) == AOP_ACC) {
1206 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1207 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1209 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1210 AOP(right)->aopu.aop_dir,
1211 AOP(right)->aopu.aop_dir);
1212 pic16_emitcode(" xorlw","1");
1214 pic16_mov2w(AOP(left),0);
1215 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1216 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
1218 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1219 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1220 AOP(right)->aopu.aop_dir,
1221 AOP(right)->aopu.aop_dir);
1222 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1225 if(AOP_TYPE(result) != AOP_ACC) {
1227 if(AOP_TYPE(result) == AOP_CRY) {
1228 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1229 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0));
1231 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0));
1233 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0));
1234 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1241 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1242 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1244 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1245 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
1247 pic16_emitcode("clrz","");
1249 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1250 AOP(right)->aopu.aop_dir,
1251 AOP(right)->aopu.aop_dir);
1252 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1255 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
1256 pic16_mov2w(AOP(left),0);
1257 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1258 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1259 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
1262 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1263 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1264 AOP(right)->aopu.aop_dir,
1265 AOP(right)->aopu.aop_dir);
1266 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1267 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1273 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++));
1274 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE));
1282 // Note: the following is an example of WISC code, eg.
1283 // it's supposed to run on a Weird Instruction Set Computer :o)
1285 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1287 if ( AOP_TYPE(left) == AOP_ACC) {
1288 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1289 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
1290 if ( AOP_TYPE(result) != AOP_ACC)
1291 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1292 goto release; // we're done, since WREG is 1 byte
1296 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1298 size = min( AOP_SIZE(result), AOP_SIZE(right) );
1299 size = min( size, AOP_SIZE(left) );
1302 if(pic16_debug_verbose) {
1303 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
1304 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
1305 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
1310 if ((AOP_TYPE(left) == AOP_PCODE) && (
1311 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
1312 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
1313 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
1315 // add to literal operand
1318 for(i=0; i<size; i++) {
1319 if (AOP_TYPE(right) == AOP_ACC) {
1320 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1322 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1323 if(i) { // add with carry
1324 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1325 } else { // add without
1326 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1329 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1332 DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
1334 // add leftover bytes
1335 if (SPEC_USIGN(getSpec(operandType(right)))) {
1336 // right is unsigned
1337 for(i=size; i< AOP_SIZE(result); i++) {
1338 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1339 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1340 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1344 // right is signed, oh dear ...
1345 for(i=size; i< AOP_SIZE(result); i++) {
1346 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1347 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1348 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),i));
1349 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1350 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1360 for(i=0; i<size; i++) {
1361 if (AOP_TYPE(right) != AOP_ACC)
1362 pic16_mov2w(AOP(right),i);
1363 if (pic16_sameRegs(AOP(left), AOP(result)))
1365 if(i) { // add with carry
1366 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1367 } else { // add without
1368 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1370 } else { // not same
1371 if(i) { // add with carry
1372 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1373 } else { // add without
1374 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1376 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1380 // add leftover bytes
1381 // either left or right is too short
1382 for (i=size; i < AOP_SIZE(result); i++) {
1383 // get right operand into WREG
1384 if (i < AOP_SIZE(right)) {
1385 pic16_mov2w (AOP(right), i);
1387 // right is too short
1388 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1389 if (!SPEC_USIGN(getSpec(operandType(right)))) {
1390 // right operand is signed
1391 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1392 pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1396 // get left+WREG+CARRY into result
1397 if (i < AOP_SIZE(left)) {
1398 if (pic16_sameRegs (AOP(left), AOP(result))) {
1399 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1401 pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
1402 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1405 // left is too short
1406 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
1407 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1408 // left operand is signed
1409 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1410 pic16_emitpcode(POC_SETF, pic16_popGet (AOP(result), i));
1412 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1423 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1424 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1425 pic16_freeAsmop(result,NULL,ic,TRUE);
1428 /*-----------------------------------------------------------------*/
1429 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1430 /*-----------------------------------------------------------------*/
1431 bool pic16_genMinusDec (iCode *ic)
1433 unsigned int icount ;
1434 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1437 /* will try to generate an increment */
1438 /* if the right side is not a literal
1440 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1441 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1442 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1445 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1447 /* if the literal value of the right hand side
1448 is greater than 4 then it is not worth it */
1449 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1452 /* if decrement 16 bits in register */
1453 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1458 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1460 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1462 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1463 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1464 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1466 /* size is 3 or 4 */
1467 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1468 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1469 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1470 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1472 pic16_emitcode("movlw","0xff");
1473 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1476 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1478 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1481 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1483 pic16_emitcode("skpnc","");
1485 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1494 /* if the sizes are greater than 1 then we cannot */
1495 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1496 AOP_SIZE(IC_LEFT(ic)) > 1 )
1499 /* we can if the aops of the left & result match or
1500 if they are in registers and the registers are the
1502 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1505 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1507 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1512 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1513 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1514 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1517 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1518 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1520 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1521 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1529 /*-----------------------------------------------------------------*/
1530 /* pic16_addSign - propogate sign bit to higher bytes */
1531 /*-----------------------------------------------------------------*/
1532 void pic16_addSign(operand *result, int offset, int sign)
1534 int size = (pic16_getDataSize(result) - offset);
1535 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1538 if(sign && offset) {
1541 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1542 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1543 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
1546 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1547 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1548 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1550 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1555 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1559 /*-----------------------------------------------------------------*/
1560 /* pic16_genMinusBits - generates code for subtraction of two bits */
1561 /*-----------------------------------------------------------------*/
1562 void pic16_genMinusBits (iCode *ic)
1564 symbol *lbl = newiTempLabel(NULL);
1567 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1568 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1569 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1570 pic16_emitcode("cpl","c");
1571 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1572 pic16_outBitC(IC_RESULT(ic));
1575 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1576 pic16_emitcode("subb","a,acc");
1577 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1578 pic16_emitcode("inc","a");
1579 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1580 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1581 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1585 /*-----------------------------------------------------------------*/
1586 /* pic16_genMinus - generates code for subtraction */
1587 /*-----------------------------------------------------------------*/
1588 void pic16_genMinus (iCode *ic)
1590 int size, offset = 0, same=0;
1591 unsigned long lit = 0L;
1594 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1595 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1596 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1598 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1599 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1600 operand *t = IC_RIGHT(ic);
1601 IC_RIGHT(ic) = IC_LEFT(ic);
1605 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1606 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1607 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1608 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1610 /* special cases :- */
1611 /* if both left & right are in bit space */
1612 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1613 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1614 pic16_genPlusBits (ic);
1618 /* if I can do an decrement instead
1619 of subtract then GOOD for ME */
1620 // if (pic16_genMinusDec (ic) == TRUE)
1623 size = pic16_getDataSize(IC_RESULT(ic));
1624 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1626 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1627 /* Add a literal to something else */
1629 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1632 genAddLit ( ic, lit);
1635 /* add the first byte: */
1636 pic16_emitcode("movlw","0x%x", lit & 0xff);
1637 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1638 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1639 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1651 if((lit & 0xff) == 0xff) {
1652 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1654 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1656 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1658 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1659 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1663 /* do the rlf known zero trick here */
1664 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1666 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1671 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1674 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1675 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1676 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1678 /* here we are subtracting a bit from a char or int */
1680 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1682 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1683 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1685 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1686 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1687 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1688 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1691 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1692 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1693 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1694 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1695 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1697 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1699 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1700 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1702 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1703 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1706 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1708 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1710 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1711 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1715 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1716 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1717 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1718 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1723 pic16_mov2w(AOP(IC_LEFT(ic)),0);
1724 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1725 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1728 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1730 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1733 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1735 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1737 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1744 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1745 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1746 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1748 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1749 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1750 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1751 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1752 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1755 if( (size == 1) && ((lit & 0xff) == 0) ) {
1756 /* res = 0 - right */
1757 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1758 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1760 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1761 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1762 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1767 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1768 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1769 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1777 // here we have x = lit - x for sizeof(x)>1
1778 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1779 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1781 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1782 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1783 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1790 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1791 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1792 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1793 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1795 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1796 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1797 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1798 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1799 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1800 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1803 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1804 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1805 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1807 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1808 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1810 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1811 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1812 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1814 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1816 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1817 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1818 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1820 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1822 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1828 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1830 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1831 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1833 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1834 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1841 if (offset < AOP_SIZE(IC_RIGHT(ic)))
1842 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1844 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1845 if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
1846 // signed -- sign extend the right operand
1847 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));
1848 pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1851 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1852 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1854 if (offset < AOP_SIZE(IC_LEFT(ic))) {
1855 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1856 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1858 // zero extend the left operand
1859 pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
1860 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
1861 // signed -- sign extend the left operand
1862 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));
1863 pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
1865 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1874 // adjustArithmeticResult(ic);
1877 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1878 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1879 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1883 /*-----------------------------------------------------------------*
1884 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1887 *-----------------------------------------------------------------*/
1888 void pic16_genUMult8XLit_8 (operand *left,
1894 int size = AOP_SIZE(result);
1898 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1900 if (AOP_TYPE(right) != AOP_LIT){
1901 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1905 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1907 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1908 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1910 same = pic16_sameRegs(AOP(left), AOP(result));
1915 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1919 // its faster to left shift
1920 for (i=1; i < size; i++) {
1921 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1924 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1926 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1930 if(AOP_TYPE(left) != AOP_ACC)
1931 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1932 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1933 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1934 pic16_popGet(AOP(result), 0)));
1936 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1937 pic16_popGet(AOP(result), 1)));
1938 for (i=2; i < size; i++) {
1939 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1945 // operands different
1949 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1953 for (i=1; i < size; i++) {
1954 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1957 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1958 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1960 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1963 if(AOP_TYPE(left) != AOP_ACC)
1964 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1965 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1966 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1967 pic16_popGet(AOP(result), 0)));
1970 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1971 pic16_popGet(AOP(result), 1)));
1972 for (i=2; i < size; i++) {
1973 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1981 /*-----------------------------------------------------------------------*
1982 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1983 *-----------------------------------------------------------------------*/
1984 void pic16_genUMult16XLit_16 (operand *left,
1988 pCodeOp *pct1, *pct2, *pct3, *pct4;
1995 if (AOP_TYPE(right) != AOP_LIT){
1996 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2000 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2003 same = pic16_sameRegs(AOP(left), AOP(result));
2007 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2008 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2011 // its faster to left shift
2013 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2014 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2018 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2020 pct1 = pic16_popGetTempReg(1);
2021 pct2 = pic16_popGetTempReg(1);
2022 pct3 = pic16_popGetTempReg(1);
2023 pct4 = pic16_popGetTempReg(1);
2025 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2026 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2027 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2028 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2029 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2030 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2032 /* WREG still holds the low literal */
2033 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2034 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2035 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2037 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2038 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2039 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2040 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2043 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2044 pct1, pic16_popGet(AOP(result), 0)));
2045 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2046 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2047 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2048 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2050 pic16_popReleaseTempReg(pct4,1);
2051 pic16_popReleaseTempReg(pct3,1);
2052 pic16_popReleaseTempReg(pct2,1);
2053 pic16_popReleaseTempReg(pct1,1);
2057 // operands different
2060 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2061 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2065 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2066 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2067 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2068 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2072 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2073 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2074 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2075 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2076 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2077 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2079 /* WREG still holds the low literal */
2080 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2081 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2082 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2084 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2085 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2086 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2087 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2095 /*-----------------------------------------------------------------*
2096 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
2099 *-----------------------------------------------------------------*/
2100 void pic16_genUMult8X8_8 (operand *left,
2108 if (AOP_TYPE(right) == AOP_LIT) {
2109 pic16_genUMult8XLit_8(left,right,result);
2119 /* if result == right then exchange left and right */
2120 if(pic16_sameRegs(AOP(result), AOP(right))) {
2127 if(AOP_TYPE(left) != AOP_ACC) {
2129 if(AOP_TYPE(right) != AOP_ACC) {
2130 pic16_mov2w(AOP(left), 0);
2131 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2133 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2136 // left is WREG, right cannot be WREG (or can?!)
2137 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
2140 /* result is in PRODL:PRODH */
2141 if(AOP_TYPE(result) != AOP_ACC) {
2142 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
2143 pic16_popGet(AOP(result), 0)));
2146 if(AOP_SIZE(result)>1) {
2149 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
2150 pic16_popGet(AOP(result), 1)));
2152 for(i=2;i<AOP_SIZE(result);i++)
2153 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
2156 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2160 /*------------------------------------------------------------------*
2161 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
2162 *------------------------------------------------------------------*/
2163 void pic16_genUMult16X16_16 (operand *left,
2168 pCodeOp *pct1, *pct2, *pct3, *pct4;
2173 if (AOP_TYPE(right) == AOP_LIT) {
2174 pic16_genUMult8XLit_8(left,right,result);
2182 /* if result == right then exchange left and right */
2183 if(pic16_sameRegs(AOP(result), AOP(right))) {
2191 if(pic16_sameRegs(AOP(result), AOP(left))) {
2193 pct1 = pic16_popGetTempReg(1);
2194 pct2 = pic16_popGetTempReg(1);
2195 pct3 = pic16_popGetTempReg(1);
2196 pct4 = pic16_popGetTempReg(1);
2198 pic16_mov2w(AOP(left), 0);
2199 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2200 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2201 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2202 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2203 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2205 /* WREG still holds the lower left */
2206 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2207 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2208 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2210 pic16_mov2w(AOP(left), 1);
2211 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2212 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2213 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2216 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2217 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2218 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2219 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2220 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2221 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2223 pic16_popReleaseTempReg( pct4, 1 );
2224 pic16_popReleaseTempReg( pct3, 1 );
2225 pic16_popReleaseTempReg( pct2, 1 );
2226 pic16_popReleaseTempReg( pct1, 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_popGet(AOP(result), 0)));
2234 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2235 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2237 /* WREG still holds the lower left */
2238 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2239 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2240 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2242 pic16_mov2w(AOP(left), 1);
2243 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2244 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2245 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2250 void pic16_genSMult16X16_16(operand *left,
2258 /*-----------------------------------------------------------------*
2259 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
2261 * this routine will call the unsigned multiply routine and then
2262 * post-fix the sign bit.
2263 *-----------------------------------------------------------------*/
2264 void pic16_genSMult8X8_8 (operand *left,
2267 pCodeOpReg *result_hi)
2269 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2273 result_hi = PCOR(pic16_popGet(AOP(result),1));
2277 pic16_genUMult8X8_8(left,right,result);
2281 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2282 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2283 pic16_mov2w(AOP(left),0);
2284 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2285 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2290 /*-----------------------------------------------------------------*
2291 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
2292 *-----------------------------------------------------------------*/
2293 void pic16_genMult8X8_8 (operand *left,
2299 if(AOP_TYPE(right) == AOP_LIT)
2300 pic16_genUMult8XLit_8(left,right,result);
2302 pic16_genUMult8X8_8(left,right,result);
2306 /*-----------------------------------------------------------------*
2307 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
2308 *-----------------------------------------------------------------*/
2309 void pic16_genMult16X16_16 (operand *left,
2315 if (AOP_TYPE(right) == AOP_LIT)
2316 pic16_genUMult16XLit_16(left,right,result);
2318 pic16_genUMult16X16_16(left,right,result);
2324 /*-----------------------------------------------------------------------*
2325 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2326 *-----------------------------------------------------------------------*/
2327 void pic16_genUMult32XLit_32 (operand *left,
2331 pCodeOp *pct1, *pct2, *pct3, *pct4;
2338 if (AOP_TYPE(right) != AOP_LIT){
2339 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2343 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2346 same = pic16_sameRegs(AOP(left), AOP(result));
2350 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2351 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2354 // its faster to left shift
2356 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2357 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2361 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2363 pct1 = pic16_popGetTempReg(1);
2364 pct2 = pic16_popGetTempReg(1);
2365 pct3 = pic16_popGetTempReg(1);
2366 pct4 = pic16_popGetTempReg(1);
2368 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2369 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2370 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2371 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2372 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2373 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2375 /* WREG still holds the low literal */
2376 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2377 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2378 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2380 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2381 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2382 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2383 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2386 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2387 pct1, pic16_popGet(AOP(result), 0)));
2388 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2389 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2390 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2391 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2393 pic16_popReleaseTempReg( pct4, 1 );
2394 pic16_popReleaseTempReg( pct3, 1 );
2395 pic16_popReleaseTempReg( pct2, 1 );
2396 pic16_popReleaseTempReg( pct1, 1 );
2400 // operands different
2403 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2404 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2408 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2409 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2410 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2411 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2415 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2416 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2417 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2418 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2419 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2420 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2422 /* WREG still holds the low literal */
2423 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2424 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2425 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2427 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2428 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2429 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2430 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2438 /*------------------------------------------------------------------*
2439 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2440 *------------------------------------------------------------------*/
2441 void pic16_genUMult32X32_32 (operand *left,
2446 pCodeOp *pct1, *pct2, *pct3, *pct4;
2450 if (AOP_TYPE(right) == AOP_LIT) {
2451 pic16_genUMult8XLit_8(left,right,result);
2459 /* if result == right then exchange left and right */
2460 if(pic16_sameRegs(AOP(result), AOP(right))) {
2468 if(pic16_sameRegs(AOP(result), AOP(left))) {
2470 pct1 = pic16_popGetTempReg(1);
2471 pct2 = pic16_popGetTempReg(1);
2472 pct3 = pic16_popGetTempReg(1);
2473 pct4 = pic16_popGetTempReg(1);
2475 pic16_mov2w(AOP(left), 0);
2476 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2477 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2478 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2479 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2480 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2482 /* WREG still holds the lower left */
2483 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2484 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2485 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2487 pic16_mov2w(AOP(left), 1);
2488 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2489 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2490 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2493 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2494 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2495 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2496 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2497 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2498 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2500 pic16_popReleaseTempReg( pct4, 1 );
2501 pic16_popReleaseTempReg( pct3, 1 );
2502 pic16_popReleaseTempReg( pct2, 1 );
2503 pic16_popReleaseTempReg( pct1, 1 );
2507 pic16_mov2w(AOP(left), 0);
2508 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2509 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2510 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2511 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2512 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2514 /* WREG still holds the lower left */
2515 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2516 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2517 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2519 pic16_mov2w(AOP(left), 1);
2520 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2521 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2522 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2527 /*-----------------------------------------------------------------*
2528 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2529 *-----------------------------------------------------------------*/
2530 void pic16_genMult32X32_32 (operand *left,
2536 if (AOP_TYPE(right) == AOP_LIT)
2537 pic16_genUMult32XLit_32(left,right,result);
2539 pic16_genUMult32X32_32(left,right,result);
2549 /*-----------------------------------------------------------------*/
2550 /* constMult - generates code for multiplication by a constant */
2551 /*-----------------------------------------------------------------*/
2552 void genMultConst(unsigned C)
2556 unsigned sr3; // Shift right 3
2562 Convert a string of 3 binary 1's in the lit into
2566 mask = 7 << ( (size*8) - 3);
2570 while(mask < (1<<size*8)) {
2572 if( (mask & lit) == lit) {
2575 /* We found 3 (or more) consecutive 1's */
2577 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2579 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2581 lit ^= consecutive_bits;
2585 sr3 |= (consecutive + lsb);