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";
116 case PO_TWO_OPS: return "PO_TWO_OPS";
120 return "BAD PO_TYPE";
123 const char *pic16_pCodeOpSubType(pCodeOp *pcop)
126 if(pcop && (pcop->type == PO_GPR_BIT)) {
128 switch(PCORB(pcop)->subtype) {
130 case PO_NONE: return "PO_NONE";
131 case PO_W: return "PO_W";
132 case PO_WREG: return "PO_WREG";
133 case PO_STATUS: return "PO_STATUS";
134 case PO_BSR: return "PO_BSR";
135 case PO_FSR0: return "PO_FSR0";
136 case PO_INDF0: return "PO_INDF0";
137 case PO_INTCON: return "PO_INTCON";
138 case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
139 case PO_GPR_BIT: return "PO_GPR_BIT";
140 case PO_GPR_TEMP: return "PO_GPR_TEMP";
141 case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
142 case PO_PCL: return "PO_PCL";
143 case PO_PCLATH: return "PO_PCLATH";
144 case PO_PCLATU: return "PO_PCLATU";
145 case PO_PRODL: return "PO_PRODL";
146 case PO_PRODH: return "PO_PRODH";
147 case PO_LITERAL: return "PO_LITERAL";
148 case PO_REL_ADDR: return "PO_REL_ADDR";
149 case PO_IMMEDIATE: return "PO_IMMEDIATE";
150 case PO_DIR: return "PO_DIR";
151 case PO_CRY: return "PO_CRY";
152 case PO_BIT: return "PO_BIT";
153 case PO_STR: return "PO_STR";
154 case PO_LABEL: return "PO_LABEL";
155 case PO_WILD: return "PO_WILD";
156 case PO_TWO_OPS: return "PO_TWO_OPS";
160 return "BAD PO_TYPE";
163 /*-----------------------------------------------------------------*/
164 /* pic16_genPlusIncr :- does addition with increment if possible */
165 /*-----------------------------------------------------------------*/
166 bool pic16_genPlusIncr (iCode *ic)
168 unsigned int icount ;
169 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
173 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
174 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
175 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
176 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
178 /* will try to generate an increment */
179 /* if the right side is not a literal
181 if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
184 DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
185 /* if the literal value of the right hand side
186 is greater than 2 then it is faster to add */
187 if ((icount = (unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
190 /* if increment 16 bits in register */
191 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
196 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
197 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
201 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
202 //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
208 // DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
209 /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
210 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
211 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
213 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
214 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
215 AOP(IC_RESULT(ic))->aopu.aop_dir,
216 AOP(IC_RESULT(ic))->aopu.aop_dir);
218 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
219 //pic16_emitcode("xorlw","1");
221 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
222 //pic16_emitcode("andlw","1");
225 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
226 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
227 AOP(IC_RESULT(ic))->aopu.aop_dir,
228 AOP(IC_RESULT(ic))->aopu.aop_dir);
234 /* if the sizes are greater than 1 then we cannot */
235 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
236 AOP_SIZE(IC_LEFT(ic)) > 1 )
239 /* If we are incrementing the same register by two: */
241 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
244 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
245 //pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
250 DEBUGpic16_emitcode ("; ","couldn't increment ");
255 /*-----------------------------------------------------------------*/
256 /* pic16_outBitAcc - output a bit in acc */
257 /*-----------------------------------------------------------------*/
258 void pic16_outBitAcc(operand *result)
260 symbol *tlbl = newiTempLabel(NULL);
261 /* if the result is a bit */
262 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
264 assert(0); // not implemented for PIC16?
266 if (AOP_TYPE(result) == AOP_CRY){
267 pic16_aopPut(AOP(result),"a",0);
270 pic16_emitcode("jz","%05d_DS_",tlbl->key+100);
271 pic16_emitcode("mov","a,#01");
272 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
273 pic16_outAcc(result);
277 /*-----------------------------------------------------------------*/
278 /* pic16_genPlusBits - generates code for addition of two bits */
279 /*-----------------------------------------------------------------*/
280 void pic16_genPlusBits (iCode *ic)
284 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
285 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
286 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
287 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
289 The following block of code will add two bits.
290 Note that it'll even work if the destination is
291 the carry (C in the status register).
292 It won't work if the 'Z' bit is a source or destination.
295 /* If the result is stored in the accumulator (w) */
296 //if(strcmp(pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) {
297 switch(AOP_TYPE(IC_RESULT(ic))) {
299 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
300 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
301 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
302 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
303 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
305 pic16_emitcode("clrw","");
306 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
307 AOP(IC_RIGHT(ic))->aopu.aop_dir,
308 AOP(IC_RIGHT(ic))->aopu.aop_dir);
309 pic16_emitcode("xorlw","1");
310 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
311 AOP(IC_LEFT(ic))->aopu.aop_dir,
312 AOP(IC_LEFT(ic))->aopu.aop_dir);
313 pic16_emitcode("xorlw","1");
316 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
317 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
318 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
319 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
320 pic16_emitpcode(POC_XORLW, pic16_popGetLit(1));
321 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
324 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_RESULT(ic)),0));
325 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
326 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
327 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
328 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_LEFT(ic)),0));
329 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
331 pic16_emitcode("movlw","(1 << (%s & 7))",
332 AOP(IC_RESULT(ic))->aopu.aop_dir,
333 AOP(IC_RESULT(ic))->aopu.aop_dir);
334 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
335 AOP(IC_RESULT(ic))->aopu.aop_dir,
336 AOP(IC_RESULT(ic))->aopu.aop_dir);
337 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
338 AOP(IC_RIGHT(ic))->aopu.aop_dir,
339 AOP(IC_RIGHT(ic))->aopu.aop_dir);
340 pic16_emitcode("xorwf","(%s >>3),f",
341 AOP(IC_RESULT(ic))->aopu.aop_dir);
342 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
343 AOP(IC_LEFT(ic))->aopu.aop_dir,
344 AOP(IC_LEFT(ic))->aopu.aop_dir);
345 pic16_emitcode("xorwf","(%s>>3),f",
346 AOP(IC_RESULT(ic))->aopu.aop_dir);
353 /* This is the original version of this code.
355 * This is being kept around for reference,
356 * because I am not entirely sure I got it right...
358 static void adjustArithmeticResult(iCode *ic)
360 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
361 AOP_SIZE(IC_LEFT(ic)) == 3 &&
362 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
363 pic16_aopPut(AOP(IC_RESULT(ic)),
364 pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
367 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
368 AOP_SIZE(IC_RIGHT(ic)) == 3 &&
369 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
370 pic16_aopPut(AOP(IC_RESULT(ic)),
371 pic16_aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
374 if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
375 AOP_SIZE(IC_LEFT(ic)) < 3 &&
376 AOP_SIZE(IC_RIGHT(ic)) < 3 &&
377 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
378 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
380 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
381 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
385 /* This is the pure and virtuous version of this code.
386 * I'm pretty certain it's right, but not enough to toss the old
389 static void adjustArithmeticResult(iCode *ic)
391 if (opIsGptr(IC_RESULT(ic)) &&
392 opIsGptr(IC_LEFT(ic)) &&
393 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
395 pic16_aopPut(AOP(IC_RESULT(ic)),
396 pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
400 if (opIsGptr(IC_RESULT(ic)) &&
401 opIsGptr(IC_RIGHT(ic)) &&
402 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
404 pic16_aopPut(AOP(IC_RESULT(ic)),
405 pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
409 if (opIsGptr(IC_RESULT(ic)) &&
410 AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
411 AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
412 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
413 !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
415 sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
416 pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
422 /*-----------------------------------------------------------------*/
423 /* genAddlit - generates code for addition */
424 /*-----------------------------------------------------------------*/
425 static void genAddLit2byte (operand *result, int offr, int lit)
433 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offr));
436 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
439 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
440 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
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));
463 static void genAddLit (iCode *ic, int lit)
476 result = IC_RESULT(ic);
477 same = pic16_sameRegs(AOP(left), AOP(result));
478 size = pic16_getDataSize(result);
482 /* Handle special cases first */
484 genAddLit2byte (result, 0, lit);
487 int hi = 0xff & (lit >> 8);
494 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
499 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
501 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
504 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
505 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
506 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
510 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
511 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
513 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
521 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
524 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
527 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
528 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
530 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
532 case 0xff: /* 0x01ff */
533 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
534 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
535 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
536 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
538 default: /* 0x01LL */
539 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
540 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
542 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
543 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
548 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
552 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
555 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
556 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
558 /* case 0xff: * 0xffff *
559 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
560 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
561 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
565 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
566 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
568 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
575 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
580 genAddLit2byte (result, MSB16, hi);
583 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
584 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
585 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
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 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
606 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
609 lo = BYTEofLONG(lit,0);
612 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
613 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
615 /* no carry info from previous step */
616 /* this means this is the first time to add */
621 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
625 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
626 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
628 carry_info = 3; /* Were adding only one byte and propogating the carry */
639 lo = BYTEofLONG(lit,0);
644 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
647 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
648 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
651 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
653 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
655 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
664 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
668 if(AOP_TYPE(left) == AOP_ACC) {
669 /* left addend is already in accumulator */
672 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
676 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
677 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
681 /* left addend is in a register */
684 pic16_mov2w(AOP(left),0);
685 emitMOVWF(result, 0);
688 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
689 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
693 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
694 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
698 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
699 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
700 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
708 /* left is not the accumulator */
710 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
711 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
713 pic16_mov2w(AOP(left),0);
714 /* We don't know the state of the carry bit at this point */
717 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
721 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
722 if (offset < AOP_SIZE(left)) {
723 pic16_emitpcode(clear_carry ? POC_ADDFW : POC_ADDFWC, pic16_popGet(AOP(left),offset));
724 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
726 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
727 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
728 /* sign-extend left (in result) */
729 pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left),AOP_SIZE(left)-1,7));
730 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
732 pic16_emitpcode(clear_carry ? POC_ADDWF : POC_ADDWFC, pic16_popGet(AOP(result),offset));
742 /* this fails when result is an SFR because value is written there
743 * during addition and not at the end */
745 static void genAddLit (iCode *ic, int lit)
758 result = IC_RESULT(ic);
759 same = pic16_sameRegs(AOP(left), AOP(result));
760 size = pic16_getDataSize(result);
761 sizeL = pic16_getDataSize(left);
764 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
765 /* move left to result -- possibly sign extend */
766 for (i=0; i < MIN(size, sizeL); i++) {
767 pic16_mov2f (AOP(result), AOP(left), i);
771 /* extend to result size */
772 pic16_addSign(result, sizeL, !IS_UNSIGNED(operandType(left)));
777 } else if (lit == 1) {
783 pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(result), 0));
787 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), 0));
788 for (i=1; i < size-1; i++) {
789 emitSKPNC; /* a jump here saves up to 2(size-2)cycles */
790 pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), i));
796 pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1));
800 /* add literal to result */
801 for (i=0; i < size; i++) {
802 pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit));
803 llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */
804 pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC,
805 pic16_popGet (AOP(result), i));
813 /* Handle special cases first */
815 genAddLit2byte (result, 0, lit);
818 int hi = 0xff & (lit >> 8);
825 DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
830 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
832 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
835 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
836 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
837 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
841 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
842 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
844 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
852 DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
855 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
858 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
859 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
861 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
863 case 0xff: /* 0x01ff */
864 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
865 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
866 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
867 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
869 default: /* 0x01LL */
870 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
871 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
873 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
874 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
879 DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
883 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
886 pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
887 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
889 /* case 0xff: * 0xffff *
890 pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
891 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
892 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
896 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
897 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
899 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
906 DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
911 genAddLit2byte (result, MSB16, hi);
914 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
915 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
916 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
918 /* case 0xff: * 0xHHff *
919 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
920 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
921 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
922 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
924 */ default: /* 0xHHLL */
925 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
926 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
927 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
928 pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
937 DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
940 lo = BYTEofLONG(lit,0);
943 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
944 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
946 /* no carry info from previous step */
947 /* this means this is the first time to add */
952 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
956 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
957 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
959 carry_info = 3; /* Were adding only one byte and propogating the carry */
970 lo = BYTEofLONG(lit,0);
975 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
978 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
979 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
982 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
984 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
986 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
995 DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
999 if(AOP_TYPE(left) == AOP_ACC) {
1000 /* left addend is already in accumulator */
1001 switch(lit & 0xff) {
1003 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1004 emitMOVWF(result,0);
1007 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
1008 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1009 emitMOVWF(result,0);
1012 /* left addend is in a register */
1013 switch(lit & 0xff) {
1015 pic16_mov2w(AOP(left),0);
1016 emitMOVWF(result, 0);
1019 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1020 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1021 emitMOVWF(result,0);
1024 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
1025 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1026 emitMOVWF(result,0);
1029 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1030 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1031 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1032 emitMOVWF(result,0);
1039 /* left is not the accumulator */
1041 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1042 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
1044 pic16_mov2w(AOP(left),0);
1045 /* We don't know the state of the carry bit at this point */
1048 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
1049 emitMOVWF(result,0);
1055 /* The ls byte of the lit must've been zero - that
1056 means we don't have to deal with carry */
1058 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1059 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
1060 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1065 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1066 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
1067 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
1071 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
1072 pic16_mov2w(AOP(left),offset);
1073 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
1084 /*-----------------------------------------------------------------*/
1085 /* pic16_genPlus - generates code for addition */
1086 /*-----------------------------------------------------------------*/
1087 void pic16_genPlus (iCode *ic)
1089 int i, size, offset = 0;
1090 operand *result, *left, *right;
1094 /* special cases :- */
1095 result = IC_RESULT(ic);
1097 right = IC_RIGHT(ic);
1098 pic16_aopOp (left,ic,FALSE);
1099 pic16_aopOp (right,ic,FALSE);
1100 pic16_aopOp (result,ic,TRUE);
1101 DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
1102 // pic16_DumpOp("(left)",left);
1104 /* if literal, literal on the right or
1105 if left requires ACC or right is already
1108 if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
1110 right = IC_RIGHT(ic) = left;
1111 left = IC_LEFT(ic) = t;
1114 /* if both left & right are in bit space */
1115 if (AOP_TYPE(left) == AOP_CRY &&
1116 AOP_TYPE(right) == AOP_CRY) {
1117 pic16_genPlusBits (ic);
1121 /* if left in bit space & right literal */
1122 if (AOP_TYPE(left) == AOP_CRY &&
1123 AOP_TYPE(right) == AOP_LIT) {
1124 /* if result in bit space */
1125 if(AOP_TYPE(result) == AOP_CRY){
1126 if(ulFromVal (AOP(right)->aopu.aop_lit) != 0L) {
1127 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
1128 if (!pic16_sameRegs(AOP(left), AOP(result)) )
1129 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
1130 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
1133 unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit);
1134 size = pic16_getDataSize(result);
1136 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
1137 pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
1138 pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
1139 //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
1140 //pic16_emitcode("addc","a,#00 ;%d",__LINE__);
1141 //pic16_aopPut(AOP(result),"a",offset++);
1147 /* if I can do an increment instead
1148 of add then GOOD for ME */
1149 if (pic16_genPlusIncr (ic) == TRUE)
1152 size = pic16_getDataSize(result);
1154 if(AOP(right)->type == AOP_LIT) {
1155 /* Add a literal to something else */
1157 unsigned lit = (unsigned) ulFromVal (AOP(right)->aopu.aop_lit);
1161 DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
1163 genAddLit (ic, lit);
1166 } else if(AOP_TYPE(right) == AOP_CRY) {
1168 pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
1169 pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
1170 pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
1172 /* here we are adding a bit to a char or int */
1174 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1176 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1177 pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0));
1179 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1180 AOP(right)->aopu.aop_dir,
1181 AOP(right)->aopu.aop_dir);
1182 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1183 } else { // not same
1185 if(AOP_TYPE(left) == AOP_ACC) {
1186 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1187 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1189 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1190 AOP(right)->aopu.aop_dir,
1191 AOP(right)->aopu.aop_dir);
1192 pic16_emitcode(" xorlw","1");
1194 pic16_mov2w(AOP(left),0);
1195 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
1196 pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
1198 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1199 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1200 AOP(right)->aopu.aop_dir,
1201 AOP(right)->aopu.aop_dir);
1202 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1205 if(AOP_TYPE(result) != AOP_ACC) {
1207 if(AOP_TYPE(result) == AOP_CRY) {
1208 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1209 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0));
1211 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0));
1213 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0));
1214 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1221 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1222 if (pic16_sameRegs(AOP(left), AOP(result)) ) {
1224 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1225 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
1227 pic16_emitcode("clrz","");
1229 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1230 AOP(right)->aopu.aop_dir,
1231 AOP(right)->aopu.aop_dir);
1232 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1235 emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
1236 pic16_mov2w(AOP(left),0);
1237 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
1238 pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
1239 //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
1242 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1243 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1244 AOP(right)->aopu.aop_dir,
1245 AOP(right)->aopu.aop_dir);
1246 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
1247 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
1253 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++));
1254 //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE));
1262 // Note: the following is an example of WISC code, eg.
1263 // it's supposed to run on a Weird Instruction Set Computer :o)
1265 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1267 if ( AOP_TYPE(left) == AOP_ACC) {
1268 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1269 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
1270 if ( AOP_TYPE(result) != AOP_ACC)
1271 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1272 goto release; // we're done, since WREG is 1 byte
1276 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1278 size = min( AOP_SIZE(result), AOP_SIZE(right) );
1279 size = min( size, AOP_SIZE(left) );
1282 if(pic16_debug_verbose) {
1283 // fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
1284 // AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
1285 // fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
1290 if ((AOP_TYPE(left) == AOP_PCODE) && (
1291 (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
1292 // (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
1293 (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
1295 // add to literal operand
1298 for(i=0; i<size; i++) {
1299 if (AOP_TYPE(right) == AOP_ACC) {
1300 pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
1302 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1303 if(i) { // add with carry
1304 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
1305 } else { // add without
1306 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
1309 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1312 DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
1314 // add leftover bytes
1315 if (SPEC_USIGN(getSpec(operandType(right)))) {
1316 // right is unsigned
1317 for(i=size; i< AOP_SIZE(result); i++) {
1318 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1319 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1320 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1324 // right is signed, oh dear ...
1325 for(i=size; i< AOP_SIZE(result); i++) {
1326 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1327 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1328 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),i));
1329 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
1330 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
1339 if (pic16_sameRegs(AOP(left), AOP(result))
1340 && (AOP_SIZE(left) < AOP_SIZE(result)))
1342 // extend left operand, sign-bit still intact
1343 pic16_addSign (result, AOP_SIZE(left), !SPEC_USIGN(getSpec(operandType(left))));
1347 for(i=0; i<size; i++) {
1348 if (AOP_TYPE(right) != AOP_ACC)
1349 pic16_mov2w(AOP(right),i);
1350 if (pic16_sameRegs(AOP(left), AOP(result)))
1352 if(i) { // add with carry
1353 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
1354 } else { // add without
1355 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
1357 } else { // not same
1358 if(i) { // add with carry
1359 pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
1360 } else { // add without
1361 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
1363 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1367 // add leftover bytes
1368 // either left or right is too short
1369 for (i=size; i < AOP_SIZE(result); i++) {
1370 // get right operand into WREG
1371 if (i < AOP_SIZE(right)) {
1372 pic16_mov2w (AOP(right), i);
1374 // right is too short, not overwritten with result
1375 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1376 if (!SPEC_USIGN(getSpec(operandType(right)))) {
1377 // right operand is signed
1378 // Make sure that right's sign is not yet overwritten
1379 assert (!pic16_sameRegs (AOP(right), AOP(result)));
1380 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1381 pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1385 // get left+WREG+CARRY into result
1386 if (pic16_sameRegs (AOP(left), AOP(result))) {
1387 // left might have been extended in result above
1388 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1389 } else if (i < AOP_SIZE(left)) {
1390 pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
1391 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1393 // left is too short, not overwritten with result
1394 pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
1395 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1396 // left operand is signed
1397 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1398 pic16_emitpcode(POC_SETF, pic16_popGet (AOP(result), i));
1400 pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
1411 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1412 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1413 pic16_freeAsmop(result,NULL,ic,TRUE);
1416 /*-----------------------------------------------------------------*/
1417 /* pic16_genMinusDec :- does subtraction with decrement if possible */
1418 /*-----------------------------------------------------------------*/
1419 bool pic16_genMinusDec (iCode *ic)
1421 unsigned int icount ;
1422 unsigned int size = pic16_getDataSize(IC_RESULT(ic));
1425 /* will try to generate an increment */
1426 /* if the right side is not a literal
1428 if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
1429 (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
1430 (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
1433 DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
1435 /* if the literal value of the right hand side
1436 is greater than 4 then it is not worth it */
1437 if ((icount = (unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
1440 /* if decrement 16 bits in register */
1441 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
1446 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1448 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1450 pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1451 pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1452 pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1454 /* size is 3 or 4 */
1455 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
1456 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
1457 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
1458 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
1460 pic16_emitcode("movlw","0xff");
1461 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
1464 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
1466 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
1469 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
1471 pic16_emitcode("skpnc","");
1473 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
1482 /* if the sizes are greater than 1 then we cannot */
1483 if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
1484 AOP_SIZE(IC_LEFT(ic)) > 1 )
1487 /* we can if the aops of the left & result match or
1488 if they are in registers and the registers are the
1490 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1493 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1495 //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1500 DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
1501 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
1502 pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1505 pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1506 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1508 pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1509 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1517 /*-----------------------------------------------------------------*/
1518 /* pic16_addSign - propogate sign bit to higher bytes */
1519 /*-----------------------------------------------------------------*/
1520 void pic16_addSign(operand *result, int offset, int sign)
1522 int size = (pic16_getDataSize(result) - offset);
1523 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1526 if(sign && offset) {
1529 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
1530 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1531 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
1534 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1535 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
1536 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1538 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
1543 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1547 /*-----------------------------------------------------------------*/
1548 /* pic16_genMinusBits - generates code for subtraction of two bits */
1549 /*-----------------------------------------------------------------*/
1550 void pic16_genMinusBits (iCode *ic)
1552 symbol *lbl = newiTempLabel(NULL);
1555 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
1556 pic16_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
1557 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
1558 pic16_emitcode("cpl","c");
1559 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1560 pic16_outBitC(IC_RESULT(ic));
1563 pic16_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
1564 pic16_emitcode("subb","a,acc");
1565 pic16_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
1566 pic16_emitcode("inc","a");
1567 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
1568 pic16_aopPut(AOP(IC_RESULT(ic)),"a",0);
1569 pic16_addSign(IC_RESULT(ic), MSB16, !IS_UNSIGNED(operandType(IC_RESULT(ic))));
1573 /*-----------------------------------------------------------------*/
1574 /* pic16_genMinus - generates code for subtraction */
1575 /*-----------------------------------------------------------------*/
1576 void pic16_genMinus (iCode *ic)
1578 int size, offset = 0, same=0;
1579 unsigned long lit = 0L;
1582 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1583 pic16_aopOp (IC_RIGHT(ic),ic,FALSE);
1584 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1586 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1587 AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
1588 operand *t = IC_RIGHT(ic);
1589 IC_RIGHT(ic) = IC_LEFT(ic);
1593 DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
1594 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1595 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1596 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1598 /* special cases :- */
1599 /* if both left & right are in bit space */
1600 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
1601 AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1602 pic16_genPlusBits (ic);
1606 /* if I can do an decrement instead
1607 of subtract then GOOD for ME */
1608 // if (pic16_genMinusDec (ic) == TRUE)
1611 size = pic16_getDataSize(IC_RESULT(ic));
1612 same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
1614 if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
1615 /* Add a literal to something else */
1617 lit = ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
1620 genAddLit ( ic, lit);
1621 } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
1624 pic16_emitcode(";bitsub","right is bit: %s",pic16_aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1625 pic16_emitcode(";bitsub","left is bit: %s",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1626 pic16_emitcode(";bitsub","result is bit: %s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1628 /* here we are subtracting a bit from a char or int */
1630 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1632 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1633 pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1635 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
1636 AOP(IC_RIGHT(ic))->aopu.aop_dir,
1637 AOP(IC_RIGHT(ic))->aopu.aop_dir);
1638 pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1641 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1642 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1643 pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
1644 }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1645 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1647 lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
1649 if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1650 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1652 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
1653 pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1656 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1658 pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1660 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1661 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1665 pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
1666 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1667 pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
1668 //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1673 pic16_mov2w(AOP(IC_LEFT(ic)),0);
1674 pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
1675 pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
1678 if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1680 pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1683 pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
1685 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1687 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1694 } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1695 (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
1696 (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
1698 lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
1699 DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
1700 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1701 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1702 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1705 if( (size == 1) && ((lit & 0xff) == 0) ) {
1706 /* res = 0 - right */
1707 if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
1708 pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1710 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1711 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1712 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1717 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1718 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
1719 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1727 // here we have x = lit - x for sizeof(x)>1
1728 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1729 pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1731 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
1732 pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
1733 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1740 DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
1741 pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
1742 pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
1743 pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
1745 if ((AOP_SIZE(IC_LEFT(ic)) < AOP_SIZE(IC_RESULT(ic)))
1746 && pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1747 // extend left in result
1748 pic16_addSign (IC_RESULT(ic), AOP_SIZE(IC_LEFT(ic)), !SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))));
1751 if ((AOP_SIZE(IC_RIGHT(ic)) < AOP_SIZE(IC_RESULT(ic)))
1752 && pic16_sameRegs (AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1753 // extend right in result---fails if left resides in result as well...
1754 assert ((IC_LEFT(ic) == IC_RIGHT(ic)) || !pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))));
1755 pic16_addSign (IC_RESULT(ic), AOP_SIZE(IC_RIGHT(ic)), !SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))));
1758 if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
1759 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1760 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
1761 pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
1762 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
1763 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1766 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1767 if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
1768 pic16_mov2w(AOP(IC_RIGHT(ic)),0);
1770 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1771 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
1773 if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
1774 (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
1775 pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1777 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
1779 if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
1780 if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1781 pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1783 pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
1785 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1791 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
1793 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1794 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1796 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
1797 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
1804 if (pic16_sameRegs (AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
1805 pic16_mov2w (AOP(IC_RESULT(ic)), offset);
1806 } else if (offset < AOP_SIZE(IC_RIGHT(ic)))
1807 pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
1809 // right operand is too short, not overwritten with result
1810 pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
1811 if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
1812 // signed -- sign extend the right operand
1813 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));
1814 pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
1817 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
1818 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1819 } else if (offset < AOP_SIZE(IC_LEFT(ic))) {
1820 pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1821 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1823 // left operand is too short, not overwritten with result
1824 pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
1825 if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
1826 // signed -- sign extend the left operand
1827 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));
1828 pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
1830 pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1836 // adjustArithmeticResult(ic);
1839 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1840 pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
1841 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1845 /*-----------------------------------------------------------------*
1846 * pic_genMult8XLit_n - multiplication of two 8-bit numbers.
1849 *-----------------------------------------------------------------*/
1850 void pic16_genMult8XLit_n (operand *left,
1856 int size = AOP_SIZE(result);
1860 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
1862 if (AOP_TYPE(right) != AOP_LIT){
1863 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1867 lit = (int) ulFromVal (AOP(right)->aopu.aop_lit);
1868 assert( (lit >= -128) && (lit < 256) );
1869 pic16_emitpcomment("Unrolled 8 X 8 multiplication");
1870 pic16_emitpcomment("FIXME: the function does not support result==WREG");
1872 same = pic16_sameRegs(AOP(left), AOP(result));
1874 switch(lit & 0x00ff) {
1877 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1882 /* sign extend left in result */
1883 pic16_addSign(result, 1, !IS_UNSIGNED(operandType(left)));
1884 // its faster to left shift
1886 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
1888 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1892 if(AOP_TYPE(left) != AOP_ACC)
1893 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1894 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit & 0x00ff));
1895 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1896 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1897 /* Adjust result's high bytes below! */
1900 // operands different
1901 switch(lit & 0x00ff) {
1904 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
1909 if (IS_UNSIGNED(operandType(result))) {
1910 for (i=1; i < size; i++) {
1911 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
1914 /* sign extend left to result */
1915 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
1916 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
1917 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
1918 for (i=1; i < size; i++) {
1919 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
1923 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
1924 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
1926 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
1930 if(AOP_TYPE(left) != AOP_ACC)
1931 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
1932 pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
1933 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1934 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
1935 /* Adjust result's high bytes below! */
1940 /* We need to fix PRODH for
1941 * (a) literals < 0 and
1942 * (b) signed register operands < 0.
1944 //printf( "%s: lit %d, left unsigned: %d\n", __FUNCTION__, lit, SPEC_USIGN(getSpec(operandType(left))));
1946 /* literal negative (i.e. in [-128..-1]), high byte == -1 */
1947 pic16_mov2w(AOP(left), 0);
1948 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
1951 if (!SPEC_USIGN(getSpec(operandType(left)))) {
1952 /* register operand signed, determine signedness of high byte */
1953 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0x00ff));
1954 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
1955 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
1958 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
1959 &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
1961 /* Need to sign-extend here. */
1962 pic16_addSign(result, 2, !IS_UNSIGNED(operandType(result)));
1967 /*-----------------------------------------------------------------------*
1968 * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
1969 *-----------------------------------------------------------------------*/
1970 void pic16_genUMult16XLit_16 (operand *left,
1974 pCodeOp *pct1, *pct2, *pct3, *pct4;
1981 if (AOP_TYPE(right) != AOP_LIT){
1982 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
1986 lit = (unsigned int) ulFromVal (AOP(right)->aopu.aop_lit);
1989 same = pic16_sameRegs(AOP(left), AOP(result));
1993 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
1994 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
1997 // its faster to left shift
1999 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2000 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2004 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2006 pct1 = pic16_popGetTempReg(1);
2007 pct2 = pic16_popGetTempReg(1);
2008 pct3 = pic16_popGetTempReg(1);
2009 pct4 = pic16_popGetTempReg(1);
2011 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2012 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2013 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2014 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2015 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2016 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2018 /* WREG still holds the low literal */
2019 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2020 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2021 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2023 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2024 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2025 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2026 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2029 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2030 pct1, pic16_popGet(AOP(result), 0)));
2031 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2032 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2033 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2034 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2036 pic16_popReleaseTempReg(pct4,1);
2037 pic16_popReleaseTempReg(pct3,1);
2038 pic16_popReleaseTempReg(pct2,1);
2039 pic16_popReleaseTempReg(pct1,1);
2043 // operands different
2046 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2047 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2051 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2052 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2053 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2054 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2058 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2059 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2060 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2061 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2062 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2063 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2065 /* WREG still holds the low literal */
2066 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2067 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2068 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2070 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2071 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2072 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2073 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2082 /*-----------------------------------------------------------------*
2083 * genMult8X8_n - multiplication of two 8-bit numbers.
2086 *-----------------------------------------------------------------*/
2087 void pic16_genMult8X8_n (operand *left, operand *right, operand *result)
2093 if (AOP_TYPE(right) == AOP_LIT) {
2094 pic16_genMult8XLit_n(left,right,result);
2104 /* if result == right then exchange left and right */
2105 if(pic16_sameRegs(AOP(result), AOP(right))) {
2112 if(AOP_TYPE(left) != AOP_ACC) {
2114 if(AOP_TYPE(right) != AOP_ACC) {
2115 pic16_mov2w(AOP(left), 0);
2116 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2118 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2121 // left is WREG, right cannot be WREG (or can?!)
2122 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0));
2125 /* result is in PRODL:PRODH */
2126 if(AOP_TYPE(result) != AOP_ACC) {
2127 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
2128 &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2131 if(AOP_SIZE(result)>1) {
2133 /* If s8 x s8 --> s16 multiplication was called for, fixup high byte.
2134 * (left=a1a0, right=b1b0, X1: high byte, X0: low byte)
2141 * a0b0 a1= 0, b1= 0 (both unsigned)
2142 * -b0 a0b0 a1=-1, b1= 0 (a signed and < 0, b unsigned or >= 0)
2143 * -a0 a0b0 a1= 0, b1=-1 (b signed and < 0, a unsigned or >= 0)
2144 * -(a0+b0) a0b0 a1=-1, b1=-1 (a and b signed and < 0)
2146 * Currently, PRODH:PRODL holds a0b0 as 16 bit value; we need to
2147 * subtract a0 and/or b0 from PRODH. */
2148 if (!IS_UNSIGNED(operandType(right))) {
2149 /* right operand (b1) signed and < 0, then subtract left op (a0) */
2150 pic16_mov2w( AOP(left), 0 );
2151 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
2152 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
2155 if (!IS_UNSIGNED(getSpec(operandType(left)))) {
2156 /* left operand (a1) signed and < 0, then subtract right op (b0) */
2157 pic16_mov2w( AOP(right), 0 );
2158 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
2159 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
2162 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
2163 &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2165 /* Must sign-extend here. */
2166 pic16_addSign(result, 2, !IS_UNSIGNED(operandType(left)));
2169 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2174 /*------------------------------------------------------------------*
2175 * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
2176 *------------------------------------------------------------------*/
2177 void pic16_genUMult16X16_16 (operand *left,
2182 pCodeOp *pct1, *pct2, *pct3, *pct4;
2187 if (AOP_TYPE(right) == AOP_LIT) {
2188 pic16_genMult8XLit_n(left,right,result);
2196 /* if result == right then exchange left and right */
2197 if(pic16_sameRegs(AOP(result), AOP(right))) {
2205 if(pic16_sameRegs(AOP(result), AOP(left))) {
2207 pct1 = pic16_popGetTempReg(1);
2208 pct2 = pic16_popGetTempReg(1);
2209 pct3 = pic16_popGetTempReg(1);
2210 pct4 = pic16_popGetTempReg(1);
2212 pic16_mov2w(AOP(left), 0);
2213 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2214 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2215 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2216 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2217 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2219 /* WREG still holds the lower left */
2220 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2221 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2222 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2224 pic16_mov2w(AOP(left), 1);
2225 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2226 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2227 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2230 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2231 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2232 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2233 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2234 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2235 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2237 pic16_popReleaseTempReg( pct4, 1 );
2238 pic16_popReleaseTempReg( pct3, 1 );
2239 pic16_popReleaseTempReg( pct2, 1 );
2240 pic16_popReleaseTempReg( pct1, 1 );
2244 pic16_mov2w(AOP(left), 0);
2245 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2246 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2247 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2248 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2249 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2251 /* WREG still holds the lower left */
2252 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2253 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2254 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2256 pic16_mov2w(AOP(left), 1);
2257 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2258 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2259 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2265 void pic16_genSMult16X16_16(operand *left,
2274 /*-----------------------------------------------------------------*
2275 * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
2277 * this routine will call the unsigned multiply routine and then
2278 * post-fix the sign bit.
2279 *-----------------------------------------------------------------*/
2280 void pic16_genSMult8X8_8 (operand *left,
2283 pCodeOpReg *result_hi)
2285 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2289 result_hi = PCOR(pic16_popGet(AOP(result),1));
2293 pic16_genUMult8X8_8(left,right,result);
2297 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2298 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
2299 pic16_mov2w(AOP(left),0);
2300 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
2301 pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
2306 /*-----------------------------------------------------------------*
2307 * pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
2308 *-----------------------------------------------------------------*/
2309 void pic16_genMult8X8_8 (operand *left,
2315 if(AOP_TYPE(right) == AOP_LIT)
2316 pic16_genMult8XLit_n(left,right,result);
2318 pic16_genMult8X8_n(left,right,result);
2323 /*-----------------------------------------------------------------*
2324 * pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
2325 *-----------------------------------------------------------------*/
2326 void pic16_genMult16X16_16 (operand *left,
2332 if (AOP_TYPE(right) == AOP_LIT)
2333 pic16_genUMult16XLit_16(left,right,result);
2335 pic16_genUMult16X16_16(left,right,result);
2341 /*-----------------------------------------------------------------------*
2342 * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
2343 *-----------------------------------------------------------------------*/
2344 void pic16_genUMult32XLit_32 (operand *left,
2348 pCodeOp *pct1, *pct2, *pct3, *pct4;
2355 if (AOP_TYPE(right) != AOP_LIT){
2356 fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
2360 lit = (unsigned int) ulFromVal (AOP(right)->aopu.aop_lit);
2363 same = pic16_sameRegs(AOP(left), AOP(result));
2367 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
2368 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
2371 // its faster to left shift
2373 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
2374 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
2378 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2380 pct1 = pic16_popGetTempReg(1);
2381 pct2 = pic16_popGetTempReg(1);
2382 pct3 = pic16_popGetTempReg(1);
2383 pct4 = pic16_popGetTempReg(1);
2385 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2386 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2387 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2388 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2389 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2390 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2392 /* WREG still holds the low literal */
2393 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2394 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2395 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2397 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2398 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2399 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2400 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2403 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2404 pct1, pic16_popGet(AOP(result), 0)));
2405 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
2406 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2407 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2408 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2410 pic16_popReleaseTempReg( pct4, 1 );
2411 pic16_popReleaseTempReg( pct3, 1 );
2412 pic16_popReleaseTempReg( pct2, 1 );
2413 pic16_popReleaseTempReg( pct1, 1 );
2417 // operands different
2420 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
2421 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
2425 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
2426 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
2427 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
2428 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2432 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
2433 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2434 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2435 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2436 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2437 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2439 /* WREG still holds the low literal */
2440 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
2441 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2442 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2444 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
2445 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
2446 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2447 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2456 /*------------------------------------------------------------------*
2457 * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
2458 *------------------------------------------------------------------*/
2459 void pic16_genUMult32X32_32 (operand *left,
2464 pCodeOp *pct1, *pct2, *pct3, *pct4;
2468 if (AOP_TYPE(right) == AOP_LIT) {
2469 pic16_genMult8XLit_n(left,right,result);
2477 /* if result == right then exchange left and right */
2478 if(pic16_sameRegs(AOP(result), AOP(right))) {
2486 if(pic16_sameRegs(AOP(result), AOP(left))) {
2488 pct1 = pic16_popGetTempReg(1);
2489 pct2 = pic16_popGetTempReg(1);
2490 pct3 = pic16_popGetTempReg(1);
2491 pct4 = pic16_popGetTempReg(1);
2493 pic16_mov2w(AOP(left), 0);
2494 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2495 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2496 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
2497 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2498 pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
2500 /* WREG still holds the lower left */
2501 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2502 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2503 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
2505 pic16_mov2w(AOP(left), 1);
2506 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2507 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2508 pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
2511 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2512 pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
2513 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
2514 pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
2515 pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
2516 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
2518 pic16_popReleaseTempReg( pct4, 1 );
2519 pic16_popReleaseTempReg( pct3, 1 );
2520 pic16_popReleaseTempReg( pct2, 1 );
2521 pic16_popReleaseTempReg( pct1, 1 );
2525 pic16_mov2w(AOP(left), 0);
2526 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2527 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2528 pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
2529 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2530 pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
2532 /* WREG still holds the lower left */
2533 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
2534 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2535 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
2537 pic16_mov2w(AOP(left), 1);
2538 pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
2539 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
2540 pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
2547 /*-----------------------------------------------------------------*
2548 * pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
2549 *-----------------------------------------------------------------*/
2550 void pic16_genMult32X32_32 (operand *left,
2556 if (AOP_TYPE(right) == AOP_LIT)
2557 pic16_genUMult32XLit_32(left,right,result);
2559 pic16_genUMult32X32_32(left,right,result);
2570 /*-----------------------------------------------------------------*/
2571 /* constMult - generates code for multiplication by a constant */
2572 /*-----------------------------------------------------------------*/
2573 void genMultConst(unsigned C)
2577 unsigned sr3; // Shift right 3
2583 Convert a string of 3 binary 1's in the lit into
2587 mask = 7 << ( (size*8) - 3);
2591 while(mask < (1<<size*8)) {
2593 if( (mask & lit) == lit) {
2596 /* We found 3 (or more) consecutive 1's */
2598 lsb = mask & ~(mask & (mask-1)); // lsb of mask.
2600 consecutive_bits = ((lit + lsb) & lit) ^ lit;
2602 lit ^= consecutive_bits;
2606 sr3 |= (consecutive + lsb);