> From: Paul Brook <[EMAIL PROTECTED]> > On Monday 18 December 2006 01:15, Paul Schlie wrote: >> Chris Lattner wrote: >>> On Dec 17, 2006, at 12:40 PM, Rask Engelmann Lamberts wrote: >>>> I seem unable to get a QImode shift instruction from this code: >>>> >>>> unsigned char x; >>>> >>>> void qishifttest2 (unsigned int c) >>>> { >>>> x <<= c; >>>> } >>>> >>>> should have been generated. Also, notice the redundant zero extension. >>>> Why are we not generating a QImode shift instruction? >>> >>> Consider when c = 16. With the (required) integer promotion, the result >>> is defined (the result is zero). If converted to QImode, the shift would >>> be undefined, because the (dynamic) shift amount would be larger than the >>> data type. >> >> ??? A left shift >= the precision of its shifted unsigned operand can only >> logically result in a value of 0 regardless of its potential promotion. > > Shifting >= the size of the value being shifted can and do give nonzero > results on common hardware. Typically hardware will truncate the shift count. > eg. x << 8 implemented with a QImode shift will give x, not 0. > >> Although integer promotion as specified by C may technically be performed >> lazily as a function of the implicit target precision required for a given >> operation, GCC tends to initially promote everything and then attempt to >> determine if an operation's precision may be subsequently lowered after >> having already lost critical knowledge of its originally specified >> operand's precision. > > No. You're confusing some language you just invented with C. > > The operand of the shift operator is of type unsigned int. > "x <<= c" is exactly the same as "((int)x) << c" > It doesn't matter whether the promotion is explicit or implicit, the semantics > are the same.
((char)x) = ((char)( ((int)((char)x)) << ((int)c) ) ) :: ((char)x) = ((char)( ((char)x) << ((int)c) ) ) if the shift count ((int)x) is semantically preserved. thereby conditionally shifting left ((char)x) by ((int)c) if c is less than the smaller of it's shifted operand's or target's precision (both being char in this instance) or otherwise returning 0; is semantically equivalent and typically more efficient on smaller lightly pipelined machines without needing to literally promote the shifted operand to int width. (I believe)