## [sdcc-devel] Why do we need the UMINUS iCode?

 [sdcc-devel] Why do we need the UMINUS iCode? From: Philipp Klaus Krause - 2013-01-06 15:52:21 ```What's the purpose of the UMINUS iCode? Shouldn't it always behave the same as normal - iCode with left operand 0? Philipp ```

 [sdcc-devel] Why do we need the UMINUS iCode? From: Philipp Klaus Krause - 2013-01-06 15:52:21 ```What's the purpose of the UMINUS iCode? Shouldn't it always behave the same as normal - iCode with left operand 0? Philipp ```
 Re: [sdcc-devel] Why do we need the UMINUS iCode? From: Erik Petrich - 2013-01-06 17:41:53 ```On Sun, 6 Jan 2013, Philipp Klaus Krause wrote: > What's the purpose of the UMINUS iCode? Shouldn't it always behave the > same as normal - iCode with left operand 0? > > Philipp I think it's given a separate iCode for 2 reasons. 1) so that the conversion from iCodes to function calls for floats does not pick it up. Unlike the other floating point operations, unary minus on float is trivial to handle in the code generator since it's effectively just an assignment with the most significant bit complemented. 2) many CPU instructions sets have special instructions for arithmetic negation. While #2 could be used were applicable within the code generation for binary minus, I think it's common enough that when combined with reason #1 that it's worthwhile for the iCode generator to use a distict iCode. Erik ```
 Re: [sdcc-devel] Why do we need the UMINUS iCode? From: Philipp Klaus Krause - 2013-01-06 18:00:39 ```On 06.01.2013 18:41, Erik Petrich wrote: > > On Sun, 6 Jan 2013, Philipp Klaus Krause wrote: > >> What's the purpose of the UMINUS iCode? Shouldn't it always behave the >> same as normal - iCode with left operand 0? >> >> Philipp > > I think it's given a separate iCode for 2 reasons. > > 1) so that the conversion from iCodes to function calls for floats does > not pick it up. Unlike the other floating point operations, unary minus on > float is trivial to handle in the code generator since it's effectively > just an assignment with the most significant bit complemented. > > 2) many CPU instructions sets have special instructions for arithmetic > negation. > > While #2 could be used were applicable within the code generation for > binary minus, I think it's common enough that when combined with reason #1 > that it's worthwhile for the iCode generator to use a distict iCode. > > Erik Hmm, at least the z80 backend separates the UMINUS into one code generation function for float and one for the rest anyway. So one has to check for operand type in the backend anyway; we could check for left operand being zero in float support function conversion as well. The current situation unfortunately results in code duplication in the backends. In particular, I need to support the special negation instructions in genMinus (in case the lower bytes of the left operand are zero), and need to use the ordinary subtraction with carry in genUminus (for the upper bytes). For e.g. x = 256 - x; and x = -x; One would generate very similar code assuming an 8-bit neg is available, but a 16-bit is not (and if there is a 16-bit neg one gets the same situation for long, etc): For the lower byte I would use neg, and for the upper byte sbc. Philipp ```
 Re: [sdcc-devel] Why do we need the UMINUS iCode? From: Erik Petrich - 2013-01-06 19:19:42 ```On Sun, 6 Jan 2013, Philipp Klaus Krause wrote: > x = 256 - x; > and > x = -x; > > One would generate very similar code assuming an 8-bit neg is available, > but a 16-bit is not (and if there is a 16-bit neg one gets the same > situation for long, etc): > For the lower byte I would use neg, and for the upper byte sbc. I hadn't considered using a neg instruction there, so I understand your point better now. Perhaps in the in interests of minimal disruption (and thus unexpected consequences), we could have a globally allocated literal operand with the value 0. Then the code generator uses the same function for minus and unary minus with an initialization like: if (ic->op == UNARYMINUS) { if (IS_FLOAT (operandType (IC_LEFT (ic)))) { genUnminusFloat (ic); return; } else { left = operandZero; right = IC_LEFT (ic); } } else { left = IC_LEFT (ic); right = IC_RIGHT (ic); } Erik ```