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);
419 /*-----------------------------------------------------------------*/
420 /* genAddlit - generates code for addition */
421 /*-----------------------------------------------------------------*/
422 static void genAddLit2byte (operand *result, int offr, int lit)
430 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
433 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
436 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
437 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
442 static void emitMOVWF(operand *reg, int offset)
447 if (AOP_TYPE(reg) == AOP_ACC) {
448 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
452 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
456 static void genAddLit (iCode *ic, int lit)
469 result = IC_RESULT(ic);
470 same = pic16_sameRegs(AOP(left), AOP(result));
471 size = pic16_getDataSize(result);
475 /* Handle special cases first */
477 genAddLit2byte (result, 0, lit);
480 int hi = 0xff & (lit >> 8);
487 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
492 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
494 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
497 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
498 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
499 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
503 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
504 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
506 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
514 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
517 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
520 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
521 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
523 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
525 case 0xff: /* 0x01ff */
526 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
527 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
528 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
529 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
531 default: /* 0x01LL */
532 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
533 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
535 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
536 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
541 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
545 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
548 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
549 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
551 /* case 0xff: * 0xffff *
552 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
553 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
554 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
558 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
559 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
561 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
568 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
573 genAddLit2byte (result, MSB16, hi);
576 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
577 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
578 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
580 /* case 0xff: * 0xHHff *
581 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
582 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
583 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
584 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
586 */ default: /* 0xHHLL */
587 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
588 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
589 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
590 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
599 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
602 lo = BYTEofLONG(lit,0);
605 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
606 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
608 /* no carry info from previous step */
609 /* this means this is the first time to add */
614 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
618 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
619 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
621 carry_info = 3; /* Were adding only one byte and propogating the carry */
632 lo = BYTEofLONG(lit,0);
637 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
640 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
641 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
644 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
646 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
648 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
658 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
662 if(AOP_TYPE(left) == AOP_ACC) {
663 /* left addend is already in accumulator */
666 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
670 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
671 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
675 /* left addend is in a register */
678 pic16_mov2w(AOP(left),0);
679 emitMOVWF(result, 0);
682 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
683 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
687 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
688 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
692 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
693 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
694 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
702 /* left is not the accumulator */
704 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
705 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
707 pic16_mov2w(AOP(left),0);
708 /* We don't know the state of the carry bit at this point */
711 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
718 /* The ls byte of the lit must've been zero - that
719 means we don't have to deal with carry */
721 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
722 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
723 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
728 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
729 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
730 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
734 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
735 pic16_mov2w(AOP(left),offset);
736 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
744 /*-----------------------------------------------------------------*/
745 /* pic16_genPlus - generates code for addition */
746 /*-----------------------------------------------------------------*/
747 void pic16_genPlus (iCode *ic)
749 int i, size, offset = 0;
750 operand *result, *left, *right;
754 /* special cases :- */
755 result = IC_RESULT(ic);
757 right = IC_RIGHT(ic);
758 pic16_aopOp (left,ic,FALSE);
759 pic16_aopOp (right,ic,FALSE);
760 pic16_aopOp (result,ic,TRUE);
761 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
762 // pic16_DumpOp("(left)",left);
764 /* if literal, literal on the right or
765 if left requires ACC or right is already
768 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
774 /* if both left & right are in bit space */
775 if (AOP_TYPE(left) == AOP_CRY &&
776 AOP_TYPE(right) == AOP_CRY) {
777 pic16_genPlusBits (ic);
781 /* if left in bit space & right literal */
782 if (AOP_TYPE(left) == AOP_CRY &&
783 AOP_TYPE(right) == AOP_LIT) {
784 /* if result in bit space */
785 if(AOP_TYPE(result) == AOP_CRY){
786 if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
787 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
788 if (!pic16_sameRegs(AOP(left), AOP(result)) )
789 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
790 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
793 unsigned long lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
794 size = pic16_getDataSize(result);
796 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
797 pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
798 pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
799 //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
800 //pic16_emitcode("addc","a,#00 ;%d",__LINE__);
801 //pic16_aopPut(AOP(result),"a",offset++);
807 /* if I can do an increment instead
808 of add then GOOD for ME */
809 if (pic16_genPlusIncr (ic) == TRUE)
812 size = pic16_getDataSize(IC_RESULT(ic));
814 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
815 /* Add a literal to something else */
817 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
821 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
826 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
828 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
829 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
830 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
832 /* here we are adding a bit to a char or int */
834 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
836 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
837 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
839 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
840 AOP(IC_RIGHT(ic))->aopu.aop_dir,
841 AOP(IC_RIGHT(ic))->aopu.aop_dir);
842 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
845 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
846 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
847 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
849 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
850 AOP(IC_RIGHT(ic))->aopu.aop_dir,
851 AOP(IC_RIGHT(ic))->aopu.aop_dir);
852 pic16_emitcode(" xorlw","1");
854 pic16_mov2w(AOP(IC_LEFT(ic)),0);
855 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
856 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
858 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
859 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
860 AOP(IC_RIGHT(ic))->aopu.aop_dir,
861 AOP(IC_RIGHT(ic))->aopu.aop_dir);
862 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
865 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
867 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
868 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
869 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
871 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
873 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
874 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
881 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
882 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
884 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
885 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
887 pic16_emitcode("clrz","");
889 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
890 AOP(IC_RIGHT(ic))->aopu.aop_dir,
891 AOP(IC_RIGHT(ic))->aopu.aop_dir);
892 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
895 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
896 pic16_mov2w(AOP(IC_LEFT(ic)),0);
897 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
898 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
899 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
900 emitMOVWF(IC_RIGHT(ic),0);
902 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
903 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
904 AOP(IC_RIGHT(ic))->aopu.aop_dir,
905 AOP(IC_RIGHT(ic))->aopu.aop_dir);
906 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
907 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
913 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
914 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
922 // Note: the following is an example of WISC code, eg.
923 // it's supposed to run on a Weird Instruction Set Computer :o)
925 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
927 if ( AOP_TYPE(left) == AOP_ACC) {
928 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
929 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
930 if ( AOP_TYPE(result) != AOP_ACC)
931 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
932 goto release; // we're done, since WREG is 1 byte
936 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
938 size = min( AOP_SIZE(result), AOP_SIZE(right) );
939 size = min( size, AOP_SIZE(left) );
942 if(pic16_debug_verbose) {
943 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
944 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
945 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
950 if ((AOP_TYPE(left) == AOP_PCODE) && (
951 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
952 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
953 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
955 // add to literal operand
958 for(i=0; i<size; i++) {
959 if (AOP_TYPE(right) == AOP_ACC) {
960 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
962 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
963 if(i) { // add with carry
964 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
965 } else { // add without
966 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
969 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
972 DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
974 // add leftover bytes
975 if (SPEC_USIGN(getSpec(operandType(right)))) {
977 for(i=size; i< AOP_SIZE(result); i++) {
978 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
979 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
980 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
984 // right is signed, oh dear ...
985 for(i=size; i< AOP_SIZE(result); i++) {
986 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
987 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
988 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
989 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
990 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1000 for(i=0; i<size; i++) {
1001 if (AOP_TYPE(right) != AOP_ACC)
1002 pic16_mov2w(AOP(right),i);
1003 if (pic16_sameRegs(AOP(left), AOP(result)))
1005 if(i) { // add with carry
1006 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1007 } else { // add without
1008 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1010 } else { // not same
1011 if(i) { // add with carry
1012 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1013 } else { // add without
1014 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1016 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1020 // add leftover bytes
1021 if (SPEC_USIGN(getSpec(operandType(right)))) {
1022 // right is unsigned
1023 for(i=size; i< AOP_SIZE(result); i++) {
1024 if (pic16_sameRegs(AOP(left), AOP(result)))
1026 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1027 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1028 } else { // not same
1029 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1030 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1031 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1036 for(i=size; i< AOP_SIZE(result); i++) {
1037 if(size < AOP_SIZE(left)) {
1038 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1039 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1040 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1041 if (pic16_sameRegs(AOP(left), AOP(result)))
1043 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1044 } else { // not same
1045 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1046 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1049 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1050 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1060 // TODO: anything from here to before "release:" is probably obsolete and should be removed
1061 // when the regression tests are stable
1063 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1064 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1065 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1068 /* Need to extend result to higher bytes */
1069 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1071 /* First grab the carry from the lower bytes */
1072 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1073 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1077 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1080 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1081 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1082 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1083 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1085 /* if chars or ints or being signed extended to longs: */
1087 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1088 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1089 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1097 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1099 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1106 //adjustArithmeticResult(ic);
1109 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1110 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1111 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1114 /*-----------------------------------------------------------------*/
1115 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1116 /*-----------------------------------------------------------------*/
1117 bool pic16_genMinusDec (iCode *ic)
1119 unsigned int icount ;
1120 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1123 /* will try to generate an increment */
1124 /* if the right side is not a literal
1126 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1127 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1128 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1131 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1133 /* if the literal value of the right hand side
1134 is greater than 4 then it is not worth it */
1135 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1138 /* if decrement 16 bits in register */
1139 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1144 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1145 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1146 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1147 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1149 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1150 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1151 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1153 /* size is 3 or 4 */
1154 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1155 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1157 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1159 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1161 pic16_emitcode("movlw","0xff");
1162 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1165 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1167 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1171 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1173 pic16_emitcode("skpnc","");
1175 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1184 /* if the sizes are greater than 1 then we cannot */
1185 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1186 AOP_SIZE(IC_LEFT(ic)) > 1 )
1189 /* we can if the aops of the left & result match or
1190 if they are in registers and the registers are the
1192 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1195 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1197 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1202 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1203 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1204 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1207 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1208 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1210 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1211 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1219 /*-----------------------------------------------------------------*/
1220 /* pic16_addSign - propogate sign bit to higher bytes */
1221 /*-----------------------------------------------------------------*/
1222 void pic16_addSign(operand *result, int offset, int sign)
1224 int size = (pic16_getDataSize(result) - offset);
1225 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1228 if(sign && offset) {
1231 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1232 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1233 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1236 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1237 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1238 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1240 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1245 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1249 /*-----------------------------------------------------------------*/
1250 /* pic16_genMinusBits - generates code for subtraction of two bits */
1251 /*-----------------------------------------------------------------*/
1252 void pic16_genMinusBits (iCode *ic)
1254 symbol *lbl = newiTempLabel(NULL);
1257 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1258 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1259 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1260 pic16_emitcode("cpl","c");
1261 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1262 pic16_outBitC(IC_RESULT(ic));
1265 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1266 pic16_emitcode("subb","a,acc");
1267 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1268 pic16_emitcode("inc","a");
1269 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1270 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1271 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1275 /*-----------------------------------------------------------------*/
1276 /* pic16_genMinus - generates code for subtraction */
1277 /*-----------------------------------------------------------------*/
1278 void pic16_genMinus (iCode *ic)
1280 int size, offset = 0, same=0;
1281 unsigned long lit = 0L;
1284 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1285 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1286 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1288 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1289 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1290 operand *t = IC_RIGHT(ic);
1291 IC_RIGHT(ic) = IC_LEFT(ic);
1295 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1296 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1297 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1298 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1300 /* special cases :- */
1301 /* if both left & right are in bit space */
1302 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1303 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1304 pic16_genPlusBits (ic);
1308 /* if I can do an decrement instead
1309 of subtract then GOOD for ME */
1310 // if (pic16_genMinusDec (ic) == TRUE)
1313 size = pic16_getDataSize(IC_RESULT(ic));
1314 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1316 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1317 /* Add a literal to something else */
1319 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1322 genAddLit ( ic, lit);
1325 /* add the first byte: */
1326 pic16_emitcode("movlw","0x%x", lit & 0xff);
1327 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1328 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1329 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1341 if((lit & 0xff) == 0xff) {
1342 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1344 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1346 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1348 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1349 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1353 /* do the rlf known zero trick here */
1354 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1356 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1361 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1364 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1365 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1366 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1368 /* here we are subtracting a bit from a char or int */
1370 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1372 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1373 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1375 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1376 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1377 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1378 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1381 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1382 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1383 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1384 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1385 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1387 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1389 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1390 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1392 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1393 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1396 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1398 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1400 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1401 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1405 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1406 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1407 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1408 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1413 pic16_mov2w(AOP(IC_LEFT(ic)),0);
1414 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1415 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1418 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1420 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1423 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1425 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1427 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1434 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1435 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1436 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1438 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1439 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1440 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1441 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1442 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1445 if( (size == 1) && ((lit & 0xff) == 0) ) {
1446 /* res = 0 - right */
1447 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1448 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1450 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1451 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1452 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1457 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1458 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1459 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1467 // here we have x = lit - x for sizeof(x)>1
1468 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1469 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1471 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1472 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1473 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1480 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1481 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1482 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1483 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1485 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1486 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1487 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1488 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1489 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1490 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1493 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1494 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1495 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1497 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1498 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1500 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1501 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1502 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1504 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1506 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1507 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1508 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1510 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1512 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1518 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1520 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1521 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1523 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1524 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1531 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1532 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1533 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1535 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1536 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1537 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1545 // adjustArithmeticResult(ic);
1548 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1549 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1550 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1554 /*-----------------------------------------------------------------*
1555 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1558 *-----------------------------------------------------------------*/
1559 void pic16_genUMult8XLit_8 (operand *left,
1565 int size = AOP_SIZE(result);
1569 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1571 if (AOP_TYPE(right) != AOP_LIT){
1572 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1576 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1578 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1579 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1581 same = pic16_sameRegs(AOP(left), AOP(result));
1586 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1590 // its faster to left shift
1591 for (i=1; i < size; i++) {
1592 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1595 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1597 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1601 if(AOP_TYPE(left) != AOP_ACC)
1602 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1603 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1604 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1605 pic16_popGet(AOP(result), 0)));
1607 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1608 pic16_popGet(AOP(result), 1)));
1609 for (i=2; i < size; i++) {
1610 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1616 // operands different
1620 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1624 for (i=1; i < size; i++) {
1625 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1628 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1629 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1631 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1634 if(AOP_TYPE(left) != AOP_ACC)
1635 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1636 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1637 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1638 pic16_popGet(AOP(result), 0)));
1641 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1642 pic16_popGet(AOP(result), 1)));
1643 for (i=2; i < size; i++) {
1644 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1652 /*-----------------------------------------------------------------------*
1653 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1654 *-----------------------------------------------------------------------*/
1655 void pic16_genUMult16XLit_16 (operand *left,
1659 pCodeOp *pct1, *pct2, *pct3, *pct4;
1666 if (AOP_TYPE(right) != AOP_LIT){
1667 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1671 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1674 same = pic16_sameRegs(AOP(left), AOP(result));
1678 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1679 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1682 // its faster to left shift
1684 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1685 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1689 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1691 pct1 = pic16_popGetTempReg(1);
1692 pct2 = pic16_popGetTempReg(1);
1693 pct3 = pic16_popGetTempReg(1);
1694 pct4 = pic16_popGetTempReg(1);
1696 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1697 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1698 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1699 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1700 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1701 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1703 /* WREG still holds the low literal */
1704 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1705 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1706 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1708 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1709 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1710 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1711 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1714 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1715 pct1, pic16_popGet(AOP(result), 0)));
1716 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1717 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1718 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1719 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1721 pic16_popReleaseTempReg(pct4,1);
1722 pic16_popReleaseTempReg(pct3,1);
1723 pic16_popReleaseTempReg(pct2,1);
1724 pic16_popReleaseTempReg(pct1,1);
1728 // operands different
1731 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1732 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1736 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1737 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1738 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1739 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1743 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1744 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1745 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1746 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1747 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1748 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1750 /* WREG still holds the low literal */
1751 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1752 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1753 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1755 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1756 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1757 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1758 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1766 /*-----------------------------------------------------------------*
1767 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1770 *-----------------------------------------------------------------*/
1771 void pic16_genUMult8X8_8 (operand *left,
1779 if (AOP_TYPE(right) == AOP_LIT) {
1780 pic16_genUMult8XLit_8(left,right,result);
1790 /* if result == right then exchange left and right */
1791 if(pic16_sameRegs(AOP(result), AOP(right))) {
1798 if(AOP_TYPE(left) != AOP_ACC) {
1800 if(AOP_TYPE(right) != AOP_ACC) {
1801 pic16_mov2w(AOP(left), 0);
1802 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1804 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1807 // left is WREG, right cannot be WREG (or can?!)
1808 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1811 /* result is in PRODL:PRODH */
1812 if(AOP_TYPE(result) != AOP_ACC) {
1813 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1814 pic16_popGet(AOP(result), 0)));
1817 if(AOP_SIZE(result)>1) {
1820 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1821 pic16_popGet(AOP(result), 1)));
1823 for(i=2;i<AOP_SIZE(result);i++)
1824 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1827 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1831 /*------------------------------------------------------------------*
1832 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1833 *------------------------------------------------------------------*/
1834 void pic16_genUMult16X16_16 (operand *left,
1839 pCodeOp *pct1, *pct2, *pct3, *pct4;
1844 if (AOP_TYPE(right) == AOP_LIT) {
1845 pic16_genUMult8XLit_8(left,right,result);
1853 /* if result == right then exchange left and right */
1854 if(pic16_sameRegs(AOP(result), AOP(right))) {
1862 if(pic16_sameRegs(AOP(result), AOP(left))) {
1864 pct1 = pic16_popGetTempReg(1);
1865 pct2 = pic16_popGetTempReg(1);
1866 pct3 = pic16_popGetTempReg(1);
1867 pct4 = pic16_popGetTempReg(1);
1869 pic16_mov2w(AOP(left), 0);
1870 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1871 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1872 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1873 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1874 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1876 /* WREG still holds the lower left */
1877 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1878 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1879 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1881 pic16_mov2w(AOP(left), 1);
1882 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1883 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1884 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1887 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1888 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
1889 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
1890 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1891 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1892 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1894 pic16_popReleaseTempReg( pct4, 1 );
1895 pic16_popReleaseTempReg( pct3, 1 );
1896 pic16_popReleaseTempReg( pct2, 1 );
1897 pic16_popReleaseTempReg( pct1, 1 );
1901 pic16_mov2w(AOP(left), 0);
1902 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1903 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1904 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1905 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1906 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1908 /* WREG still holds the lower left */
1909 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1910 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1911 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1913 pic16_mov2w(AOP(left), 1);
1914 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1915 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1916 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1921 void pic16_genSMult16X16_16(operand *left,
1929 /*-----------------------------------------------------------------*
1930 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1932 * this routine will call the unsigned multiply routine and then
1933 * post-fix the sign bit.
1934 *-----------------------------------------------------------------*/
1935 void pic16_genSMult8X8_8 (operand *left,
1938 pCodeOpReg *result_hi)
1940 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1944 result_hi = PCOR(pic16_popGet(AOP(result),1));
1948 pic16_genUMult8X8_8(left,right,result);
1952 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1953 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
1954 pic16_mov2w(AOP(left),0);
1955 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1956 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
1961 /*-----------------------------------------------------------------*
1962 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
1963 *-----------------------------------------------------------------*/
1964 void pic16_genMult8X8_8 (operand *left,
1970 if(AOP_TYPE(right) == AOP_LIT)
1971 pic16_genUMult8XLit_8(left,right,result);
1973 pic16_genUMult8X8_8(left,right,result);
1977 /*-----------------------------------------------------------------*
1978 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
1979 *-----------------------------------------------------------------*/
1980 void pic16_genMult16X16_16 (operand *left,
1986 if (AOP_TYPE(right) == AOP_LIT)
1987 pic16_genUMult16XLit_16(left,right,result);
1989 pic16_genUMult16X16_16(left,right,result);
1995 /*-----------------------------------------------------------------------*
1996 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
1997 *-----------------------------------------------------------------------*/
1998 void pic16_genUMult32XLit_32 (operand *left,
2002 pCodeOp *pct1, *pct2, *pct3, *pct4;
2009 if (AOP_TYPE(right) != AOP_LIT){
2010 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2014 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2017 same = pic16_sameRegs(AOP(left), AOP(result));
2021 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2022 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2025 // its faster to left shift
2027 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2028 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2032 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2034 pct1 = pic16_popGetTempReg(1);
2035 pct2 = pic16_popGetTempReg(1);
2036 pct3 = pic16_popGetTempReg(1);
2037 pct4 = pic16_popGetTempReg(1);
2039 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2040 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2041 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2042 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2043 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2044 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2046 /* WREG still holds the low literal */
2047 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2048 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2049 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2051 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2052 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2053 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2054 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2057 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2058 pct1, pic16_popGet(AOP(result), 0)));
2059 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2060 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2061 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2062 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2064 pic16_popReleaseTempReg( pct4, 1 );
2065 pic16_popReleaseTempReg( pct3, 1 );
2066 pic16_popReleaseTempReg( pct2, 1 );
2067 pic16_popReleaseTempReg( pct1, 1 );
2071 // operands different
2074 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2075 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2079 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2080 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2081 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2082 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2086 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2087 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2088 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2089 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2090 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2091 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2093 /* WREG still holds the low literal */
2094 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2095 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2096 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2098 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2099 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2100 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2101 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2109 /*------------------------------------------------------------------*
2110 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2111 *------------------------------------------------------------------*/
2112 void pic16_genUMult32X32_32 (operand *left,
2117 pCodeOp *pct1, *pct2, *pct3, *pct4;
2121 if (AOP_TYPE(right) == AOP_LIT) {
2122 pic16_genUMult8XLit_8(left,right,result);
2130 /* if result == right then exchange left and right */
2131 if(pic16_sameRegs(AOP(result), AOP(right))) {
2139 if(pic16_sameRegs(AOP(result), AOP(left))) {
2141 pct1 = pic16_popGetTempReg(1);
2142 pct2 = pic16_popGetTempReg(1);
2143 pct3 = pic16_popGetTempReg(1);
2144 pct4 = pic16_popGetTempReg(1);
2146 pic16_mov2w(AOP(left), 0);
2147 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2148 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2149 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2150 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2151 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2153 /* WREG still holds the lower left */
2154 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2155 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2156 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2158 pic16_mov2w(AOP(left), 1);
2159 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2160 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2161 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2164 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2165 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2166 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2167 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2168 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2169 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2171 pic16_popReleaseTempReg( pct4, 1 );
2172 pic16_popReleaseTempReg( pct3, 1 );
2173 pic16_popReleaseTempReg( pct2, 1 );
2174 pic16_popReleaseTempReg( pct1, 1 );
2178 pic16_mov2w(AOP(left), 0);
2179 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2180 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2181 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2182 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2183 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2185 /* WREG still holds the lower left */
2186 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2187 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2188 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2190 pic16_mov2w(AOP(left), 1);
2191 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2192 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2193 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2198 /*-----------------------------------------------------------------*
2199 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2200 *-----------------------------------------------------------------*/
2201 void pic16_genMult32X32_32 (operand *left,
2207 if (AOP_TYPE(right) == AOP_LIT)
2208 pic16_genUMult32XLit_32(left,right,result);
2210 pic16_genUMult32X32_32(left,right,result);
2220 /*-----------------------------------------------------------------*/
2221 /* constMult - generates code for multiplication by a constant */
2222 /*-----------------------------------------------------------------*/
2223 void genMultConst(unsigned C)
2227 unsigned sr3; // Shift right 3
2233 Convert a string of 3 binary 1's in the lit into
2237 mask = 7 << ( (size*8) - 3);
2241 while(mask < (1<<size*8)) {
2243 if( (mask & lit) == lit) {
2246 /* We found 3 (or more) consecutive 1's */
2248 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2250 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2252 lit ^= consecutive_bits;
2256 sr3 |= (consecutive + lsb);