From ddc90ef76e770ba6ed6120367b52cc8f4bbe2e0f Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 23 Jul 2010 10:52:58 -0600 Subject: [PATCH] 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. --- src/powerpc.cpp | 4 +++- test/Longs.java | 26 +++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/powerpc.cpp b/src/powerpc.cpp index ac753150c9..a983f7039f 100644 --- a/src/powerpc.cpp +++ b/src/powerpc.cpp @@ -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) diff --git a/test/Longs.java b/test/Longs.java index 284a72a8ca..e868dca385 100644 --- a/test/Longs.java +++ b/test/Longs.java @@ -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;