From: tecodev Date: Sun, 18 Jun 2006 16:42:39 +0000 (+0000) Subject: * src/SDCCsymt.c (initCSupport): change return type of divschar to X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=5e18c799d15ef505b96b2c369885b06a75e36625;p=fw%2Fsdcc * src/SDCCsymt.c (initCSupport): change return type of divschar to int for PIC16 * src/pic16/genarith.c (genAddLit): sign-extend via standard routine (pic16_genMinusBits): simplified sign-extension (pic16_genUMult8XLit_8,pic16_genUMult8X8_8): renamed to pic16_genMult8XLit_n resp. pic16_genMult8X8_n, fixed and adjusted to correctly handle mixed-signed operands, disabled now unused multiplciation routines * src/pic16/gen.c (pic16_pushpCodeOp): fixed to handle literals (assignResultValue): added argument denoting the size of the result as returned by the function (fixes upcasts in assigning from function calls: char foo(); int i = foo();) (genCall,genPcall,genGenPointerGet,genReceive): pass size of function result to assignResultValue (genMult): disabled inlined multiplication code (genDiv): augmented to also handle the modulus operator, fixed to handle mixed-signed operands correctly (genMod): simply call genDiv, disabled unused code (genAssign): fixed missing (sign-)extension on result * src/pic16/main.c (_hasNativeMulFor): accept literals [-128..256) as valid char operands, allow signed operands for native code, added division and modulo operator handling * device/lib/pic16/libsdcc/char/divschar.c: divschar returns an int As a consequence, onebyte.c (if split into two files) and muldiv.c pass regression tests. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4237 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index f7d2e4d0..7db19ff3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2006-06-18 Raphael Neider + + * src/SDCCsymt.c (initCSupport): change return type of divschar to + int for PIC16 + * src/pic16/genarith.c (genAddLit): sign-extend via standard routine + (pic16_genMinusBits): simplified sign-extension + (pic16_genUMult8XLit_8,pic16_genUMult8X8_8): renamed to + pic16_genMult8XLit_n resp. pic16_genMult8X8_n, fixed and + adjusted to correctly handle mixed-signed operands, disabled + now unused multiplciation routines + * src/pic16/gen.c (pic16_pushpCodeOp): fixed to handle literals + (assignResultValue): added argument denoting the size of the result + as returned by the function (fixes upcasts in assigning from + function calls: char foo(); int i = foo();) + (genCall,genPcall,genGenPointerGet,genReceive): pass size of + function result to assignResultValue + (genMult): disabled inlined multiplication code + (genDiv): augmented to also handle the modulus operator, fixed to + handle mixed-signed operands correctly + (genMod): simply call genDiv, disabled unused code + (genAssign): fixed missing (sign-)extension on result + * src/pic16/main.c (_hasNativeMulFor): accept literals [-128..256) as + valid char operands, allow signed operands for native code, added + division and modulo operator handling + * device/lib/pic16/libsdcc/char/divschar.c: divschar returns an int + + As a consequence, onebyte.c (if split into two files) and muldiv.c + pass regression tests. + 2006-06-17 Frieder Ferlemann * doc/Makefile.in: two runs of makeindex seem needed to get diff --git a/device/lib/pic16/libsdcc/char/divschar.c b/device/lib/pic16/libsdcc/char/divschar.c index 173ea905..9cfeb7c6 100644 --- a/device/lib/pic16/libsdcc/char/divschar.c +++ b/device/lib/pic16/libsdcc/char/divschar.c @@ -33,9 +33,9 @@ unsigned char _divuchar (unsigned char a, unsigned char b); -char _divschar (char a, char b) _IL_REENTRANT +int _divschar (char a, char b) _IL_REENTRANT { - register char r; + register unsigned char r; char ta, tb; if(a<0)ta = -a; else ta = a; diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 8031d9fc..6e2b7aed 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -3456,17 +3456,50 @@ initCSupport () { for (muldivmod = 1; muldivmod < 3; muldivmod++) { - /* div and mod */ - SNPRINTF (buffer, sizeof(buffer), - "_%s%s%s", - smuldivmod[muldivmod], - ssu[su], - sbwd[bwd]); - __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent); - FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1; + /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */ + if (!TARGET_IS_PIC16 || muldivmod != 1 || bwd != 0 || su != 0) + { + SNPRINTF (buffer, sizeof(buffer), + "_%s%s%s", + smuldivmod[muldivmod], + ssu[su], + sbwd[bwd]); + __muldiv[muldivmod][bwd][su] = funcOfType ( + _mangleFunctionName(buffer), + __multypes[bwd][su], + __multypes[bwd][su], + 2, + options.intlong_rent); + FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1; + } } } } + + if (TARGET_IS_PIC16) + { + /* PIC16 port wants __divschar/__modschar to return an int, so that both + * 100 / -4 = -25 and -128 / -1 = 128 can be handled correctly + * (first one would have to be sign extended, second one must not be). + * Similarly, modschar should be handled, but the iCode introduces cast + * here and forces '% : s8 x s8 -> s8' ... */ + su = 0; bwd = 0; + for (muldivmod = 1; muldivmod < 2; muldivmod++) { + SNPRINTF (buffer, sizeof(buffer), + "_%s%s%s", + smuldivmod[muldivmod], + ssu[su], + sbwd[bwd]); + __muldiv[muldivmod][bwd][su] = funcOfType ( + _mangleFunctionName(buffer), + __multypes[1][su], + __multypes[bwd][su], + 2, + options.intlong_rent); + FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1; + } + } + /* mul only */ muldivmod = 0; /* byte */ diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 2ac93042..74da6f0e 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -74,11 +74,13 @@ /* Wrapper to execute `code' at most once. */ #define PERFORM_ONCE(id,code) do { static char id = 0; if (!id) { id = 1; code } } while (0) +void pic16_genMult8X8_n (operand *, operand *,operand *); +#if 0 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); -void pic16_genMult8X8_8 (operand *, operand *,operand *); void pic16_genMult16X16_16(operand *, operand *, operand *); void pic16_genMult32X32_32(operand *, operand *, operand *); +#endif pCode *pic16_AssembleLine(char *line, int peeps); extern void pic16_printpBlock(FILE *of, pBlock *pb); static asmop *newAsmop (short type); @@ -2499,7 +2501,12 @@ void pic16_testStackOverflow(void) void pic16_pushpCodeOp(pCodeOp *pcop) { // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg( pic16_stack_postdec ))); + if (pcop->type == PO_LITERAL) { + pic16_emitpcode(POC_MOVLW, pcop); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg( pic16_stack_postdec ))); + } if(pic16_options.gstack) pic16_testStackOverflow(); @@ -2990,7 +2997,7 @@ void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src) /* assignResultValue - assign results to oper, rescall==1 is */ /* called from genCall() or genPcall() */ /*-----------------------------------------------------------------*/ -static void assignResultValue(operand * oper, int rescall) +static void assignResultValue(operand * oper, int res_size, int rescall) { int size = AOP_SIZE(oper); int offset=0; @@ -3009,20 +3016,22 @@ static void assignResultValue(operand * oper, int rescall) /* 8-bits, result in WREG */ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0)); - if(size>1) { + if(size > 1 && res_size > 1) { /* 16-bits, result in PRODL:WREG */ pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl)); } - if(size>2) { + if(size > 2 && res_size > 2) { /* 24-bits, result in PRODH:PRODL:WREG */ pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14 } - if(size>3) { + if(size > 3 && res_size > 3) { /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */ pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14 } + + pic16_addSign(oper, res_size, IS_UNSIGNED(operandType(oper))); } else { /* >32-bits, result on stack, and FSR0 points to beginning. @@ -3393,7 +3402,11 @@ static void genCall (iCode *ic) pic16_aopOp(IC_RESULT(ic),ic,FALSE); _G.accInUse--; - assignResultValue(IC_RESULT(ic), 1); + /* Must not assign an 8-bit result to a 16-bit variable; + * this would use (used...) the uninitialized PRODL! */ + /* FIXME: Need a proper way to obtain size of function result type, + * OP_SYM_ETYPE does not work: it dereferences pointer types! */ + assignResultValue(IC_RESULT(ic), getSize(OP_SYM_TYPE(IC_LEFT(ic))->next), 1); DEBUGpic16_emitcode ("; ","%d left %s",__LINE__, pic16_AopType(AOP_TYPE(IC_RESULT(ic)))); @@ -3540,7 +3553,9 @@ static void genPcall (iCode *ic) pic16_aopOp(IC_RESULT(ic),ic,FALSE); _G.accInUse--; - assignResultValue(IC_RESULT(ic), 1); + /* FIXME: Need proper way to obtain the function result's type. + * OP_SYM_TYPE(IC_LEFT(ic))->next does not work --> points to function pointer */ + assignResultValue(IC_RESULT(ic), getSize(OP_SYM_TYPE(IC_LEFT(ic))->next->next), 1); DEBUGpic16_emitcode ("; ","%d left %s",__LINE__, pic16_AopType(AOP_TYPE(IC_RESULT(ic)))); @@ -4216,9 +4231,10 @@ static void genMultOneByte (operand *left, pic16_aopGet(AOP(result),0,FALSE,FALSE)); } - pic16_genMult8X8_8 (left, right,result); + pic16_genMult8X8_n (left, right,result); } +#if 0 /*-----------------------------------------------------------------*/ /* genMultOneWord : 16 bit multiplication */ /*-----------------------------------------------------------------*/ @@ -4255,7 +4271,9 @@ static void genMultOneWord (operand *left, pic16_genMult16X16_16(left, right,result); } +#endif +#if 0 /*-----------------------------------------------------------------*/ /* genMultOneLong : 32 bit multiplication */ /*-----------------------------------------------------------------*/ @@ -4292,6 +4310,7 @@ static void genMultOneLong (operand *left, pic16_genMult32X32_32(left, right,result); } +#endif @@ -4327,6 +4346,7 @@ static void genMult (iCode *ic) goto release ; } +#if 0 /* if both are of size == 2 */ if(AOP_SIZE(left) == 2 && AOP_SIZE(right) == 2) { @@ -4340,7 +4360,11 @@ static void genMult (iCode *ic) genMultOneLong(left, right, result); goto release; } - +#endif + + fprintf( stderr, "%s: should have been transformed into function call\n",__FUNCTION__ ); + assert( !"Multiplication should have been transformed into function call!" ); + pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor."); @@ -4354,6 +4378,7 @@ release : pic16_freeAsmop(result,NULL,ic,TRUE); } +#if 0 /*-----------------------------------------------------------------*/ /* genDivbits :- division of bits */ /*-----------------------------------------------------------------*/ @@ -4523,6 +4548,7 @@ static void genDivOneByte (operand *left, pic16_aopPut(AOP(result),"a",offset++); } +#endif /*-----------------------------------------------------------------*/ /* genDiv - generates code for division */ @@ -4532,8 +4558,12 @@ static void genDiv (iCode *ic) operand *left = IC_LEFT(ic); operand *right = IC_RIGHT(ic); operand *result= IC_RESULT(ic); - - + int negated = 0; + int leftVal = 0, rightVal = 0; + int signedLits = 0; + char *functions[2][2] = { { "__divschar", "__divuchar" }, { "__modschar", "__moduchar" } }; + int op = 0; + /* Division is a very lengthy algorithm, so it is better * to call support routines than inlining algorithm. * Division functions written here just in case someone @@ -4546,6 +4576,207 @@ static void genDiv (iCode *ic) pic16_aopOp (right,ic,FALSE); pic16_aopOp (result,ic,TRUE); + if (ic->op == '/') + op = 0; + else if (ic->op == '%') + op = 1; + else + assert( !"invalid operation requested in genDivMod" ); + + /* get literal values */ + if (IS_VALOP(left)) { + leftVal = (int)floatFromVal( OP_VALUE(left) ); + assert( leftVal >= -128 && leftVal < 256 ); + if (leftVal < 0) { signedLits++; } + } + if (IS_VALOP(right)) { + rightVal = (int)floatFromVal( OP_VALUE(right) ); + assert( rightVal >= -128 && rightVal < 256 ); + if (rightVal < 0) { signedLits++; } + } + + /* We should only come here to convert all + * / : {u8_t, s8_t} x {u8_t, s8_t} -> {u8_t, s8_t} + * with exactly one operand being s8_t into + * u8_t x u8_t -> u8_t. All other cases should have been + * turned into calls to support routines beforehand... */ + if ((AOP_SIZE(left) == 1 || IS_VALOP(left)) + && (AOP_SIZE(right) == 1 || IS_VALOP(right))) + { + if ((!IS_UNSIGNED(operandType(right)) || rightVal < 0) + && (!IS_UNSIGNED(operandType(left)) || leftVal < 0)) + { + /* Both operands are signed or negative, use _divschar + * instead of _divuchar */ + pushaop(AOP(right), 0); + pushaop(AOP(left), 0); + + /* call _divschar */ + pic16_emitpcode(POC_CALL, pic16_popGetWithString(functions[op][0])); + + { + symbol *sym; + sym = newSymbol( functions[op][0], 0 ); + sym->used++; + strcpy(sym->rname, functions[op][0]); + checkAddSym(&externs, sym); + } + + /* assign result */ + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + if (AOP_SIZE(result) > 1) + { + pic16_emitpcode(POC_MOVFF, + pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), + pic16_popGet(AOP(result), 1))); + /* sign extend */ + pic16_addSign(result, 2, 1); + } + + /* clean up stack */ + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_preinc)); + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_preinc)); + + goto release; + } + + /* push right operand */ + if (IS_VALOP(right)) { + if (rightVal < 0) { + pic16_pushpCodeOp( pic16_popGetLit(-rightVal) ); + negated++; + } else { + pushaop(AOP(right), 0); + } + } else if (!IS_UNSIGNED(operandType(right))) { + pic16_mov2w(AOP(right), 0); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7)); + pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(pic16_stack_postdec)); + negated++; + } else { + pushaop(AOP(right), 0); + } + + /* push left operand */ + if (IS_VALOP(left)) { + if (leftVal < 0) { + pic16_pushpCodeOp(pic16_popGetLit(-leftVal)); + negated++; + } else { + pushaop(AOP(left), 0); + } + } else if (!IS_UNSIGNED(operandType(left))) { + pic16_mov2w(AOP(left),0); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7)); + pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(pic16_stack_postdec)); + negated++; + } else { + pushaop(AOP(left), 0); + } + + /* call _divuchar */ + pic16_emitpcode(POC_CALL, pic16_popGetWithString(functions[op][1])); + + { + symbol *sym; + sym = newSymbol( functions[op][1], 0 ); + sym->used++; + strcpy(sym->rname, functions[op][1]); + checkAddSym(&externs, sym); + } + + /* Revert negation(s) from above. + * This is inefficient: if both operands are negative, this + * should not touch WREG. However, determining that exactly + * one operand was negated costs at least 3 instructions, + * so there is nothing to be gained here, is there? + * + * I negate WREG because either operand might share registers with + * result, so assigning first might destroy an operand. */ + + /* For the modulus operator, (a/b)*b == a shall hold. + * Thus: a>0, b>0 --> a/b >= 0 and a%b >= 0 + * a>0, b<0 --> a/b <= 0 and a%b >= 0 (e.g. 128 / -5 = -25, -25*(-5) = 125 and +3 remaining) + * a<0, b>0 --> a/b <= 0 and a%b < 0 (e.g. -128 / 5 = -25, -25* 5 = -125 and -3 remaining) + * a<0, b<0 --> a/b >= 0 and a%b < 0 (e.g. -128 / -5 = 25, 25*(-5) = -125 and -3 remaining) + * Only invert the result if the left operand is negative (sigh). + */ + if (AOP_SIZE(result) <= 1 || !negated) + { + if (ic->op == '/') + { + if (IS_VALOP(right)) { + if (rightVal < 0) { + /* we negated this operand above */ + pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg)); + } + } else if (!IS_UNSIGNED(operandType(right))) { + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7)); + pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg)); + } + } + + if (IS_VALOP(left)) { + if (leftVal < 0) { + /* we negated this operand above */ + pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg)); + } + } else if (!IS_UNSIGNED(operandType(left))) { + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7)); + pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg)); + } + + /* Move result to destination. */ + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + + /* Zero-extend: no operand was signed (or result is just a byte). */ + pic16_addSign(result, 1, 0); + } else { + assert( AOP_SIZE(result) > 1 ); + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1)); + if (ic->op == '/') + { + if (IS_VALOP(right)) { + if (rightVal < 0) { + /* we negated this operand above */ + pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1)); + } + } else if (!IS_UNSIGNED(operandType(right))) { + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7)); + pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1)); + } + } + + if (IS_VALOP(left)) { + if (leftVal < 0) { + /* we negated this operand above */ + pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1)); + } + } else if (!IS_UNSIGNED(operandType(left))) { + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7)); + pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1)); + } + + /* Move result to destination. */ + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + + /* Negate result if required. */ + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(result), 1, 7)); + pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(result), 0)); + + /* Sign-extend. */ + pic16_addSign(result, 2, 1); + } + + /* clean up stack */ + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_preinc)); + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_preinc)); + goto release; + } + +#if 0 /* special cases first */ /* both are bits */ if (AOP_TYPE(left) == AOP_CRY && @@ -4560,6 +4791,7 @@ static void genDiv (iCode *ic) genDivOneByte(left,right,result); goto release ; } +#endif /* should have been converted to function call */ assert(0); @@ -4569,6 +4801,7 @@ release : pic16_freeAsmop(result,NULL,ic,TRUE); } +#if 0 /*-----------------------------------------------------------------*/ /* genModbits :- modulus of bits */ /*-----------------------------------------------------------------*/ @@ -4668,12 +4901,16 @@ static void genModOneByte (operand *left, pic16_aopPut(AOP(result),"b",0); } +#endif /*-----------------------------------------------------------------*/ /* genMod - generates code for division */ /*-----------------------------------------------------------------*/ static void genMod (iCode *ic) { + /* Task deferred to genDiv */ + genDiv(ic); +#if 0 operand *left = IC_LEFT(ic); operand *right = IC_RIGHT(ic); operand *result= IC_RESULT(ic); @@ -4707,6 +4944,7 @@ release : pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); pic16_freeAsmop(result,NULL,ic,TRUE); +#endif } /*-----------------------------------------------------------------*/ @@ -7693,6 +7931,7 @@ static void genOr (iCode *ic, iCode *ifx) unsigned long lit = 0L; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + FENTRY; pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE); pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE); @@ -7998,6 +8237,7 @@ static void genXor (iCode *ic, iCode *ifx) unsigned long lit = 0L; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + FENTRY; pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE); pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE); @@ -11218,7 +11458,7 @@ static void genGenPointerGet (operand *left, pic16_mov2w(AOP(left), 2); pic16_callGenericPointerRW(0, size); - assignResultValue(result, 1); + assignResultValue(result, size, 1); goto release; } @@ -12536,47 +12776,50 @@ static void genAssign (iCode *ic) } #endif - know_W=-1; - while (size--) { - DEBUGpic16_emitcode ("; ***","%s %d size %d",__FUNCTION__,__LINE__, size); - if(AOP_TYPE(right) == AOP_LIT) { - if(lit&0xff) { - if(know_W != (lit&0xff)) - pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff)); - know_W = lit&0xff; - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - } else - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); + size = AOP_SIZE(right); + if (size > AOP_SIZE(result)) size = AOP_SIZE(result); + know_W=-1; + while (size--) { + DEBUGpic16_emitcode ("; ***","%s %d size %d",__FUNCTION__,__LINE__, size); + if(AOP_TYPE(right) == AOP_LIT) { + if(lit&0xff) { + if(know_W != (lit&0xff)) + pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff)); + know_W = lit&0xff; + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); + } else + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); - lit >>= 8; + lit >>= 8; - } else if (AOP_TYPE(right) == AOP_CRY) { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); - if(offset == 0) { - //debugf("%s: BTFSS offset == 0\n", __FUNCTION__); - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0)); - } - } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) { + } else if (AOP_TYPE(right) == AOP_CRY) { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); + if(offset == 0) { + //debugf("%s: BTFSS offset == 0\n", __FUNCTION__); + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0)); + } + } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) { pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - } else { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + } else { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(!_G.resDirect) { /* use this aopForSym feature */ - if(AOP_TYPE(result) == AOP_ACC) { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset)); - } else - if(AOP_TYPE(right) == AOP_ACC) { - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); - } else { - pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset)); - } + if(!_G.resDirect) { /* use this aopForSym feature */ + if(AOP_TYPE(result) == AOP_ACC) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset)); + } else + if(AOP_TYPE(right) == AOP_ACC) { + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset)); + } + } } - } - + offset++; } + pic16_addSign(result, AOP_SIZE(right), !IS_UNSIGNED(operandType(right))); release: pic16_freeAsmop (right,NULL,ic,FALSE); @@ -13310,7 +13553,9 @@ static void genReceive (iCode *ic) GpsuedoStkPtr = ic->parmBytes; /* setting GpsuedoStkPtr has side effects here: */ - assignResultValue(IC_RESULT(ic), 0); + /* FIXME: What's the correct size of the return(ed) value? + * For now, assuming '4' as before... */ + assignResultValue(IC_RESULT(ic), 4, 0); } pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); diff --git a/src/pic16/genarith.c b/src/pic16/genarith.c index 1664b0cf..68fdf921 100644 --- a/src/pic16/genarith.c +++ b/src/pic16/genarith.c @@ -750,13 +750,11 @@ static void genAddLit (iCode *ic, int lit) operand *result; operand *left; - sym_link *lleft; FENTRY; left = IC_LEFT(ic); - lleft = operandType (left); result = IC_RESULT(ic); same = pic16_sameRegs(AOP(left), AOP(result)); size = pic16_getDataSize(result); @@ -771,27 +769,7 @@ static void genAddLit (iCode *ic, int lit) #undef MIN /* extend to result size */ - if (IS_UNSIGNED(lleft)) { - /* zero-extend */ - for (i = sizeL; i < size; i++) { - pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i)); - } // for i - } else { - /* sign-extend */ - if (size == sizeL + 1) { - pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), sizeL)); - pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7)); - pic16_emitpcode (POC_SETF, pic16_popGet (AOP(result), sizeL)); - } else { - pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg)); - pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7)); - pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg)); - - for (i=sizeL; i < size; i++) { - pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(result), i)); - } // for i - } // if - } // if (SIGNED) + pic16_addSign(result, sizeL, !IS_UNSIGNED(operandType(left))); /* special cases */ if (lit == 0) { @@ -1580,7 +1558,7 @@ void pic16_genMinusBits (iCode *ic) pic16_emitcode("inc","a"); pic16_emitcode("","%05d_DS_:",(lbl->key+100)); pic16_aopPut(AOP(IC_RESULT(ic)),"a",0); - pic16_addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic))))); + pic16_addSign(IC_RESULT(ic), MSB16, !IS_UNSIGNED(operandType(IC_RESULT(ic)))); } } @@ -1883,103 +1861,127 @@ void pic16_genMinus (iCode *ic) /*-----------------------------------------------------------------* - * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers. + * pic_genMult8XLit_n - multiplication of two 8-bit numbers. * * *-----------------------------------------------------------------*/ -void pic16_genUMult8XLit_8 (operand *left, - operand *right, - operand *result) +void pic16_genMult8XLit_n (operand *left, + operand *right, + operand *result) { - unsigned int lit; + int lit; int same; int size = AOP_SIZE(result); int i; - FENTRY; - DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + FENTRY; + DEBUGpic16_pic16_AopType(__LINE__,left,right,result); - if (AOP_TYPE(right) != AOP_LIT){ - fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__); - exit(1); - } + if (AOP_TYPE(right) != AOP_LIT){ + fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__); + exit(1); + } - lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit); - lit &= 0xff; - pic16_emitpcomment("Unrolled 8 X 8 multiplication"); - pic16_emitpcomment("FIXME: the function does not support result==WREG"); + lit = (int)floatFromVal(AOP(right)->aopu.aop_lit); + assert( (lit >= -128) && (lit < 256) ); + pic16_emitpcomment("Unrolled 8 X 8 multiplication"); + pic16_emitpcomment("FIXME: the function does not support result==WREG"); + + same = pic16_sameRegs(AOP(left), AOP(result)); + if(same) { + switch(lit & 0x00ff) { + case 0: + while (size--) { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size)); + } // while + return; - same = pic16_sameRegs(AOP(left), AOP(result)); - if(same) { - switch(lit) { - case 0: - while (size--) { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size)); - } // while - return; - case 2: - // its faster to left shift - for (i=1; i < size; i++) { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i)); - } // for - emitCLRC; - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0)); - if (size > 1) - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1)); - return; + case 2: + /* sign extend left in result */ + pic16_addSign(result, 1, !IS_UNSIGNED(operandType(left))); + // its faster to left shift + emitCLRC; + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0)); + if (size > 1) + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1)); + return; - default: - if(AOP_TYPE(left) != AOP_ACC) - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0)); - pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit)); - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), - pic16_popGet(AOP(result), 0))); - if (size > 1) { - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh), - pic16_popGet(AOP(result), 1))); - for (i=2; i < size; i++) { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i)); - } // for - } // if - return; - } + default: + if(AOP_TYPE(left) != AOP_ACC) + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0)); + pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit & 0x00ff)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg( + &pic16_pc_prodl), pic16_popGet(AOP(result), 0))); + /* Adjust result's high bytes below! */ + } + } else { + // operands different + switch(lit & 0x00ff) { + case 0: + while (size--) { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size)); + } // while + return; + + case 2: + if (IS_UNSIGNED(operandType(result))) { + for (i=1; i < size; i++) { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i)); + } // for } else { - // operands different - switch(lit) { - case 0: - while (size--) { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size)); - } // while - return; - case 2: - for (i=1; i < size; i++) { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i)); - } // for - emitCLRC; - pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); - if (size > 1) - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1)); - return; - default: - if(AOP_TYPE(left) != AOP_ACC) - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0)); - pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit)); - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), - pic16_popGet(AOP(result), 0))); - - if (size > 1) { - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh), - pic16_popGet(AOP(result), 1))); - for (i=2; i < size; i++) { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i)); - } // for - } // if - return; - } + /* sign extend left to result */ + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7)); + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff)); + for (i=1; i < size; i++) { + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i)); + } // for } + emitCLRC; + pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + if (size > 1) + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1)); + return; + + default: + if(AOP_TYPE(left) != AOP_ACC) + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0)); + pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg( + &pic16_pc_prodl), pic16_popGet(AOP(result), 0))); + /* Adjust result's high bytes below! */ + } + } + + if (size > 1) { + /* We need to fix PRODH for + * (a) literals < 0 and + * (b) signed register operands < 0. + */ + //printf( "%s: lit %d, left unsigned: %d\n", __FUNCTION__, lit, SPEC_USIGN(getSpec(operandType(left)))); + if (lit < 0) { + /* literal negative (i.e. in [-128..-1]), high byte == -1 */ + pic16_mov2w(AOP(left), 0); + pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh)); + } + + if (!SPEC_USIGN(getSpec(operandType(left)))) { + /* register operand signed, determine signedness of high byte */ + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0x00ff)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7)); + pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh)); + } + + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg( + &pic16_pc_prodh), pic16_popGet(AOP(result), 1))); + + /* Need to sign-extend here. */ + pic16_addSign(result, 2, !IS_UNSIGNED(operandType(result))); + } // if } +#if 0 /*-----------------------------------------------------------------------* * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers * *-----------------------------------------------------------------------*/ @@ -2092,73 +2094,101 @@ void pic16_genUMult16XLit_16 (operand *left, } } } +#endif /*-----------------------------------------------------------------* - * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers. + * genMult8X8_n - multiplication of two 8-bit numbers. * * *-----------------------------------------------------------------*/ -void pic16_genUMult8X8_8 (operand *left, - operand *right, - operand *result) +void pic16_genMult8X8_n (operand *left, operand *right, operand *result) { FENTRY; - - if (AOP_TYPE(right) == AOP_LIT) { - pic16_genUMult8XLit_8(left,right,result); - return; - } - /* cases: - A = A x B B = A x B - A = B x C - W = A x B - W = W x B W = B x W - */ - /* if result == right then exchange left and right */ - if(pic16_sameRegs(AOP(result), AOP(right))) { - operand *tmp; - tmp = left; - left = right; - right = tmp; - } - - if(AOP_TYPE(left) != AOP_ACC) { - // left is not WREG - if(AOP_TYPE(right) != AOP_ACC) { - pic16_mov2w(AOP(left), 0); - pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0)); - } else { - pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0)); - } - } else { - // left is WREG, right cannot be WREG (or can?!) - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0)); - } - - /* result is in PRODL:PRODH */ - if(AOP_TYPE(result) != AOP_ACC) { - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), - pic16_popGet(AOP(result), 0))); + if (AOP_TYPE(right) == AOP_LIT) { + pic16_genMult8XLit_n(left,right,result); + return; + } + + /* cases: + A = A x B B = A x B + A = B x C + W = A x B + W = W x B W = B x W + */ + /* if result == right then exchange left and right */ + if(pic16_sameRegs(AOP(result), AOP(right))) { + operand *tmp; + tmp = left; + left = right; + right = tmp; + } + + if(AOP_TYPE(left) != AOP_ACC) { + // left is not WREG + if(AOP_TYPE(right) != AOP_ACC) { + pic16_mov2w(AOP(left), 0); + pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0)); + } else { + pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0)); + } + } else { + // left is WREG, right cannot be WREG (or can?!) + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right), 0)); + } + /* result is in PRODL:PRODH */ + if(AOP_TYPE(result) != AOP_ACC) { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg( + &pic16_pc_prodl), pic16_popGet(AOP(result), 0))); + + + if(AOP_SIZE(result)>1) { + + /* If s8 x s8 --> s16 multiplication was called for, fixup high byte. + * (left=a1a0, right=b1b0, X1: high byte, X0: low byte) + * + * a1a0 * b1b0 + * -------------- + * a1b0 a0b0 + * a1b1 a0b1 + * --------------- + * a0b0 a1= 0, b1= 0 (both unsigned) + * -b0 a0b0 a1=-1, b1= 0 (a signed and < 0, b unsigned or >= 0) + * -a0 a0b0 a1= 0, b1=-1 (b signed and < 0, a unsigned or >= 0) + * -(a0+b0) a0b0 a1=-1, b1=-1 (a and b signed and < 0) + * + * Currently, PRODH:PRODL holds a0b0 as 16 bit value; we need to + * subtract a0 and/or b0 from PRODH. */ + if (!IS_UNSIGNED(operandType(right))) { + /* right operand (b1) signed and < 0, then subtract left op (a0) */ + pic16_mov2w( AOP(left), 0 ); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7)); + pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh)); + } - if(AOP_SIZE(result)>1) { - int i; + if (!IS_UNSIGNED(getSpec(operandType(left)))) { + /* left operand (a1) signed and < 0, then subtract right op (b0) */ + pic16_mov2w( AOP(right), 0 ); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7)); + pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh)); + } - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh), - pic16_popGet(AOP(result), 1))); - - for(i=2;iop, getSize(OP_SYMBOL(IC_RESULT(ic))->type)); + int symL, symR, symRes, sizeL = 0, sizeR = 0, sizeRes = 0; + + /* left/right are symbols? */ + symL = IS_SYMOP(IC_LEFT(ic)); + symR = IS_SYMOP(IC_RIGHT(ic)); + symRes = IS_SYMOP(IC_RESULT(ic)); + + /* --> then determine their sizes */ + sizeL = symL ? getSize(OP_SYM_TYPE(IC_LEFT(ic))) : 4; + sizeR = symR ? getSize(OP_SYM_TYPE(IC_RIGHT(ic))) : 4; + sizeRes = symRes ? getSize(OP_SYM_TYPE(IC_RESULT(ic))) : 4; /* Checks to enable native multiplication. * PICs do not offer native division at all... @@ -924,51 +935,39 @@ static bool _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right) * (regardless of the operands) * ( ii) if left and right are unsigned 8-bit operands, * use native MUL - * (iii) if left or right is a literal in the range of [0..255) + * (iii) if left or right is a literal in the range of [-128..256) * and the other is an unsigned byte, use native MUL */ if (ic->op == '*') { - int symL, symR, symRes, sizeL = 0, sizeR = 0, sizeRes = 0; - - /* left/right are symbols? */ - symL = IS_SYMOP(IC_LEFT(ic)); - symR = IS_SYMOP(IC_RIGHT(ic)); - symRes = IS_SYMOP(IC_RESULT(ic)); - - /* --> then determine their sizes */ - sizeL = symL ? getSize(OP_SYM_TYPE(IC_LEFT(ic))) : 4; - sizeR = symR ? getSize(OP_SYM_TYPE(IC_RIGHT(ic))) : 4; - sizeRes = symRes ? getSize(OP_SYM_TYPE(IC_RESULT(ic))) : 4; - /* use native mult for `*: x --> {u8_t, s8_t}' */ if (sizeRes == 1) { return TRUE; } /* use native mult for `u8_t x u8_t --> { u16_t, s16_t }' */ - if (sizeL == 1 && symL && SPEC_USIGN(OP_SYM_TYPE(IC_LEFT(ic)))) { + if (sizeL == 1 && symL /*&& SPEC_USIGN(OP_SYM_TYPE(IC_LEFT(ic)))*/) { sizeL = 1; } else { //printf( "%s: left too large (%u) / signed (%u)\n", __FUNCTION__, sizeL, symL && !SPEC_USIGN(OP_SYM_TYPE(IC_LEFT(ic)))); sizeL = 4; } - if (sizeR == 1 && symR && SPEC_USIGN(OP_SYM_TYPE(IC_RIGHT(ic)))) { + if (sizeR == 1 && symR /*&& SPEC_USIGN(OP_SYM_TYPE(IC_RIGHT(ic)))*/) { sizeR = 1; } else { //printf( "%s: right too large (%u) / signed (%u)\n", __FUNCTION__, sizeR, symR && !SPEC_USIGN(OP_SYM_TYPE(IC_RIGHT(ic)))); sizeR = 4; } - /* also allow literals [0..256) for left/right operands */ + /* also allow literals [-128..256) for left/right operands */ if (IS_VALOP(IC_LEFT(ic))) { long l = (long)floatFromVal( OP_VALUE( IC_LEFT(ic) ) ); sizeL = 4; //printf( "%s: val(left) = %ld\n", __FUNCTION__, l ); - if (l >= 0 && l < 256) + if (l >= -128 && l < 256) { sizeL = 1; } else { - //printf( "%s: left value %ld outside [0..256)\n", __FUNCTION__, l ); + //printf( "%s: left value %ld outside [-128..256)\n", __FUNCTION__, l ); } } if (IS_VALOP( IC_RIGHT(ic) )) @@ -976,11 +975,11 @@ static bool _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right) long l = (long)floatFromVal( OP_VALUE( IC_RIGHT(ic) ) ); sizeR = 4; //printf( "%s: val(right) = %ld\n", __FUNCTION__, l ); - if (l >= 0 && l < 256) + if (l >= -128 && l < 256) { sizeR = 1; } else { - //printf( "%s: right value %ld outside [0..256)\n", __FUNCTION__, l ); + //printf( "%s: right value %ld outside [-128..256)\n", __FUNCTION__, l ); } } @@ -988,6 +987,41 @@ static bool _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right) if (sizeL == 1 && sizeR == 1) { return TRUE; } } + if (ic->op == '/' || ic->op == '%') + { + /* We must catch /: {u8_t,s8_t} x {u8_t,s8_t} --> {u8_t,s8_t}, + * because SDCC will call 'divuchar' even for u8_t / s8_t. + * Example: 128 / -2 becomes 128 / 254 = 0 != -64... */ + if (sizeL == 1 && sizeR == 1) return TRUE; + + /* What about literals? */ + if (IS_VALOP( IC_LEFT(ic) )) + { + long l = (long)floatFromVal( OP_VALUE( IC_LEFT(ic) ) ); + sizeL = 4; + //printf( "%s: val(left) = %ld\n", __FUNCTION__, l ); + if (l >= -128 && l < 256) + { + sizeL = 1; + } else { + //printf( "%s: left value %ld outside [-128..256)\n", __FUNCTION__, l ); + } + } + if (IS_VALOP( IC_RIGHT(ic) )) + { + long l = (long)floatFromVal( OP_VALUE( IC_RIGHT(ic) ) ); + sizeR = 4; + //printf( "%s: val(right) = %ld\n", __FUNCTION__, l ); + if (l >= -128 && l < 256) + { + sizeR = 1; + } else { + //printf( "%s: right value %ld outside [-128..256)\n", __FUNCTION__, l ); + } + } + if (sizeL == 1 && sizeR == 1) { return TRUE; } + } + return FALSE; }