-
- /* special cases :- */
- result = IC_RESULT(ic);
- left = IC_LEFT(ic);
- right = IC_RIGHT(ic);
- pic16_aopOp (left,ic,FALSE);
- pic16_aopOp (right,ic,FALSE);
- pic16_aopOp (result,ic,TRUE);
- DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
- // pic16_DumpOp("(left)",left);
-
- /* if literal, literal on the right or
- if left requires ACC or right is already
- in ACC */
-
- if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
- operand *t = right;
- right = IC_RIGHT(ic) = left;
- left = IC_LEFT(ic) = t;
- }
-
- /* if both left & right are in bit space */
- if (AOP_TYPE(left) == AOP_CRY &&
- AOP_TYPE(right) == AOP_CRY) {
- pic16_genPlusBits (ic);
- goto release ;
- }
-
- /* if left in bit space & right literal */
- if (AOP_TYPE(left) == AOP_CRY &&
- AOP_TYPE(right) == AOP_LIT) {
- /* if result in bit space */
- if(AOP_TYPE(result) == AOP_CRY){
- if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
- if (!pic16_sameRegs(AOP(left), AOP(result)) )
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
- }
- } else {
- unsigned long lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
- size = pic16_getDataSize(result);
- while (size--) {
- pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
- pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
- pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
- //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- //pic16_emitcode("addc","a,#00 ;%d",__LINE__);
- //pic16_aopPut(AOP(result),"a",offset++);
- }
- }
- goto release ;
- } // left == CRY
-
- /* if I can do an increment instead
- of add then GOOD for ME */
- if (pic16_genPlusIncr (ic) == TRUE)
- goto release;
-
- size = pic16_getDataSize(result);
-
- if(AOP(right)->type == AOP_LIT) {
- /* Add a literal to something else */
- //bool know_W=0;
- unsigned lit = (unsigned) floatFromVal(AOP(right)->aopu.aop_lit);
- //unsigned l1=0;
-
- //offset = 0;
- DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
-
- genAddLit (ic, lit);
- goto release;
-
- } else if(AOP_TYPE(right) == AOP_CRY) {
-
- pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
- pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
- pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
-
- /* here we are adding a bit to a char or int */
- if(size == 1) {
- if (pic16_sameRegs(AOP(left), AOP(result)) ) {
-
- pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0));
-
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
- } else { // not same
-
- if(AOP_TYPE(left) == AOP_ACC) {
- pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
-
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_emitcode(" xorlw","1");
- } else {
- pic16_mov2w(AOP(left),0);
- pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
-
- pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
- }
-
- if(AOP_TYPE(result) != AOP_ACC) {
-
- if(AOP_TYPE(result) == AOP_CRY) {
- pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
- pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0));
- emitSKPZ;
- pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0));
- } else {
- pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0));
- pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
- }
- }
- }
-
- } else {
- int offset = 1;
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (pic16_sameRegs(AOP(left), AOP(result)) ) {
- emitCLRZ;
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
-
- pic16_emitcode("clrz","");
-
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
-
- } else {
- emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
- pic16_mov2w(AOP(left),0);
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
- emitMOVWF(right,0);
-
- pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
- pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
-
- }
-
- while(--size){
- emitSKPZ;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++));
- //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE));
- }
-
- }
-
- } else {
- // add bytes
-
- // Note: the following is an example of WISC code, eg.
- // it's supposed to run on a Weird Instruction Set Computer :o)
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if ( AOP_TYPE(left) == AOP_ACC) {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
- if ( AOP_TYPE(result) != AOP_ACC)
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
- goto release; // we're done, since WREG is 1 byte
- }
-
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- size = min( AOP_SIZE(result), AOP_SIZE(right) );
- size = min( size, AOP_SIZE(left) );
- offset = 0;
-
- if(pic16_debug_verbose) {
-// fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
-// AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
-// fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
- }
-
-
-
- if ((AOP_TYPE(left) == AOP_PCODE) && (
- (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
-// (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
- (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
- {
- // add to literal operand
-
- // add first bytes
- for(i=0; i<size; i++) {
- if (AOP_TYPE(right) == AOP_ACC) {
- pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
- } else {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
- if(i) { // add with carry
- pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
- } else { // add without
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
- }
- }
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
- }
-
- DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
-
- // add leftover bytes
- if (SPEC_USIGN(getSpec(operandType(right)))) {
- // right is unsigned
- for(i=size; i< AOP_SIZE(result); i++) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
- }
-
- } else {
- // right is signed, oh dear ...
- for(i=size; i< AOP_SIZE(result); i++) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),i));
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
- }