views:

350

answers:

3

I heard that the Motorola 68000 and Intel x86 architectures handle overflow from left shifting differently. Specifically the 68k LSL vs. the Intel SAL/SHL assembly instructions.

Does anyone know the specifics of this? Do they set different flags, or set them differently? I tried to look this up in the reference manuals, but I don't see any difference. Why would one want to handle this situation differently?

Thanks!

+2  A: 

The programmer's manuals for the CPUs have the specifics:

Motorola 68K:

X — Set according to the last bit shifted out of the operand; 
    unaffected for a shift count of zero. 
N — Set if the result is negative; cleared otherwise. 
Z  — Set if the result is zero; cleared otherwise. 
V — Always cleared. 
C — Set according to the last bit shifted out of the operand; 
    cleared for a shift count of zero.

Intel x86:

  • The CF flag contains the value of the last bit shifted out of the destination operand; it is undefined for SHL and SHR instructions where the count is greater than or equal to the size (in bits) of the destination operand.
  • The OF flag is affected only for 1-bit shifts (refer to “Description” above); otherwise, it is undefined.
  • The SF, ZF, and PF flags are set according to the result. If the count is 0, the flags are not affected.
  • For a non-zero count, the AF flag is undefined.

So the overflow flag is treated differently. It'll let you know in x86 if a multiply by 2 (a single bit left shift) resulted in an overflow. I don't know why it's so specific to just 1 bit shifts. I'd guess (and it's just a guess) that the OF flag gets set according to the 'last' bit shift - and that might not indicate whether the whole operation overflowed, so Intel just documented it as 'undefined'.

Michael Burr
It's for historical reasons from back in the day when one-bit shifts and arithmetic shifts were implemented differently in the silicon. They made that specification back then, and ever since we've been stuck with it for backwards compatibility.
Crashworks
A: 

(Yes I am reviewing my Motorola 68000 Reference from 1979.)

Probably what you're thinking of is the 68000's rather strange X bit. The eXtend bit is essentially a copy of the C (carry) bit, but isn't affected by non-arithmetic instructions. Suppose you are adding 12-word integers, for example. In x86, you might see something like:

  .
  .
loop:
  ADC AX,[SI]
  ADD SI,2
  INC BX         ; BX is loop index
  CMP BX, 12     ; doh, changes carry
  JB  loop

This code doesn't work because the compare instruction mucks up the carry flag. But in 68000:

  .
  .
loop:
  ADDX.W (A0)+, D0   ; both C and X set the same
  INC.W  D7          ; D7 is loop index
  CMP.W  #12, D7     ; harms C, but X left intact
  BCC  loop

Motorola thought they were doing programmer's a favor, but the X bit business ended up causing more confusion than it was worth.

I. J. Kennedy
A: 

The X bit is not involved. The confusion over the 68000 flags arises because there are two left shift instructions:

LSL, logical shift left, clears the overflow flag. ASL, Arithmetic shift left, sets the V flag if the MSB changes sign at any time during the shift.

The x86 instruction set is not nearly as powerful. If the shift count = 1 then OF, the overflow flag, = (MSB XOR CF), i.e. if the MSB changed sign as a result of the 1-bit shift, OF = 1, else OF = 0.

If the shift count is >1 then OF is undefined.

Vince Heuring, ECEE Department, Univ. of Colo. Boulder.

Vince Heuring