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));
663 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
667 if(AOP_TYPE(left) == AOP_ACC) {
668 /* left addend is already in accumulator */
671 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
675 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
676 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
680 /* left addend is in a register */
683 pic16_mov2w(AOP(left),0);
684 emitMOVWF(result, 0);
687 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
688 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
692 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
693 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
697 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
698 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
699 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
707 /* left is not the accumulator */
709 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
710 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
712 pic16_mov2w(AOP(left),0);
713 /* We don't know the state of the carry bit at this point */
716 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
723 /* The ls byte of the lit must've been zero - that
724 means we don't have to deal with carry */
726 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
727 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
728 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
733 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
734 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
735 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
739 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
740 pic16_mov2w(AOP(left),offset);
741 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
750 /* this fails when result is an SFR because value is written there
751 * during addition and not at the end */
753 static void genAddLit (iCode *ic, int lit)
767 lleft = operandType (left);
768 result = IC_RESULT(ic);
769 same = pic16_sameRegs(AOP(left), AOP(result));
770 size = pic16_getDataSize(result);
771 sizeL = pic16_getDataSize(left);
774 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
775 /* move left to result -- possibly sign extend */
776 for (i=0; i < MIN(size, sizeL); i++) {
777 pic16_mov2f (AOP(result), AOP(left), i);
781 /* extend to result size */
782 if (IS_UNSIGNED(lleft)) {
784 for (i = sizeL; i < size; i++) {
785 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
789 if (size == sizeL + 1) {
790 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), sizeL));
791 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
792 pic16_emitpcode (POC_SETF, pic16_popGet (AOP(result), sizeL));
794 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
795 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
796 pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
798 for (i=sizeL; i < size; i++) {
799 pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(result), i));
807 } else if (lit == 1) {
813 pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(result), 0));
817 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), 0));
818 for (i=1; i < size-1; i++) {
819 emitSKPNC; /* a jump here saves up to 2(size-2)cycles */
820 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), i));
826 pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1));
830 /* add literal to result */
831 for (i=0; i < size; i++) {
832 pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit));
833 llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */
834 pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC,
835 pic16_popGet (AOP(result), i));
843 /* Handle special cases first */
845 genAddLit2byte (result, 0, lit);
848 int hi = 0xff & (lit >> 8);
855 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
860 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
862 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
865 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
866 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
867 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
871 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
872 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
874 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
882 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
885 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
888 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
889 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
891 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
893 case 0xff: /* 0x01ff */
894 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
895 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
896 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
897 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
899 default: /* 0x01LL */
900 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
901 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
903 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
904 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
909 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
913 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
916 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
917 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
919 /* case 0xff: * 0xffff *
920 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
921 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
922 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
926 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
927 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
929 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
936 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
941 genAddLit2byte (result, MSB16, hi);
944 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
945 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
946 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
948 /* case 0xff: * 0xHHff *
949 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
950 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
951 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
952 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
954 */ default: /* 0xHHLL */
955 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
956 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
957 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
958 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
967 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
970 lo = BYTEofLONG(lit,0);
973 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
974 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
976 /* no carry info from previous step */
977 /* this means this is the first time to add */
982 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
986 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
987 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
989 carry_info = 3; /* Were adding only one byte and propogating the carry */
1000 lo = BYTEofLONG(lit,0);
1005 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1008 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
1009 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1012 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
1014 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
1016 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
1025 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
1029 if(AOP_TYPE(left) == AOP_ACC) {
1030 /* left addend is already in accumulator */
1031 switch(lit & 0xff) {
1033 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1034 emitMOVWF(result,0);
1037 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
1038 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1039 emitMOVWF(result,0);
1042 /* left addend is in a register */
1043 switch(lit & 0xff) {
1045 pic16_mov2w(AOP(left),0);
1046 emitMOVWF(result, 0);
1049 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1050 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1051 emitMOVWF(result,0);
1054 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
1055 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1056 emitMOVWF(result,0);
1059 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1060 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1061 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1062 emitMOVWF(result,0);
1069 /* left is not the accumulator */
1071 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1072 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1074 pic16_mov2w(AOP(left),0);
1075 /* We don't know the state of the carry bit at this point */
1078 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1079 emitMOVWF(result,0);
1085 /* The ls byte of the lit must've been zero - that
1086 means we don't have to deal with carry */
1088 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1089 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
1090 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1095 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1096 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
1097 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1101 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
1102 pic16_mov2w(AOP(left),offset);
1103 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
1114 /*-----------------------------------------------------------------*/
1115 /* pic16_genPlus - generates code for addition */
1116 /*-----------------------------------------------------------------*/
1117 void pic16_genPlus (iCode *ic)
1119 int i, size, offset = 0;
1120 operand *result, *left, *right;
1124 /* special cases :- */
1125 result = IC_RESULT(ic);
1127 right = IC_RIGHT(ic);
1128 pic16_aopOp (left,ic,FALSE);
1129 pic16_aopOp (right,ic,FALSE);
1130 pic16_aopOp (result,ic,TRUE);
1131 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
1132 // pic16_DumpOp("(left)",left);
1134 /* if literal, literal on the right or
1135 if left requires ACC or right is already
1138 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
1140 right = IC_RIGHT(ic) = left;
1141 left = IC_LEFT(ic) = t;
1144 /* if both left & right are in bit space */
1145 if (AOP_TYPE(left) == AOP_CRY &&
1146 AOP_TYPE(right) == AOP_CRY) {
1147 pic16_genPlusBits (ic);
1151 /* if left in bit space & right literal */
1152 if (AOP_TYPE(left) == AOP_CRY &&
1153 AOP_TYPE(right) == AOP_LIT) {
1154 /* if result in bit space */
1155 if(AOP_TYPE(result) == AOP_CRY){
1156 if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
1157 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
1158 if (!pic16_sameRegs(AOP(left), AOP(result)) )
1159 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
1160 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
1163 unsigned long lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
1164 size = pic16_getDataSize(result);
1166 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
1167 pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
1168 pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
1169 //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
1170 //pic16_emitcode("addc","a,#00 ;%d",__LINE__);
1171 //pic16_aopPut(AOP(result),"a",offset++);
1177 /* if I can do an increment instead
1178 of add then GOOD for ME */
1179 if (pic16_genPlusIncr (ic) == TRUE)
1182 size = pic16_getDataSize(result);
1184 if(AOP(right)->type == AOP_LIT) {
1185 /* Add a literal to something else */
1187 unsigned lit = (unsigned) floatFromVal(AOP(right)->aopu.aop_lit);
1191 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
1193 genAddLit (ic, lit);
1196 } else if(AOP_TYPE(right) == AOP_CRY) {
1198 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
1199 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
1200 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
1202 /* here we are adding a bit to a char or int */
1204 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1206 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1207 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0));
1209 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1210 AOP(right)->aopu.aop_dir,
1211 AOP(right)->aopu.aop_dir);
1212 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1213 } else { // not same
1215 if(AOP_TYPE(left) == AOP_ACC) {
1216 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1217 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1219 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1220 AOP(right)->aopu.aop_dir,
1221 AOP(right)->aopu.aop_dir);
1222 pic16_emitcode(" xorlw","1");
1224 pic16_mov2w(AOP(left),0);
1225 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1226 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
1228 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
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,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1235 if(AOP_TYPE(result) != AOP_ACC) {
1237 if(AOP_TYPE(result) == AOP_CRY) {
1238 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1239 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0));
1241 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0));
1243 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0));
1244 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1251 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1252 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1254 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1255 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
1257 pic16_emitcode("clrz","");
1259 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1260 AOP(right)->aopu.aop_dir,
1261 AOP(right)->aopu.aop_dir);
1262 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1265 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
1266 pic16_mov2w(AOP(left),0);
1267 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1268 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1269 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
1272 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1273 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1274 AOP(right)->aopu.aop_dir,
1275 AOP(right)->aopu.aop_dir);
1276 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1277 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1283 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++));
1284 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE));
1292 // Note: the following is an example of WISC code, eg.
1293 // it's supposed to run on a Weird Instruction Set Computer :o)
1295 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1297 if ( AOP_TYPE(left) == AOP_ACC) {
1298 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1299 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
1300 if ( AOP_TYPE(result) != AOP_ACC)
1301 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1302 goto release; // we're done, since WREG is 1 byte
1306 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1308 size = min( AOP_SIZE(result), AOP_SIZE(right) );
1309 size = min( size, AOP_SIZE(left) );
1312 if(pic16_debug_verbose) {
1313 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
1314 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
1315 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
1320 if ((AOP_TYPE(left) == AOP_PCODE) && (
1321 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
1322 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
1323 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
1325 // add to literal operand
1328 for(i=0; i<size; i++) {
1329 if (AOP_TYPE(right) == AOP_ACC) {
1330 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1332 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1333 if(i) { // add with carry
1334 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1335 } else { // add without
1336 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1339 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1342 DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
1344 // add leftover bytes
1345 if (SPEC_USIGN(getSpec(operandType(right)))) {
1346 // right is unsigned
1347 for(i=size; i< AOP_SIZE(result); i++) {
1348 pic16_emitpcode(POC_CLRF, 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));
1354 // right is signed, oh dear ...
1355 for(i=size; i< AOP_SIZE(result); i++) {
1356 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1357 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1358 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),i));
1359 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1360 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1370 for(i=0; i<size; i++) {
1371 if (AOP_TYPE(right) != AOP_ACC)
1372 pic16_mov2w(AOP(right),i);
1373 if (pic16_sameRegs(AOP(left), AOP(result)))
1375 if(i) { // add with carry
1376 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1377 } else { // add without
1378 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1380 } else { // not same
1381 if(i) { // add with carry
1382 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1383 } else { // add without
1384 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1386 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1390 // add leftover bytes
1391 // either left or right is too short
1392 for (i=size; i < AOP_SIZE(result); i++) {
1393 // get right operand into WREG
1394 if (i < AOP_SIZE(right)) {
1395 pic16_mov2w (AOP(right), i);
1397 // right is too short
1398 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1399 if (!SPEC_USIGN(getSpec(operandType(right)))) {
1400 // right operand is signed
1401 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1402 pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1406 // get left+WREG+CARRY into result
1407 if (i < AOP_SIZE(left)) {
1408 if (pic16_sameRegs (AOP(left), AOP(result))) {
1409 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1411 pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
1412 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1415 // left is too short
1416 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
1417 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1418 // left operand is signed
1419 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1420 pic16_emitpcode(POC_SETF, pic16_popGet (AOP(result), i));
1422 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1433 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1434 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1435 pic16_freeAsmop(result,NULL,ic,TRUE);
1438 /*-----------------------------------------------------------------*/
1439 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1440 /*-----------------------------------------------------------------*/
1441 bool pic16_genMinusDec (iCode *ic)
1443 unsigned int icount ;
1444 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1447 /* will try to generate an increment */
1448 /* if the right side is not a literal
1450 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1451 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1452 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1455 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1457 /* if the literal value of the right hand side
1458 is greater than 4 then it is not worth it */
1459 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1462 /* if decrement 16 bits in register */
1463 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1468 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1470 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1472 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1473 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1474 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1476 /* size is 3 or 4 */
1477 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1478 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1479 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1480 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1482 pic16_emitcode("movlw","0xff");
1483 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1486 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1488 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1491 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1493 pic16_emitcode("skpnc","");
1495 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1504 /* if the sizes are greater than 1 then we cannot */
1505 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1506 AOP_SIZE(IC_LEFT(ic)) > 1 )
1509 /* we can if the aops of the left & result match or
1510 if they are in registers and the registers are the
1512 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1515 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1517 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1522 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1523 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1524 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1527 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1528 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1530 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1531 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1539 /*-----------------------------------------------------------------*/
1540 /* pic16_addSign - propogate sign bit to higher bytes */
1541 /*-----------------------------------------------------------------*/
1542 void pic16_addSign(operand *result, int offset, int sign)
1544 int size = (pic16_getDataSize(result) - offset);
1545 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1548 if(sign && offset) {
1551 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1552 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1553 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
1556 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1557 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1558 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1560 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1565 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1569 /*-----------------------------------------------------------------*/
1570 /* pic16_genMinusBits - generates code for subtraction of two bits */
1571 /*-----------------------------------------------------------------*/
1572 void pic16_genMinusBits (iCode *ic)
1574 symbol *lbl = newiTempLabel(NULL);
1577 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1578 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1579 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1580 pic16_emitcode("cpl","c");
1581 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1582 pic16_outBitC(IC_RESULT(ic));
1585 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1586 pic16_emitcode("subb","a,acc");
1587 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1588 pic16_emitcode("inc","a");
1589 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1590 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1591 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1595 /*-----------------------------------------------------------------*/
1596 /* pic16_genMinus - generates code for subtraction */
1597 /*-----------------------------------------------------------------*/
1598 void pic16_genMinus (iCode *ic)
1600 int size, offset = 0, same=0;
1601 unsigned long lit = 0L;
1604 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1605 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1606 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1608 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1609 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1610 operand *t = IC_RIGHT(ic);
1611 IC_RIGHT(ic) = IC_LEFT(ic);
1615 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1616 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1617 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1618 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1620 /* special cases :- */
1621 /* if both left & right are in bit space */
1622 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1623 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1624 pic16_genPlusBits (ic);
1628 /* if I can do an decrement instead
1629 of subtract then GOOD for ME */
1630 // if (pic16_genMinusDec (ic) == TRUE)
1633 size = pic16_getDataSize(IC_RESULT(ic));
1634 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1636 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1637 /* Add a literal to something else */
1639 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1642 genAddLit ( ic, lit);
1645 /* add the first byte: */
1646 pic16_emitcode("movlw","0x%x", lit & 0xff);
1647 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1648 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1649 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1661 if((lit & 0xff) == 0xff) {
1662 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1664 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1666 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1668 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1669 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1673 /* do the rlf known zero trick here */
1674 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1676 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1681 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1684 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1685 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1686 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1688 /* here we are subtracting a bit from a char or int */
1690 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1692 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1693 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1695 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1696 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1697 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1698 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1701 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1702 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1703 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1704 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1705 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1707 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1709 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1710 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1712 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1713 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1716 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1718 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1720 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1721 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1725 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1726 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1727 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1728 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1733 pic16_mov2w(AOP(IC_LEFT(ic)),0);
1734 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1735 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1738 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1740 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1743 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1745 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1747 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1754 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1755 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1756 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1758 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1759 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1760 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1761 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1762 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1765 if( (size == 1) && ((lit & 0xff) == 0) ) {
1766 /* res = 0 - right */
1767 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1768 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1770 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1771 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1772 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1777 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1778 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1779 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1787 // here we have x = lit - x for sizeof(x)>1
1788 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1789 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1791 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1792 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1793 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1800 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1801 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1802 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1803 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1805 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1806 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1807 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1808 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1809 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1810 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1813 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1814 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1815 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1817 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1818 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1820 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1821 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1822 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1824 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1826 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1827 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1828 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1830 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1832 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1838 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1840 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1841 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1843 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1844 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1851 if (offset < AOP_SIZE(IC_RIGHT(ic)))
1852 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1854 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1855 if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
1856 // signed -- sign extend the right operand
1857 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));
1858 pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1861 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1862 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1864 if (offset < AOP_SIZE(IC_LEFT(ic))) {
1865 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1866 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1868 // zero extend the left operand
1869 pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
1870 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
1871 // signed -- sign extend the left operand
1872 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));
1873 pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
1875 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1884 // adjustArithmeticResult(ic);
1887 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1888 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1889 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1893 /*-----------------------------------------------------------------*
1894 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1897 *-----------------------------------------------------------------*/
1898 void pic16_genUMult8XLit_8 (operand *left,
1904 int size = AOP_SIZE(result);
1908 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1910 if (AOP_TYPE(right) != AOP_LIT){
1911 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1915 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1917 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1918 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1920 same = pic16_sameRegs(AOP(left), AOP(result));
1925 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1929 // its faster to left shift
1930 for (i=1; i < size; i++) {
1931 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1934 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1936 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1940 if(AOP_TYPE(left) != AOP_ACC)
1941 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1942 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1943 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1944 pic16_popGet(AOP(result), 0)));
1946 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1947 pic16_popGet(AOP(result), 1)));
1948 for (i=2; i < size; i++) {
1949 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1955 // operands different
1959 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1963 for (i=1; i < size; i++) {
1964 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1967 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1968 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1970 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1973 if(AOP_TYPE(left) != AOP_ACC)
1974 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1975 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1976 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1977 pic16_popGet(AOP(result), 0)));
1980 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1981 pic16_popGet(AOP(result), 1)));
1982 for (i=2; i < size; i++) {
1983 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1991 /*-----------------------------------------------------------------------*
1992 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1993 *-----------------------------------------------------------------------*/
1994 void pic16_genUMult16XLit_16 (operand *left,
1998 pCodeOp *pct1, *pct2, *pct3, *pct4;
2005 if (AOP_TYPE(right) != AOP_LIT){
2006 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2010 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2013 same = pic16_sameRegs(AOP(left), AOP(result));
2017 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2018 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2021 // its faster to left shift
2023 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2024 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2028 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2030 pct1 = pic16_popGetTempReg(1);
2031 pct2 = pic16_popGetTempReg(1);
2032 pct3 = pic16_popGetTempReg(1);
2033 pct4 = pic16_popGetTempReg(1);
2035 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2036 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2037 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2038 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2039 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2040 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2042 /* WREG still holds the low literal */
2043 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2044 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2045 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2047 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2048 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2049 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2050 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2053 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2054 pct1, pic16_popGet(AOP(result), 0)));
2055 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2056 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2057 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2058 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2060 pic16_popReleaseTempReg(pct4,1);
2061 pic16_popReleaseTempReg(pct3,1);
2062 pic16_popReleaseTempReg(pct2,1);
2063 pic16_popReleaseTempReg(pct1,1);
2067 // operands different
2070 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2071 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2075 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2076 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2077 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2078 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2082 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2083 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2084 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2085 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2086 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2087 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2089 /* WREG still holds the low literal */
2090 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2091 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2092 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2094 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2095 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2096 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2097 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2105 /*-----------------------------------------------------------------*
2106 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
2109 *-----------------------------------------------------------------*/
2110 void pic16_genUMult8X8_8 (operand *left,
2118 if (AOP_TYPE(right) == AOP_LIT) {
2119 pic16_genUMult8XLit_8(left,right,result);
2129 /* if result == right then exchange left and right */
2130 if(pic16_sameRegs(AOP(result), AOP(right))) {
2137 if(AOP_TYPE(left) != AOP_ACC) {
2139 if(AOP_TYPE(right) != AOP_ACC) {
2140 pic16_mov2w(AOP(left), 0);
2141 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2143 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2146 // left is WREG, right cannot be WREG (or can?!)
2147 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
2150 /* result is in PRODL:PRODH */
2151 if(AOP_TYPE(result) != AOP_ACC) {
2152 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
2153 pic16_popGet(AOP(result), 0)));
2156 if(AOP_SIZE(result)>1) {
2159 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
2160 pic16_popGet(AOP(result), 1)));
2162 for(i=2;i<AOP_SIZE(result);i++)
2163 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
2166 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2170 /*------------------------------------------------------------------*
2171 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
2172 *------------------------------------------------------------------*/
2173 void pic16_genUMult16X16_16 (operand *left,
2178 pCodeOp *pct1, *pct2, *pct3, *pct4;
2183 if (AOP_TYPE(right) == AOP_LIT) {
2184 pic16_genUMult8XLit_8(left,right,result);
2192 /* if result == right then exchange left and right */
2193 if(pic16_sameRegs(AOP(result), AOP(right))) {
2201 if(pic16_sameRegs(AOP(result), AOP(left))) {
2203 pct1 = pic16_popGetTempReg(1);
2204 pct2 = pic16_popGetTempReg(1);
2205 pct3 = pic16_popGetTempReg(1);
2206 pct4 = pic16_popGetTempReg(1);
2208 pic16_mov2w(AOP(left), 0);
2209 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2210 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2211 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2212 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2213 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2215 /* WREG still holds the lower left */
2216 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2217 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2218 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2220 pic16_mov2w(AOP(left), 1);
2221 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2222 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2223 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2226 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2227 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2228 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2229 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2230 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2231 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2233 pic16_popReleaseTempReg( pct4, 1 );
2234 pic16_popReleaseTempReg( pct3, 1 );
2235 pic16_popReleaseTempReg( pct2, 1 );
2236 pic16_popReleaseTempReg( pct1, 1 );
2240 pic16_mov2w(AOP(left), 0);
2241 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2242 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2243 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2244 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2245 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2247 /* WREG still holds the lower left */
2248 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2249 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2250 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2252 pic16_mov2w(AOP(left), 1);
2253 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2254 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2255 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2260 void pic16_genSMult16X16_16(operand *left,
2268 /*-----------------------------------------------------------------*
2269 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
2271 * this routine will call the unsigned multiply routine and then
2272 * post-fix the sign bit.
2273 *-----------------------------------------------------------------*/
2274 void pic16_genSMult8X8_8 (operand *left,
2277 pCodeOpReg *result_hi)
2279 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2283 result_hi = PCOR(pic16_popGet(AOP(result),1));
2287 pic16_genUMult8X8_8(left,right,result);
2291 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2292 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2293 pic16_mov2w(AOP(left),0);
2294 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2295 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2300 /*-----------------------------------------------------------------*
2301 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
2302 *-----------------------------------------------------------------*/
2303 void pic16_genMult8X8_8 (operand *left,
2309 if(AOP_TYPE(right) == AOP_LIT)
2310 pic16_genUMult8XLit_8(left,right,result);
2312 pic16_genUMult8X8_8(left,right,result);
2316 /*-----------------------------------------------------------------*
2317 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
2318 *-----------------------------------------------------------------*/
2319 void pic16_genMult16X16_16 (operand *left,
2325 if (AOP_TYPE(right) == AOP_LIT)
2326 pic16_genUMult16XLit_16(left,right,result);
2328 pic16_genUMult16X16_16(left,right,result);
2334 /*-----------------------------------------------------------------------*
2335 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2336 *-----------------------------------------------------------------------*/
2337 void pic16_genUMult32XLit_32 (operand *left,
2341 pCodeOp *pct1, *pct2, *pct3, *pct4;
2348 if (AOP_TYPE(right) != AOP_LIT){
2349 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2353 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2356 same = pic16_sameRegs(AOP(left), AOP(result));
2360 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2361 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2364 // its faster to left shift
2366 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2367 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2371 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2373 pct1 = pic16_popGetTempReg(1);
2374 pct2 = pic16_popGetTempReg(1);
2375 pct3 = pic16_popGetTempReg(1);
2376 pct4 = pic16_popGetTempReg(1);
2378 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2379 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2380 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2381 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2382 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2383 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2385 /* WREG still holds the low literal */
2386 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2387 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2388 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2390 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2391 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2392 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2393 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2396 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2397 pct1, pic16_popGet(AOP(result), 0)));
2398 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2399 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2400 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2401 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2403 pic16_popReleaseTempReg( pct4, 1 );
2404 pic16_popReleaseTempReg( pct3, 1 );
2405 pic16_popReleaseTempReg( pct2, 1 );
2406 pic16_popReleaseTempReg( pct1, 1 );
2410 // operands different
2413 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2414 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2418 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2419 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2420 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2421 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2425 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2426 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2427 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2428 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2429 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2430 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2432 /* WREG still holds the low literal */
2433 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2434 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2435 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2437 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2438 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2439 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2440 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2448 /*------------------------------------------------------------------*
2449 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2450 *------------------------------------------------------------------*/
2451 void pic16_genUMult32X32_32 (operand *left,
2456 pCodeOp *pct1, *pct2, *pct3, *pct4;
2460 if (AOP_TYPE(right) == AOP_LIT) {
2461 pic16_genUMult8XLit_8(left,right,result);
2469 /* if result == right then exchange left and right */
2470 if(pic16_sameRegs(AOP(result), AOP(right))) {
2478 if(pic16_sameRegs(AOP(result), AOP(left))) {
2480 pct1 = pic16_popGetTempReg(1);
2481 pct2 = pic16_popGetTempReg(1);
2482 pct3 = pic16_popGetTempReg(1);
2483 pct4 = pic16_popGetTempReg(1);
2485 pic16_mov2w(AOP(left), 0);
2486 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2487 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2488 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2489 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2490 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2492 /* WREG still holds the lower left */
2493 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2494 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2495 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2497 pic16_mov2w(AOP(left), 1);
2498 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2499 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2500 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2503 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2504 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2505 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2506 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2507 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2508 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2510 pic16_popReleaseTempReg( pct4, 1 );
2511 pic16_popReleaseTempReg( pct3, 1 );
2512 pic16_popReleaseTempReg( pct2, 1 );
2513 pic16_popReleaseTempReg( pct1, 1 );
2517 pic16_mov2w(AOP(left), 0);
2518 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2519 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2520 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2521 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2522 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2524 /* WREG still holds the lower left */
2525 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2526 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2527 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2529 pic16_mov2w(AOP(left), 1);
2530 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2531 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2532 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2537 /*-----------------------------------------------------------------*
2538 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2539 *-----------------------------------------------------------------*/
2540 void pic16_genMult32X32_32 (operand *left,
2546 if (AOP_TYPE(right) == AOP_LIT)
2547 pic16_genUMult32XLit_32(left,right,result);
2549 pic16_genUMult32X32_32(left,right,result);
2559 /*-----------------------------------------------------------------*/
2560 /* constMult - generates code for multiplication by a constant */
2561 /*-----------------------------------------------------------------*/
2562 void genMultConst(unsigned C)
2566 unsigned sr3; // Shift right 3
2572 Convert a string of 3 binary 1's in the lit into
2576 mask = 7 << ( (size*8) - 3);
2580 while(mask < (1<<size*8)) {
2582 if( (mask & lit) == lit) {
2585 /* We found 3 (or more) consecutive 1's */
2587 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2589 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2591 lit ^= consecutive_bits;
2595 sr3 |= (consecutive + lsb);