edgar@portia.Stanford.EDU (Edgar Holmann) (08/23/89)
Has the left shift operator been redefined in the MIPS systems from the typical shift to a modulo type shift? By this I mean: i << j redefined to i << (j % 32) This is evident when you shift by a quantity larger than or equal to the int size (32). When j is a constant, the compiler issues a warning message (when using the optimizer level 2 or 3). Now, I see that nobody should be shifting by a constant larger than 32 but what about shifting by another variable when creating a mask? Thus, a simple statement of the form (1L << j) - 1 or ~(~0 << j) now has to have a conditional to handle the case when j is 32. I have tried this on an R3000 running Ultrix 3.1 with cc1.31. The same result is obtained in an R2000. Is this considered a "feature" of the mips compiler or is it something that will get changed in a new release? edgar
rudy@mips.COM (Rudy Wang) (08/23/89)
In article <4724@portia.Stanford.EDU> edgar@Neon.Stanford.EDU (Edgar Holmann) writes: > >Has the left shift operator been redefined in the MIPS systems from the typical >shift to a modulo type shift? By this I mean: > i << j >redefined to > i << (j % 32) >This is evident when you shift by a quantity larger than or equal to the int >size (32). When j is a constant, the compiler issues a warning message (when >using the optimizer level 2 or 3). Now, I see that nobody should be shifting >by a constant larger than 32 but what about shifting by another variable when >creating a mask? Thus, a simple statement of the form > (1L << j) - 1 >or > ~(~0 << j) >now has to have a conditional to handle the case when j is 32. I have tried >this on an R3000 running Ultrix 3.1 with cc1.31. The same result is obtained >in an R2000. > >Is this considered a "feature" of the mips compiler or is it something that >will get changed in a new release? > >edgar Please read the definition of the "shift operators" on page 189 of the 1st edition "The C programming language" (page 206 of the 2nd edition, says the same thing). When the shift amount is greater than or equal to the length of the object in bits, the result is undefined! In Mips' case, it simply chooses to shift the amount modula 32 (or just to use the lower 5 bits). Please see page A-63 of the Mips R2000 RISC architecture, by Kane. -- UUCP: {ames,decwrl,prls,pyramid}!mips!rudy (or rudy@mips.com) DDD: 408-991-0247 Rudy Wang (or 408-720-1700, Ext. 247) USPS: MIPS Computer Systems, 930 Arques, Sunnyvale, CA 94086-3650 Quote: "Time sure is fun when you're having flies!" - Kermit the frog
earl@wright.mips.com (Earl Killian) (08/23/89)
In article <4724@portia.Stanford.EDU>, edgar@portia (Edgar Holmann) writes: >Has the left shift operator been redefined in the MIPS systems from >the typical shift to a modulo type shift? By this I mean: > i << j >redefined to > i << (j % 32) The C language does not define shifts < 0 or >= the size of the type, so any program where the above statements differ is illegal. This allows compilers to generate a raw shift instruction, which is in line with C's efficiency goals. All instruction set architectures (ISAs) that I know take the shift count modulo some small power of two (e.g. 32-256). The MIPS ISA in particular takes the shift count modulo 32, which gives different results on illegal programs than say a 68000, which takes the shift count modulo 64. So the bottom line is that you need to use conditionals when your shift count is of larger range. If C shifts were defined for shifts >= size of the type, then all variable shifts would require the compiler to generate the conditional, on all architectures, and you probably wouldn't like the performance of that. -- UUCP: {ames,decwrl,prls,pyramid}!mips!earl USPS: MIPS Computer Systems, 930 Arques Ave, Sunnyvale CA, 94086
guy@auspex.auspex.com (Guy Harris) (08/24/89)
>Has the left shift operator been redefined in the MIPS systems from the typical >shift to a modulo type shift? By this I mean: > i << j >redefined to > i << (j % 32) The C language specs I've seen - both K&R I and ANSI C - indicate that the behavior of shift operators is undefined if the shift count is larger than the size of the object being shifted, in bits. Therefore, there is no redefinition involved here; the definition of the left shift operator on the MIPS systems is exactly the same as it is on other systems. Its behavior in a case where said behavior is left undefined by the standard is different from its behavior in *some* systems, but the definition allows that. Other systems behave the way the MIPS systems do. The reason for this is that the specifiers wanted to allow shift operators with a non-constant right-hand operand to be compiled into the machine's shift instructions, and different machines do different things with that count. Some take it modulo the word size, some don't. >Thus, a simple statement of the form > (1L << j) - 1 >or > ~(~0 << j) >now has to have a conditional to handle the case when j is 32. Said statement would, on systems using R[23]000 (and SPARC and 80386 and some other) chips, have to have the conditional inserted into the compiled code anyway. The question is which end users are better off having the language specify the behavior in the "shift count larger than the size of the shifted object" case, and having the compiler insert the conditional in the compiled code, or having the language not specify the behavior and obliging the user to insert the condition *in those cases where it matters* - which are not all cases. (Consider, for example, code used to maintain a "bit array"; the shift count is already going to be less than the size of the object, in bits.) The ANSI C standard isn't going to change at this late date, so if you don't like the fact that it permits the type of behavior you see on the MIPS, you'll have to lobby the vendors of all systems to which you might want to port your code to have their compilers ensure the behavior you want.