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));
175 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
176 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
177 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
178 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
180 /* will try to generate an increment */
181 /* if the right side is not a literal
183 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
186 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
187 /* if the literal value of the right hand side
188 is greater than 2 then it is faster to add */
189 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
192 /* if increment 16 bits in register */
193 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
198 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
199 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
203 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
204 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
210 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
211 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
212 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
213 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
215 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
216 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
217 AOP(IC_RESULT(ic))->aopu.aop_dir,
218 AOP(IC_RESULT(ic))->aopu.aop_dir);
220 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
221 //pic16_emitcode("xorlw","1");
223 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
224 //pic16_emitcode("andlw","1");
227 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
228 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
229 AOP(IC_RESULT(ic))->aopu.aop_dir,
230 AOP(IC_RESULT(ic))->aopu.aop_dir);
236 /* if the sizes are greater than 1 then we cannot */
237 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
238 AOP_SIZE(IC_LEFT(ic)) > 1 )
241 /* If we are incrementing the same register by two: */
243 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
246 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
247 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
252 DEBUGpic16_emitcode ("; ","couldn't increment ");
257 /*-----------------------------------------------------------------*/
258 /* pic16_outBitAcc - output a bit in acc */
259 /*-----------------------------------------------------------------*/
260 void pic16_outBitAcc(operand *result)
262 symbol *tlbl = newiTempLabel(NULL);
263 /* if the result is a bit */
264 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
266 assert(0); // not implemented for PIC16?
268 if (AOP_TYPE(result) == AOP_CRY){
269 pic16_aopPut(AOP(result),"a",0);
272 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
273 pic16_emitcode("mov","a,#01");
274 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
275 pic16_outAcc(result);
279 /*-----------------------------------------------------------------*/
280 /* pic16_genPlusBits - generates code for addition of two bits */
281 /*-----------------------------------------------------------------*/
282 void pic16_genPlusBits (iCode *ic)
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)
434 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
437 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
440 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
441 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
446 static void emitMOVWF(operand *reg, int offset)
451 if (AOP_TYPE(reg) == AOP_ACC) {
452 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
456 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
460 static void genAddLit (iCode *ic, int lit)
473 result = IC_RESULT(ic);
474 same = pic16_sameRegs(AOP(left), AOP(result));
475 size = pic16_getDataSize(result);
479 /* Handle special cases first */
481 genAddLit2byte (result, 0, lit);
484 int hi = 0xff & (lit >> 8);
491 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
496 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
498 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
501 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
502 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
503 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
507 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
508 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
510 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
518 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
521 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
524 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
525 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
527 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
529 case 0xff: /* 0x01ff */
530 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
531 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
532 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
533 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
535 default: /* 0x01LL */
536 D_POS("FIXED: added default case for adding 0x01??");
537 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
538 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
540 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
541 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
546 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
550 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
553 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
554 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
556 /* case 0xff: * 0xffff *
557 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
558 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
559 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
563 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
564 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
566 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
573 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
578 genAddLit2byte (result, MSB16, hi);
581 D_POS(">>> IMPROVED");
582 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
583 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
584 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
585 D_POS("<<< IMPROVED");
587 /* case 0xff: * 0xHHff *
588 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
589 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
590 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
591 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
593 */ default: /* 0xHHLL */
594 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
595 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
596 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
597 D_POS(">>> IMPROVED");
598 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
599 D_POS("<<< IMPROVED");
608 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
611 lo = BYTEofLONG(lit,0);
616 D_POS(">>> IMPROVED and compacted 0");
618 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
619 D_POS("<<< IMPROVED and compacted");
622 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
623 D_POS(">>> Changed from SKPZ/SKPC to always SKPC");
625 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
628 D_POS(">>> IMPROVED and compacted - default");
629 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
630 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
631 D_POS("<<< IMPROVED and compacted");
635 /* no carry info from previous step */
636 /* this means this is the first time to add */
641 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
645 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
646 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
648 carry_info = 3; /* Were adding only one byte and propogating the carry */
659 lo = BYTEofLONG(lit,0);
664 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
667 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
668 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
671 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
673 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
675 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
685 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
689 if(AOP_TYPE(left) == AOP_ACC) {
690 /* left addend is already in accumulator */
693 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
697 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
698 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
702 /* left addend is in a register */
705 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
706 emitMOVWF(result, 0);
707 D_POS(">>> REMOVED double assignment");
710 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
711 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
715 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
716 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
720 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
721 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
722 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
730 /* left is not the accumulator */
732 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
733 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
735 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
736 /* We don't know the state of the carry bit at this point */
739 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
746 /* The ls byte of the lit must've been zero - that
747 means we don't have to deal with carry */
749 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
750 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
751 D_POS(">>> FIXED from left to result");
752 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
753 D_POS("<<< FIXED from left to result");
759 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
760 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
761 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
766 D_POS(">>> IMPROVED");
767 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
768 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
769 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
770 D_POS("<<< IMPROVED");
778 /*-----------------------------------------------------------------*/
779 /* pic16_genPlus - generates code for addition */
780 /*-----------------------------------------------------------------*/
781 void pic16_genPlus (iCode *ic)
783 int i, size, offset = 0;
784 operand *result, *left, *right;
788 /* special cases :- */
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 DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
1004 // add leftover bytes
1005 if (SPEC_USIGN(getSpec(operandType(right)))) {
1006 // right is unsigned
1007 for(i=size; i< AOP_SIZE(result); i++) {
1008 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1009 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1010 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1014 // right is signed, oh dear ...
1015 for(i=size; i< AOP_SIZE(result); i++) {
1016 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1017 D_POS(">>> FIXED sign test from result to right");
1018 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1019 D_POS("<<< FIXED sign test from result to right");
1020 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
1021 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1022 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1032 for(i=0; i<size; i++) {
1033 if (AOP_TYPE(right) != AOP_ACC)
1034 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),i));
1035 if (pic16_sameRegs(AOP(left), AOP(result)))
1037 if(i) { // add with carry
1038 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1039 } else { // add without
1040 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1042 } else { // not same
1043 if(i) { // add with carry
1044 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1045 } else { // add without
1046 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1048 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1052 // add leftover bytes
1053 if (SPEC_USIGN(getSpec(operandType(right)))) {
1054 // right is unsigned
1055 for(i=size; i< AOP_SIZE(result); i++) {
1056 if (pic16_sameRegs(AOP(left), AOP(result)))
1058 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1059 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1060 } else { // not same
1061 D_POS (">>> FIXED added to uninitialized result");
1062 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1063 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1064 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1065 D_POS ("<<< FIXED");
1070 for(i=size; i< AOP_SIZE(result); i++) {
1071 if(size < AOP_SIZE(left)) {
1072 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1073 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1074 pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg));
1075 if (pic16_sameRegs(AOP(left), AOP(result)))
1077 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1078 } else { // not same
1079 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1080 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1083 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1084 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i));
1094 // TODO: anything from here to before "release:" is probably obsolete and should be removed
1095 // when the regression tests are stable
1097 if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
1098 int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
1099 SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
1102 /* Need to extend result to higher bytes */
1103 size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
1105 /* First grab the carry from the lower bytes */
1106 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1107 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1111 /* Now this is really horrid. Gotta check the sign of the addends and propogate
1114 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1115 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1116 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1117 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1119 /* if chars or ints or being signed extended to longs: */
1121 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1122 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1123 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1131 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1133 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1140 //adjustArithmeticResult(ic);
1143 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1144 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1145 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1148 /*-----------------------------------------------------------------*/
1149 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1150 /*-----------------------------------------------------------------*/
1151 bool pic16_genMinusDec (iCode *ic)
1153 unsigned int icount ;
1154 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1157 /* will try to generate an increment */
1158 /* if the right side is not a literal
1160 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1161 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1162 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1165 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1167 /* if the literal value of the right hand side
1168 is greater than 4 then it is not worth it */
1169 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1172 /* if decrement 16 bits in register */
1173 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1178 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1179 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1180 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1181 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1183 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1184 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1185 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1187 /* size is 3 or 4 */
1188 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1189 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1191 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1193 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1195 pic16_emitcode("movlw","0xff");
1196 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1199 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1201 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1205 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1207 pic16_emitcode("skpnc","");
1209 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1218 /* if the sizes are greater than 1 then we cannot */
1219 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1220 AOP_SIZE(IC_LEFT(ic)) > 1 )
1223 /* we can if the aops of the left & result match or
1224 if they are in registers and the registers are the
1226 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1229 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1231 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1236 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1237 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1238 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1241 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1242 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1244 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1245 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1253 /*-----------------------------------------------------------------*/
1254 /* pic16_addSign - propogate sign bit to higher bytes */
1255 /*-----------------------------------------------------------------*/
1256 void pic16_addSign(operand *result, int offset, int sign)
1258 int size = (pic16_getDataSize(result) - offset);
1259 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1262 if(sign && offset) {
1265 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1266 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1267 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
1270 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1271 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1272 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1274 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1279 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1283 /*-----------------------------------------------------------------*/
1284 /* pic16_genMinusBits - generates code for subtraction of two bits */
1285 /*-----------------------------------------------------------------*/
1286 void pic16_genMinusBits (iCode *ic)
1288 symbol *lbl = newiTempLabel(NULL);
1291 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1292 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1293 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1294 pic16_emitcode("cpl","c");
1295 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1296 pic16_outBitC(IC_RESULT(ic));
1299 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1300 pic16_emitcode("subb","a,acc");
1301 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1302 pic16_emitcode("inc","a");
1303 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1304 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1305 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1309 /*-----------------------------------------------------------------*/
1310 /* pic16_genMinus - generates code for subtraction */
1311 /*-----------------------------------------------------------------*/
1312 void pic16_genMinus (iCode *ic)
1314 int size, offset = 0, same=0;
1315 unsigned long lit = 0L;
1318 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1319 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1320 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1322 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1323 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1324 operand *t = IC_RIGHT(ic);
1325 IC_RIGHT(ic) = IC_LEFT(ic);
1329 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1330 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1331 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1332 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1334 /* special cases :- */
1335 /* if both left & right are in bit space */
1336 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1337 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1338 pic16_genPlusBits (ic);
1342 /* if I can do an decrement instead
1343 of subtract then GOOD for ME */
1344 // if (pic16_genMinusDec (ic) == TRUE)
1347 size = pic16_getDataSize(IC_RESULT(ic));
1348 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1350 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1351 /* Add a literal to something else */
1353 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1356 genAddLit ( ic, lit);
1359 /* add the first byte: */
1360 pic16_emitcode("movlw","0x%x", lit & 0xff);
1361 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1362 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1363 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1375 if((lit & 0xff) == 0xff) {
1376 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1378 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1380 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1382 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1383 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1387 /* do the rlf known zero trick here */
1388 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1390 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1395 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1398 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1399 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1400 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1402 /* here we are subtracting a bit from a char or int */
1404 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1406 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1407 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1409 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1410 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1411 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1412 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1415 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1416 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1417 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1418 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1419 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1421 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1423 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1424 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1426 D_POS(">>> FIXED from MOVLW right(=result) to MOVLW left(=literal,left&1==1)");
1427 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1428 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1431 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1433 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1435 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1436 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1440 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1441 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1442 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1443 D_POS(">>> IMPROVED removed following assignment W-->result");
1444 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1449 pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1450 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1451 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1454 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1456 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1459 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1461 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1463 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1470 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1471 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1472 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1474 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1475 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1476 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1477 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1478 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1481 if( (size == 1) && ((lit & 0xff) == 0) ) {
1482 /* res = 0 - right */
1483 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1484 D_POS(">>> IMPROVED changed comf,incf to negf");
1485 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1486 D_POS("<<< IMPROVED changed comf,incf to negf");
1488 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1489 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1490 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1495 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1496 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1497 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1504 D_POS(">>> FIXED and compacted");
1506 // here we have x = lit - x for sizeof(x)>1
1507 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1508 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1510 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1511 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1512 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1514 D_POS("<<< FIXED and compacted");
1520 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1521 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1522 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1523 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1525 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1526 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1527 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1528 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1529 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1530 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1533 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1534 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1535 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
1537 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1538 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1540 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1541 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1542 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1544 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1546 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1547 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1548 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1550 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1552 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1558 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1560 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1561 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1563 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1564 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1571 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1572 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1573 D_POS(">>> IMPROVED by replacing emitSKPC, incfszw by subwfb");
1574 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1575 D_POS("<<< IMPROVED by replacing emitSKPC, incfszw by subwfb");
1577 D_POS(">>> FIXED for same regs right and result");
1578 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1579 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1580 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1588 // adjustArithmeticResult(ic);
1591 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1592 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1593 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1597 /*-----------------------------------------------------------------*
1598 * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
1601 *-----------------------------------------------------------------*/
1602 void pic16_genUMult8XLit_8 (operand *left,
1608 int size = AOP_SIZE(result);
1612 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1614 if (AOP_TYPE(right) != AOP_LIT){
1615 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1619 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1621 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1622 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1624 same = pic16_sameRegs(AOP(left), AOP(result));
1629 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1633 // its faster to left shift
1634 for (i=1; i < size; i++) {
1635 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1638 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1640 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1644 if(AOP_TYPE(left) != AOP_ACC)
1645 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1646 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1647 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1648 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));
1659 // operands different
1663 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1667 for (i=1; i < size; i++) {
1668 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1671 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1672 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1674 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1677 if(AOP_TYPE(left) != AOP_ACC)
1678 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1679 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1680 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1681 pic16_popGet(AOP(result), 0)));
1684 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1685 pic16_popGet(AOP(result), 1)));
1686 for (i=2; i < size; i++) {
1687 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1695 /*-----------------------------------------------------------------------*
1696 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1697 *-----------------------------------------------------------------------*/
1698 void pic16_genUMult16XLit_16 (operand *left,
1702 pCodeOp *pct1, *pct2, *pct3, *pct4;
1709 if (AOP_TYPE(right) != AOP_LIT){
1710 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1714 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
1717 same = pic16_sameRegs(AOP(left), AOP(result));
1721 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1722 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1725 // its faster to left shift
1727 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1728 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
1732 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1734 pct1 = pic16_popGetTempReg(1);
1735 pct2 = pic16_popGetTempReg(1);
1736 pct3 = pic16_popGetTempReg(1);
1737 pct4 = pic16_popGetTempReg(1);
1739 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1740 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1741 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1742 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1743 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1744 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1746 /* WREG still holds the low literal */
1747 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1748 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1749 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1751 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1752 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1753 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1754 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1757 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1758 pct1, pic16_popGet(AOP(result), 0)));
1759 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
1760 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1761 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1762 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1764 pic16_popReleaseTempReg(pct4,1);
1765 pic16_popReleaseTempReg(pct3,1);
1766 pic16_popReleaseTempReg(pct2,1);
1767 pic16_popReleaseTempReg(pct1,1);
1771 // operands different
1774 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
1775 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
1779 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1780 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1781 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
1782 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1786 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
1787 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1788 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1789 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1790 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1791 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1793 /* WREG still holds the low literal */
1794 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
1795 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1796 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1798 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
1799 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1800 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1801 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1809 /*-----------------------------------------------------------------*
1810 * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
1813 *-----------------------------------------------------------------*/
1814 void pic16_genUMult8X8_8 (operand *left,
1822 if (AOP_TYPE(right) == AOP_LIT) {
1823 pic16_genUMult8XLit_8(left,right,result);
1833 /* if result == right then exchange left and right */
1834 if(pic16_sameRegs(AOP(result), AOP(right))) {
1841 if(AOP_TYPE(left) != AOP_ACC) {
1843 if(AOP_TYPE(right) != AOP_ACC) {
1844 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1845 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1847 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
1850 // left is WREG, right cannot be WREG (or can?!)
1851 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
1854 /* result is in PRODL:PRODH */
1855 if(AOP_TYPE(result) != AOP_ACC) {
1856 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
1857 pic16_popGet(AOP(result), 0)));
1860 if(AOP_SIZE(result)>1) {
1863 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh),
1864 pic16_popGet(AOP(result), 1)));
1866 for(i=2;i<AOP_SIZE(result);i++)
1867 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
1870 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1874 /*------------------------------------------------------------------*
1875 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
1876 *------------------------------------------------------------------*/
1877 void pic16_genUMult16X16_16 (operand *left,
1882 pCodeOp *pct1, *pct2, *pct3, *pct4;
1887 if (AOP_TYPE(right) == AOP_LIT) {
1888 pic16_genUMult8XLit_8(left,right,result);
1896 /* if result == right then exchange left and right */
1897 if(pic16_sameRegs(AOP(result), AOP(right))) {
1905 if(pic16_sameRegs(AOP(result), AOP(left))) {
1907 pct1 = pic16_popGetTempReg(1);
1908 pct2 = pic16_popGetTempReg(1);
1909 pct3 = pic16_popGetTempReg(1);
1910 pct4 = pic16_popGetTempReg(1);
1912 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1913 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1914 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1915 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
1916 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1917 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
1919 /* WREG still holds the lower left */
1920 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1921 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1922 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
1924 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1925 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1926 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1927 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
1930 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1931 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
1932 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
1933 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
1934 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
1935 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
1937 pic16_popReleaseTempReg( pct4, 1 );
1938 pic16_popReleaseTempReg( pct3, 1 );
1939 pic16_popReleaseTempReg( pct2, 1 );
1940 pic16_popReleaseTempReg( pct1, 1 );
1944 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1945 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1946 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1947 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1948 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1949 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1951 /* WREG still holds the lower left */
1952 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
1953 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1954 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
1956 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
1957 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
1958 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
1959 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
1964 void pic16_genSMult16X16_16(operand *left,
1972 /*-----------------------------------------------------------------*
1973 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
1975 * this routine will call the unsigned multiply routine and then
1976 * post-fix the sign bit.
1977 *-----------------------------------------------------------------*/
1978 void pic16_genSMult8X8_8 (operand *left,
1981 pCodeOpReg *result_hi)
1983 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1987 result_hi = PCOR(pic16_popGet(AOP(result),1));
1991 pic16_genUMult8X8_8(left,right,result);
1995 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1996 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
1997 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
1998 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1999 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2004 /*-----------------------------------------------------------------*
2005 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
2006 *-----------------------------------------------------------------*/
2007 void pic16_genMult8X8_8 (operand *left,
2013 if(AOP_TYPE(right) == AOP_LIT)
2014 pic16_genUMult8XLit_8(left,right,result);
2016 pic16_genUMult8X8_8(left,right,result);
2020 /*-----------------------------------------------------------------*
2021 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
2022 *-----------------------------------------------------------------*/
2023 void pic16_genMult16X16_16 (operand *left,
2029 if (AOP_TYPE(right) == AOP_LIT)
2030 pic16_genUMult16XLit_16(left,right,result);
2032 pic16_genUMult16X16_16(left,right,result);
2038 /*-----------------------------------------------------------------------*
2039 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2040 *-----------------------------------------------------------------------*/
2041 void pic16_genUMult32XLit_32 (operand *left,
2045 pCodeOp *pct1, *pct2, *pct3, *pct4;
2052 if (AOP_TYPE(right) != AOP_LIT){
2053 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2057 lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
2060 same = pic16_sameRegs(AOP(left), AOP(result));
2064 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2065 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2068 // its faster to left shift
2070 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2071 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2075 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2077 pct1 = pic16_popGetTempReg(1);
2078 pct2 = pic16_popGetTempReg(1);
2079 pct3 = pic16_popGetTempReg(1);
2080 pct4 = pic16_popGetTempReg(1);
2082 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2083 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2084 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2085 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2086 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2087 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2089 /* WREG still holds the low literal */
2090 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2091 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2092 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2094 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2095 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2096 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2097 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2100 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2101 pct1, pic16_popGet(AOP(result), 0)));
2102 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2103 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2104 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2105 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2107 pic16_popReleaseTempReg( pct4, 1 );
2108 pic16_popReleaseTempReg( pct3, 1 );
2109 pic16_popReleaseTempReg( pct2, 1 );
2110 pic16_popReleaseTempReg( pct1, 1 );
2114 // operands different
2117 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2118 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2122 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2123 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2124 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2125 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2129 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2130 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2131 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2132 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2133 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2134 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2136 /* WREG still holds the low literal */
2137 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2138 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2139 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2141 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2142 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2143 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2144 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2152 /*------------------------------------------------------------------*
2153 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2154 *------------------------------------------------------------------*/
2155 void pic16_genUMult32X32_32 (operand *left,
2160 pCodeOp *pct1, *pct2, *pct3, *pct4;
2164 if (AOP_TYPE(right) == AOP_LIT) {
2165 pic16_genUMult8XLit_8(left,right,result);
2173 /* if result == right then exchange left and right */
2174 if(pic16_sameRegs(AOP(result), AOP(right))) {
2182 if(pic16_sameRegs(AOP(result), AOP(left))) {
2184 pct1 = pic16_popGetTempReg(1);
2185 pct2 = pic16_popGetTempReg(1);
2186 pct3 = pic16_popGetTempReg(1);
2187 pct4 = pic16_popGetTempReg(1);
2189 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2190 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2191 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2192 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2193 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2194 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2196 /* WREG still holds the lower left */
2197 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2198 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2199 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2201 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2202 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2203 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2204 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2207 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2208 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2209 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2210 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2211 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2212 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2214 pic16_popReleaseTempReg( pct4, 1 );
2215 pic16_popReleaseTempReg( pct3, 1 );
2216 pic16_popReleaseTempReg( pct2, 1 );
2217 pic16_popReleaseTempReg( pct1, 1 );
2221 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
2222 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2223 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2224 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2225 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2226 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2228 /* WREG still holds the lower left */
2229 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2230 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2231 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2233 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
2234 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2235 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2236 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2241 /*-----------------------------------------------------------------*
2242 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2243 *-----------------------------------------------------------------*/
2244 void pic16_genMult32X32_32 (operand *left,
2250 if (AOP_TYPE(right) == AOP_LIT)
2251 pic16_genUMult32XLit_32(left,right,result);
2253 pic16_genUMult32X32_32(left,right,result);
2263 /*-----------------------------------------------------------------*/
2264 /* constMult - generates code for multiplication by a constant */
2265 /*-----------------------------------------------------------------*/
2266 void genMultConst(unsigned C)
2270 unsigned sr3; // Shift right 3
2276 Convert a string of 3 binary 1's in the lit into
2280 mask = 7 << ( (size*8) - 3);
2284 while(mask < (1<<size*8)) {
2286 if( (mask & lit) == lit) {
2289 /* We found 3 (or more) consecutive 1's */
2291 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2293 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2295 lit ^= consecutive_bits;
2299 sr3 |= (consecutive + lsb);