1 /*-------------------------------------------------------------------------
3 genarith.c - source file for code generation - arithmetic
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 and - Jean-Louis VERN.jlvern@writeme.com (1999)
7 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
8 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2, or (at your option) any
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 In other words, you are welcome to use, share and improve this program.
26 You are forbidden to forbid anyone else to use, share and improve
27 what you give them. Help stamp out software-hoarding!
30 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
31 Made everything static
32 -------------------------------------------------------------------------*/
38 #include "SDCCglobl.h"
41 #if defined(_MSC_VER) && (_MSC_VER < 1300)
42 #define __FUNCTION__ __FILE__
46 #include "SDCCpeeph.h"
52 #define pic16_emitcode DEBUGpic16_emitcode
55 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
56 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
57 void pic16_emitpcomment(char *, ...);
58 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst);
59 const char *pic16_AopType(short type)
62 case AOP_LIT: return "AOP_LIT";
63 case AOP_REG: return "AOP_REG";
64 case AOP_DIR: return "AOP_DIR";
65 case AOP_DPTR: return "AOP_DPTR";
66 case AOP_DPTR2: return "AOP_DPTR2";
67 case AOP_FSR0: return "AOP_FSR0";
68 case AOP_FSR2: return "AOP_FSR2";
69 case AOP_R0: return "AOP_R0";
70 case AOP_R1: return "AOP_R1";
71 case AOP_STK: return "AOP_STK";
72 case AOP_IMMD: return "AOP_IMMD";
73 case AOP_STR: return "AOP_STR";
74 case AOP_CRY: return "AOP_CRY";
75 case AOP_ACC: return "AOP_ACC";
76 case AOP_PCODE: return "AOP_PCODE";
77 case AOP_STA: return "AOP_STA";
83 const char *pic16_pCodeOpType(pCodeOp *pcop)
90 case PO_NONE: return "PO_NONE";
91 case PO_W: return "PO_W";
92 case PO_WREG: return "PO_WREG";
93 case PO_STATUS: return "PO_STATUS";
94 case PO_BSR: return "PO_BSR";
95 case PO_FSR0: return "PO_FSR0";
96 case PO_INDF0: return "PO_INDF0";
97 case PO_INTCON: return "PO_INTCON";
98 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
99 case PO_GPR_BIT: return "PO_GPR_BIT";
100 case PO_GPR_TEMP: return "PO_GPR_TEMP";
101 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
102 case PO_PCL: return "PO_PCL";
103 case PO_PCLATH: return "PO_PCLATH";
104 case PO_PCLATU: return "PO_PCLATU";
105 case PO_PRODL: return "PO_PRODL";
106 case PO_PRODH: return "PO_PRODH";
107 case PO_LITERAL: return "PO_LITERAL";
108 case PO_REL_ADDR: return "PO_REL_ADDR";
109 case PO_IMMEDIATE: return "PO_IMMEDIATE";
110 case PO_DIR: return "PO_DIR";
111 case PO_CRY: return "PO_CRY";
112 case PO_BIT: return "PO_BIT";
113 case PO_STR: return "PO_STR";
114 case PO_LABEL: return "PO_LABEL";
115 case PO_WILD: return "PO_WILD";
119 return "BAD PO_TYPE";
122 const char *pic16_pCodeOpSubType(pCodeOp *pcop)
125 if(pcop && (pcop->type == PO_GPR_BIT)) {
127 switch(PCORB(pcop)->subtype) {
129 case PO_NONE: return "PO_NONE";
130 case PO_W: return "PO_W";
131 case PO_WREG: return "PO_WREG";
132 case PO_STATUS: return "PO_STATUS";
133 case PO_BSR: return "PO_BSR";
134 case PO_FSR0: return "PO_FSR0";
135 case PO_INDF0: return "PO_INDF0";
136 case PO_INTCON: return "PO_INTCON";
137 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
138 case PO_GPR_BIT: return "PO_GPR_BIT";
139 case PO_GPR_TEMP: return "PO_GPR_TEMP";
140 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
141 case PO_PCL: return "PO_PCL";
142 case PO_PCLATH: return "PO_PCLATH";
143 case PO_PCLATU: return "PO_PCLATU";
144 case PO_PRODL: return "PO_PRODL";
145 case PO_PRODH: return "PO_PRODH";
146 case PO_LITERAL: return "PO_LITERAL";
147 case PO_REL_ADDR: return "PO_REL_ADDR";
148 case PO_IMMEDIATE: return "PO_IMMEDIATE";
149 case PO_DIR: return "PO_DIR";
150 case PO_CRY: return "PO_CRY";
151 case PO_BIT: return "PO_BIT";
152 case PO_STR: return "PO_STR";
153 case PO_LABEL: return "PO_LABEL";
154 case PO_WILD: return "PO_WILD";
158 return "BAD PO_TYPE";
161 /*-----------------------------------------------------------------*/
162 /* pic16_genPlusIncr :- does addition with increment if possible */
163 /*-----------------------------------------------------------------*/
164 bool pic16_genPlusIncr (iCode *ic)
166 unsigned int icount ;
167 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
171 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
172 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
173 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
174 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
176 /* will try to generate an increment */
177 /* if the right side is not a literal
179 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
182 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
183 /* if the literal value of the right hand side
184 is greater than 2 then it is faster to add */
185 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
188 /* if increment 16 bits in register */
189 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
194 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
195 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
199 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
200 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
206 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
207 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
208 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
209 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
211 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
212 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
213 AOP(IC_RESULT(ic))->aopu.aop_dir,
214 AOP(IC_RESULT(ic))->aopu.aop_dir);
216 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
217 //pic16_emitcode("xorlw","1");
219 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
220 //pic16_emitcode("andlw","1");
223 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
224 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
225 AOP(IC_RESULT(ic))->aopu.aop_dir,
226 AOP(IC_RESULT(ic))->aopu.aop_dir);
232 /* if the sizes are greater than 1 then we cannot */
233 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
234 AOP_SIZE(IC_LEFT(ic)) > 1 )
237 /* If we are incrementing the same register by two: */
239 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
242 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
243 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
248 DEBUGpic16_emitcode ("; ","couldn't increment ");
253 /*-----------------------------------------------------------------*/
254 /* pic16_outBitAcc - output a bit in acc */
255 /*-----------------------------------------------------------------*/
256 void pic16_outBitAcc(operand *result)
258 symbol *tlbl = newiTempLabel(NULL);
259 /* if the result is a bit */
260 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
262 assert(0); // not implemented for PIC16?
264 if (AOP_TYPE(result) == AOP_CRY){
265 pic16_aopPut(AOP(result),"a",0);
268 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
269 pic16_emitcode("mov","a,#01");
270 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
271 pic16_outAcc(result);
275 /*-----------------------------------------------------------------*/
276 /* pic16_genPlusBits - generates code for addition of two bits */
277 /*-----------------------------------------------------------------*/
278 void pic16_genPlusBits (iCode *ic)
282 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
283 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
284 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
285 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
287 The following block of code will add two bits.
288 Note that it'll even work if the destination is
289 the carry (C in the status register).
290 It won't work if the 'Z' bit is a source or destination.
293 /* If the result is stored in the accumulator (w) */
294 //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
295 switch(AOP_TYPE(IC_RESULT(ic))) {
297 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
298 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
299 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
300 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
301 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
303 pic16_emitcode("clrw","");
304 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
305 AOP(IC_RIGHT(ic))->aopu.aop_dir,
306 AOP(IC_RIGHT(ic))->aopu.aop_dir);
307 pic16_emitcode("xorlw","1");
308 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
309 AOP(IC_LEFT(ic))->aopu.aop_dir,
310 AOP(IC_LEFT(ic))->aopu.aop_dir);
311 pic16_emitcode("xorlw","1");
314 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
315 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
316 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
317 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
318 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
319 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
322 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
323 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
324 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
325 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
326 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
327 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
329 pic16_emitcode("movlw","(1 << (%s & 7))",
330 AOP(IC_RESULT(ic))->aopu.aop_dir,
331 AOP(IC_RESULT(ic))->aopu.aop_dir);
332 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
333 AOP(IC_RESULT(ic))->aopu.aop_dir,
334 AOP(IC_RESULT(ic))->aopu.aop_dir);
335 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
336 AOP(IC_RIGHT(ic))->aopu.aop_dir,
337 AOP(IC_RIGHT(ic))->aopu.aop_dir);
338 pic16_emitcode("xorwf","(%s >>3),f",
339 AOP(IC_RESULT(ic))->aopu.aop_dir);
340 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
341 AOP(IC_LEFT(ic))->aopu.aop_dir,
342 AOP(IC_LEFT(ic))->aopu.aop_dir);
343 pic16_emitcode("xorwf","(%s>>3),f",
344 AOP(IC_RESULT(ic))->aopu.aop_dir);
351 /* This is the original version of this code.
353 * This is being kept around for reference,
354 * because I am not entirely sure I got it right...
356 static void adjustArithmeticResult(iCode *ic)
358 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
359 AOP_SIZE(IC_LEFT(ic)) == 3 &&
360 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
361 pic16_aopPut(AOP(IC_RESULT(ic)),
362 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
365 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
366 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
367 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
368 pic16_aopPut(AOP(IC_RESULT(ic)),
369 pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
372 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
373 AOP_SIZE(IC_LEFT(ic)) < 3 &&
374 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
375 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
376 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
378 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
379 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
383 /* This is the pure and virtuous version of this code.
384 * I'm pretty certain it's right, but not enough to toss the old
387 static void adjustArithmeticResult(iCode *ic)
389 if (opIsGptr(IC_RESULT(ic)) &&
390 opIsGptr(IC_LEFT(ic)) &&
391 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
393 pic16_aopPut(AOP(IC_RESULT(ic)),
394 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
398 if (opIsGptr(IC_RESULT(ic)) &&
399 opIsGptr(IC_RIGHT(ic)) &&
400 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
402 pic16_aopPut(AOP(IC_RESULT(ic)),
403 pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
407 if (opIsGptr(IC_RESULT(ic)) &&
408 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
409 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
410 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
411 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
413 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
414 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
420 /*-----------------------------------------------------------------*/
421 /* genAddlit - generates code for addition */
422 /*-----------------------------------------------------------------*/
423 static void genAddLit2byte (operand *result, int offr, int lit)
431 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
434 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
437 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
438 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
444 static void emitMOVWF(operand *reg, int offset)
449 if (AOP_TYPE(reg) == AOP_ACC) {
450 DEBUGpic16_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
454 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(reg),offset));
458 static void genAddLit (iCode *ic, int lit)
472 lleft = operandType (left);
473 result = IC_RESULT(ic);
474 same = pic16_sameRegs(AOP(left), AOP(result));
475 size = pic16_getDataSize(result);
476 sizeL = pic16_getDataSize(left);
479 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
480 /* move left to result -- possibly sign extend */
481 for (i=0; i < MIN(size, sizeL); i++) {
482 pic16_mov2f (AOP(result), AOP(left), i);
486 /* extend to result size */
487 if (IS_UNSIGNED(lleft)) {
489 for (i = sizeL; i < size; i++) {
490 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
494 if (size == sizeL + 1) {
495 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), sizeL));
496 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
497 pic16_emitpcode (POC_SETF, pic16_popGet (AOP(result), sizeL));
499 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
500 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7));
501 pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
503 for (i=sizeL; i < size; i++) {
504 pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(result), i));
512 } else if (lit == 1) {
518 pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(result), 0));
522 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), 0));
523 for (i=1; i < size-1; i++) {
524 emitSKPNC; /* a jump here saves up to 2(size-2)cycles */
525 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), i));
531 pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1));
535 /* add literal to result */
536 for (i=0; i < size; i++) {
537 pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit));
538 llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */
539 pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC,
540 pic16_popGet (AOP(result), i));
548 /* Handle special cases first */
550 genAddLit2byte (result, 0, lit);
553 int hi = 0xff & (lit >> 8);
560 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
565 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
567 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
570 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
571 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
572 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
576 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
577 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
579 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
587 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
590 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
593 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
594 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
596 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
598 case 0xff: /* 0x01ff */
599 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
600 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
601 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
602 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
604 default: /* 0x01LL */
605 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
606 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
608 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
609 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
614 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
618 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
621 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
622 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
624 /* case 0xff: * 0xffff *
625 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
626 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
627 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
631 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
632 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
634 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
641 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
646 genAddLit2byte (result, MSB16, hi);
649 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
650 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
651 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
653 /* case 0xff: * 0xHHff *
654 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
655 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
656 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
657 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
659 */ default: /* 0xHHLL */
660 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
661 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
662 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
663 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
672 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
675 lo = BYTEofLONG(lit,0);
678 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
679 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
681 /* no carry info from previous step */
682 /* this means this is the first time to add */
687 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
691 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
692 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
694 carry_info = 3; /* Were adding only one byte and propogating the carry */
705 lo = BYTEofLONG(lit,0);
710 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
713 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
714 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
717 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
719 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
721 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
731 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
735 if(AOP_TYPE(left) == AOP_ACC) {
736 /* left addend is already in accumulator */
739 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
743 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
744 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
748 /* left addend is in a register */
751 pic16_mov2w(AOP(left),0);
752 emitMOVWF(result, 0);
755 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
756 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
760 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
761 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
765 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
766 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
767 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
775 /* left is not the accumulator */
777 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
778 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
780 pic16_mov2w(AOP(left),0);
781 /* We don't know the state of the carry bit at this point */
784 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
791 /* The ls byte of the lit must've been zero - that
792 means we don't have to deal with carry */
794 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
795 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
796 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
801 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
802 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
803 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
807 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
808 pic16_mov2w(AOP(left),offset);
809 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
818 /*-----------------------------------------------------------------*/
819 /* pic16_genPlus - generates code for addition */
820 /*-----------------------------------------------------------------*/
821 void pic16_genPlus (iCode *ic)
823 int i, size, offset = 0;
824 operand *result, *left, *right;
828 /* special cases :- */
829 result = IC_RESULT(ic);
831 right = IC_RIGHT(ic);
832 pic16_aopOp (left,ic,FALSE);
833 pic16_aopOp (right,ic,FALSE);
834 pic16_aopOp (result,ic,TRUE);
835 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
836 // pic16_DumpOp("(left)",left);
838 /* if literal, literal on the right or
839 if left requires ACC or right is already
842 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
844 right = IC_RIGHT(ic) = left;
845 left = IC_LEFT(ic) = t;
848 /* if both left & right are in bit space */
849 if (AOP_TYPE(left) == AOP_CRY &&
850 AOP_TYPE(right) == AOP_CRY) {
851 pic16_genPlusBits (ic);
855 /* if left in bit space & right literal */
856 if (AOP_TYPE(left) == AOP_CRY &&
857 AOP_TYPE(right) == AOP_LIT) {
858 /* if result in bit space */
859 if(AOP_TYPE(result) == AOP_CRY){
860 if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
861 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
862 if (!pic16_sameRegs(AOP(left), AOP(result)) )
863 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
864 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
867 unsigned long lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
868 size = pic16_getDataSize(result);
870 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
871 pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
872 pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
873 //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
874 //pic16_emitcode("addc","a,#00 ;%d",__LINE__);
875 //pic16_aopPut(AOP(result),"a",offset++);
881 /* if I can do an increment instead
882 of add then GOOD for ME */
883 if (pic16_genPlusIncr (ic) == TRUE)
886 size = pic16_getDataSize(result);
888 if(AOP(right)->type == AOP_LIT) {
889 /* Add a literal to something else */
891 unsigned lit = (unsigned) floatFromVal(AOP(right)->aopu.aop_lit);
895 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
900 } else if(AOP_TYPE(right) == AOP_CRY) {
902 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
903 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
904 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
906 /* here we are adding a bit to a char or int */
908 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
910 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
911 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0));
913 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
914 AOP(right)->aopu.aop_dir,
915 AOP(right)->aopu.aop_dir);
916 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
919 if(AOP_TYPE(left) == AOP_ACC) {
920 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
921 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
923 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
924 AOP(right)->aopu.aop_dir,
925 AOP(right)->aopu.aop_dir);
926 pic16_emitcode(" xorlw","1");
928 pic16_mov2w(AOP(left),0);
929 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
930 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
932 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
933 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
934 AOP(right)->aopu.aop_dir,
935 AOP(right)->aopu.aop_dir);
936 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
939 if(AOP_TYPE(result) != AOP_ACC) {
941 if(AOP_TYPE(result) == AOP_CRY) {
942 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
943 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0));
945 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0));
947 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0));
948 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
955 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
956 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
958 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
959 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
961 pic16_emitcode("clrz","");
963 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
964 AOP(right)->aopu.aop_dir,
965 AOP(right)->aopu.aop_dir);
966 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
969 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
970 pic16_mov2w(AOP(left),0);
971 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
972 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
973 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
976 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
977 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
978 AOP(right)->aopu.aop_dir,
979 AOP(right)->aopu.aop_dir);
980 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
981 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
987 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++));
988 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE));
996 // Note: the following is an example of WISC code, eg.
997 // it's supposed to run on a Weird Instruction Set Computer :o)
999 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1001 if ( AOP_TYPE(left) == AOP_ACC) {
1002 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1003 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
1004 if ( AOP_TYPE(result) != AOP_ACC)
1005 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1006 goto release; // we're done, since WREG is 1 byte
1010 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1012 size = min( AOP_SIZE(result), AOP_SIZE(right) );
1013 size = min( size, AOP_SIZE(left) );
1016 if(pic16_debug_verbose) {
1017 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
1018 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
1019 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
1024 if ((AOP_TYPE(left) == AOP_PCODE) && (
1025 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
1026 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
1027 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
1029 // add to literal operand
1032 for(i=0; i<size; i++) {
1033 if (AOP_TYPE(right) == AOP_ACC) {
1034 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1036 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1037 if(i) { // add with carry
1038 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1039 } else { // add without
1040 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1043 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1046 DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
1048 // add leftover bytes
1049 if (SPEC_USIGN(getSpec(operandType(right)))) {
1050 // right is unsigned
1051 for(i=size; i< AOP_SIZE(result); i++) {
1052 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1053 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1054 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1058 // right is signed, oh dear ...
1059 for(i=size; i< AOP_SIZE(result); i++) {
1060 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1061 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1062 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),i));
1063 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1064 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1074 for(i=0; i<size; i++) {
1075 if (AOP_TYPE(right) != AOP_ACC)
1076 pic16_mov2w(AOP(right),i);
1077 if (pic16_sameRegs(AOP(left), AOP(result)))
1079 if(i) { // add with carry
1080 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1081 } else { // add without
1082 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1084 } else { // not same
1085 if(i) { // add with carry
1086 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1087 } else { // add without
1088 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1090 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1094 // add leftover bytes
1095 // either left or right is too short
1096 for (i=size; i < AOP_SIZE(result); i++) {
1097 // get right operand into WREG
1098 if (i < AOP_SIZE(right)) {
1099 pic16_mov2w (AOP(right), i);
1101 // right is too short
1102 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1103 if (!SPEC_USIGN(getSpec(operandType(right)))) {
1104 // right operand is signed
1105 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1106 pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1110 // get left+WREG+CARRY into result
1111 if (i < AOP_SIZE(left)) {
1112 if (pic16_sameRegs (AOP(left), AOP(result))) {
1113 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1115 pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
1116 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1119 // left is too short
1120 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
1121 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1122 // left operand is signed
1123 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1124 pic16_emitpcode(POC_SETF, pic16_popGet (AOP(result), i));
1126 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1137 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1138 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1139 pic16_freeAsmop(result,NULL,ic,TRUE);
1142 /*-----------------------------------------------------------------*/
1143 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1144 /*-----------------------------------------------------------------*/
1145 bool pic16_genMinusDec (iCode *ic)
1147 unsigned int icount ;
1148 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1151 /* will try to generate an increment */
1152 /* if the right side is not a literal
1154 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1155 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1156 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1159 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1161 /* if the literal value of the right hand side
1162 is greater than 4 then it is not worth it */
1163 if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1166 /* if decrement 16 bits in register */
1167 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1172 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1174 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1176 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1177 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1178 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1180 /* size is 3 or 4 */
1181 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1182 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1183 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1184 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1186 pic16_emitcode("movlw","0xff");
1187 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1190 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1192 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1195 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1197 pic16_emitcode("skpnc","");
1199 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1208 /* if the sizes are greater than 1 then we cannot */
1209 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1210 AOP_SIZE(IC_LEFT(ic)) > 1 )
1213 /* we can if the aops of the left & result match or
1214 if they are in registers and the registers are the
1216 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1219 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1221 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1226 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1227 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1228 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1231 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1232 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1234 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1235 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1243 /*-----------------------------------------------------------------*/
1244 /* pic16_addSign - propogate sign bit to higher bytes */
1245 /*-----------------------------------------------------------------*/
1246 void pic16_addSign(operand *result, int offset, int sign)
1248 int size = (pic16_getDataSize(result) - offset);
1249 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1252 if(sign && offset) {
1255 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1256 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1257 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
1260 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1261 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1262 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1264 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1269 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1273 /*-----------------------------------------------------------------*/
1274 /* pic16_genMinusBits - generates code for subtraction of two bits */
1275 /*-----------------------------------------------------------------*/
1276 void pic16_genMinusBits (iCode *ic)
1278 symbol *lbl = newiTempLabel(NULL);
1281 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1282 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1283 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1284 pic16_emitcode("cpl","c");
1285 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1286 pic16_outBitC(IC_RESULT(ic));
1289 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1290 pic16_emitcode("subb","a,acc");
1291 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1292 pic16_emitcode("inc","a");
1293 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1294 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1295 pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
1299 /*-----------------------------------------------------------------*/
1300 /* pic16_genMinus - generates code for subtraction */
1301 /*-----------------------------------------------------------------*/
1302 void pic16_genMinus (iCode *ic)
1304 int size, offset = 0, same=0;
1305 unsigned long lit = 0L;
1308 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1309 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1310 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1312 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1313 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1314 operand *t = IC_RIGHT(ic);
1315 IC_RIGHT(ic) = IC_LEFT(ic);
1319 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1320 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1321 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1322 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1324 /* special cases :- */
1325 /* if both left & right are in bit space */
1326 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1327 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1328 pic16_genPlusBits (ic);
1332 /* if I can do an decrement instead
1333 of subtract then GOOD for ME */
1334 // if (pic16_genMinusDec (ic) == TRUE)
1337 size = pic16_getDataSize(IC_RESULT(ic));
1338 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1340 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1341 /* Add a literal to something else */
1343 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
1346 genAddLit ( ic, lit);
1349 /* add the first byte: */
1350 pic16_emitcode("movlw","0x%x", lit & 0xff);
1351 pic16_emitcode("addwf","%s,f", pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1352 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1353 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1365 if((lit & 0xff) == 0xff) {
1366 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1368 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1370 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1372 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
1373 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1377 /* do the rlf known zero trick here */
1378 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
1380 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1385 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1388 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1389 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1390 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1392 /* here we are subtracting a bit from a char or int */
1394 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1396 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1397 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1399 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1400 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1401 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1402 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1405 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1406 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1407 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1408 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1409 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1411 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1413 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1414 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1416 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1417 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1420 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1422 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1424 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1425 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1429 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1430 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1431 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1432 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1437 pic16_mov2w(AOP(IC_LEFT(ic)),0);
1438 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1439 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1442 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1444 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1447 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1449 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1451 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1458 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1459 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1460 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1462 lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
1463 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1464 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1465 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1466 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1469 if( (size == 1) && ((lit & 0xff) == 0) ) {
1470 /* res = 0 - right */
1471 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1472 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1474 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1475 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1476 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1481 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1482 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1483 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1491 // here we have x = lit - x for sizeof(x)>1
1492 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1493 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1495 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1496 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1497 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1504 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1505 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1506 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1507 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1509 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1510 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1511 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1512 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1513 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1514 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1517 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1518 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1519 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1521 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1522 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1524 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1525 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1526 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1528 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1530 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1531 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1532 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1534 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1536 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1542 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1544 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1545 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1547 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1548 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1555 if (offset < AOP_SIZE(IC_RIGHT(ic)))
1556 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1558 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1559 if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
1560 // signed -- sign extend the right operand
1561 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),AOP_SIZE(IC_RIGHT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1562 pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1565 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1566 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1568 if (offset < AOP_SIZE(IC_LEFT(ic))) {
1569 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1570 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1572 // zero extend the left operand
1573 pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
1574 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
1575 // signed -- sign extend the left operand
1576 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),AOP_SIZE(IC_LEFT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1577 pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
1579 pic16_emitpcode(POC_SUBWFB_D1, 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_mov2w(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_mov2w(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_mov2w(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_mov2w(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_mov2w(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_mov2w(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_mov2w(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_mov2w(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_mov2w(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_mov2w(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);