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);
608 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
611 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
613 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
616 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
617 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
621 /* no carry info from previous step */
622 /* this means this is the first time to add */
627 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
631 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
632 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
634 carry_info = 3; /* Were adding only one byte and propogating the carry */
645 lo = BYTEofLONG(lit,0);
650 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
653 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
654 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
657 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
659 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
661 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
671 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
675 if(AOP_TYPE(left) == AOP_ACC) {
676 /* left addend is already in accumulator */
679 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
683 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
684 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
688 /* left addend is in a register */
692 emitMOVWF(result, 0);
695 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
696 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
700 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
701 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
705 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
706 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
707 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
715 /* left is not the accumulator */
717 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
718 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
721 /* We don't know the state of the carry bit at this point */
724 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
731 /* The ls byte of the lit must've been zero - that
732 means we don't have to deal with carry */
734 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
735 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
736 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
741 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
742 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
743 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
747 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
748 mov2w(AOP(left),offset);
749 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
757 /*-----------------------------------------------------------------*/
758 /* pic16_genPlus - generates code for addition */
759 /*-----------------------------------------------------------------*/
760 void pic16_genPlus (iCode *ic)
762 int i, size, offset = 0;
763 operand *result, *left, *right;
767 /* special cases :- */
768 result = IC_RESULT(ic);
770 right = IC_RIGHT(ic);
771 pic16_aopOp (left,ic,FALSE);
772 pic16_aopOp (right,ic,FALSE);
773 pic16_aopOp (result,ic,TRUE);
774 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
775 // pic16_DumpOp("(left)",left);
777 /* if literal, literal on the right or
778 if left requires ACC or right is already
781 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
787 /* if both left & right are in bit space */
788 if (AOP_TYPE(left) == AOP_CRY &&
789 AOP_TYPE(right) == AOP_CRY) {
790 pic16_genPlusBits (ic);
794 /* if left in bit space & right literal */
795 if (AOP_TYPE(left) == AOP_CRY &&
796 AOP_TYPE(right) == AOP_LIT) {
797 /* if result in bit space */
798 if(AOP_TYPE(result) == AOP_CRY){
799 if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
800 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
801 if (!pic16_sameRegs(AOP(left), AOP(result)) )
802 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
803 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
806 size = pic16_getDataSize(result);
808 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
809 pic16_emitcode("addc","a,#00 ;%d",__LINE__);
810 pic16_aopPut(AOP(result),"a",offset++);
816 /* if I can do an increment instead
817 of add then GOOD for ME */
818 if (pic16_genPlusIncr (ic) == TRUE)
821 size = pic16_getDataSize(IC_RESULT(ic));
823 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
824 /* Add a literal to something else */
826 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
830 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
835 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
837 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
838 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
839 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
841 /* here we are adding a bit to a char or int */
843 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
845 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
846 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
848 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
849 AOP(IC_RIGHT(ic))->aopu.aop_dir,
850 AOP(IC_RIGHT(ic))->aopu.aop_dir);
851 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
854 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
855 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
856 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
858 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
859 AOP(IC_RIGHT(ic))->aopu.aop_dir,
860 AOP(IC_RIGHT(ic))->aopu.aop_dir);
861 pic16_emitcode(" xorlw","1");
863 mov2w(AOP(IC_LEFT(ic)),0);
864 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
865 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
867 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
868 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
869 AOP(IC_RIGHT(ic))->aopu.aop_dir,
870 AOP(IC_RIGHT(ic))->aopu.aop_dir);
871 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
874 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
876 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
877 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
878 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
880 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
882 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
883 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
890 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
891 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
893 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
894 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
896 pic16_emitcode("clrz","");
898 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
899 AOP(IC_RIGHT(ic))->aopu.aop_dir,
900 AOP(IC_RIGHT(ic))->aopu.aop_dir);
901 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
904 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
905 mov2w(AOP(IC_LEFT(ic)),0);
906 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
907 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
908 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
909 emitMOVWF(IC_RIGHT(ic),0);
911 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
912 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
913 AOP(IC_RIGHT(ic))->aopu.aop_dir,
914 AOP(IC_RIGHT(ic))->aopu.aop_dir);
915 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
916 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
922 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
923 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
931 // Note: the following is an example of WISC code, eg.
932 // it's supposed to run on a Weird Instruction Set Computer :o)
934 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
936 if ( AOP_TYPE(left) == AOP_ACC) {
937 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
938 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
939 if ( AOP_TYPE(result) != AOP_ACC)
940 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
941 goto release; // we're done, since WREG is 1 byte
945 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
947 size = min( AOP_SIZE(result), AOP_SIZE(right) );
948 size = min( size, AOP_SIZE(left) );
951 if(pic16_debug_verbose) {
952 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
953 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
954 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
959 if ((AOP_TYPE(left) == AOP_PCODE) && (
960 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
961 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
962 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
964 // add to literal operand
967 for(i=0; i<size; i++) {
968 if (AOP_TYPE(right) == AOP_ACC) {
969 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
971 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
972 if(i) { // add with carry
973 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
974 } else { // add without
975 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
978 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
981 DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
983 // add leftover bytes
984 if (SPEC_USIGN(getSpec(operandType(right)))) {
986 for(i=size; i< AOP_SIZE(result); i++) {
987 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
988 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
989 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
993 // right is signed, oh dear ...
994 for(i=size; i< AOP_SIZE(result); i++) {
995 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
996 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
997 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
998 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
999 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1009 for(i=0; i<size; i++) {
1010 if (AOP_TYPE(right) != AOP_ACC)
1011 mov2w(AOP(right),i);
1012 if (pic16_sameRegs(AOP(left), AOP(result)))
1014 if(i) { // add with carry
1015 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1016 } else { // add without
1017 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1019 } else { // not same
1020 if(i) { // add with carry
1021 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1022 } else { // add without
1023 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1025 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1029 // add leftover bytes
1030 if (SPEC_USIGN(getSpec(operandType(right)))) {
1031 // right is unsigned
1032 for(i=size; i< AOP_SIZE(result); i++) {
1033 if (pic16_sameRegs(AOP(left), AOP(result)))
1035 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1036 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1037 } else { // not same
1038 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1039 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1040 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1045 for(i=size; i< AOP_SIZE(result); i++) {
1046 if(size < AOP_SIZE(left)) {
1047 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1048 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1049 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1050 if (pic16_sameRegs(AOP(left), AOP(result)))
1052 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1053 } else { // not same
1054 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1055 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1058 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1059 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1069 // TODO: anything from here to before "release:" is probably obsolete and should be removed
1070 // when the regression tests are stable
1072 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1073 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1074 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1077 /* Need to extend result to higher bytes */
1078 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1080 /* First grab the carry from the lower bytes */
1081 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1082 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1086 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1089 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1090 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1091 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1092 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1094 /* if chars or ints or being signed extended to longs: */
1096 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1097 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1098 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1106 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1108 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1115 //adjustArithmeticResult(ic);
1118 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1119 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1120 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1123 /*-----------------------------------------------------------------*/
1124 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1125 /*-----------------------------------------------------------------*/
1126 bool pic16_genMinusDec (iCode *ic)
1128 unsigned int icount ;
1129 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1132 /* will try to generate an increment */
1133 /* if the right side is not a literal
1135 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1136 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1137 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1140 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1142 /* if the literal value of the right hand side
1143 is greater than 4 then it is not worth it */
1144 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1147 /* if decrement 16 bits in register */
1148 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1153 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1154 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1155 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1156 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1158 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1159 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1160 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1162 /* size is 3 or 4 */
1163 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1164 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1166 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1168 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1170 pic16_emitcode("movlw","0xff");
1171 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1174 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1176 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1180 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1182 pic16_emitcode("skpnc","");
1184 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1193 /* if the sizes are greater than 1 then we cannot */
1194 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1195 AOP_SIZE(IC_LEFT(ic)) > 1 )
1198 /* we can if the aops of the left & result match or
1199 if they are in registers and the registers are the
1201 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1204 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1206 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1211 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1212 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1213 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1216 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1217 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1219 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1220 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1228 /*-----------------------------------------------------------------*/
1229 /* pic16_addSign - propogate sign bit to higher bytes */
1230 /*-----------------------------------------------------------------*/
1231 void pic16_addSign(operand *result, int offset, int sign)
1233 int size = (pic16_getDataSize(result) - offset);
1234 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1237 if(sign && offset) {
1240 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1241 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1242 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1245 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1246 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1247 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1249 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1254 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1258 /*-----------------------------------------------------------------*/
1259 /* pic16_genMinusBits - generates code for subtraction of two bits */
1260 /*-----------------------------------------------------------------*/
1261 void pic16_genMinusBits (iCode *ic)
1263 symbol *lbl = newiTempLabel(NULL);
1266 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1267 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1268 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1269 pic16_emitcode("cpl","c");
1270 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1271 pic16_outBitC(IC_RESULT(ic));
1274 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1275 pic16_emitcode("subb","a,acc");
1276 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1277 pic16_emitcode("inc","a");
1278 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1279 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1280 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1284 /*-----------------------------------------------------------------*/
1285 /* pic16_genMinus - generates code for subtraction */
1286 /*-----------------------------------------------------------------*/
1287 void pic16_genMinus (iCode *ic)
1289 int size, offset = 0, same=0;
1290 unsigned long lit = 0L;
1293 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1294 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1295 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1297 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1298 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1299 operand *t = IC_RIGHT(ic);
1300 IC_RIGHT(ic) = IC_LEFT(ic);
1304 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1305 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1306 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1307 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1309 /* special cases :- */
1310 /* if both left & right are in bit space */
1311 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1312 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1313 pic16_genPlusBits (ic);
1317 /* if I can do an decrement instead
1318 of subtract then GOOD for ME */
1319 // if (pic16_genMinusDec (ic) == TRUE)
1322 size = pic16_getDataSize(IC_RESULT(ic));
1323 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1325 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1326 /* Add a literal to something else */
1328 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1331 genAddLit ( ic, lit);
1334 /* add the first byte: */
1335 pic16_emitcode("movlw","0x%x", lit & 0xff);
1336 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1337 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1338 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1350 if((lit & 0xff) == 0xff) {
1351 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1353 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1355 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1357 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1358 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1362 /* do the rlf known zero trick here */
1363 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1365 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1370 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1373 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1374 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1375 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1377 /* here we are subtracting a bit from a char or int */
1379 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1381 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1382 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1384 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1385 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1386 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1387 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1390 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1391 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1392 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1393 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1394 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1396 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1398 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1399 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1401 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1402 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1405 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1407 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1409 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1410 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1414 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1415 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1416 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1417 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1422 mov2w(AOP(IC_LEFT(ic)),0);
1423 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1424 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1427 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1429 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1432 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1434 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1436 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1443 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1444 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1445 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1447 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1448 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1449 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1450 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1451 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1454 if( (size == 1) && ((lit & 0xff) == 0) ) {
1455 /* res = 0 - right */
1456 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1457 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1459 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1460 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1461 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1466 mov2w(AOP(IC_RIGHT(ic)),0);
1467 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1468 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1476 // here we have x = lit - x for sizeof(x)>1
1477 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1478 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1480 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1481 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1482 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1489 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1490 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1491 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1492 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1494 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1495 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1496 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1497 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1498 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1499 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1502 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1503 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1504 mov2w(AOP(IC_RIGHT(ic)),0);
1506 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1507 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1509 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1510 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1511 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1513 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1515 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1516 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1517 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1519 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1521 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1527 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1529 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1530 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1532 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1533 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1540 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1541 mov2w(AOP(IC_RIGHT(ic)),offset);
1542 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1544 mov2w(AOP(IC_RIGHT(ic)),offset);
1545 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1546 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1554 // adjustArithmeticResult(ic);
1557 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1558 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1559 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1563 /*-----------------------------------------------------------------*
1564 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1567 *-----------------------------------------------------------------*/
1568 void pic16_genUMult8XLit_8 (operand *left,
1574 int size = AOP_SIZE(result);
1578 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1580 if (AOP_TYPE(right) != AOP_LIT){
1581 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1585 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1587 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1588 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1590 same = pic16_sameRegs(AOP(left), AOP(result));
1595 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1599 // its faster to left shift
1600 for (i=1; i < size; i++) {
1601 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1604 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1606 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1610 if(AOP_TYPE(left) != AOP_ACC)
1611 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1612 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1613 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1614 pic16_popGet(AOP(result), 0)));
1616 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1617 pic16_popGet(AOP(result), 1)));
1618 for (i=2; i < size; i++) {
1619 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1625 // operands different
1629 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1633 for (i=1; i < size; i++) {
1634 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1637 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1638 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1640 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1643 if(AOP_TYPE(left) != AOP_ACC)
1644 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1645 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1646 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1647 pic16_popGet(AOP(result), 0)));
1650 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1651 pic16_popGet(AOP(result), 1)));
1652 for (i=2; i < size; i++) {
1653 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1661 /*-----------------------------------------------------------------------*
1662 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1663 *-----------------------------------------------------------------------*/
1664 void pic16_genUMult16XLit_16 (operand *left,
1668 pCodeOp *pct1, *pct2, *pct3, *pct4;
1675 if (AOP_TYPE(right) != AOP_LIT){
1676 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1680 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1683 same = pic16_sameRegs(AOP(left), AOP(result));
1687 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1688 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1691 // its faster to left shift
1693 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1694 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1698 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1700 pct1 = pic16_popGetTempReg(1);
1701 pct2 = pic16_popGetTempReg(1);
1702 pct3 = pic16_popGetTempReg(1);
1703 pct4 = pic16_popGetTempReg(1);
1705 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1706 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1707 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1708 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1709 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1710 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1712 /* WREG still holds the low literal */
1713 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1714 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1715 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1717 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1718 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1719 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1720 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1723 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1724 pct1, pic16_popGet(AOP(result), 0)));
1725 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1726 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1727 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1728 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1730 pic16_popReleaseTempReg(pct4,1);
1731 pic16_popReleaseTempReg(pct3,1);
1732 pic16_popReleaseTempReg(pct2,1);
1733 pic16_popReleaseTempReg(pct1,1);
1737 // operands different
1740 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1741 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1745 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1746 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1747 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1748 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1752 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1753 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1754 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1755 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1756 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1757 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1759 /* WREG still holds the low literal */
1760 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1761 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1762 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1764 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1765 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1766 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1767 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1775 /*-----------------------------------------------------------------*
1776 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1779 *-----------------------------------------------------------------*/
1780 void pic16_genUMult8X8_8 (operand *left,
1788 if (AOP_TYPE(right) == AOP_LIT) {
1789 pic16_genUMult8XLit_8(left,right,result);
1799 /* if result == right then exchange left and right */
1800 if(pic16_sameRegs(AOP(result), AOP(right))) {
1807 if(AOP_TYPE(left) != AOP_ACC) {
1809 if(AOP_TYPE(right) != AOP_ACC) {
1810 mov2w(AOP(left), 0);
1811 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1813 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1816 // left is WREG, right cannot be WREG (or can?!)
1817 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1820 /* result is in PRODL:PRODH */
1821 if(AOP_TYPE(result) != AOP_ACC) {
1822 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1823 pic16_popGet(AOP(result), 0)));
1826 if(AOP_SIZE(result)>1) {
1829 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1830 pic16_popGet(AOP(result), 1)));
1832 for(i=2;i<AOP_SIZE(result);i++)
1833 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1836 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1840 /*------------------------------------------------------------------*
1841 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1842 *------------------------------------------------------------------*/
1843 void pic16_genUMult16X16_16 (operand *left,
1848 pCodeOp *pct1, *pct2, *pct3, *pct4;
1853 if (AOP_TYPE(right) == AOP_LIT) {
1854 pic16_genUMult8XLit_8(left,right,result);
1862 /* if result == right then exchange left and right */
1863 if(pic16_sameRegs(AOP(result), AOP(right))) {
1871 if(pic16_sameRegs(AOP(result), AOP(left))) {
1873 pct1 = pic16_popGetTempReg(1);
1874 pct2 = pic16_popGetTempReg(1);
1875 pct3 = pic16_popGetTempReg(1);
1876 pct4 = pic16_popGetTempReg(1);
1878 mov2w(AOP(left), 0);
1879 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1880 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1881 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1882 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1883 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1885 /* WREG still holds the lower left */
1886 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1887 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1888 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1890 mov2w(AOP(left), 1);
1891 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1892 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1893 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1896 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1897 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
1898 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
1899 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1900 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1901 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1903 pic16_popReleaseTempReg( pct4, 1 );
1904 pic16_popReleaseTempReg( pct3, 1 );
1905 pic16_popReleaseTempReg( pct2, 1 );
1906 pic16_popReleaseTempReg( pct1, 1 );
1910 mov2w(AOP(left), 0);
1911 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1912 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1913 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1914 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1915 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1917 /* WREG still holds the lower left */
1918 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1919 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1920 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1922 mov2w(AOP(left), 1);
1923 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1924 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1925 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1930 void pic16_genSMult16X16_16(operand *left,
1938 /*-----------------------------------------------------------------*
1939 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1941 * this routine will call the unsigned multiply routine and then
1942 * post-fix the sign bit.
1943 *-----------------------------------------------------------------*/
1944 void pic16_genSMult8X8_8 (operand *left,
1947 pCodeOpReg *result_hi)
1949 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1953 result_hi = PCOR(pic16_popGet(AOP(result),1));
1957 pic16_genUMult8X8_8(left,right,result);
1961 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1962 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
1964 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1965 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
1970 /*-----------------------------------------------------------------*
1971 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
1972 *-----------------------------------------------------------------*/
1973 void pic16_genMult8X8_8 (operand *left,
1979 if(AOP_TYPE(right) == AOP_LIT)
1980 pic16_genUMult8XLit_8(left,right,result);
1982 pic16_genUMult8X8_8(left,right,result);
1986 /*-----------------------------------------------------------------*
1987 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
1988 *-----------------------------------------------------------------*/
1989 void pic16_genMult16X16_16 (operand *left,
1995 if (AOP_TYPE(right) == AOP_LIT)
1996 pic16_genUMult16XLit_16(left,right,result);
1998 pic16_genUMult16X16_16(left,right,result);
2004 /*-----------------------------------------------------------------------*
2005 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2006 *-----------------------------------------------------------------------*/
2007 void pic16_genUMult32XLit_32 (operand *left,
2011 pCodeOp *pct1, *pct2, *pct3, *pct4;
2018 if (AOP_TYPE(right) != AOP_LIT){
2019 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2023 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2026 same = pic16_sameRegs(AOP(left), AOP(result));
2030 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2031 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2034 // its faster to left shift
2036 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2037 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2041 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2043 pct1 = pic16_popGetTempReg(1);
2044 pct2 = pic16_popGetTempReg(1);
2045 pct3 = pic16_popGetTempReg(1);
2046 pct4 = pic16_popGetTempReg(1);
2048 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2049 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2050 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2051 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2052 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2053 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2055 /* WREG still holds the low literal */
2056 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2057 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2058 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2060 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2061 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2062 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2063 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2066 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2067 pct1, pic16_popGet(AOP(result), 0)));
2068 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2069 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2070 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2071 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2073 pic16_popReleaseTempReg( pct4, 1 );
2074 pic16_popReleaseTempReg( pct3, 1 );
2075 pic16_popReleaseTempReg( pct2, 1 );
2076 pic16_popReleaseTempReg( pct1, 1 );
2080 // operands different
2083 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2084 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2088 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2089 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2090 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2091 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2095 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2096 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2097 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2098 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2099 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2100 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2102 /* WREG still holds the low literal */
2103 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2104 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2105 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2107 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2108 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2109 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2110 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2118 /*------------------------------------------------------------------*
2119 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2120 *------------------------------------------------------------------*/
2121 void pic16_genUMult32X32_32 (operand *left,
2126 pCodeOp *pct1, *pct2, *pct3, *pct4;
2130 if (AOP_TYPE(right) == AOP_LIT) {
2131 pic16_genUMult8XLit_8(left,right,result);
2139 /* if result == right then exchange left and right */
2140 if(pic16_sameRegs(AOP(result), AOP(right))) {
2148 if(pic16_sameRegs(AOP(result), AOP(left))) {
2150 pct1 = pic16_popGetTempReg(1);
2151 pct2 = pic16_popGetTempReg(1);
2152 pct3 = pic16_popGetTempReg(1);
2153 pct4 = pic16_popGetTempReg(1);
2155 mov2w(AOP(left), 0);
2156 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2157 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2158 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2159 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2160 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2162 /* WREG still holds the lower left */
2163 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2164 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2165 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2167 mov2w(AOP(left), 1);
2168 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2169 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2170 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2173 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2174 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2175 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2176 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2177 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2178 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2180 pic16_popReleaseTempReg( pct4, 1 );
2181 pic16_popReleaseTempReg( pct3, 1 );
2182 pic16_popReleaseTempReg( pct2, 1 );
2183 pic16_popReleaseTempReg( pct1, 1 );
2187 mov2w(AOP(left), 0);
2188 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2189 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2190 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2191 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2192 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2194 /* WREG still holds the lower left */
2195 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2196 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2197 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2199 mov2w(AOP(left), 1);
2200 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2201 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2202 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2207 /*-----------------------------------------------------------------*
2208 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2209 *-----------------------------------------------------------------*/
2210 void pic16_genMult32X32_32 (operand *left,
2216 if (AOP_TYPE(right) == AOP_LIT)
2217 pic16_genUMult32XLit_32(left,right,result);
2219 pic16_genUMult32X32_32(left,right,result);
2229 /*-----------------------------------------------------------------*/
2230 /* constMult - generates code for multiplication by a constant */
2231 /*-----------------------------------------------------------------*/
2232 void genMultConst(unsigned C)
2236 unsigned sr3; // Shift right 3
2242 Convert a string of 3 binary 1's in the lit into
2246 mask = 7 << ( (size*8) - 3);
2250 while(mask < (1<<size*8)) {
2252 if( (mask & lit) == lit) {
2255 /* We found 3 (or more) consecutive 1's */
2257 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2259 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2261 lit ^= consecutive_bits;
2265 sr3 |= (consecutive + lsb);