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 size = pic16_getDataSize(result);
795 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
796 pic16_emitcode("addc","a,#00 ;%d",__LINE__);
797 pic16_aopPut(AOP(result),"a",offset++);
803 /* if I can do an increment instead
804 of add then GOOD for ME */
805 if (pic16_genPlusIncr (ic) == TRUE)
808 size = pic16_getDataSize(IC_RESULT(ic));
810 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
811 /* Add a literal to something else */
813 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
817 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
822 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
824 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
825 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
826 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
828 /* here we are adding a bit to a char or int */
830 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
832 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
833 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
835 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
836 AOP(IC_RIGHT(ic))->aopu.aop_dir,
837 AOP(IC_RIGHT(ic))->aopu.aop_dir);
838 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
841 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
842 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
843 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
845 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
846 AOP(IC_RIGHT(ic))->aopu.aop_dir,
847 AOP(IC_RIGHT(ic))->aopu.aop_dir);
848 pic16_emitcode(" xorlw","1");
850 pic16_mov2w(AOP(IC_LEFT(ic)),0);
851 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
852 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
854 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
855 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
856 AOP(IC_RIGHT(ic))->aopu.aop_dir,
857 AOP(IC_RIGHT(ic))->aopu.aop_dir);
858 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
861 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
863 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
864 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
865 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
867 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
869 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
870 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
877 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
878 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
880 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
881 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
883 pic16_emitcode("clrz","");
885 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
886 AOP(IC_RIGHT(ic))->aopu.aop_dir,
887 AOP(IC_RIGHT(ic))->aopu.aop_dir);
888 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
891 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
892 pic16_mov2w(AOP(IC_LEFT(ic)),0);
893 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
894 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
895 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
896 emitMOVWF(IC_RIGHT(ic),0);
898 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
899 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
900 AOP(IC_RIGHT(ic))->aopu.aop_dir,
901 AOP(IC_RIGHT(ic))->aopu.aop_dir);
902 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
903 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
909 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
910 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
918 // Note: the following is an example of WISC code, eg.
919 // it's supposed to run on a Weird Instruction Set Computer :o)
921 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
923 if ( AOP_TYPE(left) == AOP_ACC) {
924 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
925 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
926 if ( AOP_TYPE(result) != AOP_ACC)
927 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
928 goto release; // we're done, since WREG is 1 byte
932 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
934 size = min( AOP_SIZE(result), AOP_SIZE(right) );
935 size = min( size, AOP_SIZE(left) );
938 if(pic16_debug_verbose) {
939 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
940 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
941 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
946 if ((AOP_TYPE(left) == AOP_PCODE) && (
947 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
948 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
949 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
951 // add to literal operand
954 for(i=0; i<size; i++) {
955 if (AOP_TYPE(right) == AOP_ACC) {
956 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
958 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
959 if(i) { // add with carry
960 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
961 } else { // add without
962 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
965 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
968 DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
970 // add leftover bytes
971 if (SPEC_USIGN(getSpec(operandType(right)))) {
973 for(i=size; i< AOP_SIZE(result); i++) {
974 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
975 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
976 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
980 // right is signed, oh dear ...
981 for(i=size; i< AOP_SIZE(result); i++) {
982 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
983 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
984 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
985 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
986 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
996 for(i=0; i<size; i++) {
997 if (AOP_TYPE(right) != AOP_ACC)
998 pic16_mov2w(AOP(right),i);
999 if (pic16_sameRegs(AOP(left), AOP(result)))
1001 if(i) { // add with carry
1002 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1003 } else { // add without
1004 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1006 } else { // not same
1007 if(i) { // add with carry
1008 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1009 } else { // add without
1010 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1012 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1016 // add leftover bytes
1017 if (SPEC_USIGN(getSpec(operandType(right)))) {
1018 // right is unsigned
1019 for(i=size; i< AOP_SIZE(result); i++) {
1020 if (pic16_sameRegs(AOP(left), AOP(result)))
1022 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1023 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1024 } else { // not same
1025 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1026 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1027 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1032 for(i=size; i< AOP_SIZE(result); i++) {
1033 if(size < AOP_SIZE(left)) {
1034 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1035 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1036 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1037 if (pic16_sameRegs(AOP(left), AOP(result)))
1039 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1040 } else { // not same
1041 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1042 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1045 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1046 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1056 // TODO: anything from here to before "release:" is probably obsolete and should be removed
1057 // when the regression tests are stable
1059 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1060 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1061 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1064 /* Need to extend result to higher bytes */
1065 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1067 /* First grab the carry from the lower bytes */
1068 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1069 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1073 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1076 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1077 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1078 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1079 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1081 /* if chars or ints or being signed extended to longs: */
1083 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1084 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1085 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1093 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1095 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1102 //adjustArithmeticResult(ic);
1105 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1106 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1107 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1110 /*-----------------------------------------------------------------*/
1111 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1112 /*-----------------------------------------------------------------*/
1113 bool pic16_genMinusDec (iCode *ic)
1115 unsigned int icount ;
1116 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1119 /* will try to generate an increment */
1120 /* if the right side is not a literal
1122 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1123 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1124 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1127 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1129 /* if the literal value of the right hand side
1130 is greater than 4 then it is not worth it */
1131 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1134 /* if decrement 16 bits in register */
1135 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1140 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1141 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1142 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1143 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1145 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1146 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1147 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1149 /* size is 3 or 4 */
1150 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1151 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1153 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1155 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1157 pic16_emitcode("movlw","0xff");
1158 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1161 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1163 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1167 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1169 pic16_emitcode("skpnc","");
1171 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1180 /* if the sizes are greater than 1 then we cannot */
1181 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1182 AOP_SIZE(IC_LEFT(ic)) > 1 )
1185 /* we can if the aops of the left & result match or
1186 if they are in registers and the registers are the
1188 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1191 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1193 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1198 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1199 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1200 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1203 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1204 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1206 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1207 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1215 /*-----------------------------------------------------------------*/
1216 /* pic16_addSign - propogate sign bit to higher bytes */
1217 /*-----------------------------------------------------------------*/
1218 void pic16_addSign(operand *result, int offset, int sign)
1220 int size = (pic16_getDataSize(result) - offset);
1221 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1224 if(sign && offset) {
1227 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1228 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1229 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1232 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1233 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1234 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1236 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1241 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1245 /*-----------------------------------------------------------------*/
1246 /* pic16_genMinusBits - generates code for subtraction of two bits */
1247 /*-----------------------------------------------------------------*/
1248 void pic16_genMinusBits (iCode *ic)
1250 symbol *lbl = newiTempLabel(NULL);
1253 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1254 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1255 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1256 pic16_emitcode("cpl","c");
1257 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1258 pic16_outBitC(IC_RESULT(ic));
1261 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1262 pic16_emitcode("subb","a,acc");
1263 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1264 pic16_emitcode("inc","a");
1265 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1266 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1267 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1271 /*-----------------------------------------------------------------*/
1272 /* pic16_genMinus - generates code for subtraction */
1273 /*-----------------------------------------------------------------*/
1274 void pic16_genMinus (iCode *ic)
1276 int size, offset = 0, same=0;
1277 unsigned long lit = 0L;
1280 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1281 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1282 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1284 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1285 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1286 operand *t = IC_RIGHT(ic);
1287 IC_RIGHT(ic) = IC_LEFT(ic);
1291 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1292 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1293 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1294 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1296 /* special cases :- */
1297 /* if both left & right are in bit space */
1298 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1299 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1300 pic16_genPlusBits (ic);
1304 /* if I can do an decrement instead
1305 of subtract then GOOD for ME */
1306 // if (pic16_genMinusDec (ic) == TRUE)
1309 size = pic16_getDataSize(IC_RESULT(ic));
1310 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1312 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1313 /* Add a literal to something else */
1315 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1318 genAddLit ( ic, lit);
1321 /* add the first byte: */
1322 pic16_emitcode("movlw","0x%x", lit & 0xff);
1323 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1324 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1325 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1337 if((lit & 0xff) == 0xff) {
1338 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1340 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1342 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1344 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1345 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1349 /* do the rlf known zero trick here */
1350 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1352 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1357 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1360 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1361 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1362 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1364 /* here we are subtracting a bit from a char or int */
1366 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1368 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1369 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1371 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1372 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1373 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1374 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1377 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1378 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1379 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1380 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1381 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1383 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1385 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1386 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1388 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1389 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1392 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1394 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1396 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1397 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1401 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1402 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1403 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1404 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1409 pic16_mov2w(AOP(IC_LEFT(ic)),0);
1410 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1411 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1414 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1416 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1419 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1421 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1423 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1430 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1431 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1432 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1434 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1435 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1436 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1437 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1438 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1441 if( (size == 1) && ((lit & 0xff) == 0) ) {
1442 /* res = 0 - right */
1443 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1444 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1446 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1447 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1448 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1453 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1454 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1455 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1463 // here we have x = lit - x for sizeof(x)>1
1464 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1465 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1467 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1468 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1469 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1476 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1477 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1478 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1479 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1481 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1482 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1483 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1484 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1485 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1486 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1489 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1490 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1491 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1493 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1494 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1496 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1497 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1498 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1500 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1502 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1503 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1504 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1506 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1508 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1514 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1516 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1517 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1519 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1520 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1527 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1528 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1529 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1531 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1532 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1533 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1541 // adjustArithmeticResult(ic);
1544 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1545 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1546 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1550 /*-----------------------------------------------------------------*
1551 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1554 *-----------------------------------------------------------------*/
1555 void pic16_genUMult8XLit_8 (operand *left,
1561 int size = AOP_SIZE(result);
1565 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1567 if (AOP_TYPE(right) != AOP_LIT){
1568 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1572 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1574 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1575 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1577 same = pic16_sameRegs(AOP(left), AOP(result));
1582 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1586 // its faster to left shift
1587 for (i=1; i < size; i++) {
1588 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1591 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1593 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1597 if(AOP_TYPE(left) != AOP_ACC)
1598 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1599 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1600 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1601 pic16_popGet(AOP(result), 0)));
1603 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1604 pic16_popGet(AOP(result), 1)));
1605 for (i=2; i < size; i++) {
1606 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1612 // operands different
1616 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1620 for (i=1; i < size; i++) {
1621 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1624 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1625 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1627 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1630 if(AOP_TYPE(left) != AOP_ACC)
1631 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1632 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1633 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1634 pic16_popGet(AOP(result), 0)));
1637 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1638 pic16_popGet(AOP(result), 1)));
1639 for (i=2; i < size; i++) {
1640 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1648 /*-----------------------------------------------------------------------*
1649 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1650 *-----------------------------------------------------------------------*/
1651 void pic16_genUMult16XLit_16 (operand *left,
1655 pCodeOp *pct1, *pct2, *pct3, *pct4;
1662 if (AOP_TYPE(right) != AOP_LIT){
1663 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1667 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1670 same = pic16_sameRegs(AOP(left), AOP(result));
1674 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1675 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1678 // its faster to left shift
1680 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1681 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1685 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1687 pct1 = pic16_popGetTempReg(1);
1688 pct2 = pic16_popGetTempReg(1);
1689 pct3 = pic16_popGetTempReg(1);
1690 pct4 = pic16_popGetTempReg(1);
1692 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1693 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1694 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1695 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1696 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1697 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1699 /* WREG still holds the low literal */
1700 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1701 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1702 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1704 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1705 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1706 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1707 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1710 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1711 pct1, pic16_popGet(AOP(result), 0)));
1712 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1713 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1714 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1715 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1717 pic16_popReleaseTempReg(pct4,1);
1718 pic16_popReleaseTempReg(pct3,1);
1719 pic16_popReleaseTempReg(pct2,1);
1720 pic16_popReleaseTempReg(pct1,1);
1724 // operands different
1727 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1728 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1732 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1733 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1734 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1735 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1739 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1740 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1741 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1742 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1743 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1744 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1746 /* WREG still holds the low literal */
1747 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1748 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1749 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1751 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1752 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1753 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1754 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1762 /*-----------------------------------------------------------------*
1763 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1766 *-----------------------------------------------------------------*/
1767 void pic16_genUMult8X8_8 (operand *left,
1775 if (AOP_TYPE(right) == AOP_LIT) {
1776 pic16_genUMult8XLit_8(left,right,result);
1786 /* if result == right then exchange left and right */
1787 if(pic16_sameRegs(AOP(result), AOP(right))) {
1794 if(AOP_TYPE(left) != AOP_ACC) {
1796 if(AOP_TYPE(right) != AOP_ACC) {
1797 pic16_mov2w(AOP(left), 0);
1798 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1800 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1803 // left is WREG, right cannot be WREG (or can?!)
1804 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1807 /* result is in PRODL:PRODH */
1808 if(AOP_TYPE(result) != AOP_ACC) {
1809 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1810 pic16_popGet(AOP(result), 0)));
1813 if(AOP_SIZE(result)>1) {
1816 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1817 pic16_popGet(AOP(result), 1)));
1819 for(i=2;i<AOP_SIZE(result);i++)
1820 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1823 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1827 /*------------------------------------------------------------------*
1828 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1829 *------------------------------------------------------------------*/
1830 void pic16_genUMult16X16_16 (operand *left,
1835 pCodeOp *pct1, *pct2, *pct3, *pct4;
1840 if (AOP_TYPE(right) == AOP_LIT) {
1841 pic16_genUMult8XLit_8(left,right,result);
1849 /* if result == right then exchange left and right */
1850 if(pic16_sameRegs(AOP(result), AOP(right))) {
1858 if(pic16_sameRegs(AOP(result), AOP(left))) {
1860 pct1 = pic16_popGetTempReg(1);
1861 pct2 = pic16_popGetTempReg(1);
1862 pct3 = pic16_popGetTempReg(1);
1863 pct4 = pic16_popGetTempReg(1);
1865 pic16_mov2w(AOP(left), 0);
1866 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1867 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1868 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1869 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1870 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1872 /* WREG still holds the lower left */
1873 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1874 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1875 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1877 pic16_mov2w(AOP(left), 1);
1878 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1879 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1880 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1883 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1884 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
1885 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
1886 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1887 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1888 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1890 pic16_popReleaseTempReg( pct4, 1 );
1891 pic16_popReleaseTempReg( pct3, 1 );
1892 pic16_popReleaseTempReg( pct2, 1 );
1893 pic16_popReleaseTempReg( pct1, 1 );
1897 pic16_mov2w(AOP(left), 0);
1898 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1899 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1900 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1901 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1902 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1904 /* WREG still holds the lower left */
1905 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1906 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1907 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1909 pic16_mov2w(AOP(left), 1);
1910 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1911 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1912 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1917 void pic16_genSMult16X16_16(operand *left,
1925 /*-----------------------------------------------------------------*
1926 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1928 * this routine will call the unsigned multiply routine and then
1929 * post-fix the sign bit.
1930 *-----------------------------------------------------------------*/
1931 void pic16_genSMult8X8_8 (operand *left,
1934 pCodeOpReg *result_hi)
1936 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1940 result_hi = PCOR(pic16_popGet(AOP(result),1));
1944 pic16_genUMult8X8_8(left,right,result);
1948 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1949 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
1950 pic16_mov2w(AOP(left),0);
1951 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1952 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
1957 /*-----------------------------------------------------------------*
1958 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
1959 *-----------------------------------------------------------------*/
1960 void pic16_genMult8X8_8 (operand *left,
1966 if(AOP_TYPE(right) == AOP_LIT)
1967 pic16_genUMult8XLit_8(left,right,result);
1969 pic16_genUMult8X8_8(left,right,result);
1973 /*-----------------------------------------------------------------*
1974 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
1975 *-----------------------------------------------------------------*/
1976 void pic16_genMult16X16_16 (operand *left,
1982 if (AOP_TYPE(right) == AOP_LIT)
1983 pic16_genUMult16XLit_16(left,right,result);
1985 pic16_genUMult16X16_16(left,right,result);
1991 /*-----------------------------------------------------------------------*
1992 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
1993 *-----------------------------------------------------------------------*/
1994 void pic16_genUMult32XLit_32 (operand *left,
1998 pCodeOp *pct1, *pct2, *pct3, *pct4;
2005 if (AOP_TYPE(right) != AOP_LIT){
2006 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2010 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2013 same = pic16_sameRegs(AOP(left), AOP(result));
2017 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2018 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2021 // its faster to left shift
2023 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2024 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2028 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2030 pct1 = pic16_popGetTempReg(1);
2031 pct2 = pic16_popGetTempReg(1);
2032 pct3 = pic16_popGetTempReg(1);
2033 pct4 = pic16_popGetTempReg(1);
2035 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2036 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2037 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2038 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2039 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2040 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2042 /* WREG still holds the low literal */
2043 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2044 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2045 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2047 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2048 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2049 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2050 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2053 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2054 pct1, pic16_popGet(AOP(result), 0)));
2055 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2056 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2057 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2058 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2060 pic16_popReleaseTempReg( pct4, 1 );
2061 pic16_popReleaseTempReg( pct3, 1 );
2062 pic16_popReleaseTempReg( pct2, 1 );
2063 pic16_popReleaseTempReg( pct1, 1 );
2067 // operands different
2070 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2071 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2075 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2076 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2077 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2078 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2082 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2083 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2084 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2085 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2086 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2087 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2089 /* WREG still holds the low literal */
2090 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2091 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2092 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2094 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2095 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2096 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2097 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2105 /*------------------------------------------------------------------*
2106 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2107 *------------------------------------------------------------------*/
2108 void pic16_genUMult32X32_32 (operand *left,
2113 pCodeOp *pct1, *pct2, *pct3, *pct4;
2117 if (AOP_TYPE(right) == AOP_LIT) {
2118 pic16_genUMult8XLit_8(left,right,result);
2126 /* if result == right then exchange left and right */
2127 if(pic16_sameRegs(AOP(result), AOP(right))) {
2135 if(pic16_sameRegs(AOP(result), AOP(left))) {
2137 pct1 = pic16_popGetTempReg(1);
2138 pct2 = pic16_popGetTempReg(1);
2139 pct3 = pic16_popGetTempReg(1);
2140 pct4 = pic16_popGetTempReg(1);
2142 pic16_mov2w(AOP(left), 0);
2143 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2144 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2145 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2146 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2147 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2149 /* WREG still holds the lower left */
2150 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2151 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2152 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2154 pic16_mov2w(AOP(left), 1);
2155 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2156 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2157 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2160 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2161 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2162 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2163 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2164 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2165 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2167 pic16_popReleaseTempReg( pct4, 1 );
2168 pic16_popReleaseTempReg( pct3, 1 );
2169 pic16_popReleaseTempReg( pct2, 1 );
2170 pic16_popReleaseTempReg( pct1, 1 );
2174 pic16_mov2w(AOP(left), 0);
2175 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2176 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2177 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2178 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2179 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2181 /* WREG still holds the lower left */
2182 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2183 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2184 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2186 pic16_mov2w(AOP(left), 1);
2187 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2188 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2189 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2194 /*-----------------------------------------------------------------*
2195 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2196 *-----------------------------------------------------------------*/
2197 void pic16_genMult32X32_32 (operand *left,
2203 if (AOP_TYPE(right) == AOP_LIT)
2204 pic16_genUMult32XLit_32(left,right,result);
2206 pic16_genUMult32X32_32(left,right,result);
2216 /*-----------------------------------------------------------------*/
2217 /* constMult - generates code for multiplication by a constant */
2218 /*-----------------------------------------------------------------*/
2219 void genMultConst(unsigned C)
2223 unsigned sr3; // Shift right 3
2229 Convert a string of 3 binary 1's in the lit into
2233 mask = 7 << ( (size*8) - 3);
2237 while(mask < (1<<size*8)) {
2239 if( (mask & lit) == lit) {
2242 /* We found 3 (or more) consecutive 1's */
2244 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2246 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2248 lit ^= consecutive_bits;
2252 sr3 |= (consecutive + lsb);