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"
51 //#define D_POS(txt) DEBUGpic16_emitcode ("; TECODEV::: " txt, " (%s:%d (%s))", __FILE__, __LINE__, __FUNCTION__)
53 #define D_POS(msg) DEBUGpic16_emitcode("; ", msg, "%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__)
56 #define pic16_emitcode DEBUGpic16_emitcode
59 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
60 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
61 void pic16_emitpcomment(char *, ...);
62 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst);
63 const char *pic16_AopType(short type)
66 case AOP_LIT: return "AOP_LIT";
67 case AOP_REG: return "AOP_REG";
68 case AOP_DIR: return "AOP_DIR";
69 case AOP_DPTR: return "AOP_DPTR";
70 case AOP_DPTR2: return "AOP_DPTR2";
71 case AOP_FSR0: return "AOP_FSR0";
72 case AOP_FSR2: return "AOP_FSR2";
73 case AOP_R0: return "AOP_R0";
74 case AOP_R1: return "AOP_R1";
75 case AOP_STK: return "AOP_STK";
76 case AOP_IMMD: return "AOP_IMMD";
77 case AOP_STR: return "AOP_STR";
78 case AOP_CRY: return "AOP_CRY";
79 case AOP_ACC: return "AOP_ACC";
80 case AOP_PCODE: return "AOP_PCODE";
81 case AOP_STA: return "AOP_STA";
87 const char *pic16_pCodeOpType(pCodeOp *pcop)
94 case PO_NONE: return "PO_NONE";
95 case PO_W: return "PO_W";
96 case PO_WREG: return "PO_WREG";
97 case PO_STATUS: return "PO_STATUS";
98 case PO_BSR: return "PO_BSR";
99 case PO_FSR0: return "PO_FSR0";
100 case PO_INDF0: return "PO_INDF0";
101 case PO_INTCON: return "PO_INTCON";
102 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
103 case PO_GPR_BIT: return "PO_GPR_BIT";
104 case PO_GPR_TEMP: return "PO_GPR_TEMP";
105 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
106 case PO_PCL: return "PO_PCL";
107 case PO_PCLATH: return "PO_PCLATH";
108 case PO_PCLATU: return "PO_PCLATU";
109 case PO_PRODL: return "PO_PRODL";
110 case PO_PRODH: return "PO_PRODH";
111 case PO_LITERAL: return "PO_LITERAL";
112 case PO_REL_ADDR: return "PO_REL_ADDR";
113 case PO_IMMEDIATE: return "PO_IMMEDIATE";
114 case PO_DIR: return "PO_DIR";
115 case PO_CRY: return "PO_CRY";
116 case PO_BIT: return "PO_BIT";
117 case PO_STR: return "PO_STR";
118 case PO_LABEL: return "PO_LABEL";
119 case PO_WILD: return "PO_WILD";
123 return "BAD PO_TYPE";
126 const char *pic16_pCodeOpSubType(pCodeOp *pcop)
129 if(pcop && (pcop->type == PO_GPR_BIT)) {
131 switch(PCORB(pcop)->subtype) {
133 case PO_NONE: return "PO_NONE";
134 case PO_W: return "PO_W";
135 case PO_WREG: return "PO_WREG";
136 case PO_STATUS: return "PO_STATUS";
137 case PO_BSR: return "PO_BSR";
138 case PO_FSR0: return "PO_FSR0";
139 case PO_INDF0: return "PO_INDF0";
140 case PO_INTCON: return "PO_INTCON";
141 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
142 case PO_GPR_BIT: return "PO_GPR_BIT";
143 case PO_GPR_TEMP: return "PO_GPR_TEMP";
144 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
145 case PO_PCL: return "PO_PCL";
146 case PO_PCLATH: return "PO_PCLATH";
147 case PO_PCLATU: return "PO_PCLATU";
148 case PO_PRODL: return "PO_PRODL";
149 case PO_PRODH: return "PO_PRODH";
150 case PO_LITERAL: return "PO_LITERAL";
151 case PO_REL_ADDR: return "PO_REL_ADDR";
152 case PO_IMMEDIATE: return "PO_IMMEDIATE";
153 case PO_DIR: return "PO_DIR";
154 case PO_CRY: return "PO_CRY";
155 case PO_BIT: return "PO_BIT";
156 case PO_STR: return "PO_STR";
157 case PO_LABEL: return "PO_LABEL";
158 case PO_WILD: return "PO_WILD";
162 return "BAD PO_TYPE";
165 /*-----------------------------------------------------------------*/
166 /* pic16_genPlusIncr :- does addition with increment if possible */
167 /*-----------------------------------------------------------------*/
168 bool pic16_genPlusIncr (iCode *ic)
170 unsigned int icount ;
171 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
173 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
174 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
175 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
176 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
177 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
179 /* will try to generate an increment */
180 /* if the right side is not a literal
182 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
185 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
186 /* if the literal value of the right hand side
187 is greater than 2 then it is faster to add */
188 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
191 /* if increment 16 bits in register */
192 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
197 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
198 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
202 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
203 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
209 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
210 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
211 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
212 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
214 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
215 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
216 AOP(IC_RESULT(ic))->aopu.aop_dir,
217 AOP(IC_RESULT(ic))->aopu.aop_dir);
219 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
220 //pic16_emitcode("xorlw","1");
222 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
223 //pic16_emitcode("andlw","1");
226 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
227 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
228 AOP(IC_RESULT(ic))->aopu.aop_dir,
229 AOP(IC_RESULT(ic))->aopu.aop_dir);
235 /* if the sizes are greater than 1 then we cannot */
236 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
237 AOP_SIZE(IC_LEFT(ic)) > 1 )
240 /* If we are incrementing the same register by two: */
242 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
245 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
246 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
251 DEBUGpic16_emitcode ("; ","couldn't increment ");
256 /*-----------------------------------------------------------------*/
257 /* pic16_outBitAcc - output a bit in acc */
258 /*-----------------------------------------------------------------*/
259 void pic16_outBitAcc(operand *result)
261 symbol *tlbl = newiTempLabel(NULL);
262 /* if the result is a bit */
263 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
265 assert(0); // not implemented for PIC16?
267 if (AOP_TYPE(result) == AOP_CRY){
268 pic16_aopPut(AOP(result),"a",0);
271 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
272 pic16_emitcode("mov","a,#01");
273 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
274 pic16_outAcc(result);
278 /*-----------------------------------------------------------------*/
279 /* pic16_genPlusBits - generates code for addition of two bits */
280 /*-----------------------------------------------------------------*/
281 void pic16_genPlusBits (iCode *ic)
284 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
286 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
287 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
288 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
289 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
291 The following block of code will add two bits.
292 Note that it'll even work if the destination is
293 the carry (C in the status register).
294 It won't work if the 'Z' bit is a source or destination.
297 /* If the result is stored in the accumulator (w) */
298 //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
299 switch(AOP_TYPE(IC_RESULT(ic))) {
301 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
302 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
303 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
304 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
305 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
307 pic16_emitcode("clrw","");
308 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
309 AOP(IC_RIGHT(ic))->aopu.aop_dir,
310 AOP(IC_RIGHT(ic))->aopu.aop_dir);
311 pic16_emitcode("xorlw","1");
312 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
313 AOP(IC_LEFT(ic))->aopu.aop_dir,
314 AOP(IC_LEFT(ic))->aopu.aop_dir);
315 pic16_emitcode("xorlw","1");
318 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
319 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
320 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
321 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
322 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
323 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
326 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
327 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
328 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
329 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
330 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
331 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
333 pic16_emitcode("movlw","(1 << (%s & 7))",
334 AOP(IC_RESULT(ic))->aopu.aop_dir,
335 AOP(IC_RESULT(ic))->aopu.aop_dir);
336 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
337 AOP(IC_RESULT(ic))->aopu.aop_dir,
338 AOP(IC_RESULT(ic))->aopu.aop_dir);
339 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
340 AOP(IC_RIGHT(ic))->aopu.aop_dir,
341 AOP(IC_RIGHT(ic))->aopu.aop_dir);
342 pic16_emitcode("xorwf","(%s >>3),f",
343 AOP(IC_RESULT(ic))->aopu.aop_dir);
344 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
345 AOP(IC_LEFT(ic))->aopu.aop_dir,
346 AOP(IC_LEFT(ic))->aopu.aop_dir);
347 pic16_emitcode("xorwf","(%s>>3),f",
348 AOP(IC_RESULT(ic))->aopu.aop_dir);
355 /* This is the original version of this code.
357 * This is being kept around for reference,
358 * because I am not entirely sure I got it right...
360 static void adjustArithmeticResult(iCode *ic)
362 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
363 AOP_SIZE(IC_LEFT(ic)) == 3 &&
364 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
365 pic16_aopPut(AOP(IC_RESULT(ic)),
366 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
369 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
370 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
371 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
372 pic16_aopPut(AOP(IC_RESULT(ic)),
373 pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
376 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
377 AOP_SIZE(IC_LEFT(ic)) < 3 &&
378 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
379 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
380 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
382 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
383 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
387 /* This is the pure and virtuous version of this code.
388 * I'm pretty certain it's right, but not enough to toss the old
391 static void adjustArithmeticResult(iCode *ic)
393 if (opIsGptr(IC_RESULT(ic)) &&
394 opIsGptr(IC_LEFT(ic)) &&
395 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
397 pic16_aopPut(AOP(IC_RESULT(ic)),
398 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
402 if (opIsGptr(IC_RESULT(ic)) &&
403 opIsGptr(IC_RIGHT(ic)) &&
404 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
406 pic16_aopPut(AOP(IC_RESULT(ic)),
407 pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
411 if (opIsGptr(IC_RESULT(ic)) &&
412 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
413 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
414 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
415 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
417 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
418 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
423 /*-----------------------------------------------------------------*/
424 /* genAddlit - generates code for addition */
425 /*-----------------------------------------------------------------*/
426 static void genAddLit2byte (operand *result, int offr, int lit)
433 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
436 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
439 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
440 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
445 static void emitMOVWF(operand *reg, int offset)
450 if (AOP_TYPE(reg) == AOP_ACC) {
451 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
455 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
459 static void genAddLit (iCode *ic, int lit)
468 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
472 result = IC_RESULT(ic);
473 same = pic16_sameRegs(AOP(left), AOP(result));
474 size = pic16_getDataSize(result);
478 /* Handle special cases first */
480 genAddLit2byte (result, 0, lit);
483 int hi = 0xff & (lit >> 8);
490 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
495 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
497 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
500 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
501 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
502 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
506 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
507 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
509 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
517 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
520 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
523 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
524 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
526 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
528 case 0xff: /* 0x01ff */
529 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
530 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
531 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
532 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
534 default: /* 0x01LL */
535 D_POS("FIXED: added default case for adding 0x01??");
536 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
537 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
539 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
540 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
545 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
549 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
552 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
553 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
555 /* case 0xff: * 0xffff *
556 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
557 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
558 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
562 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
563 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
565 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
572 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
577 genAddLit2byte (result, MSB16, hi);
580 D_POS(">>> IMPROVED");
581 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
582 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
583 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
584 D_POS("<<< IMPROVED");
586 /* case 0xff: * 0xHHff *
587 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
588 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
589 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
590 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
592 */ default: /* 0xHHLL */
593 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
594 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
595 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
596 D_POS(">>> IMPROVED");
597 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
598 D_POS("<<< IMPROVED");
607 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
610 lo = BYTEofLONG(lit,0);
615 D_POS(">>> IMPROVED and compacted");
617 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
618 D_POS("<<< IMPROVED and compacted");
621 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
622 D_POS(">>> Changed from SKPZ/SKPC to always SKPC");
624 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
627 D_POS(">>> IMPROVED and compacted");
628 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
629 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
630 D_POS("<<< IMPROVED and compacted");
634 /* no carry info from previous step */
635 /* this means this is the first time to add */
640 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
644 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
645 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
647 carry_info = 3; /* Were adding only one byte and propogating the carry */
658 lo = BYTEofLONG(lit,0);
663 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
666 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
667 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
670 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
672 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
674 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
684 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
688 if(AOP_TYPE(left) == AOP_ACC) {
689 /* left addend is already in accumulator */
692 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
696 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
697 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
701 /* left addend is in a register */
704 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
705 emitMOVWF(result, 0);
706 D_POS(">>> REMOVED double assignment");
709 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
710 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
714 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
715 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
719 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
720 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
721 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
729 /* left is not the accumulator */
731 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
732 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
734 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
735 /* We don't know the state of the carry bit at this point */
738 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
745 /* The ls byte of the lit must've been zero - that
746 means we don't have to deal with carry */
748 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
749 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
750 D_POS(">>> FIXED from left to result");
751 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
752 D_POS("<<< FIXED from left to result");
758 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
759 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
760 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
765 D_POS(">>> IMPROVED");
766 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
767 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
768 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
769 D_POS("<<< IMPROVED");
777 /*-----------------------------------------------------------------*/
778 /* pic16_genPlus - generates code for addition */
779 /*-----------------------------------------------------------------*/
780 void pic16_genPlus (iCode *ic)
782 int i, size, offset = 0;
783 operand *result, *left, *right;
785 /* special cases :- */
786 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
789 result = IC_RESULT(ic);
791 right = IC_RIGHT(ic);
792 pic16_aopOp (left,ic,FALSE);
793 pic16_aopOp (right,ic,FALSE);
794 pic16_aopOp (result,ic,TRUE);
795 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
796 // pic16_DumpOp("(left)",left);
798 /* if literal, literal on the right or
799 if left requires ACC or right is already
802 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
808 /* if both left & right are in bit space */
809 if (AOP_TYPE(left) == AOP_CRY &&
810 AOP_TYPE(right) == AOP_CRY) {
811 pic16_genPlusBits (ic);
815 /* if left in bit space & right literal */
816 if (AOP_TYPE(left) == AOP_CRY &&
817 AOP_TYPE(right) == AOP_LIT) {
818 /* if result in bit space */
819 if(AOP_TYPE(result) == AOP_CRY){
820 if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
821 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
822 if (!pic16_sameRegs(AOP(left), AOP(result)) )
823 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
824 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
827 size = pic16_getDataSize(result);
829 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
830 pic16_emitcode("addc","a,#00 ;%d",__LINE__);
831 pic16_aopPut(AOP(result),"a",offset++);
837 /* if I can do an increment instead
838 of add then GOOD for ME */
839 if (pic16_genPlusIncr (ic) == TRUE)
842 size = pic16_getDataSize(IC_RESULT(ic));
844 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
845 /* Add a literal to something else */
847 unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
851 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
856 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
858 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
859 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
860 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
862 /* here we are adding a bit to a char or int */
864 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
866 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
867 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
869 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
870 AOP(IC_RIGHT(ic))->aopu.aop_dir,
871 AOP(IC_RIGHT(ic))->aopu.aop_dir);
872 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
875 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
876 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
877 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
879 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
880 AOP(IC_RIGHT(ic))->aopu.aop_dir,
881 AOP(IC_RIGHT(ic))->aopu.aop_dir);
882 pic16_emitcode(" xorlw","1");
884 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
885 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
886 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
888 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
889 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
890 AOP(IC_RIGHT(ic))->aopu.aop_dir,
891 AOP(IC_RIGHT(ic))->aopu.aop_dir);
892 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
895 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
897 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
898 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
899 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
901 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
903 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
904 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
911 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
912 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
914 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
915 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
917 pic16_emitcode("clrz","");
919 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
920 AOP(IC_RIGHT(ic))->aopu.aop_dir,
921 AOP(IC_RIGHT(ic))->aopu.aop_dir);
922 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
925 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
926 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
927 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
928 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
929 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
930 emitMOVWF(IC_RIGHT(ic),0);
932 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
933 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
934 AOP(IC_RIGHT(ic))->aopu.aop_dir,
935 AOP(IC_RIGHT(ic))->aopu.aop_dir);
936 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
937 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
943 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
944 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
952 // Note: the following is an example of WISC code, eg.
953 // it's supposed to run on a Weird Instruction Set Computer :o)
955 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
957 if ( AOP_TYPE(left) == AOP_ACC) {
958 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
959 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
960 if ( AOP_TYPE(result) != AOP_ACC)
961 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
962 goto release; // we're done, since WREG is 1 byte
966 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
968 size = min( AOP_SIZE(result), AOP_SIZE(right) );
969 size = min( size, AOP_SIZE(left) );
972 if(pic16_debug_verbose) {
973 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
974 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
975 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
980 if ((AOP_TYPE(left) == AOP_PCODE) && (
981 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
982 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
983 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
985 // add to literal operand
988 for(i=0; i<size; i++) {
989 if (AOP_TYPE(right) == AOP_ACC) {
990 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
992 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
993 if(i) { // add with carry
994 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
995 } else { // add without
996 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
999 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1002 // add leftover bytes
1003 if (SPEC_USIGN(getSpec(operandType(right)))) {
1004 // right is unsigned
1005 for(i=size; i< AOP_SIZE(result); i++) {
1006 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1007 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1008 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1012 // right is signed, oh dear ...
1013 for(i=size; i< AOP_SIZE(result); i++) {
1014 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1015 D_POS(">>> FIXED sign test from result to right");
1016 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1017 D_POS("<<< FIXED sign test from result to right");
1018 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
1019 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1020 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1030 for(i=0; i<size; i++) {
1031 if (AOP_TYPE(right) != AOP_ACC)
1032 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),i));
1033 if (pic16_sameRegs(AOP(left), AOP(result)))
1035 if(i) { // add with carry
1036 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1037 } else { // add without
1038 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1040 } else { // not same
1041 if(i) { // add with carry
1042 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1043 } else { // add without
1044 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1046 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1050 // add leftover bytes
1051 if (SPEC_USIGN(getSpec(operandType(right)))) {
1052 // right is unsigned
1053 for(i=size; i< AOP_SIZE(result); i++) {
1054 if (pic16_sameRegs(AOP(left), AOP(result)))
1056 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1057 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1058 } else { // not same
1059 D_POS (">>> FIXED added to uninitialized result");
1060 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1061 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1062 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1063 D_POS ("<<< FIXED");
1068 for(i=size; i< AOP_SIZE(result); i++) {
1069 if(size < AOP_SIZE(left)) {
1070 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1071 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1072 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1073 if (pic16_sameRegs(AOP(left), AOP(result)))
1075 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1076 } else { // not same
1077 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1078 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1081 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1082 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1092 // TODO: anything from here to before "release:" is probably obsolete and should be removed
1093 // when the regression tests are stable
1095 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1096 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1097 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1100 /* Need to extend result to higher bytes */
1101 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1103 /* First grab the carry from the lower bytes */
1104 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1105 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1109 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1112 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1113 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1114 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1115 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1117 /* if chars or ints or being signed extended to longs: */
1119 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1120 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1121 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1129 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1131 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1138 //adjustArithmeticResult(ic);
1141 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1142 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1143 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1146 /*-----------------------------------------------------------------*/
1147 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1148 /*-----------------------------------------------------------------*/
1149 bool pic16_genMinusDec (iCode *ic)
1151 unsigned int icount ;
1152 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1154 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1155 /* will try to generate an increment */
1156 /* if the right side is not a literal
1158 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1159 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1160 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1163 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1165 /* if the literal value of the right hand side
1166 is greater than 4 then it is not worth it */
1167 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1170 /* if decrement 16 bits in register */
1171 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1176 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1177 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1178 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1179 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1181 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1182 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1183 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1185 /* size is 3 or 4 */
1186 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1187 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1189 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1191 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1193 pic16_emitcode("movlw","0xff");
1194 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1197 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1199 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1203 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1205 pic16_emitcode("skpnc","");
1207 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1216 /* if the sizes are greater than 1 then we cannot */
1217 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1218 AOP_SIZE(IC_LEFT(ic)) > 1 )
1221 /* we can if the aops of the left & result match or
1222 if they are in registers and the registers are the
1224 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1227 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1229 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1234 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1235 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1236 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1239 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1240 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1242 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1243 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1251 /*-----------------------------------------------------------------*/
1252 /* pic16_addSign - propogate sign bit to higher bytes */
1253 /*-----------------------------------------------------------------*/
1254 void pic16_addSign(operand *result, int offset, int sign)
1256 int size = (pic16_getDataSize(result) - offset);
1257 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1260 if(sign && offset) {
1263 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1264 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1265 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1268 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1269 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1270 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1272 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1277 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1281 /*-----------------------------------------------------------------*/
1282 /* pic16_genMinusBits - generates code for subtraction of two bits */
1283 /*-----------------------------------------------------------------*/
1284 void pic16_genMinusBits (iCode *ic)
1286 symbol *lbl = newiTempLabel(NULL);
1287 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1288 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1289 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1290 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1291 pic16_emitcode("cpl","c");
1292 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1293 pic16_outBitC(IC_RESULT(ic));
1296 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1297 pic16_emitcode("subb","a,acc");
1298 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1299 pic16_emitcode("inc","a");
1300 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1301 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1302 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1306 /*-----------------------------------------------------------------*/
1307 /* pic16_genMinus - generates code for subtraction */
1308 /*-----------------------------------------------------------------*/
1309 void pic16_genMinus (iCode *ic)
1311 int size, offset = 0, same=0;
1312 unsigned long lit = 0L;
1314 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1315 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1316 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1317 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1319 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1320 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1321 operand *t = IC_RIGHT(ic);
1322 IC_RIGHT(ic) = IC_LEFT(ic);
1326 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1327 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1328 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1329 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1331 /* special cases :- */
1332 /* if both left & right are in bit space */
1333 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1334 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1335 pic16_genPlusBits (ic);
1339 /* if I can do an decrement instead
1340 of subtract then GOOD for ME */
1341 // if (pic16_genMinusDec (ic) == TRUE)
1344 size = pic16_getDataSize(IC_RESULT(ic));
1345 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1347 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1348 /* Add a literal to something else */
1350 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1353 genAddLit ( ic, lit);
1356 /* add the first byte: */
1357 pic16_emitcode("movlw","0x%x", lit & 0xff);
1358 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1359 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1360 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1372 if((lit & 0xff) == 0xff) {
1373 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1375 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1377 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1379 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1380 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1384 /* do the rlf known zero trick here */
1385 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1387 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1392 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1395 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1396 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1397 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1399 /* here we are subtracting a bit from a char or int */
1401 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1403 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1404 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1406 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1407 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1408 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1409 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1412 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1413 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1414 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1415 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1416 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1418 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1420 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1421 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1423 D_POS(">>> FIXED from MOVLW right(=result) to MOVLW left(=literal,left&1==1)");
1424 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1425 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1428 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1430 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1432 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1433 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1437 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1438 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1439 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1440 D_POS(">>> IMPROVED removed following assignment W-->result");
1441 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1446 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1447 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1448 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1451 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1453 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1456 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1458 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1460 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1467 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1468 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1469 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1471 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1472 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1473 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1474 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1475 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1478 if( (size == 1) && ((lit & 0xff) == 0) ) {
1479 /* res = 0 - right */
1480 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1481 D_POS(">>> IMPROVED changed comf,incf to negf");
1482 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1483 D_POS("<<< IMPROVED changed comf,incf to negf");
1485 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1486 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1487 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1492 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1493 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1494 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1501 D_POS(">>> FIXED and compacted");
1503 // here we have x = lit - x for sizeof(x)>1
1504 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1505 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1507 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1508 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1509 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1511 D_POS("<<< FIXED and compacted");
1517 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1518 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1519 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1520 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1522 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1523 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1524 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1525 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1526 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1527 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1530 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1531 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1532 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1534 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1535 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1537 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1538 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1539 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1541 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1543 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1544 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1545 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1547 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1549 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1555 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1557 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1558 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1560 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1561 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1568 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1569 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1570 D_POS(">>> IMPROVED by replacing emitSKPC, incfszw by subwfb");
1571 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1572 D_POS("<<< IMPROVED by replacing emitSKPC, incfszw by subwfb");
1574 D_POS(">>> FIXED for same regs right and result");
1575 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1576 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1577 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1585 // adjustArithmeticResult(ic);
1588 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1589 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1590 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1594 /*-----------------------------------------------------------------*
1595 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1598 *-----------------------------------------------------------------*/
1599 void pic16_genUMult8XLit_8 (operand *left,
1607 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1608 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1610 if (AOP_TYPE(right) != AOP_LIT){
1611 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1615 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1617 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1618 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1620 same = pic16_sameRegs(AOP(left), AOP(result));
1624 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1627 // its faster to left shift
1629 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1633 if(AOP_TYPE(left) != AOP_ACC)
1634 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1635 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1636 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1637 pic16_popGet(AOP(result), 0)));
1641 // operands different
1644 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1648 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1649 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1652 if(AOP_TYPE(left) != AOP_ACC)
1653 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1654 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1655 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1656 pic16_popGet(AOP(result), 0)));
1662 /*-----------------------------------------------------------------------*
1663 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1664 *-----------------------------------------------------------------------*/
1665 void pic16_genUMult16XLit_16 (operand *left,
1669 pCodeOp *pct1, *pct2, *pct3, *pct4;
1674 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1676 if (AOP_TYPE(right) != AOP_LIT){
1677 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1681 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1684 same = pic16_sameRegs(AOP(left), AOP(result));
1688 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1689 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1692 // its faster to left shift
1694 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1695 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1699 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1701 pct1 = pic16_popGetTempReg(1);
1702 pct2 = pic16_popGetTempReg(1);
1703 pct3 = pic16_popGetTempReg(1);
1704 pct4 = pic16_popGetTempReg(1);
1706 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1707 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1708 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1709 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1710 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1711 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1713 /* WREG still holds the low literal */
1714 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1715 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1716 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1718 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1719 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1720 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1721 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1724 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1725 pct1, pic16_popGet(AOP(result), 0)));
1726 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1727 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1728 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1729 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1731 pic16_popReleaseTempReg(pct4,1);
1732 pic16_popReleaseTempReg(pct3,1);
1733 pic16_popReleaseTempReg(pct2,1);
1734 pic16_popReleaseTempReg(pct1,1);
1738 // operands different
1741 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1742 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1746 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1747 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1748 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1749 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1753 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1754 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1755 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1756 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1757 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1758 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1760 /* WREG still holds the low literal */
1761 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1762 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1763 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1765 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1766 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1767 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1768 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1776 /*-----------------------------------------------------------------*
1777 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1780 *-----------------------------------------------------------------*/
1781 void pic16_genUMult8X8_8 (operand *left,
1786 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1789 if (AOP_TYPE(right) == AOP_LIT) {
1790 pic16_genUMult8XLit_8(left,right,result);
1800 /* if result == right then exchange left and right */
1801 if(pic16_sameRegs(AOP(result), AOP(right))) {
1808 if(AOP_TYPE(left) != AOP_ACC) {
1810 if(AOP_TYPE(right) != AOP_ACC) {
1811 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1812 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1814 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1817 // left is WREG, right cannot be WREG (or can?!)
1818 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1821 /* result is in PRODL:PRODH */
1822 if(AOP_TYPE(result) != AOP_ACC) {
1823 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1824 pic16_popGet(AOP(result), 0)));
1827 if(AOP_SIZE(result)>1) {
1830 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1831 pic16_popGet(AOP(result), 1)));
1833 for(i=2;i<AOP_SIZE(result);i++)
1834 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1837 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1841 /*------------------------------------------------------------------*
1842 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1843 *------------------------------------------------------------------*/
1844 void pic16_genUMult16X16_16 (operand *left,
1849 pCodeOp *pct1, *pct2, *pct3, *pct4;
1851 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1854 if (AOP_TYPE(right) == AOP_LIT) {
1855 pic16_genUMult8XLit_8(left,right,result);
1863 /* if result == right then exchange left and right */
1864 if(pic16_sameRegs(AOP(result), AOP(right))) {
1872 if(pic16_sameRegs(AOP(result), AOP(left))) {
1874 pct1 = pic16_popGetTempReg(1);
1875 pct2 = pic16_popGetTempReg(1);
1876 pct3 = pic16_popGetTempReg(1);
1877 pct4 = pic16_popGetTempReg(1);
1879 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1880 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1881 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1882 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1883 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1884 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1886 /* WREG still holds the lower left */
1887 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1888 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1889 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1891 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1892 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1893 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1894 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1897 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1898 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
1899 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
1900 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1901 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1902 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1904 pic16_popReleaseTempReg( pct4, 1 );
1905 pic16_popReleaseTempReg( pct3, 1 );
1906 pic16_popReleaseTempReg( pct2, 1 );
1907 pic16_popReleaseTempReg( pct1, 1 );
1911 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1912 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1913 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1914 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1915 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1916 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1918 /* WREG still holds the lower left */
1919 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1920 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1921 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1923 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1924 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1925 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1926 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1931 void pic16_genSMult16X16_16(operand *left,
1939 /*-----------------------------------------------------------------*
1940 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1942 * this routine will call the unsigned multiply routine and then
1943 * post-fix the sign bit.
1944 *-----------------------------------------------------------------*/
1945 void pic16_genSMult8X8_8 (operand *left,
1948 pCodeOpReg *result_hi)
1950 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1954 result_hi = PCOR(pic16_popGet(AOP(result),1));
1958 pic16_genUMult8X8_8(left,right,result);
1962 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1963 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
1964 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1965 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1966 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
1971 /*-----------------------------------------------------------------*
1972 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
1973 *-----------------------------------------------------------------*/
1974 void pic16_genMult8X8_8 (operand *left,
1978 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1980 if(AOP_TYPE(right) == AOP_LIT)
1981 pic16_genUMult8XLit_8(left,right,result);
1983 pic16_genUMult8X8_8(left,right,result);
1987 /*-----------------------------------------------------------------*
1988 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
1989 *-----------------------------------------------------------------*/
1990 void pic16_genMult16X16_16 (operand *left,
1994 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1996 if (AOP_TYPE(right) == AOP_LIT)
1997 pic16_genUMult16XLit_16(left,right,result);
1999 pic16_genUMult16X16_16(left,right,result);
2006 /*-----------------------------------------------------------------------*
2007 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2008 *-----------------------------------------------------------------------*/
2009 void pic16_genUMult32XLit_32 (operand *left,
2013 pCodeOp *pct1, *pct2, *pct3, *pct4;
2018 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2020 if (AOP_TYPE(right) != AOP_LIT){
2021 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2025 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2028 same = pic16_sameRegs(AOP(left), AOP(result));
2032 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2033 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2036 // its faster to left shift
2038 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2039 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2043 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2045 pct1 = pic16_popGetTempReg(1);
2046 pct2 = pic16_popGetTempReg(1);
2047 pct3 = pic16_popGetTempReg(1);
2048 pct4 = pic16_popGetTempReg(1);
2050 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2051 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2052 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2053 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2054 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2055 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2057 /* WREG still holds the low literal */
2058 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2059 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2060 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2062 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2063 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2064 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2065 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2068 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2069 pct1, pic16_popGet(AOP(result), 0)));
2070 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2071 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2072 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2073 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2075 pic16_popReleaseTempReg( pct4, 1 );
2076 pic16_popReleaseTempReg( pct3, 1 );
2077 pic16_popReleaseTempReg( pct2, 1 );
2078 pic16_popReleaseTempReg( pct1, 1 );
2082 // operands different
2085 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2086 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2090 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2091 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2092 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2093 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2097 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2098 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2099 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2100 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2101 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2102 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2104 /* WREG still holds the low literal */
2105 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2106 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2107 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2109 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2110 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2111 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2112 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2120 /*------------------------------------------------------------------*
2121 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2122 *------------------------------------------------------------------*/
2123 void pic16_genUMult32X32_32 (operand *left,
2128 pCodeOp *pct1, *pct2, *pct3, *pct4;
2130 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2133 if (AOP_TYPE(right) == AOP_LIT) {
2134 pic16_genUMult8XLit_8(left,right,result);
2142 /* if result == right then exchange left and right */
2143 if(pic16_sameRegs(AOP(result), AOP(right))) {
2151 if(pic16_sameRegs(AOP(result), AOP(left))) {
2153 pct1 = pic16_popGetTempReg(1);
2154 pct2 = pic16_popGetTempReg(1);
2155 pct3 = pic16_popGetTempReg(1);
2156 pct4 = pic16_popGetTempReg(1);
2158 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2159 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2160 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2161 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2162 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2163 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2165 /* WREG still holds the lower left */
2166 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2167 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2168 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2170 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2171 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2172 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2173 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2176 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2177 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2178 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2179 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2180 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2181 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2183 pic16_popReleaseTempReg( pct4, 1 );
2184 pic16_popReleaseTempReg( pct3, 1 );
2185 pic16_popReleaseTempReg( pct2, 1 );
2186 pic16_popReleaseTempReg( pct1, 1 );
2190 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2191 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2192 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2193 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2194 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2195 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2197 /* WREG still holds the lower left */
2198 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2199 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2200 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2202 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2203 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2204 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2205 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2210 /*-----------------------------------------------------------------*
2211 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2212 *-----------------------------------------------------------------*/
2213 void pic16_genMult32X32_32 (operand *left,
2217 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2219 if (AOP_TYPE(right) == AOP_LIT)
2220 pic16_genUMult32XLit_32(left,right,result);
2222 pic16_genUMult32X32_32(left,right,result);
2233 /*-----------------------------------------------------------------*/
2234 /* constMult - generates code for multiplication by a constant */
2235 /*-----------------------------------------------------------------*/
2236 void genMultConst(unsigned C)
2240 unsigned sr3; // Shift right 3
2246 Convert a string of 3 binary 1's in the lit into
2250 mask = 7 << ( (size*8) - 3);
2254 while(mask < (1<<size*8)) {
2256 if( (mask & lit) == lit) {
2259 /* We found 3 (or more) consecutive 1's */
2261 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2263 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2265 lit ^= consecutive_bits;
2269 sr3 |= (consecutive + lsb);