From d24c9346138b7b8723461d94d9866762a59929d9 Mon Sep 17 00:00:00 2001 From: nikolay serdjuk Date: Mon, 10 Nov 2014 16:53:27 +0700 Subject: [PATCH] ART: GenNegLong incorrectly handled register overlap for x86 There is a bug in the GenNegLong: it should invoke OpRegCopy(temp_reg, rl_result.reg.GetHigh()); instead of OpRegCopy(temp_reg, rl_result.reg); But, anyway there is no need to handle the overlap anymore because it is already handled in OpRegCopyWide() which is invoked from StoreValueWide(). Change-Id: I379ed23434c72a91e875e753708387be6502bc57 Signed-off-by: nikolay serdjuk --- compiler/dex/quick/x86/int_x86.cc | 7 -- test/800-smali/expected.txt | 1 + test/800-smali/smali/negLong.smali | 186 +++++++++++++++++++++++++++++++++++++ test/800-smali/src/Main.java | 1 + 4 files changed, 188 insertions(+), 7 deletions(-) create mode 100755 test/800-smali/smali/negLong.smali diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc index 781c12807..3f501b4cd 100755 --- a/compiler/dex/quick/x86/int_x86.cc +++ b/compiler/dex/quick/x86/int_x86.cc @@ -2250,13 +2250,6 @@ void X86Mir2Lir::GenNegLong(RegLocation rl_dest, RegLocation rl_src) { OpRegReg(kOpNeg, rl_result.reg, rl_src.reg); } else { rl_result = ForceTempWide(rl_src); - if (((rl_dest.location == kLocPhysReg) && (rl_src.location == kLocPhysReg)) && - ((rl_dest.reg.GetLowReg() == rl_src.reg.GetHighReg()))) { - // The registers are the same, so we would clobber it before the use. - RegStorage temp_reg = AllocTemp(); - OpRegCopy(temp_reg, rl_result.reg); - rl_result.reg.SetHighReg(temp_reg.GetReg()); - } OpRegReg(kOpNeg, rl_result.reg.GetLow(), rl_result.reg.GetLow()); // rLow = -rLow OpRegImm(kOpAdc, rl_result.reg.GetHigh(), 0); // rHigh = rHigh + CF OpRegReg(kOpNeg, rl_result.reg.GetHigh(), rl_result.reg.GetHigh()); // rHigh = -rHigh diff --git a/test/800-smali/expected.txt b/test/800-smali/expected.txt index 4002fbf7a..3e3955b10 100644 --- a/test/800-smali/expected.txt +++ b/test/800-smali/expected.txt @@ -1,3 +1,4 @@ b/17790197 FloatBadArgReg +negLong Done! diff --git a/test/800-smali/smali/negLong.smali b/test/800-smali/smali/negLong.smali new file mode 100755 index 000000000..29d416e06 --- /dev/null +++ b/test/800-smali/smali/negLong.smali @@ -0,0 +1,186 @@ +.class public LnegLong; +.super Ljava/lang/Object; +.source "negLong.java" +# static fields +.field public static final N:I = 0x64 +.field public static i:I +# direct methods +.method static constructor ()V + .registers 1 + .prologue + .line 5 + const/16 v0, 0x44da + sput v0, LnegLong;->i:I + return-void +.end method +.method public constructor ()V + .registers 1 + .prologue + .line 1 + invoke-direct {p0}, Ljava/lang/Object;->()V + return-void +.end method +.method public static checkSum1([S)J + .registers 7 + .prologue + .line 14 + array-length v3, p0 + .line 15 + const-wide/16 v0, 0x0 + .line 16 + const/4 v2, 0x0 + :goto_4 + if-ge v2, v3, :cond_d + .line 17 + aget-short v4, p0, v2 + int-to-long v4, v4 + add-long/2addr v0, v4 + .line 16 + add-int/lit8 v2, v2, 0x1 + goto :goto_4 + .line 18 + :cond_d + return-wide v0 +.end method +.method public static init1([SS)V + .registers 4 + .prologue + .line 8 + array-length v1, p0 + .line 9 + const/4 v0, 0x0 + :goto_2 + if-ge v0, v1, :cond_9 + .line 10 + aput-short p1, p0, v0 + .line 9 + add-int/lit8 v0, v0, 0x1 + goto :goto_2 + .line 11 + :cond_9 + return-void +.end method +.method public static main([Ljava/lang/String;)V + .registers 6 + .prologue + .line 50 + invoke-static {}, LnegLong;->negLong()J + move-result-wide v0 + .line 51 + sget-object v2, Ljava/lang/System;->out:Ljava/io/PrintStream; + new-instance v3, Ljava/lang/StringBuilder; + invoke-direct {v3}, Ljava/lang/StringBuilder;->()V + const-string v4, "nbp ztw p = " + invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; + move-result-object v3 + invoke-virtual {v3, v0, v1}, Ljava/lang/StringBuilder;->append(J)Ljava/lang/StringBuilder; + move-result-object v0 + invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; + move-result-object v0 + invoke-virtual {v2, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V + .line 52 + return-void +.end method +.method public static negLong()J + .registers 17 + .prologue + .line 23 + const-wide v1, -0x4c4a1f4aa9b1db83L + .line 24 + const v7, -0x3f727efa + .line 25 + const/16 v4, -0x284b + const v3, 0xdc01 + .line 26 + const/16 v0, 0x64 + new-array v8, v0, [S + .line 28 + const/16 v0, 0x1c60 + invoke-static {v8, v0}, LnegLong;->init1([SS)V + .line 29 + const/4 v0, 0x2 + move v6, v0 + :goto_18 + const/16 v0, 0x56 + if-ge v6, v0, :cond_64 + .line 30 + const/4 v0, 0x1 + move v5, v0 + move v0, v3 + move-wide v15, v1 + move-wide v2, v15 + :goto_21 + if-ge v5, v6, :cond_5d + .line 31 + int-to-float v0, v4 + neg-float v1, v7 + add-float/2addr v0, v1 + float-to-int v1, v0 + .line 32 + const/4 v0, 0x1 + move v4, v1 + move-wide v15, v2 + move-wide v1, v15 + .line 33 + :goto_2b + add-int/lit8 v3, v0, 0x1 + const/16 v0, 0x1b + if-ge v3, v0, :cond_3a + .line 35 + int-to-long v9, v5 + mul-long v0, v9, v1 + neg-long v1, v0 + .line 38 + sget v0, LnegLong;->i:I + move v4, v0 + move v0, v3 + goto :goto_2b + .line 40 + :cond_3a + aget-short v0, v8, v6 + int-to-double v9, v0 + long-to-double v11, v1 + const-wide v13, 0x403f9851eb851eb8L + sub-double/2addr v11, v13 + add-double/2addr v9, v11 + double-to-int v0, v9 + int-to-short v0, v0 + aput-short v0, v8, v6 + .line 41 + const/4 v0, 0x2 + :goto_4a + const/16 v9, 0x43 + if-ge v0, v9, :cond_56 + .line 42 + neg-long v9, v1 + const-wide/16 v11, 0x1 + or-long/2addr v9, v11 + add-long/2addr v1, v9 + .line 41 + add-int/lit8 v0, v0, 0x1 + goto :goto_4a + .line 30 + :cond_56 + add-int/lit8 v0, v5, 0x1 + move v5, v0 + move v0, v3 + move-wide v15, v1 + move-wide v2, v15 + goto :goto_21 + .line 29 + :cond_5d + add-int/lit8 v1, v6, 0x1 + move v6, v1 + move-wide v15, v2 + move-wide v1, v15 + move v3, v0 + goto :goto_18 + .line 45 + :cond_64 + invoke-static {v8}, LnegLong;->checkSum1([S)J + move-result-wide v0 + int-to-long v2, v3 + add-long/2addr v0, v2 + .line 46 + return-wide v0 +.end method diff --git a/test/800-smali/src/Main.java b/test/800-smali/src/Main.java index c86470ce6..87549d9fd 100644 --- a/test/800-smali/src/Main.java +++ b/test/800-smali/src/Main.java @@ -51,6 +51,7 @@ public class Main { testCases.add(new TestCase("b/17790197", "B17790197", "getInt", null, null, 100)); testCases.add(new TestCase("FloatBadArgReg", "FloatBadArgReg", "getInt", new Object[]{100}, null, 100)); + testCases.add(new TestCase("negLong", "negLong", "negLong", null, null, 122142L)); } public void runTests() { -- 2.11.0