fix 64-bit left shifts with constant shifts greater than or equal to 32

The shiftLeftC function in powerpc.cpp was miscompiling such shifts,
leading to crashes due to illegal instructions and other weirdness due
to instructions that meant something completely different.  This
commit fixes that and adds a test to Longs.java to make sure it stays
fixed.
This commit is contained in:
Joel Dice 2010-07-23 10:52:58 -06:00
parent 4034a219d0
commit ddc90ef76e
2 changed files with 28 additions and 2 deletions

View File

@ -471,12 +471,14 @@ void shiftLeftC(Context* con, unsigned size, Assembler::Constant* a, Assembler::
if (sh < 32) {
emit(con, rlwinm(t->high,b->high,sh,0,31-sh));
emit(con, rlwimi(t->high,b->low,sh,32-sh,31));
emit(con, slwi(t->low, b->low, sh));
} else {
emit(con, rlwinm(t->high,b->low,sh-32,0,63-sh));
emit(con, li(t->low,0));
}
} else {
emit(con, slwi(t->low, b->low, sh));
}
emit(con, slwi(t->low, b->low, sh));
}
void shiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t)

View File

@ -3,6 +3,22 @@ public class Longs {
if (! v) throw new RuntimeException();
}
public static long readLongFrom(java.io.InputStream in)
throws java.io.IOException
{
long b1 = in.read();
long b2 = in.read();
long b3 = in.read();
long b4 = in.read();
long b5 = in.read();
long b6 = in.read();
long b7 = in.read();
long b8 = in.read();
if (b8 == -1) throw new java.io.EOFException();
return (long) ((b1 << 56) | (b2 << 48) | (b3 << 40) | (b4 << 32) |
(b5 << 24) | (b6 << 16) | (b7 << 8) | (b8));
}
public static void putInt(int val, byte[] dst, int offset) {
System.out.println("put " + val);
dst[offset] = (byte)((val >> 24) & 0xff);
@ -43,7 +59,15 @@ public class Longs {
return x >>> 32;
}
public static void main(String[] args) {
public static void main(String[] args) throws Exception {
expect(readLongFrom(new java.io.InputStream() {
int step;
public int read() {
return ++step;
}
}) == 0x0102030405060708L);
expect(((long) negativeOne()) == -1);
{ long foo = 25214903884L;