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))) ) {
770 right = IC_RIGHT(ic) = left;
771 left = IC_LEFT(ic) = t;
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(result);
814 if(AOP(right)->type == AOP_LIT) {
815 /* Add a literal to something else */
817 unsigned lit = (unsigned) floatFromVal(AOP(right)->aopu.aop_lit);
821 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
826 } else if(AOP_TYPE(right) == AOP_CRY) {
828 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
829 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
830 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
832 /* here we are adding a bit to a char or int */
834 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
836 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
837 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0));
839 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
840 AOP(right)->aopu.aop_dir,
841 AOP(right)->aopu.aop_dir);
842 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
845 if(AOP_TYPE(left) == AOP_ACC) {
846 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
847 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
849 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
850 AOP(right)->aopu.aop_dir,
851 AOP(right)->aopu.aop_dir);
852 pic16_emitcode(" xorlw","1");
854 pic16_mov2w(AOP(left),0);
855 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
856 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
858 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
859 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
860 AOP(right)->aopu.aop_dir,
861 AOP(right)->aopu.aop_dir);
862 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
865 if(AOP_TYPE(result) != AOP_ACC) {
867 if(AOP_TYPE(result) == AOP_CRY) {
868 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
869 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0));
871 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0));
873 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0));
874 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
881 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
882 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
884 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
885 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
887 pic16_emitcode("clrz","");
889 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
890 AOP(right)->aopu.aop_dir,
891 AOP(right)->aopu.aop_dir);
892 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
895 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
896 pic16_mov2w(AOP(left),0);
897 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
898 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
899 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
902 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
903 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
904 AOP(right)->aopu.aop_dir,
905 AOP(right)->aopu.aop_dir);
906 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
907 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
913 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++));
914 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),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 // either left or right is too short
1022 for (i=size; i < AOP_SIZE(result); i++) {
1023 // get right operand into WREG
1024 if (i < AOP_SIZE(right)) {
1025 pic16_mov2w (AOP(right), i);
1027 // right is too short
1028 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1029 if (!SPEC_USIGN(getSpec(operandType(right)))) {
1030 // right operand is signed
1031 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1032 pic16_emitpcode(POC_COMF, pic16_popCopyReg (&pic16_pc_wreg));
1036 // get left+WREG+CARRY into result
1037 if (i < AOP_SIZE(left)) {
1038 if (pic16_sameRegs (AOP(left), AOP(result))) {
1039 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1041 pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
1042 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1045 // left is too short
1046 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
1047 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1048 // left operand is signed
1049 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1050 pic16_emitpcode(POC_COMF, pic16_popGet (AOP(result), i));
1052 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1058 // add leftover bytes
1059 if (SPEC_USIGN(getSpec(operandType(right)))) {
1060 // right is unsigned
1061 for(i=size; i< AOP_SIZE(result); i++) {
1062 if (pic16_sameRegs(AOP(left), AOP(result)))
1064 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1065 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1066 } else { // not same
1067 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1068 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1069 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1074 for(i=size; i< AOP_SIZE(result); i++) {
1075 if(size < AOP_SIZE(left)) {
1076 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1077 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1078 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1079 if (pic16_sameRegs(AOP(left), AOP(result)))
1081 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1082 } else { // not same
1083 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1084 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1087 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1088 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1099 // TODO: anything from here to before "release:" is probably obsolete and should be removed
1100 // when the regression tests are stable
1102 if (AOP_SIZE(result) > AOP_SIZE(right)) {
1103 int sign = !(SPEC_USIGN(getSpec(operandType(left))) |
1104 SPEC_USIGN(getSpec(operandType(right))) );
1107 /* Need to extend result to higher bytes */
1108 size = AOP_SIZE(result) - AOP_SIZE(right) - 1;
1110 /* First grab the carry from the lower bytes */
1111 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
1112 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset));
1116 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1119 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1120 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1121 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1122 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1124 /* if chars or ints or being signed extended to longs: */
1126 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1127 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1128 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1136 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1138 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
1145 //adjustArithmeticResult(ic);
1148 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1149 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1150 pic16_freeAsmop(result,NULL,ic,TRUE);
1153 /*-----------------------------------------------------------------*/
1154 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1155 /*-----------------------------------------------------------------*/
1156 bool pic16_genMinusDec (iCode *ic)
1158 unsigned int icount ;
1159 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1162 /* will try to generate an increment */
1163 /* if the right side is not a literal
1165 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1166 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1167 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1170 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1172 /* if the literal value of the right hand side
1173 is greater than 4 then it is not worth it */
1174 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1177 /* if decrement 16 bits in register */
1178 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1183 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1185 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1187 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1188 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1189 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1191 /* size is 3 or 4 */
1192 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1193 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1194 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1195 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1197 pic16_emitcode("movlw","0xff");
1198 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1201 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1203 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1206 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1208 pic16_emitcode("skpnc","");
1210 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1219 /* if the sizes are greater than 1 then we cannot */
1220 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1221 AOP_SIZE(IC_LEFT(ic)) > 1 )
1224 /* we can if the aops of the left & result match or
1225 if they are in registers and the registers are the
1227 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1230 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1232 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1237 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1238 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1239 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1242 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1243 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1245 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1246 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1254 /*-----------------------------------------------------------------*/
1255 /* pic16_addSign - propogate sign bit to higher bytes */
1256 /*-----------------------------------------------------------------*/
1257 void pic16_addSign(operand *result, int offset, int sign)
1259 int size = (pic16_getDataSize(result) - offset);
1260 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1263 if(sign && offset) {
1266 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1267 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1268 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1271 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1272 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1273 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1275 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1280 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1284 /*-----------------------------------------------------------------*/
1285 /* pic16_genMinusBits - generates code for subtraction of two bits */
1286 /*-----------------------------------------------------------------*/
1287 void pic16_genMinusBits (iCode *ic)
1289 symbol *lbl = newiTempLabel(NULL);
1292 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1293 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1294 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1295 pic16_emitcode("cpl","c");
1296 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1297 pic16_outBitC(IC_RESULT(ic));
1300 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1301 pic16_emitcode("subb","a,acc");
1302 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1303 pic16_emitcode("inc","a");
1304 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1305 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1306 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1310 /*-----------------------------------------------------------------*/
1311 /* pic16_genMinus - generates code for subtraction */
1312 /*-----------------------------------------------------------------*/
1313 void pic16_genMinus (iCode *ic)
1315 int size, offset = 0, same=0;
1316 unsigned long lit = 0L;
1319 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1320 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1321 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1323 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1324 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1325 operand *t = IC_RIGHT(ic);
1326 IC_RIGHT(ic) = IC_LEFT(ic);
1330 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1331 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1332 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1333 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1335 /* special cases :- */
1336 /* if both left & right are in bit space */
1337 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1338 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1339 pic16_genPlusBits (ic);
1343 /* if I can do an decrement instead
1344 of subtract then GOOD for ME */
1345 // if (pic16_genMinusDec (ic) == TRUE)
1348 size = pic16_getDataSize(IC_RESULT(ic));
1349 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1351 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1352 /* Add a literal to something else */
1354 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1357 genAddLit ( ic, lit);
1360 /* add the first byte: */
1361 pic16_emitcode("movlw","0x%x", lit & 0xff);
1362 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1363 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1364 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1376 if((lit & 0xff) == 0xff) {
1377 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1379 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1381 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1383 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1384 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1388 /* do the rlf known zero trick here */
1389 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1391 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1396 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1399 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1400 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1401 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1403 /* here we are subtracting a bit from a char or int */
1405 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1407 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1408 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1410 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1411 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1412 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1413 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1416 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1417 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1418 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1419 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1420 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1422 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1424 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1425 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1427 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1428 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1431 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1433 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1435 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1436 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1440 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1441 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1442 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1443 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1448 pic16_mov2w(AOP(IC_LEFT(ic)),0);
1449 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1450 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1453 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1455 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1458 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1460 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1462 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1469 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1470 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1471 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1473 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1474 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1475 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1476 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1477 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1480 if( (size == 1) && ((lit & 0xff) == 0) ) {
1481 /* res = 0 - right */
1482 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1483 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1485 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1486 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1487 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1492 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1493 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1494 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1502 // here we have x = lit - x for sizeof(x)>1
1503 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1504 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1506 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1507 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1508 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1515 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1516 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1517 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1518 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1520 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1521 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1522 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1523 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1524 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1525 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1528 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1529 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1530 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1532 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1533 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1535 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1536 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1537 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1539 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1541 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1542 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1543 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1545 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1547 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1553 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1555 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1556 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1558 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1559 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1566 if (offset < AOP_SIZE(IC_RIGHT(ic)))
1567 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1569 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1570 if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
1571 // signed -- sign extend the right operand
1572 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));
1573 pic16_emitpcode (POC_COMF, pic16_popCopyReg (&pic16_pc_wreg));
1576 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1577 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1579 if (offset < AOP_SIZE(IC_LEFT(ic))) {
1580 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1581 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1583 // zero extend the left operand
1584 pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
1585 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
1586 // signed -- sign extend the left operand
1587 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));
1588 pic16_emitpcode (POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
1590 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1599 // adjustArithmeticResult(ic);
1602 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1603 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1604 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1608 /*-----------------------------------------------------------------*
1609 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1612 *-----------------------------------------------------------------*/
1613 void pic16_genUMult8XLit_8 (operand *left,
1619 int size = AOP_SIZE(result);
1623 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1625 if (AOP_TYPE(right) != AOP_LIT){
1626 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1630 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1632 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1633 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1635 same = pic16_sameRegs(AOP(left), AOP(result));
1640 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1644 // its faster to left shift
1645 for (i=1; i < size; i++) {
1646 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1649 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1651 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1655 if(AOP_TYPE(left) != AOP_ACC)
1656 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1657 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1658 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1659 pic16_popGet(AOP(result), 0)));
1661 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1662 pic16_popGet(AOP(result), 1)));
1663 for (i=2; i < size; i++) {
1664 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1670 // operands different
1674 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1678 for (i=1; i < size; i++) {
1679 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1682 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1683 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1685 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1688 if(AOP_TYPE(left) != AOP_ACC)
1689 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1690 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1691 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1692 pic16_popGet(AOP(result), 0)));
1695 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1696 pic16_popGet(AOP(result), 1)));
1697 for (i=2; i < size; i++) {
1698 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1706 /*-----------------------------------------------------------------------*
1707 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1708 *-----------------------------------------------------------------------*/
1709 void pic16_genUMult16XLit_16 (operand *left,
1713 pCodeOp *pct1, *pct2, *pct3, *pct4;
1720 if (AOP_TYPE(right) != AOP_LIT){
1721 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1725 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1728 same = pic16_sameRegs(AOP(left), AOP(result));
1732 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1733 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1736 // its faster to left shift
1738 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1739 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1743 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1745 pct1 = pic16_popGetTempReg(1);
1746 pct2 = pic16_popGetTempReg(1);
1747 pct3 = pic16_popGetTempReg(1);
1748 pct4 = pic16_popGetTempReg(1);
1750 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1751 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1752 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1753 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1754 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1755 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1757 /* WREG still holds the low literal */
1758 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1759 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1760 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1762 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1763 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1764 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1765 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1768 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1769 pct1, pic16_popGet(AOP(result), 0)));
1770 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1771 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1772 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1773 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1775 pic16_popReleaseTempReg(pct4,1);
1776 pic16_popReleaseTempReg(pct3,1);
1777 pic16_popReleaseTempReg(pct2,1);
1778 pic16_popReleaseTempReg(pct1,1);
1782 // operands different
1785 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1786 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1790 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1791 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1792 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1793 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1797 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1798 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1799 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1800 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1801 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1802 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1804 /* WREG still holds the low literal */
1805 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1806 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1807 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1809 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1810 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1811 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1812 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1820 /*-----------------------------------------------------------------*
1821 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1824 *-----------------------------------------------------------------*/
1825 void pic16_genUMult8X8_8 (operand *left,
1833 if (AOP_TYPE(right) == AOP_LIT) {
1834 pic16_genUMult8XLit_8(left,right,result);
1844 /* if result == right then exchange left and right */
1845 if(pic16_sameRegs(AOP(result), AOP(right))) {
1852 if(AOP_TYPE(left) != AOP_ACC) {
1854 if(AOP_TYPE(right) != AOP_ACC) {
1855 pic16_mov2w(AOP(left), 0);
1856 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1858 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1861 // left is WREG, right cannot be WREG (or can?!)
1862 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1865 /* result is in PRODL:PRODH */
1866 if(AOP_TYPE(result) != AOP_ACC) {
1867 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1868 pic16_popGet(AOP(result), 0)));
1871 if(AOP_SIZE(result)>1) {
1874 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1875 pic16_popGet(AOP(result), 1)));
1877 for(i=2;i<AOP_SIZE(result);i++)
1878 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1881 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1885 /*------------------------------------------------------------------*
1886 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1887 *------------------------------------------------------------------*/
1888 void pic16_genUMult16X16_16 (operand *left,
1893 pCodeOp *pct1, *pct2, *pct3, *pct4;
1898 if (AOP_TYPE(right) == AOP_LIT) {
1899 pic16_genUMult8XLit_8(left,right,result);
1907 /* if result == right then exchange left and right */
1908 if(pic16_sameRegs(AOP(result), AOP(right))) {
1916 if(pic16_sameRegs(AOP(result), AOP(left))) {
1918 pct1 = pic16_popGetTempReg(1);
1919 pct2 = pic16_popGetTempReg(1);
1920 pct3 = pic16_popGetTempReg(1);
1921 pct4 = pic16_popGetTempReg(1);
1923 pic16_mov2w(AOP(left), 0);
1924 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1925 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1926 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1927 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1928 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1930 /* WREG still holds the lower left */
1931 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1932 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1933 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1935 pic16_mov2w(AOP(left), 1);
1936 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1937 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1938 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1941 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1942 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
1943 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
1944 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1945 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1946 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1948 pic16_popReleaseTempReg( pct4, 1 );
1949 pic16_popReleaseTempReg( pct3, 1 );
1950 pic16_popReleaseTempReg( pct2, 1 );
1951 pic16_popReleaseTempReg( pct1, 1 );
1955 pic16_mov2w(AOP(left), 0);
1956 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1957 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1958 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1959 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1960 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1962 /* WREG still holds the lower left */
1963 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1964 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1965 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1967 pic16_mov2w(AOP(left), 1);
1968 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1969 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1970 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1975 void pic16_genSMult16X16_16(operand *left,
1983 /*-----------------------------------------------------------------*
1984 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1986 * this routine will call the unsigned multiply routine and then
1987 * post-fix the sign bit.
1988 *-----------------------------------------------------------------*/
1989 void pic16_genSMult8X8_8 (operand *left,
1992 pCodeOpReg *result_hi)
1994 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1998 result_hi = PCOR(pic16_popGet(AOP(result),1));
2002 pic16_genUMult8X8_8(left,right,result);
2006 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2007 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2008 pic16_mov2w(AOP(left),0);
2009 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2010 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2015 /*-----------------------------------------------------------------*
2016 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
2017 *-----------------------------------------------------------------*/
2018 void pic16_genMult8X8_8 (operand *left,
2024 if(AOP_TYPE(right) == AOP_LIT)
2025 pic16_genUMult8XLit_8(left,right,result);
2027 pic16_genUMult8X8_8(left,right,result);
2031 /*-----------------------------------------------------------------*
2032 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
2033 *-----------------------------------------------------------------*/
2034 void pic16_genMult16X16_16 (operand *left,
2040 if (AOP_TYPE(right) == AOP_LIT)
2041 pic16_genUMult16XLit_16(left,right,result);
2043 pic16_genUMult16X16_16(left,right,result);
2049 /*-----------------------------------------------------------------------*
2050 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2051 *-----------------------------------------------------------------------*/
2052 void pic16_genUMult32XLit_32 (operand *left,
2056 pCodeOp *pct1, *pct2, *pct3, *pct4;
2063 if (AOP_TYPE(right) != AOP_LIT){
2064 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2068 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2071 same = pic16_sameRegs(AOP(left), AOP(result));
2075 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2076 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2079 // its faster to left shift
2081 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2082 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2086 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2088 pct1 = pic16_popGetTempReg(1);
2089 pct2 = pic16_popGetTempReg(1);
2090 pct3 = pic16_popGetTempReg(1);
2091 pct4 = pic16_popGetTempReg(1);
2093 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2094 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2095 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2096 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2097 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2098 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2100 /* WREG still holds the low literal */
2101 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2102 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2103 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2105 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2106 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2107 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2108 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2111 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2112 pct1, pic16_popGet(AOP(result), 0)));
2113 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2114 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2115 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2116 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2118 pic16_popReleaseTempReg( pct4, 1 );
2119 pic16_popReleaseTempReg( pct3, 1 );
2120 pic16_popReleaseTempReg( pct2, 1 );
2121 pic16_popReleaseTempReg( pct1, 1 );
2125 // operands different
2128 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2129 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2133 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2134 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2135 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2136 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2140 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2141 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2142 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2143 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2144 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2145 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2147 /* WREG still holds the low literal */
2148 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2149 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2150 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2152 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2153 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2154 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2155 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2163 /*------------------------------------------------------------------*
2164 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2165 *------------------------------------------------------------------*/
2166 void pic16_genUMult32X32_32 (operand *left,
2171 pCodeOp *pct1, *pct2, *pct3, *pct4;
2175 if (AOP_TYPE(right) == AOP_LIT) {
2176 pic16_genUMult8XLit_8(left,right,result);
2184 /* if result == right then exchange left and right */
2185 if(pic16_sameRegs(AOP(result), AOP(right))) {
2193 if(pic16_sameRegs(AOP(result), AOP(left))) {
2195 pct1 = pic16_popGetTempReg(1);
2196 pct2 = pic16_popGetTempReg(1);
2197 pct3 = pic16_popGetTempReg(1);
2198 pct4 = pic16_popGetTempReg(1);
2200 pic16_mov2w(AOP(left), 0);
2201 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2202 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2203 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2204 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2205 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2207 /* WREG still holds the lower left */
2208 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2209 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2210 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2212 pic16_mov2w(AOP(left), 1);
2213 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2214 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2215 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2218 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2219 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2220 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2221 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2222 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2223 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2225 pic16_popReleaseTempReg( pct4, 1 );
2226 pic16_popReleaseTempReg( pct3, 1 );
2227 pic16_popReleaseTempReg( pct2, 1 );
2228 pic16_popReleaseTempReg( pct1, 1 );
2232 pic16_mov2w(AOP(left), 0);
2233 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2234 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2235 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2236 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2237 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2239 /* WREG still holds the lower left */
2240 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2241 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2242 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2244 pic16_mov2w(AOP(left), 1);
2245 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2246 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2247 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2252 /*-----------------------------------------------------------------*
2253 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2254 *-----------------------------------------------------------------*/
2255 void pic16_genMult32X32_32 (operand *left,
2261 if (AOP_TYPE(right) == AOP_LIT)
2262 pic16_genUMult32XLit_32(left,right,result);
2264 pic16_genUMult32X32_32(left,right,result);
2274 /*-----------------------------------------------------------------*/
2275 /* constMult - generates code for multiplication by a constant */
2276 /*-----------------------------------------------------------------*/
2277 void genMultConst(unsigned C)
2281 unsigned sr3; // Shift right 3
2287 Convert a string of 3 binary 1's in the lit into
2291 mask = 7 << ( (size*8) - 3);
2295 while(mask < (1<<size*8)) {
2297 if( (mask & lit) == lit) {
2300 /* We found 3 (or more) consecutive 1's */
2302 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2304 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2306 lit ^= consecutive_bits;
2310 sr3 |= (consecutive + lsb);